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 10 #if defined(PETSC_HAVE_STRINGS_H) 11 # include <strings.h> /* strcasecmp */ 12 #endif 13 14 #undef __FUNCT__ 15 #define __FUNCT__ "PetscStrToArray" 16 /*@C 17 PetscStrToArray - Seperates a string by a charactor (for example ' ' or '\n') and creates an array of strings 18 19 Not Collective 20 21 Input Parameters: 22 + s - pointer to string 23 - sp - separator charactor 24 25 Output Parameter: 26 + argc - the number of entries in the array 27 - args - an array of the entries with a null at the end 28 29 Level: intermediate 30 31 Notes: this may be called before PetscInitialize() or after PetscFinalize() 32 33 Not for use in Fortran 34 35 Developer Notes: Using raw malloc() and does not call error handlers since this may be used before PETSc is initialized. Used 36 to generate argc, args arguments passed to MPI_Init() 37 38 .seealso: PetscStrToArrayDestroy(), PetscToken, PetscTokenCreate() 39 40 @*/ 41 PetscErrorCode PetscStrToArray(const char s[],char sp,int *argc,char ***args) 42 { 43 int i,n,*lens,cnt = 0; 44 PetscBool flg = PETSC_FALSE; 45 46 if (!s) n = 0; 47 else n = strlen(s); 48 *argc = 0; 49 if (!n) { 50 *args = 0; 51 return(0); 52 } 53 for (i=0; i<n; i++) { 54 if (s[i] != sp) break; 55 } 56 for (;i<n+1; i++) { 57 if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;} 58 else if (s[i] != sp) {flg = PETSC_FALSE;} 59 } 60 (*args) = (char**) malloc(((*argc)+1)*sizeof(char*)); if (!*args) return PETSC_ERR_MEM; 61 lens = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM; 62 for (i=0; i<*argc; i++) lens[i] = 0; 63 64 *argc = 0; 65 for (i=0; i<n; i++) { 66 if (s[i] != sp) break; 67 } 68 for (;i<n+1; i++) { 69 if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;} 70 else if (s[i] != sp) {lens[*argc]++;flg = PETSC_FALSE;} 71 } 72 73 for (i=0; i<*argc; i++) { 74 (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char)); if (!(*args)[i]) return PETSC_ERR_MEM; 75 } 76 free(lens); 77 (*args)[*argc] = 0; 78 79 *argc = 0; 80 for (i=0; i<n; i++) { 81 if (s[i] != sp) break; 82 } 83 for (;i<n+1; i++) { 84 if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;} 85 else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;} 86 } 87 return 0; 88 } 89 90 #undef __FUNCT__ 91 #define __FUNCT__ "PetscStrToArrayDestroy" 92 /*@C 93 PetscStrToArrayDestroy - Frees array created with PetscStrToArray(). 94 95 Not Collective 96 97 Output Parameters: 98 + argc - the number of arguments 99 - args - the array of arguments 100 101 Level: intermediate 102 103 Concepts: command line arguments 104 105 Notes: This may be called before PetscInitialize() or after PetscFinalize() 106 107 Not for use in Fortran 108 109 .seealso: PetscStrToArray() 110 111 @*/ 112 PetscErrorCode PetscStrToArrayDestroy(int argc,char **args) 113 { 114 PetscInt i; 115 116 for (i=0; i<argc; i++) free(args[i]); 117 if (args) free(args); 118 return 0; 119 } 120 121 #undef __FUNCT__ 122 #define __FUNCT__ "PetscStrlen" 123 /*@C 124 PetscStrlen - Gets length of a string 125 126 Not Collective 127 128 Input Parameters: 129 . s - pointer to string 130 131 Output Parameter: 132 . len - length in bytes 133 134 Level: intermediate 135 136 Note: 137 This routine is analogous to strlen(). 138 139 Null string returns a length of zero 140 141 Not for use in Fortran 142 143 Concepts: string length 144 145 @*/ 146 PetscErrorCode PetscStrlen(const char s[],size_t *len) 147 { 148 PetscFunctionBegin; 149 if (!s) *len = 0; 150 else *len = strlen(s); 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] = 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__ "PetscStrcmpNoError" 391 /* 392 Only to be used with PetscCheck__FUNCT__()! 393 394 Will be removed once we eliminate the __FUNCT__ paradigm 395 */ 396 void PetscStrcmpNoError(const char a[],const char b[],PetscBool *flg) 397 { 398 int c; 399 400 if (!a && !b) *flg = PETSC_TRUE; 401 else if (!a || !b) *flg = PETSC_FALSE; 402 else { 403 c = strcmp(a,b); 404 if (c) *flg = PETSC_FALSE; 405 else *flg = PETSC_TRUE; 406 } 407 } 408 409 #undef __FUNCT__ 410 #define __FUNCT__ "PetscStrcmp" 411 /*@C 412 PetscStrcmp - Compares two strings, 413 414 Not Collective 415 416 Input Parameters: 417 + a - pointer to string first string 418 - b - pointer to second string 419 420 Output Parameter: 421 . flg - PETSC_TRUE if the two strings are equal 422 423 Level: intermediate 424 425 Notes: Not for use in Fortran 426 427 .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp() 428 429 @*/ 430 PetscErrorCode PetscStrcmp(const char a[],const char b[],PetscBool *flg) 431 { 432 int c; 433 434 PetscFunctionBegin; 435 if (!a && !b) *flg = PETSC_TRUE; 436 else if (!a || !b) *flg = PETSC_FALSE; 437 else { 438 c = strcmp(a,b); 439 if (c) *flg = PETSC_FALSE; 440 else *flg = PETSC_TRUE; 441 } 442 PetscFunctionReturn(0); 443 } 444 445 #undef __FUNCT__ 446 #define __FUNCT__ "PetscStrgrt" 447 /*@C 448 PetscStrgrt - If first string is greater than the second 449 450 Not Collective 451 452 Input Parameters: 453 + a - pointer to first string 454 - b - pointer to second string 455 456 Output Parameter: 457 . flg - if the first string is greater 458 459 Notes: 460 Null arguments are ok, a null string is considered smaller than 461 all others 462 463 Not for use in Fortran 464 465 Level: intermediate 466 467 .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp() 468 469 @*/ 470 PetscErrorCode PetscStrgrt(const char a[],const char b[],PetscBool *t) 471 { 472 int c; 473 474 PetscFunctionBegin; 475 if (!a && !b) *t = PETSC_FALSE; 476 else if (a && !b) *t = PETSC_TRUE; 477 else if (!a && b) *t = PETSC_FALSE; 478 else { 479 c = strcmp(a,b); 480 if (c > 0) *t = PETSC_TRUE; 481 else *t = PETSC_FALSE; 482 } 483 PetscFunctionReturn(0); 484 } 485 486 #undef __FUNCT__ 487 #define __FUNCT__ "PetscStrcasecmp" 488 /*@C 489 PetscStrcasecmp - Returns true if the two strings are the same 490 except possibly for case. 491 492 Not Collective 493 494 Input Parameters: 495 + a - pointer to first string 496 - b - pointer to second string 497 498 Output Parameter: 499 . flg - if the two strings are the same 500 501 Notes: 502 Null arguments are ok 503 504 Not for use in Fortran 505 506 Level: intermediate 507 508 .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt() 509 510 @*/ 511 PetscErrorCode PetscStrcasecmp(const char a[],const char b[],PetscBool *t) 512 { 513 int c; 514 515 PetscFunctionBegin; 516 if (!a && !b) c = 0; 517 else if (!a || !b) c = 1; 518 #if defined(PETSC_HAVE_STRCASECMP) 519 else c = strcasecmp(a,b); 520 #elif defined(PETSC_HAVE_STRICMP) 521 else c = stricmp(a,b); 522 #else 523 else { 524 char *aa,*bb; 525 PetscErrorCode ierr; 526 ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr); 527 ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr); 528 ierr = PetscStrtolower(aa);CHKERRQ(ierr); 529 ierr = PetscStrtolower(bb);CHKERRQ(ierr); 530 ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr); 531 ierr = PetscFree(aa);CHKERRQ(ierr); 532 ierr = PetscFree(bb);CHKERRQ(ierr); 533 PetscFunctionReturn(0); 534 } 535 #endif 536 if (!c) *t = PETSC_TRUE; 537 else *t = PETSC_FALSE; 538 PetscFunctionReturn(0); 539 } 540 541 542 543 #undef __FUNCT__ 544 #define __FUNCT__ "PetscStrncmp" 545 /*@C 546 PetscStrncmp - Compares two strings, up to a certain length 547 548 Not Collective 549 550 Input Parameters: 551 + a - pointer to first string 552 . b - pointer to second string 553 - n - length to compare up to 554 555 Output Parameter: 556 . t - if the two strings are equal 557 558 Level: intermediate 559 560 Notes: Not for use in Fortran 561 562 .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp() 563 564 @*/ 565 PetscErrorCode PetscStrncmp(const char a[],const char b[],size_t n,PetscBool *t) 566 { 567 int c; 568 569 PetscFunctionBegin; 570 c = strncmp(a,b,n); 571 if (!c) *t = PETSC_TRUE; 572 else *t = PETSC_FALSE; 573 PetscFunctionReturn(0); 574 } 575 576 #undef __FUNCT__ 577 #define __FUNCT__ "PetscStrchr" 578 /*@C 579 PetscStrchr - Locates first occurance of a character in a string 580 581 Not Collective 582 583 Input Parameters: 584 + a - pointer to string 585 - b - character 586 587 Output Parameter: 588 . c - location of occurance, NULL if not found 589 590 Level: intermediate 591 592 Notes: Not for use in Fortran 593 594 @*/ 595 PetscErrorCode PetscStrchr(const char a[],char b,char *c[]) 596 { 597 PetscFunctionBegin; 598 *c = (char*)strchr(a,b); 599 PetscFunctionReturn(0); 600 } 601 602 #undef __FUNCT__ 603 #define __FUNCT__ "PetscStrrchr" 604 /*@C 605 PetscStrrchr - Locates one location past the last occurance of a character in a string, 606 if the character is not found then returns entire string 607 608 Not Collective 609 610 Input Parameters: 611 + a - pointer to string 612 - b - character 613 614 Output Parameter: 615 . tmp - location of occurance, a if not found 616 617 Level: intermediate 618 619 Notes: Not for use in Fortran 620 621 @*/ 622 PetscErrorCode PetscStrrchr(const char a[],char b,char *tmp[]) 623 { 624 PetscFunctionBegin; 625 *tmp = (char*)strrchr(a,b); 626 if (!*tmp) *tmp = (char*)a; 627 else *tmp = *tmp + 1; 628 PetscFunctionReturn(0); 629 } 630 631 #undef __FUNCT__ 632 #define __FUNCT__ "PetscStrtolower" 633 /*@C 634 PetscStrtolower - Converts string to lower case 635 636 Not Collective 637 638 Input Parameters: 639 . a - pointer to string 640 641 Level: intermediate 642 643 Notes: Not for use in Fortran 644 645 @*/ 646 PetscErrorCode PetscStrtolower(char a[]) 647 { 648 PetscFunctionBegin; 649 while (*a) { 650 if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A'; 651 a++; 652 } 653 PetscFunctionReturn(0); 654 } 655 656 #undef __FUNCT__ 657 #define __FUNCT__ "PetscStrtoupper" 658 /*@C 659 PetscStrtolower - Converts string to upper case 660 661 Not Collective 662 663 Input Parameters: 664 . a - pointer to string 665 666 Level: intermediate 667 668 Notes: Not for use in Fortran 669 670 @*/ 671 PetscErrorCode PetscStrtoupper(char a[]) 672 { 673 PetscFunctionBegin; 674 while (*a) { 675 if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a'; 676 a++; 677 } 678 PetscFunctionReturn(0); 679 } 680 681 #undef __FUNCT__ 682 #define __FUNCT__ "PetscStrendswith" 683 /*@C 684 PetscStrendswith - Determines if a string ends with a certain string 685 686 Not Collective 687 688 Input Parameters: 689 + a - pointer to string 690 - b - string to endwith 691 692 Output Parameter: 693 . flg - PETSC_TRUE or PETSC_FALSE 694 695 Notes: Not for use in Fortran 696 697 Level: intermediate 698 699 @*/ 700 PetscErrorCode PetscStrendswith(const char a[],const char b[],PetscBool *flg) 701 { 702 char *test; 703 PetscErrorCode ierr; 704 size_t na,nb; 705 706 PetscFunctionBegin; 707 *flg = PETSC_FALSE; 708 ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr); 709 if (test) { 710 ierr = PetscStrlen(a,&na);CHKERRQ(ierr); 711 ierr = PetscStrlen(b,&nb);CHKERRQ(ierr); 712 if (a+na-nb == test) *flg = PETSC_TRUE; 713 } 714 PetscFunctionReturn(0); 715 } 716 717 #undef __FUNCT__ 718 #define __FUNCT__ "PetscStrbeginswith" 719 /*@C 720 PetscStrbeginswith - Determines if a string begins with a certain string 721 722 Not Collective 723 724 Input Parameters: 725 + a - pointer to string 726 - b - string to beginwith 727 728 Output Parameter: 729 . flg - PETSC_TRUE or PETSC_FALSE 730 731 Notes: Not for use in Fortran 732 733 Level: intermediate 734 735 @*/ 736 PetscErrorCode PetscStrbeginswith(const char a[],const char b[],PetscBool *flg) 737 { 738 char *test; 739 PetscErrorCode ierr; 740 741 PetscFunctionBegin; 742 *flg = PETSC_FALSE; 743 ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr); 744 if (test && (test == a)) *flg = PETSC_TRUE; 745 PetscFunctionReturn(0); 746 } 747 748 749 #undef __FUNCT__ 750 #define __FUNCT__ "PetscStrendswithwhich" 751 /*@C 752 PetscStrendswithwhich - Determines if a string ends with one of several possible strings 753 754 Not Collective 755 756 Input Parameters: 757 + a - pointer to string 758 - bs - strings to endwith (last entry must be null) 759 760 Output Parameter: 761 . cnt - the index of the string it ends with or 1+the last possible index 762 763 Notes: Not for use in Fortran 764 765 Level: intermediate 766 767 @*/ 768 PetscErrorCode PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt) 769 { 770 PetscBool flg; 771 PetscErrorCode ierr; 772 773 PetscFunctionBegin; 774 *cnt = 0; 775 while (bs[*cnt]) { 776 ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr); 777 if (flg) PetscFunctionReturn(0); 778 *cnt += 1; 779 } 780 PetscFunctionReturn(0); 781 } 782 783 #undef __FUNCT__ 784 #define __FUNCT__ "PetscStrrstr" 785 /*@C 786 PetscStrrstr - Locates last occurance of string in another string 787 788 Not Collective 789 790 Input Parameters: 791 + a - pointer to string 792 - b - string to find 793 794 Output Parameter: 795 . tmp - location of occurance 796 797 Notes: Not for use in Fortran 798 799 Level: intermediate 800 801 @*/ 802 PetscErrorCode PetscStrrstr(const char a[],const char b[],char *tmp[]) 803 { 804 const char *stmp = a, *ltmp = 0; 805 806 PetscFunctionBegin; 807 while (stmp) { 808 stmp = (char*)strstr(stmp,b); 809 if (stmp) {ltmp = stmp;stmp++;} 810 } 811 *tmp = (char*)ltmp; 812 PetscFunctionReturn(0); 813 } 814 815 #undef __FUNCT__ 816 #define __FUNCT__ "PetscStrstr" 817 /*@C 818 PetscStrstr - Locates first occurance of string in another string 819 820 Not Collective 821 822 Input Parameters: 823 + haystack - string to search 824 - needle - string to find 825 826 Output Parameter: 827 . tmp - location of occurance, is a NULL if the string is not found 828 829 Notes: Not for use in Fortran 830 831 Level: intermediate 832 833 @*/ 834 PetscErrorCode PetscStrstr(const char haystack[],const char needle[],char *tmp[]) 835 { 836 PetscFunctionBegin; 837 *tmp = (char*)strstr(haystack,needle); 838 PetscFunctionReturn(0); 839 } 840 841 struct _p_PetscToken {char token;char *array;char *current;}; 842 843 #undef __FUNCT__ 844 #define __FUNCT__ "PetscTokenFind" 845 /*@C 846 PetscTokenFind - Locates next "token" in a string 847 848 Not Collective 849 850 Input Parameters: 851 . a - pointer to token 852 853 Output Parameter: 854 . result - location of occurance, NULL if not found 855 856 Notes: 857 858 This version is different from the system version in that 859 it allows you to pass a read-only string into the function. 860 861 This version also treats all characters etc. inside a double quote " 862 as a single token. 863 864 Not for use in Fortran 865 866 Level: intermediate 867 868 869 .seealso: PetscTokenCreate(), PetscTokenDestroy() 870 @*/ 871 PetscErrorCode PetscTokenFind(PetscToken a,char *result[]) 872 { 873 char *ptr = a->current,token; 874 875 PetscFunctionBegin; 876 *result = a->current; 877 if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);} 878 token = a->token; 879 if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;} 880 while (ptr) { 881 if (*ptr == token) { 882 *ptr++ = 0; 883 while (*ptr == a->token) ptr++; 884 a->current = ptr; 885 break; 886 } 887 if (!*ptr) { 888 a->current = 0; 889 break; 890 } 891 ptr++; 892 } 893 PetscFunctionReturn(0); 894 } 895 896 #undef __FUNCT__ 897 #define __FUNCT__ "PetscTokenCreate" 898 /*@C 899 PetscTokenCreate - Creates a PetscToken used to find tokens in a string 900 901 Not Collective 902 903 Input Parameters: 904 + string - the string to look in 905 - token - the character to look for 906 907 Output Parameter: 908 . a - pointer to token 909 910 Notes: 911 912 This version is different from the system version in that 913 it allows you to pass a read-only string into the function. 914 915 Not for use in Fortran 916 917 Level: intermediate 918 919 .seealso: PetscTokenFind(), PetscTokenDestroy() 920 @*/ 921 PetscErrorCode PetscTokenCreate(const char a[],const char b,PetscToken *t) 922 { 923 PetscErrorCode ierr; 924 925 PetscFunctionBegin; 926 ierr = PetscNew(struct _p_PetscToken,t);CHKERRQ(ierr); 927 ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr); 928 929 (*t)->current = (*t)->array; 930 (*t)->token = b; 931 PetscFunctionReturn(0); 932 } 933 934 #undef __FUNCT__ 935 #define __FUNCT__ "PetscTokenDestroy" 936 /*@C 937 PetscTokenDestroy - Destroys a PetscToken 938 939 Not Collective 940 941 Input Parameters: 942 . a - pointer to token 943 944 Level: intermediate 945 946 Notes: Not for use in Fortran 947 948 .seealso: PetscTokenCreate(), PetscTokenFind() 949 @*/ 950 PetscErrorCode PetscTokenDestroy(PetscToken *a) 951 { 952 PetscErrorCode ierr; 953 954 PetscFunctionBegin; 955 if (!*a) PetscFunctionReturn(0); 956 ierr = PetscFree((*a)->array);CHKERRQ(ierr); 957 ierr = PetscFree(*a);CHKERRQ(ierr); 958 PetscFunctionReturn(0); 959 } 960 961 962 #undef __FUNCT__ 963 #define __FUNCT__ "PetscGetPetscDir" 964 /*@C 965 PetscGetPetscDir - Gets the directory PETSc is installed in 966 967 Not Collective 968 969 Output Parameter: 970 . dir - the directory 971 972 Level: developer 973 974 Notes: Not for use in Fortran 975 976 @*/ 977 PetscErrorCode PetscGetPetscDir(const char *dir[]) 978 { 979 PetscFunctionBegin; 980 *dir = PETSC_DIR; 981 PetscFunctionReturn(0); 982 } 983 984 #undef __FUNCT__ 985 #define __FUNCT__ "PetscStrreplace" 986 /*@C 987 PetscStrreplace - Replaces substrings in string with other substrings 988 989 Not Collective 990 991 Input Parameters: 992 + comm - MPI_Comm of processors that are processing the string 993 . aa - the string to look in 994 . b - the resulting copy of a with replaced strings (b can be the same as a) 995 - len - the length of b 996 997 Notes: 998 Replaces ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY}, 999 ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values 1000 as well as any environmental variables. 1001 1002 PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what 1003 PETSc was built with and do not use environmental variables. 1004 1005 Not for use in Fortran 1006 1007 Level: intermediate 1008 1009 @*/ 1010 PetscErrorCode PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len) 1011 { 1012 PetscErrorCode ierr; 1013 int i = 0; 1014 size_t l,l1,l2,l3; 1015 char *work,*par,*epar,env[1024],*tfree,*a = (char*)aa; 1016 const char *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0}; 1017 const char *r[] = {0,0,0,0,0,0,0,0,0}; 1018 PetscBool flag; 1019 1020 PetscFunctionBegin; 1021 if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull"); 1022 if (aa == b) { 1023 ierr = PetscStrallocpy(aa,(char**)&a);CHKERRQ(ierr); 1024 } 1025 ierr = PetscMalloc(len*sizeof(char*),&work);CHKERRQ(ierr); 1026 1027 /* get values for replaced variables */ 1028 ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr); 1029 ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr); 1030 ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr); 1031 ierr = PetscMalloc(256*sizeof(char),&r[3]);CHKERRQ(ierr); 1032 ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[4]);CHKERRQ(ierr); 1033 ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[5]);CHKERRQ(ierr); 1034 ierr = PetscMalloc(256*sizeof(char),&r[6]);CHKERRQ(ierr); 1035 ierr = PetscMalloc(256*sizeof(char),&r[7]);CHKERRQ(ierr); 1036 ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr); 1037 ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 1038 ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 1039 ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr); 1040 ierr = PetscGetHostName((char*)r[7],256);CHKERRQ(ierr); 1041 1042 /* replace that are in environment */ 1043 ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr); 1044 if (flag) { 1045 ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr); 1046 } 1047 1048 /* replace the requested strings */ 1049 ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr); 1050 while (s[i]) { 1051 ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr); 1052 ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr); 1053 while (par) { 1054 *par = 0; 1055 par += l; 1056 1057 ierr = PetscStrlen(b,&l1);CHKERRQ(ierr); 1058 ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr); 1059 ierr = PetscStrlen(par,&l3);CHKERRQ(ierr); 1060 if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values"); 1061 ierr = PetscStrcpy(work,b);CHKERRQ(ierr); 1062 ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr); 1063 ierr = PetscStrcat(work,par);CHKERRQ(ierr); 1064 ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr); 1065 ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr); 1066 } 1067 i++; 1068 } 1069 i = 0; 1070 while (r[i]) { 1071 tfree = (char*)r[i]; 1072 ierr = PetscFree(tfree);CHKERRQ(ierr); 1073 i++; 1074 } 1075 1076 /* look for any other ${xxx} strings to replace from environmental variables */ 1077 ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr); 1078 while (par) { 1079 *par = 0; 1080 par += 2; 1081 ierr = PetscStrcpy(work,b);CHKERRQ(ierr); 1082 ierr = PetscStrstr(par,"}",&epar);CHKERRQ(ierr); 1083 *epar = 0; 1084 epar += 1; 1085 ierr = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr); 1086 if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par); 1087 ierr = PetscStrcat(work,env);CHKERRQ(ierr); 1088 ierr = PetscStrcat(work,epar);CHKERRQ(ierr); 1089 ierr = PetscStrcpy(b,work);CHKERRQ(ierr); 1090 ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr); 1091 } 1092 ierr = PetscFree(work);CHKERRQ(ierr); 1093 if (aa == b) { 1094 ierr = PetscFree(a);CHKERRQ(ierr); 1095 } 1096 PetscFunctionReturn(0); 1097 } 1098 1099 1100