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