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