1 2 /* 3 We define the string operations here. The reason we just do not use 4 the standard string routines in the PETSc code is that on some machines 5 they are broken or have the wrong prototypes. 6 7 */ 8 #include <petscsys.h> /*I "petscsys.h" I*/ 9 #if defined(PETSC_HAVE_STRING_H) 10 #include <string.h> 11 #endif 12 #if defined(PETSC_HAVE_STRINGS_H) 13 #include <strings.h> 14 #endif 15 16 #undef __FUNCT__ 17 #define __FUNCT__ "PetscStrToArray" 18 /*@C 19 PetscStrToArray - Seperates a string by its spaces and creates an array of strings 20 21 Not Collective 22 23 Input Parameters: 24 . s - pointer to string 25 26 Output Parameter: 27 + argc - the number of entries in the array 28 - args - an array of the entries with a null at the end 29 30 Level: intermediate 31 32 Notes: this may be called before PetscInitialize() or after PetscFinalize() 33 34 Not for use in Fortran 35 36 Developer Notes: Using raw malloc() and does not call error handlers since this may be used before PETSc is initialized. Used 37 to generate argc, args arguments passed to MPI_Init() 38 39 .seealso: PetscStrToArrayDestroy(), PetscToken, PetscTokenCreate() 40 41 @*/ 42 PetscErrorCode PetscStrToArray(const char s[],int *argc,char ***args) 43 { 44 int i,n,*lens,cnt = 0; 45 PetscBool flg = PETSC_FALSE; 46 47 n = strlen(s); 48 *argc = 0; 49 for (i=0; i<n; i++) { 50 if (s[i] != ' ') break; 51 } 52 for (;i<n+1; i++) { 53 if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;} 54 else if (s[i] != ' ') {flg = PETSC_FALSE;} 55 } 56 (*args) = (char **) malloc(((*argc)+1)*sizeof(char**)); if (!*args) return PETSC_ERR_MEM; 57 lens = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM; 58 for (i=0; i<*argc; i++) lens[i] = 0; 59 60 *argc = 0; 61 for (i=0; i<n; i++) { 62 if (s[i] != ' ') break; 63 } 64 for (;i<n+1; i++) { 65 if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;} 66 else if (s[i] != ' ') {lens[*argc]++;flg = PETSC_FALSE;} 67 } 68 69 for (i=0; i<*argc; i++) { 70 (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char)); if (!(*args)[i]) return PETSC_ERR_MEM; 71 } 72 (*args)[*argc] = 0; 73 74 *argc = 0; 75 for (i=0; i<n; i++) { 76 if (s[i] != ' ') break; 77 } 78 for (;i<n+1; i++) { 79 if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;} 80 else if (s[i] != ' ' && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;} 81 } 82 return 0; 83 } 84 85 #undef __FUNCT__ 86 #define __FUNCT__ "PetscStrToArrayDestroy" 87 /*@C 88 PetscStrToArrayDestroy - Frees array created with PetscStrToArray(). 89 90 Not Collective 91 92 Output Parameters: 93 + argc - the number of arguments 94 - args - the array of arguments 95 96 Level: intermediate 97 98 Concepts: command line arguments 99 100 Notes: This may be called before PetscInitialize() or after PetscFinalize() 101 102 Not for use in Fortran 103 104 .seealso: PetscStrToArray() 105 106 @*/ 107 PetscErrorCode PetscStrToArrayDestroy(int argc,char **args) 108 { 109 PetscInt i; 110 111 for (i=0; i<argc; i++) { 112 free(args[i]); 113 } 114 free(args); 115 return 0; 116 } 117 118 #undef __FUNCT__ 119 #define __FUNCT__ "PetscStrlen" 120 /*@C 121 PetscStrlen - Gets length of a string 122 123 Not Collective 124 125 Input Parameters: 126 . s - pointer to string 127 128 Output Parameter: 129 . len - length in bytes 130 131 Level: intermediate 132 133 Note: 134 This routine is analogous to strlen(). 135 136 Null string returns a length of zero 137 138 Not for use in Fortran 139 140 Concepts: string length 141 142 @*/ 143 PetscErrorCode PetscStrlen(const char s[],size_t *len) 144 { 145 PetscFunctionBegin; 146 if (!s) { 147 *len = 0; 148 } else { 149 *len = strlen(s); 150 } 151 PetscFunctionReturn(0); 152 } 153 154 #undef __FUNCT__ 155 #define __FUNCT__ "PetscStrallocpy" 156 /*@C 157 PetscStrallocpy - Allocates space to hold a copy of a string then copies the string 158 159 Not Collective 160 161 Input Parameters: 162 . s - pointer to string 163 164 Output Parameter: 165 . t - the copied string 166 167 Level: intermediate 168 169 Note: 170 Null string returns a new null string 171 172 Not for use in Fortran 173 174 Concepts: string copy 175 176 @*/ 177 PetscErrorCode PetscStrallocpy(const char s[],char *t[]) 178 { 179 PetscErrorCode ierr; 180 size_t len; 181 char *tmp = 0; 182 183 PetscFunctionBegin; 184 if (s) { 185 ierr = PetscStrlen(s,&len);CHKERRQ(ierr); 186 ierr = PetscMalloc((1+len)*sizeof(char),&tmp);CHKERRQ(ierr); 187 ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr); 188 } 189 *t = tmp; 190 PetscFunctionReturn(0); 191 } 192 193 #undef __FUNCT__ 194 #define __FUNCT__ "PetscStrArrayallocpy" 195 /*@C 196 PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings 197 198 Not Collective 199 200 Input Parameters: 201 . s - pointer to array of strings (final string is a null) 202 203 Output Parameter: 204 . t - the copied array string 205 206 Level: intermediate 207 208 Note: 209 Not for use in Fortran 210 211 Concepts: string copy 212 213 .seealso: PetscStrallocpy() PetscStrArrayDestroy() 214 215 @*/ 216 PetscErrorCode PetscStrArrayallocpy(const char *const*list,char ***t) 217 { 218 PetscErrorCode ierr; 219 PetscInt i,n = 0; 220 221 PetscFunctionBegin; 222 while (list[n++]) ; 223 ierr = PetscMalloc((n+1)*sizeof(char**),t);CHKERRQ(ierr); 224 for (i=0; i<n; i++) { 225 ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr); 226 } 227 (*t)[n] = PETSC_NULL; 228 PetscFunctionReturn(0); 229 } 230 231 #undef __FUNCT__ 232 #define __FUNCT__ "PetscStrArrayDestroy" 233 /*@C 234 PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy(). 235 236 Not Collective 237 238 Output Parameters: 239 . list - array of strings 240 241 Level: intermediate 242 243 Concepts: command line arguments 244 245 Notes: Not for use in Fortran 246 247 .seealso: PetscStrArrayallocpy() 248 249 @*/ 250 PetscErrorCode PetscStrArrayDestroy(char ***list) 251 { 252 PetscInt n = 0; 253 PetscErrorCode ierr; 254 255 PetscFunctionBegin; 256 if (!*list) PetscFunctionReturn(0); 257 while ((*list)[n]) { 258 ierr = PetscFree((*list)[n]);CHKERRQ(ierr); 259 n++; 260 } 261 ierr = PetscFree(*list);CHKERRQ(ierr); 262 PetscFunctionReturn(0); 263 } 264 265 #undef __FUNCT__ 266 #define __FUNCT__ "PetscStrcpy" 267 /*@C 268 PetscStrcpy - Copies a string 269 270 Not Collective 271 272 Input Parameters: 273 . t - pointer to string 274 275 Output Parameter: 276 . s - the copied string 277 278 Level: intermediate 279 280 Notes: 281 Null string returns a string starting with zero 282 283 Not for use in Fortran 284 285 Concepts: string copy 286 287 .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat() 288 289 @*/ 290 291 PetscErrorCode PetscStrcpy(char s[],const char t[]) 292 { 293 PetscFunctionBegin; 294 if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer"); 295 if (t) {strcpy(s,t);} 296 else if (s) {s[0] = 0;} 297 PetscFunctionReturn(0); 298 } 299 300 #undef __FUNCT__ 301 #define __FUNCT__ "PetscStrncpy" 302 /*@C 303 PetscStrncpy - Copies a string up to a certain length 304 305 Not Collective 306 307 Input Parameters: 308 + t - pointer to string 309 - n - the length to copy 310 311 Output Parameter: 312 . s - the copied string 313 314 Level: intermediate 315 316 Note: 317 Null string returns a string starting with zero 318 319 Concepts: string copy 320 321 .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat() 322 323 @*/ 324 PetscErrorCode PetscStrncpy(char s[],const char t[],size_t n) 325 { 326 PetscFunctionBegin; 327 if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer"); 328 if (t) {strncpy(s,t,n);} 329 else if (s) {s[0] = 0;} 330 PetscFunctionReturn(0); 331 } 332 333 #undef __FUNCT__ 334 #define __FUNCT__ "PetscStrcat" 335 /*@C 336 PetscStrcat - Concatenates a string onto a given string 337 338 Not Collective 339 340 Input Parameters: 341 + s - string to be added to 342 - t - pointer to string to be added to end 343 344 Level: intermediate 345 346 Notes: Not for use in Fortran 347 348 Concepts: string copy 349 350 .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat() 351 352 @*/ 353 PetscErrorCode PetscStrcat(char s[],const char t[]) 354 { 355 PetscFunctionBegin; 356 if (!t) PetscFunctionReturn(0); 357 strcat(s,t); 358 PetscFunctionReturn(0); 359 } 360 361 #undef __FUNCT__ 362 #define __FUNCT__ "PetscStrncat" 363 /*@C 364 PetscStrncat - Concatenates a string onto a given string, up to a given length 365 366 Not Collective 367 368 Input Parameters: 369 + s - pointer to string to be added to end 370 . t - string to be added to 371 . n - maximum length to copy 372 373 Level: intermediate 374 375 Notes: Not for use in Fortran 376 377 Concepts: string copy 378 379 .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat() 380 381 @*/ 382 PetscErrorCode PetscStrncat(char s[],const char t[],size_t n) 383 { 384 PetscFunctionBegin; 385 strncat(s,t,n); 386 PetscFunctionReturn(0); 387 } 388 389 #undef __FUNCT__ 390 #define __FUNCT__ "PetscStrcmp" 391 /*@C 392 PetscStrcmp - Compares two strings, 393 394 Not Collective 395 396 Input Parameters: 397 + a - pointer to string first string 398 - b - pointer to second string 399 400 Output Parameter: 401 . flg - PETSC_TRUE if the two strings are equal 402 403 Level: intermediate 404 405 Notes: Not for use in Fortran 406 407 .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp() 408 409 @*/ 410 PetscErrorCode PetscStrcmp(const char a[],const char b[],PetscBool *flg) 411 { 412 int c; 413 414 PetscFunctionBegin; 415 if (!a && !b) { 416 *flg = PETSC_TRUE; 417 } else if (!a || !b) { 418 *flg = PETSC_FALSE; 419 } else { 420 c = strcmp(a,b); 421 if (c) *flg = PETSC_FALSE; 422 else *flg = PETSC_TRUE; 423 } 424 PetscFunctionReturn(0); 425 } 426 427 #undef __FUNCT__ 428 #define __FUNCT__ "PetscStrgrt" 429 /*@C 430 PetscStrgrt - If first string is greater than the second 431 432 Not Collective 433 434 Input Parameters: 435 + a - pointer to first string 436 - b - pointer to second string 437 438 Output Parameter: 439 . flg - if the first string is greater 440 441 Notes: 442 Null arguments are ok, a null string is considered smaller than 443 all others 444 445 Not for use in Fortran 446 447 Level: intermediate 448 449 .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp() 450 451 @*/ 452 PetscErrorCode PetscStrgrt(const char a[],const char b[],PetscBool *t) 453 { 454 int c; 455 456 PetscFunctionBegin; 457 if (!a && !b) { 458 *t = PETSC_FALSE; 459 } else if (a && !b) { 460 *t = PETSC_TRUE; 461 } else if (!a && b) { 462 *t = PETSC_FALSE; 463 } else { 464 c = strcmp(a,b); 465 if (c > 0) *t = PETSC_TRUE; 466 else *t = PETSC_FALSE; 467 } 468 PetscFunctionReturn(0); 469 } 470 471 #undef __FUNCT__ 472 #define __FUNCT__ "PetscStrcasecmp" 473 /*@C 474 PetscStrcasecmp - Returns true if the two strings are the same 475 except possibly for case. 476 477 Not Collective 478 479 Input Parameters: 480 + a - pointer to first string 481 - b - pointer to second string 482 483 Output Parameter: 484 . flg - if the two strings are the same 485 486 Notes: 487 Null arguments are ok 488 489 Not for use in Fortran 490 491 Level: intermediate 492 493 .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt() 494 495 @*/ 496 PetscErrorCode PetscStrcasecmp(const char a[],const char b[],PetscBool *t) 497 { 498 int c; 499 500 PetscFunctionBegin; 501 if (!a && !b) c = 0; 502 else if (!a || !b) c = 1; 503 #if defined(PETSC_HAVE_STRCASECMP) 504 else c = strcasecmp(a,b); 505 #elif defined(PETSC_HAVE_STRICMP) 506 else c = stricmp(a,b); 507 #else 508 else { 509 char *aa,*bb; 510 PetscErrorCode ierr; 511 ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr); 512 ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr); 513 ierr = PetscStrtolower(aa);CHKERRQ(ierr); 514 ierr = PetscStrtolower(bb);CHKERRQ(ierr); 515 ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr); 516 ierr = PetscFree(aa);CHKERRQ(ierr); 517 ierr = PetscFree(bb);CHKERRQ(ierr); 518 PetscFunctionReturn(0); 519 } 520 #endif 521 if (!c) *t = PETSC_TRUE; 522 else *t = PETSC_FALSE; 523 PetscFunctionReturn(0); 524 } 525 526 527 528 #undef __FUNCT__ 529 #define __FUNCT__ "PetscStrncmp" 530 /*@C 531 PetscStrncmp - Compares two strings, up to a certain length 532 533 Not Collective 534 535 Input Parameters: 536 + a - pointer to first string 537 . b - pointer to second string 538 - n - length to compare up to 539 540 Output Parameter: 541 . t - if the two strings are equal 542 543 Level: intermediate 544 545 Notes: Not for use in Fortran 546 547 .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp() 548 549 @*/ 550 PetscErrorCode PetscStrncmp(const char a[],const char b[],size_t n,PetscBool *t) 551 { 552 int c; 553 554 PetscFunctionBegin; 555 c = strncmp(a,b,n); 556 if (!c) *t = PETSC_TRUE; 557 else *t = PETSC_FALSE; 558 PetscFunctionReturn(0); 559 } 560 561 #undef __FUNCT__ 562 #define __FUNCT__ "PetscStrchr" 563 /*@C 564 PetscStrchr - Locates first occurance of a character in a string 565 566 Not Collective 567 568 Input Parameters: 569 + a - pointer to string 570 - b - character 571 572 Output Parameter: 573 . c - location of occurance, PETSC_NULL if not found 574 575 Level: intermediate 576 577 Notes: Not for use in Fortran 578 579 @*/ 580 PetscErrorCode PetscStrchr(const char a[],char b,char *c[]) 581 { 582 PetscFunctionBegin; 583 *c = (char *)strchr(a,b); 584 PetscFunctionReturn(0); 585 } 586 587 #undef __FUNCT__ 588 #define __FUNCT__ "PetscStrrchr" 589 /*@C 590 PetscStrrchr - Locates one location past the last occurance of a character in a string, 591 if the character is not found then returns entire string 592 593 Not Collective 594 595 Input Parameters: 596 + a - pointer to string 597 - b - character 598 599 Output Parameter: 600 . tmp - location of occurance, a if not found 601 602 Level: intermediate 603 604 Notes: Not for use in Fortran 605 606 @*/ 607 PetscErrorCode PetscStrrchr(const char a[],char b,char *tmp[]) 608 { 609 PetscFunctionBegin; 610 *tmp = (char *)strrchr(a,b); 611 if (!*tmp) *tmp = (char*)a; else *tmp = *tmp + 1; 612 PetscFunctionReturn(0); 613 } 614 615 #undef __FUNCT__ 616 #define __FUNCT__ "PetscStrtolower" 617 /*@C 618 PetscStrtolower - Converts string to lower case 619 620 Not Collective 621 622 Input Parameters: 623 . a - pointer to string 624 625 Level: intermediate 626 627 Notes: Not for use in Fortran 628 629 @*/ 630 PetscErrorCode PetscStrtolower(char a[]) 631 { 632 PetscFunctionBegin; 633 while (*a) { 634 if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A'; 635 a++; 636 } 637 PetscFunctionReturn(0); 638 } 639 640 #undef __FUNCT__ 641 #define __FUNCT__ "PetscStrendswith" 642 /*@C 643 PetscStrendswith - Determines if a string ends with a certain string 644 645 Not Collective 646 647 Input Parameters: 648 + a - pointer to string 649 - b - string to endwith 650 651 Output Parameter: 652 . flg - PETSC_TRUE or PETSC_FALSE 653 654 Notes: Not for use in Fortran 655 656 Level: intermediate 657 658 @*/ 659 PetscErrorCode PetscStrendswith(const char a[],const char b[],PetscBool *flg) 660 { 661 char *test; 662 PetscErrorCode ierr; 663 size_t na,nb; 664 665 PetscFunctionBegin; 666 *flg = PETSC_FALSE; 667 ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr); 668 if (test) { 669 ierr = PetscStrlen(a,&na);CHKERRQ(ierr); 670 ierr = PetscStrlen(b,&nb);CHKERRQ(ierr); 671 if (a+na-nb == test) *flg = PETSC_TRUE; 672 } 673 PetscFunctionReturn(0); 674 } 675 676 #undef __FUNCT__ 677 #define __FUNCT__ "PetscStrendswithwhich" 678 /*@C 679 PetscStrendswithwhich - Determines if a string ends with one of several possible strings 680 681 Not Collective 682 683 Input Parameters: 684 + a - pointer to string 685 - bs - strings to endwith (last entry must be null) 686 687 Output Parameter: 688 . cnt - the index of the string it ends with or 1+the last possible index 689 690 Notes: Not for use in Fortran 691 692 Level: intermediate 693 694 @*/ 695 PetscErrorCode PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt) 696 { 697 PetscBool flg; 698 PetscErrorCode ierr; 699 700 PetscFunctionBegin; 701 *cnt = 0; 702 while (bs[*cnt]) { 703 ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr); 704 if (flg) PetscFunctionReturn(0); 705 *cnt += 1; 706 } 707 PetscFunctionReturn(0); 708 } 709 710 #undef __FUNCT__ 711 #define __FUNCT__ "PetscStrrstr" 712 /*@C 713 PetscStrrstr - Locates last occurance of string in another string 714 715 Not Collective 716 717 Input Parameters: 718 + a - pointer to string 719 - b - string to find 720 721 Output Parameter: 722 . tmp - location of occurance 723 724 Notes: Not for use in Fortran 725 726 Level: intermediate 727 728 @*/ 729 PetscErrorCode PetscStrrstr(const char a[],const char b[],char *tmp[]) 730 { 731 const char *stmp = a, *ltmp = 0; 732 733 PetscFunctionBegin; 734 while (stmp) { 735 stmp = (char *)strstr(stmp,b); 736 if (stmp) {ltmp = stmp;stmp++;} 737 } 738 *tmp = (char *)ltmp; 739 PetscFunctionReturn(0); 740 } 741 742 #undef __FUNCT__ 743 #define __FUNCT__ "PetscStrstr" 744 /*@C 745 PetscStrstr - Locates first occurance of string in another string 746 747 Not Collective 748 749 Input Parameters: 750 + haystack - string to search 751 - needle - string to find 752 753 Output Parameter: 754 . tmp - location of occurance, is a PETSC_NULL if the string is not found 755 756 Notes: Not for use in Fortran 757 758 Level: intermediate 759 760 @*/ 761 PetscErrorCode PetscStrstr(const char haystack[],const char needle[],char *tmp[]) 762 { 763 PetscFunctionBegin; 764 *tmp = (char *)strstr(haystack,needle); 765 PetscFunctionReturn(0); 766 } 767 768 struct _p_PetscToken {char token;char *array;char *current;}; 769 770 #undef __FUNCT__ 771 #define __FUNCT__ "PetscTokenFind" 772 /*@C 773 PetscTokenFind - Locates next "token" in a string 774 775 Not Collective 776 777 Input Parameters: 778 . a - pointer to token 779 780 Output Parameter: 781 . result - location of occurance, PETSC_NULL if not found 782 783 Notes: 784 785 This version is different from the system version in that 786 it allows you to pass a read-only string into the function. 787 788 This version also treats all characters etc. inside a double quote " 789 as a single token. 790 791 Not for use in Fortran 792 793 Level: intermediate 794 795 796 .seealso: PetscTokenCreate(), PetscTokenDestroy() 797 @*/ 798 PetscErrorCode PetscTokenFind(PetscToken a,char *result[]) 799 { 800 char *ptr = a->current,token; 801 802 PetscFunctionBegin; 803 *result = a->current; 804 if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);} 805 token = a->token; 806 if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;} 807 while (ptr) { 808 if (*ptr == token) { 809 *ptr++ = 0; 810 while (*ptr == a->token) ptr++; 811 a->current = ptr; 812 break; 813 } 814 if (!*ptr) { 815 a->current = 0; 816 break; 817 } 818 ptr++; 819 } 820 PetscFunctionReturn(0); 821 } 822 823 #undef __FUNCT__ 824 #define __FUNCT__ "PetscTokenCreate" 825 /*@C 826 PetscTokenCreate - Creates a PetscToken used to find tokens in a string 827 828 Not Collective 829 830 Input Parameters: 831 + string - the string to look in 832 - token - the character to look for 833 834 Output Parameter: 835 . a - pointer to token 836 837 Notes: 838 839 This version is different from the system version in that 840 it allows you to pass a read-only string into the function. 841 842 Not for use in Fortran 843 844 Level: intermediate 845 846 .seealso: PetscTokenFind(), PetscTokenDestroy() 847 @*/ 848 PetscErrorCode PetscTokenCreate(const char a[],const char b,PetscToken *t) 849 { 850 PetscErrorCode ierr; 851 852 PetscFunctionBegin; 853 ierr = PetscNew(struct _p_PetscToken,t);CHKERRQ(ierr); 854 ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr); 855 (*t)->current = (*t)->array; 856 (*t)->token = b; 857 PetscFunctionReturn(0); 858 } 859 860 #undef __FUNCT__ 861 #define __FUNCT__ "PetscTokenDestroy" 862 /*@C 863 PetscTokenDestroy - Destroys a PetscToken 864 865 Not Collective 866 867 Input Parameters: 868 . a - pointer to token 869 870 Level: intermediate 871 872 Notes: Not for use in Fortran 873 874 .seealso: PetscTokenCreate(), PetscTokenFind() 875 @*/ 876 PetscErrorCode PetscTokenDestroy(PetscToken *a) 877 { 878 PetscErrorCode ierr; 879 880 PetscFunctionBegin; 881 if (!*a) PetscFunctionReturn(0); 882 ierr = PetscFree((*a)->array);CHKERRQ(ierr); 883 ierr = PetscFree(*a);CHKERRQ(ierr); 884 PetscFunctionReturn(0); 885 } 886 887 888 #undef __FUNCT__ 889 #define __FUNCT__ "PetscGetPetscDir" 890 /*@C 891 PetscGetPetscDir - Gets the directory PETSc is installed in 892 893 Not Collective 894 895 Output Parameter: 896 . dir - the directory 897 898 Level: developer 899 900 Notes: Not for use in Fortran 901 902 @*/ 903 PetscErrorCode PetscGetPetscDir(const char *dir[]) 904 { 905 PetscFunctionBegin; 906 *dir = PETSC_DIR; 907 PetscFunctionReturn(0); 908 } 909 910 #undef __FUNCT__ 911 #define __FUNCT__ "PetscStrreplace" 912 /*@C 913 PetscStrreplace - Replaces substrings in string with other substrings 914 915 Not Collective 916 917 Input Parameters: 918 + comm - MPI_Comm of processors that are processing the string 919 . aa - the string to look in 920 . b - the resulting copy of a with replaced strings (b can be the same as a) 921 - len - the length of b 922 923 Notes: 924 Replaces ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY}, 925 ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values 926 as well as any environmental variables. 927 928 PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what 929 PETSc was built with and do not use environmental variables. 930 931 Not for use in Fortran 932 933 Level: intermediate 934 935 @*/ 936 PetscErrorCode PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len) 937 { 938 PetscErrorCode ierr; 939 int i = 0; 940 size_t l,l1,l2,l3; 941 char *work,*par,*epar,env[1024],*tfree,*a = (char*)aa; 942 const char *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0}; 943 const char *r[] = {0,0,0,0,0,0,0,0,0}; 944 PetscBool flag; 945 946 PetscFunctionBegin; 947 if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull"); 948 if (aa == b) { 949 ierr = PetscStrallocpy(aa,(char **)&a);CHKERRQ(ierr); 950 } 951 ierr = PetscMalloc(len*sizeof(char*),&work);CHKERRQ(ierr); 952 953 /* get values for replaced variables */ 954 ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr); 955 ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr); 956 ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr); 957 ierr = PetscMalloc(256*sizeof(char),&r[3]);CHKERRQ(ierr); 958 ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[4]);CHKERRQ(ierr); 959 ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[5]);CHKERRQ(ierr); 960 ierr = PetscMalloc(256*sizeof(char),&r[6]);CHKERRQ(ierr); 961 ierr = PetscMalloc(256*sizeof(char),&r[7]);CHKERRQ(ierr); 962 ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr); 963 ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 964 ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 965 ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr); 966 ierr = PetscGetHostName((char*)r[7],256);CHKERRQ(ierr); 967 968 /* replace that are in environment */ 969 ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr); 970 if (flag) { 971 ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr); 972 } 973 974 /* replace the requested strings */ 975 ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr); 976 while (s[i]) { 977 ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr); 978 ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr); 979 while (par) { 980 *par = 0; 981 par += l; 982 983 ierr = PetscStrlen(b,&l1);CHKERRQ(ierr); 984 ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr); 985 ierr = PetscStrlen(par,&l3);CHKERRQ(ierr); 986 if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values"); 987 ierr = PetscStrcpy(work,b);CHKERRQ(ierr); 988 ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr); 989 ierr = PetscStrcat(work,par);CHKERRQ(ierr); 990 ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr); 991 ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr); 992 } 993 i++; 994 } 995 i = 0; 996 while (r[i]) { 997 tfree = (char*)r[i]; 998 ierr = PetscFree(tfree);CHKERRQ(ierr); 999 i++; 1000 } 1001 1002 /* look for any other ${xxx} strings to replace from environmental variables */ 1003 ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr); 1004 while (par) { 1005 *par = 0; 1006 par += 2; 1007 ierr = PetscStrcpy(work,b);CHKERRQ(ierr); 1008 ierr = PetscStrstr(par,"}",&epar);CHKERRQ(ierr); 1009 *epar = 0; 1010 epar += 1; 1011 ierr = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr); 1012 if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par); 1013 ierr = PetscStrcat(work,env);CHKERRQ(ierr); 1014 ierr = PetscStrcat(work,epar);CHKERRQ(ierr); 1015 ierr = PetscStrcpy(b,work);CHKERRQ(ierr); 1016 ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr); 1017 } 1018 ierr = PetscFree(work);CHKERRQ(ierr); 1019 if (aa == b) { 1020 ierr = PetscFree(a);CHKERRQ(ierr); 1021 } 1022 PetscFunctionReturn(0); 1023 } 1024 1025 1026