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