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> /* strstr */ 11 #endif 12 #if defined(PETSC_HAVE_STRINGS_H) 13 # include <strings.h> /* strcasecmp */ 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 - separator 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 free(lens); 79 (*args)[*argc] = 0; 80 81 *argc = 0; 82 for (i=0; i<n; i++) { 83 if (s[i] != sp) break; 84 } 85 for (;i<n+1; i++) { 86 if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;} 87 else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;} 88 } 89 return 0; 90 } 91 92 #undef __FUNCT__ 93 #define __FUNCT__ "PetscStrToArrayDestroy" 94 /*@C 95 PetscStrToArrayDestroy - Frees array created with PetscStrToArray(). 96 97 Not Collective 98 99 Output Parameters: 100 + argc - the number of arguments 101 - args - the array of arguments 102 103 Level: intermediate 104 105 Concepts: command line arguments 106 107 Notes: This may be called before PetscInitialize() or after PetscFinalize() 108 109 Not for use in Fortran 110 111 .seealso: PetscStrToArray() 112 113 @*/ 114 PetscErrorCode PetscStrToArrayDestroy(int argc,char **args) 115 { 116 PetscInt i; 117 118 for (i=0; i<argc; i++) free(args[i]); 119 if (args) free(args); 120 return 0; 121 } 122 123 #undef __FUNCT__ 124 #define __FUNCT__ "PetscStrlen" 125 /*@C 126 PetscStrlen - Gets length of a string 127 128 Not Collective 129 130 Input Parameters: 131 . s - pointer to string 132 133 Output Parameter: 134 . len - length in bytes 135 136 Level: intermediate 137 138 Note: 139 This routine is analogous to strlen(). 140 141 Null string returns a length of zero 142 143 Not for use in Fortran 144 145 Concepts: string length 146 147 @*/ 148 PetscErrorCode PetscStrlen(const char s[],size_t *len) 149 { 150 PetscFunctionBegin; 151 if (!s) *len = 0; 152 else *len = strlen(s); 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 = PetscMalloc1(1+len,&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 = PetscMalloc1(n+1,t);CHKERRQ(ierr); 226 for (i=0; i<n; i++) { 227 ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr); 228 } 229 (*t)[n] = 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 If the string that is being copied is of length n or larger then the entire string is not 322 copied and the file location of s is set to NULL. This is different then the behavior of 323 strncpy() which leaves s non-terminated. 324 325 Concepts: string copy 326 327 .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat() 328 329 @*/ 330 PetscErrorCode PetscStrncpy(char s[],const char t[],size_t n) 331 { 332 PetscFunctionBegin; 333 if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer"); 334 if (t) { 335 if (n > 1) { 336 strncpy(s,t,n-1); 337 s[n-1] = '\0'; 338 } else { 339 s[0] = '\0'; 340 } 341 } else if (s) s[0] = 0; 342 PetscFunctionReturn(0); 343 } 344 345 #undef __FUNCT__ 346 #define __FUNCT__ "PetscStrcat" 347 /*@C 348 PetscStrcat - Concatenates a string onto a given string 349 350 Not Collective 351 352 Input Parameters: 353 + s - string to be added to 354 - t - pointer to string to be added to end 355 356 Level: intermediate 357 358 Notes: Not for use in Fortran 359 360 Concepts: string copy 361 362 .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat() 363 364 @*/ 365 PetscErrorCode PetscStrcat(char s[],const char t[]) 366 { 367 PetscFunctionBegin; 368 if (!t) PetscFunctionReturn(0); 369 strcat(s,t); 370 PetscFunctionReturn(0); 371 } 372 373 #undef __FUNCT__ 374 #define __FUNCT__ "PetscStrncat" 375 /*@C 376 PetscStrncat - Concatenates a string onto a given string, up to a given length 377 378 Not Collective 379 380 Input Parameters: 381 + s - pointer to string to be added to end 382 . t - string to be added to 383 . n - maximum length to copy 384 385 Level: intermediate 386 387 Notes: Not for use in Fortran 388 389 Concepts: string copy 390 391 .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat() 392 393 @*/ 394 PetscErrorCode PetscStrncat(char s[],const char t[],size_t n) 395 { 396 PetscFunctionBegin; 397 strncat(s,t,n); 398 PetscFunctionReturn(0); 399 } 400 401 #undef __FUNCT__ 402 #define __FUNCT__ "PetscStrcmpNoError" 403 /* 404 Only to be used with PetscCheck__FUNCT__()! 405 406 Will be removed once we eliminate the __FUNCT__ paradigm 407 */ 408 void PetscStrcmpNoError(const char a[],const char b[],PetscBool *flg) 409 { 410 int c; 411 412 if (!a && !b) *flg = PETSC_TRUE; 413 else if (!a || !b) *flg = PETSC_FALSE; 414 else { 415 c = strcmp(a,b); 416 if (c) *flg = PETSC_FALSE; 417 else *flg = PETSC_TRUE; 418 } 419 } 420 421 #undef __FUNCT__ 422 #define __FUNCT__ "PetscStrcmp" 423 /*@C 424 PetscStrcmp - Compares two strings, 425 426 Not Collective 427 428 Input Parameters: 429 + a - pointer to string first string 430 - b - pointer to second string 431 432 Output Parameter: 433 . flg - PETSC_TRUE if the two strings are equal 434 435 Level: intermediate 436 437 Notes: Not for use in Fortran 438 439 .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp() 440 441 @*/ 442 PetscErrorCode PetscStrcmp(const char a[],const char b[],PetscBool *flg) 443 { 444 int c; 445 446 PetscFunctionBegin; 447 if (!a && !b) *flg = PETSC_TRUE; 448 else if (!a || !b) *flg = PETSC_FALSE; 449 else { 450 c = strcmp(a,b); 451 if (c) *flg = PETSC_FALSE; 452 else *flg = PETSC_TRUE; 453 } 454 PetscFunctionReturn(0); 455 } 456 457 #undef __FUNCT__ 458 #define __FUNCT__ "PetscStrgrt" 459 /*@C 460 PetscStrgrt - If first string is greater than the second 461 462 Not Collective 463 464 Input Parameters: 465 + a - pointer to first string 466 - b - pointer to second string 467 468 Output Parameter: 469 . flg - if the first string is greater 470 471 Notes: 472 Null arguments are ok, a null string is considered smaller than 473 all others 474 475 Not for use in Fortran 476 477 Level: intermediate 478 479 .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp() 480 481 @*/ 482 PetscErrorCode PetscStrgrt(const char a[],const char b[],PetscBool *t) 483 { 484 int c; 485 486 PetscFunctionBegin; 487 if (!a && !b) *t = PETSC_FALSE; 488 else if (a && !b) *t = PETSC_TRUE; 489 else if (!a && b) *t = PETSC_FALSE; 490 else { 491 c = strcmp(a,b); 492 if (c > 0) *t = PETSC_TRUE; 493 else *t = PETSC_FALSE; 494 } 495 PetscFunctionReturn(0); 496 } 497 498 #undef __FUNCT__ 499 #define __FUNCT__ "PetscStrcasecmp" 500 /*@C 501 PetscStrcasecmp - Returns true if the two strings are the same 502 except possibly for case. 503 504 Not Collective 505 506 Input Parameters: 507 + a - pointer to first string 508 - b - pointer to second string 509 510 Output Parameter: 511 . flg - if the two strings are the same 512 513 Notes: 514 Null arguments are ok 515 516 Not for use in Fortran 517 518 Level: intermediate 519 520 .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt() 521 522 @*/ 523 PetscErrorCode PetscStrcasecmp(const char a[],const char b[],PetscBool *t) 524 { 525 int c; 526 527 PetscFunctionBegin; 528 if (!a && !b) c = 0; 529 else if (!a || !b) c = 1; 530 #if defined(PETSC_HAVE_STRCASECMP) 531 else c = strcasecmp(a,b); 532 #elif defined(PETSC_HAVE_STRICMP) 533 else c = stricmp(a,b); 534 #else 535 else { 536 char *aa,*bb; 537 PetscErrorCode ierr; 538 ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr); 539 ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr); 540 ierr = PetscStrtolower(aa);CHKERRQ(ierr); 541 ierr = PetscStrtolower(bb);CHKERRQ(ierr); 542 ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr); 543 ierr = PetscFree(aa);CHKERRQ(ierr); 544 ierr = PetscFree(bb);CHKERRQ(ierr); 545 PetscFunctionReturn(0); 546 } 547 #endif 548 if (!c) *t = PETSC_TRUE; 549 else *t = PETSC_FALSE; 550 PetscFunctionReturn(0); 551 } 552 553 554 555 #undef __FUNCT__ 556 #define __FUNCT__ "PetscStrncmp" 557 /*@C 558 PetscStrncmp - Compares two strings, up to a certain length 559 560 Not Collective 561 562 Input Parameters: 563 + a - pointer to first string 564 . b - pointer to second string 565 - n - length to compare up to 566 567 Output Parameter: 568 . t - if the two strings are equal 569 570 Level: intermediate 571 572 Notes: Not for use in Fortran 573 574 .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp() 575 576 @*/ 577 PetscErrorCode PetscStrncmp(const char a[],const char b[],size_t n,PetscBool *t) 578 { 579 int c; 580 581 PetscFunctionBegin; 582 c = strncmp(a,b,n); 583 if (!c) *t = PETSC_TRUE; 584 else *t = PETSC_FALSE; 585 PetscFunctionReturn(0); 586 } 587 588 #undef __FUNCT__ 589 #define __FUNCT__ "PetscStrchr" 590 /*@C 591 PetscStrchr - Locates first occurance of a character in a string 592 593 Not Collective 594 595 Input Parameters: 596 + a - pointer to string 597 - b - character 598 599 Output Parameter: 600 . c - location of occurance, NULL if not found 601 602 Level: intermediate 603 604 Notes: Not for use in Fortran 605 606 @*/ 607 PetscErrorCode PetscStrchr(const char a[],char b,char *c[]) 608 { 609 PetscFunctionBegin; 610 *c = (char*)strchr(a,b); 611 PetscFunctionReturn(0); 612 } 613 614 #undef __FUNCT__ 615 #define __FUNCT__ "PetscStrrchr" 616 /*@C 617 PetscStrrchr - Locates one location past the last occurance of a character in a string, 618 if the character is not found then returns entire string 619 620 Not Collective 621 622 Input Parameters: 623 + a - pointer to string 624 - b - character 625 626 Output Parameter: 627 . tmp - location of occurance, a if not found 628 629 Level: intermediate 630 631 Notes: Not for use in Fortran 632 633 @*/ 634 PetscErrorCode PetscStrrchr(const char a[],char b,char *tmp[]) 635 { 636 PetscFunctionBegin; 637 *tmp = (char*)strrchr(a,b); 638 if (!*tmp) *tmp = (char*)a; 639 else *tmp = *tmp + 1; 640 PetscFunctionReturn(0); 641 } 642 643 #undef __FUNCT__ 644 #define __FUNCT__ "PetscStrtolower" 645 /*@C 646 PetscStrtolower - Converts string to lower case 647 648 Not Collective 649 650 Input Parameters: 651 . a - pointer to string 652 653 Level: intermediate 654 655 Notes: Not for use in Fortran 656 657 @*/ 658 PetscErrorCode PetscStrtolower(char a[]) 659 { 660 PetscFunctionBegin; 661 while (*a) { 662 if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A'; 663 a++; 664 } 665 PetscFunctionReturn(0); 666 } 667 668 #undef __FUNCT__ 669 #define __FUNCT__ "PetscStrtoupper" 670 /*@C 671 PetscStrtolower - Converts string to upper case 672 673 Not Collective 674 675 Input Parameters: 676 . a - pointer to string 677 678 Level: intermediate 679 680 Notes: Not for use in Fortran 681 682 @*/ 683 PetscErrorCode PetscStrtoupper(char a[]) 684 { 685 PetscFunctionBegin; 686 while (*a) { 687 if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a'; 688 a++; 689 } 690 PetscFunctionReturn(0); 691 } 692 693 #undef __FUNCT__ 694 #define __FUNCT__ "PetscStrendswith" 695 /*@C 696 PetscStrendswith - Determines if a string ends with a certain string 697 698 Not Collective 699 700 Input Parameters: 701 + a - pointer to string 702 - b - string to endwith 703 704 Output Parameter: 705 . flg - PETSC_TRUE or PETSC_FALSE 706 707 Notes: Not for use in Fortran 708 709 Level: intermediate 710 711 @*/ 712 PetscErrorCode PetscStrendswith(const char a[],const char b[],PetscBool *flg) 713 { 714 char *test; 715 PetscErrorCode ierr; 716 size_t na,nb; 717 718 PetscFunctionBegin; 719 *flg = PETSC_FALSE; 720 ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr); 721 if (test) { 722 ierr = PetscStrlen(a,&na);CHKERRQ(ierr); 723 ierr = PetscStrlen(b,&nb);CHKERRQ(ierr); 724 if (a+na-nb == test) *flg = PETSC_TRUE; 725 } 726 PetscFunctionReturn(0); 727 } 728 729 #undef __FUNCT__ 730 #define __FUNCT__ "PetscStrbeginswith" 731 /*@C 732 PetscStrbeginswith - Determines if a string begins with a certain string 733 734 Not Collective 735 736 Input Parameters: 737 + a - pointer to string 738 - b - string to beginwith 739 740 Output Parameter: 741 . flg - PETSC_TRUE or PETSC_FALSE 742 743 Notes: Not for use in Fortran 744 745 Level: intermediate 746 747 @*/ 748 PetscErrorCode PetscStrbeginswith(const char a[],const char b[],PetscBool *flg) 749 { 750 char *test; 751 PetscErrorCode ierr; 752 753 PetscFunctionBegin; 754 *flg = PETSC_FALSE; 755 ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr); 756 if (test && (test == a)) *flg = PETSC_TRUE; 757 PetscFunctionReturn(0); 758 } 759 760 761 #undef __FUNCT__ 762 #define __FUNCT__ "PetscStrendswithwhich" 763 /*@C 764 PetscStrendswithwhich - Determines if a string ends with one of several possible strings 765 766 Not Collective 767 768 Input Parameters: 769 + a - pointer to string 770 - bs - strings to endwith (last entry must be null) 771 772 Output Parameter: 773 . cnt - the index of the string it ends with or 1+the last possible index 774 775 Notes: Not for use in Fortran 776 777 Level: intermediate 778 779 @*/ 780 PetscErrorCode PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt) 781 { 782 PetscBool flg; 783 PetscErrorCode ierr; 784 785 PetscFunctionBegin; 786 *cnt = 0; 787 while (bs[*cnt]) { 788 ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr); 789 if (flg) PetscFunctionReturn(0); 790 *cnt += 1; 791 } 792 PetscFunctionReturn(0); 793 } 794 795 #undef __FUNCT__ 796 #define __FUNCT__ "PetscStrrstr" 797 /*@C 798 PetscStrrstr - Locates last occurance of string in another string 799 800 Not Collective 801 802 Input Parameters: 803 + a - pointer to string 804 - b - string to find 805 806 Output Parameter: 807 . tmp - location of occurance 808 809 Notes: Not for use in Fortran 810 811 Level: intermediate 812 813 @*/ 814 PetscErrorCode PetscStrrstr(const char a[],const char b[],char *tmp[]) 815 { 816 const char *stmp = a, *ltmp = 0; 817 818 PetscFunctionBegin; 819 while (stmp) { 820 stmp = (char*)strstr(stmp,b); 821 if (stmp) {ltmp = stmp;stmp++;} 822 } 823 *tmp = (char*)ltmp; 824 PetscFunctionReturn(0); 825 } 826 827 #undef __FUNCT__ 828 #define __FUNCT__ "PetscStrstr" 829 /*@C 830 PetscStrstr - Locates first occurance of string in another string 831 832 Not Collective 833 834 Input Parameters: 835 + haystack - string to search 836 - needle - string to find 837 838 Output Parameter: 839 . tmp - location of occurance, is a NULL if the string is not found 840 841 Notes: Not for use in Fortran 842 843 Level: intermediate 844 845 @*/ 846 PetscErrorCode PetscStrstr(const char haystack[],const char needle[],char *tmp[]) 847 { 848 PetscFunctionBegin; 849 *tmp = (char*)strstr(haystack,needle); 850 PetscFunctionReturn(0); 851 } 852 853 struct _p_PetscToken {char token;char *array;char *current;}; 854 855 #undef __FUNCT__ 856 #define __FUNCT__ "PetscTokenFind" 857 /*@C 858 PetscTokenFind - Locates next "token" in a string 859 860 Not Collective 861 862 Input Parameters: 863 . a - pointer to token 864 865 Output Parameter: 866 . result - location of occurance, NULL if not found 867 868 Notes: 869 870 This version is different from the system version in that 871 it allows you to pass a read-only string into the function. 872 873 This version also treats all characters etc. inside a double quote " 874 as a single token. 875 876 Not for use in Fortran 877 878 Level: intermediate 879 880 881 .seealso: PetscTokenCreate(), PetscTokenDestroy() 882 @*/ 883 PetscErrorCode PetscTokenFind(PetscToken a,char *result[]) 884 { 885 char *ptr = a->current,token; 886 887 PetscFunctionBegin; 888 *result = a->current; 889 if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);} 890 token = a->token; 891 if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;} 892 while (ptr) { 893 if (*ptr == token) { 894 *ptr++ = 0; 895 while (*ptr == a->token) ptr++; 896 a->current = ptr; 897 break; 898 } 899 if (!*ptr) { 900 a->current = 0; 901 break; 902 } 903 ptr++; 904 } 905 PetscFunctionReturn(0); 906 } 907 908 #undef __FUNCT__ 909 #define __FUNCT__ "PetscTokenCreate" 910 /*@C 911 PetscTokenCreate - Creates a PetscToken used to find tokens in a string 912 913 Not Collective 914 915 Input Parameters: 916 + string - the string to look in 917 - token - the character to look for 918 919 Output Parameter: 920 . a - pointer to token 921 922 Notes: 923 924 This version is different from the system version in that 925 it allows you to pass a read-only string into the function. 926 927 Not for use in Fortran 928 929 Level: intermediate 930 931 .seealso: PetscTokenFind(), PetscTokenDestroy() 932 @*/ 933 PetscErrorCode PetscTokenCreate(const char a[],const char b,PetscToken *t) 934 { 935 PetscErrorCode ierr; 936 937 PetscFunctionBegin; 938 ierr = PetscNew(t);CHKERRQ(ierr); 939 ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr); 940 941 (*t)->current = (*t)->array; 942 (*t)->token = b; 943 PetscFunctionReturn(0); 944 } 945 946 #undef __FUNCT__ 947 #define __FUNCT__ "PetscTokenDestroy" 948 /*@C 949 PetscTokenDestroy - Destroys a PetscToken 950 951 Not Collective 952 953 Input Parameters: 954 . a - pointer to token 955 956 Level: intermediate 957 958 Notes: Not for use in Fortran 959 960 .seealso: PetscTokenCreate(), PetscTokenFind() 961 @*/ 962 PetscErrorCode PetscTokenDestroy(PetscToken *a) 963 { 964 PetscErrorCode ierr; 965 966 PetscFunctionBegin; 967 if (!*a) PetscFunctionReturn(0); 968 ierr = PetscFree((*a)->array);CHKERRQ(ierr); 969 ierr = PetscFree(*a);CHKERRQ(ierr); 970 PetscFunctionReturn(0); 971 } 972 973 974 #undef __FUNCT__ 975 #define __FUNCT__ "PetscGetPetscDir" 976 /*@C 977 PetscGetPetscDir - Gets the directory PETSc is installed in 978 979 Not Collective 980 981 Output Parameter: 982 . dir - the directory 983 984 Level: developer 985 986 Notes: Not for use in Fortran 987 988 @*/ 989 PetscErrorCode PetscGetPetscDir(const char *dir[]) 990 { 991 PetscFunctionBegin; 992 *dir = PETSC_DIR; 993 PetscFunctionReturn(0); 994 } 995 996 #undef __FUNCT__ 997 #define __FUNCT__ "PetscStrreplace" 998 /*@C 999 PetscStrreplace - Replaces substrings in string with other substrings 1000 1001 Not Collective 1002 1003 Input Parameters: 1004 + comm - MPI_Comm of processors that are processing the string 1005 . aa - the string to look in 1006 . b - the resulting copy of a with replaced strings (b can be the same as a) 1007 - len - the length of b 1008 1009 Notes: 1010 Replaces ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY}, 1011 ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values 1012 as well as any environmental variables. 1013 1014 PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what 1015 PETSc was built with and do not use environmental variables. 1016 1017 Not for use in Fortran 1018 1019 Level: intermediate 1020 1021 @*/ 1022 PetscErrorCode PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len) 1023 { 1024 PetscErrorCode ierr; 1025 int i = 0; 1026 size_t l,l1,l2,l3; 1027 char *work,*par,*epar,env[1024],*tfree,*a = (char*)aa; 1028 const char *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0}; 1029 const char *r[] = {0,0,0,0,0,0,0,0,0}; 1030 PetscBool flag; 1031 1032 PetscFunctionBegin; 1033 if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull"); 1034 if (aa == b) { 1035 ierr = PetscStrallocpy(aa,(char**)&a);CHKERRQ(ierr); 1036 } 1037 ierr = PetscMalloc1(len,&work);CHKERRQ(ierr); 1038 1039 /* get values for replaced variables */ 1040 ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr); 1041 ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr); 1042 ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr); 1043 ierr = PetscMalloc1(256,&r[3]);CHKERRQ(ierr); 1044 ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[4]);CHKERRQ(ierr); 1045 ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[5]);CHKERRQ(ierr); 1046 ierr = PetscMalloc1(256,&r[6]);CHKERRQ(ierr); 1047 ierr = PetscMalloc1(256,&r[7]);CHKERRQ(ierr); 1048 ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr); 1049 ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 1050 ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 1051 ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr); 1052 ierr = PetscGetHostName((char*)r[7],256);CHKERRQ(ierr); 1053 1054 /* replace that are in environment */ 1055 ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr); 1056 if (flag) { 1057 ierr = PetscFree(r[2]);CHKERRQ(ierr); 1058 ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr); 1059 } 1060 1061 /* replace the requested strings */ 1062 ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr); 1063 while (s[i]) { 1064 ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr); 1065 ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr); 1066 while (par) { 1067 *par = 0; 1068 par += l; 1069 1070 ierr = PetscStrlen(b,&l1);CHKERRQ(ierr); 1071 ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr); 1072 ierr = PetscStrlen(par,&l3);CHKERRQ(ierr); 1073 if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values"); 1074 ierr = PetscStrcpy(work,b);CHKERRQ(ierr); 1075 ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr); 1076 ierr = PetscStrcat(work,par);CHKERRQ(ierr); 1077 ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr); 1078 ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr); 1079 } 1080 i++; 1081 } 1082 i = 0; 1083 while (r[i]) { 1084 tfree = (char*)r[i]; 1085 ierr = PetscFree(tfree);CHKERRQ(ierr); 1086 i++; 1087 } 1088 1089 /* look for any other ${xxx} strings to replace from environmental variables */ 1090 ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr); 1091 while (par) { 1092 *par = 0; 1093 par += 2; 1094 ierr = PetscStrcpy(work,b);CHKERRQ(ierr); 1095 ierr = PetscStrstr(par,"}",&epar);CHKERRQ(ierr); 1096 *epar = 0; 1097 epar += 1; 1098 ierr = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr); 1099 if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par); 1100 ierr = PetscStrcat(work,env);CHKERRQ(ierr); 1101 ierr = PetscStrcat(work,epar);CHKERRQ(ierr); 1102 ierr = PetscStrcpy(b,work);CHKERRQ(ierr); 1103 ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr); 1104 } 1105 ierr = PetscFree(work);CHKERRQ(ierr); 1106 if (aa == b) { 1107 ierr = PetscFree(a);CHKERRQ(ierr); 1108 } 1109 PetscFunctionReturn(0); 1110 } 1111 1112 #undef __FUNCT__ 1113 #define __FUNCT__ "PetscEListFind" 1114 /*@C 1115 PetscEListFind - searches list of strings for given string, using case insensitive matching 1116 1117 Not Collective 1118 1119 Input Parameters: 1120 + n - number of strings in 1121 . list - list of strings to search 1122 - str - string to look for, empty string "" accepts default (first entry in list) 1123 1124 Output Parameters: 1125 + value - index of matching string (if found) 1126 - found - boolean indicating whether string was found (can be NULL) 1127 1128 Notes: 1129 Not for use in Fortran 1130 1131 Level: advanced 1132 @*/ 1133 PetscErrorCode PetscEListFind(PetscInt n,const char *const *list,const char *str,PetscInt *value,PetscBool *found) 1134 { 1135 PetscErrorCode ierr; 1136 PetscBool matched; 1137 PetscInt i; 1138 1139 PetscFunctionBegin; 1140 if (found) *found = PETSC_FALSE; 1141 for (i=0; i<n; i++) { 1142 ierr = PetscStrcasecmp(str,list[i],&matched);CHKERRQ(ierr); 1143 if (matched || !str[0]) { 1144 if (found) *found = PETSC_TRUE; 1145 *value = i; 1146 break; 1147 } 1148 } 1149 PetscFunctionReturn(0); 1150 } 1151 1152 #undef __FUNCT__ 1153 #define __FUNCT__ "PetscEnumFind" 1154 /*@C 1155 PetscEListFind - searches enum list of strings for given string, using case insensitive matching 1156 1157 Not Collective 1158 1159 Input Parameters: 1160 + enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL 1161 - str - string to look for 1162 1163 Output Parameters: 1164 + value - index of matching string (if found) 1165 - found - boolean indicating whether string was found (can be NULL) 1166 1167 Notes: 1168 Not for use in Fortran 1169 1170 Level: advanced 1171 @*/ 1172 PetscErrorCode PetscEnumFind(const char *const *enumlist,const char *str,PetscEnum *value,PetscBool *found) 1173 { 1174 PetscErrorCode ierr; 1175 PetscInt n,evalue; 1176 PetscBool efound; 1177 1178 PetscFunctionBegin; 1179 for (n = 0; enumlist[n]; n++) { 1180 if (n > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries"); 1181 } 1182 if (n < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix"); 1183 n -= 3; /* drop enum name, prefix, and null termination */ 1184 ierr = PetscEListFind(n,enumlist,str,&evalue,&efound);CHKERRQ(ierr); 1185 if (efound) *value = (PetscEnum)evalue; 1186 if (found) *found = efound; 1187 PetscFunctionReturn(0); 1188 } 1189