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 final location of s is set to NULL. This is different then the behavior of 386 strncpy() which leaves s non-terminated if there is not room for the entire string. 387 388 Concepts: string copy 389 390 Developers Note: Should this be PetscStrlcpy() to reflect its behavior which is like strlcpy() not strncpy() 391 392 .seealso: PetscStrcpy(), PetscStrcat(), PetscStrlcat() 393 394 @*/ 395 PetscErrorCode PetscStrncpy(char s[],const char t[],size_t n) 396 { 397 PetscFunctionBegin; 398 if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer"); 399 if (s && !n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Requires an output string of length at least 1 to hold the termination character"); 400 if (t) { 401 if (n > 1) { 402 strncpy(s,t,n-1); 403 s[n-1] = '\0'; 404 } else { 405 s[0] = '\0'; 406 } 407 } else if (s) s[0] = 0; 408 PetscFunctionReturn(0); 409 } 410 411 /*@C 412 PetscStrcat - Concatenates a string onto a given string 413 414 Not Collective 415 416 Input Parameters: 417 + s - string to be added to 418 - t - pointer to string to be added to end 419 420 Level: intermediate 421 422 Notes: 423 Not for use in Fortran 424 425 Concepts: string copy 426 427 .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrlcat() 428 429 @*/ 430 PetscErrorCode PetscStrcat(char s[],const char t[]) 431 { 432 PetscFunctionBegin; 433 if (!t) PetscFunctionReturn(0); 434 strcat(s,t); 435 PetscFunctionReturn(0); 436 } 437 438 /*@C 439 PetscStrlcat - Concatenates a string onto a given string, up to a given length 440 441 Not Collective 442 443 Input Parameters: 444 + s - pointer to string to be added to end 445 . t - string to be added to 446 - n - length of the original allocated string 447 448 Level: intermediate 449 450 Notes: 451 Not for use in Fortran 452 453 Unlike the system call strncat(), the length passed in is the length of the 454 original allocated space, not the length of the left-over space. This is 455 similar to the BSD system call strlcat(). 456 457 Concepts: string copy 458 459 .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat() 460 461 @*/ 462 PetscErrorCode PetscStrlcat(char s[],const char t[],size_t n) 463 { 464 size_t len; 465 PetscErrorCode ierr; 466 467 PetscFunctionBegin; 468 ierr = PetscStrlen(t,&len);CHKERRQ(ierr); 469 strncat(s,t,n - len); 470 PetscFunctionReturn(0); 471 } 472 473 /* 474 Only to be used with PetscCheck__FUNCT__()! 475 476 */ 477 void PetscStrcmpNoError(const char a[],const char b[],PetscBool *flg) 478 { 479 int c; 480 481 if (!a && !b) *flg = PETSC_TRUE; 482 else if (!a || !b) *flg = PETSC_FALSE; 483 else { 484 c = strcmp(a,b); 485 if (c) *flg = PETSC_FALSE; 486 else *flg = PETSC_TRUE; 487 } 488 } 489 490 /*@C 491 PetscStrcmp - Compares two strings, 492 493 Not Collective 494 495 Input Parameters: 496 + a - pointer to string first string 497 - b - pointer to second string 498 499 Output Parameter: 500 . flg - PETSC_TRUE if the two strings are equal 501 502 Level: intermediate 503 504 Notes: 505 Not for use in Fortran 506 507 .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp() 508 509 @*/ 510 PetscErrorCode PetscStrcmp(const char a[],const char b[],PetscBool *flg) 511 { 512 int c; 513 514 PetscFunctionBegin; 515 if (!a && !b) *flg = PETSC_TRUE; 516 else if (!a || !b) *flg = PETSC_FALSE; 517 else { 518 c = strcmp(a,b); 519 if (c) *flg = PETSC_FALSE; 520 else *flg = PETSC_TRUE; 521 } 522 PetscFunctionReturn(0); 523 } 524 525 /*@C 526 PetscStrgrt - If first string is greater than the second 527 528 Not Collective 529 530 Input Parameters: 531 + a - pointer to first string 532 - b - pointer to second string 533 534 Output Parameter: 535 . flg - if the first string is greater 536 537 Notes: 538 Null arguments are ok, a null string is considered smaller than 539 all others 540 541 Not for use in Fortran 542 543 Level: intermediate 544 545 .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp() 546 547 @*/ 548 PetscErrorCode PetscStrgrt(const char a[],const char b[],PetscBool *t) 549 { 550 int c; 551 552 PetscFunctionBegin; 553 if (!a && !b) *t = PETSC_FALSE; 554 else if (a && !b) *t = PETSC_TRUE; 555 else if (!a && b) *t = PETSC_FALSE; 556 else { 557 c = strcmp(a,b); 558 if (c > 0) *t = PETSC_TRUE; 559 else *t = PETSC_FALSE; 560 } 561 PetscFunctionReturn(0); 562 } 563 564 /*@C 565 PetscStrcasecmp - Returns true if the two strings are the same 566 except possibly for case. 567 568 Not Collective 569 570 Input Parameters: 571 + a - pointer to first string 572 - b - pointer to second string 573 574 Output Parameter: 575 . flg - if the two strings are the same 576 577 Notes: 578 Null arguments are ok 579 580 Not for use in Fortran 581 582 Level: intermediate 583 584 .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt() 585 586 @*/ 587 PetscErrorCode PetscStrcasecmp(const char a[],const char b[],PetscBool *t) 588 { 589 int c; 590 591 PetscFunctionBegin; 592 if (!a && !b) c = 0; 593 else if (!a || !b) c = 1; 594 #if defined(PETSC_HAVE_STRCASECMP) 595 else c = strcasecmp(a,b); 596 #elif defined(PETSC_HAVE_STRICMP) 597 else c = stricmp(a,b); 598 #else 599 else { 600 char *aa,*bb; 601 PetscErrorCode ierr; 602 ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr); 603 ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr); 604 ierr = PetscStrtolower(aa);CHKERRQ(ierr); 605 ierr = PetscStrtolower(bb);CHKERRQ(ierr); 606 ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr); 607 ierr = PetscFree(aa);CHKERRQ(ierr); 608 ierr = PetscFree(bb);CHKERRQ(ierr); 609 PetscFunctionReturn(0); 610 } 611 #endif 612 if (!c) *t = PETSC_TRUE; 613 else *t = PETSC_FALSE; 614 PetscFunctionReturn(0); 615 } 616 617 618 619 /*@C 620 PetscStrncmp - Compares two strings, up to a certain length 621 622 Not Collective 623 624 Input Parameters: 625 + a - pointer to first string 626 . b - pointer to second string 627 - n - length to compare up to 628 629 Output Parameter: 630 . t - if the two strings are equal 631 632 Level: intermediate 633 634 Notes: 635 Not for use in Fortran 636 637 .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp() 638 639 @*/ 640 PetscErrorCode PetscStrncmp(const char a[],const char b[],size_t n,PetscBool *t) 641 { 642 int c; 643 644 PetscFunctionBegin; 645 c = strncmp(a,b,n); 646 if (!c) *t = PETSC_TRUE; 647 else *t = PETSC_FALSE; 648 PetscFunctionReturn(0); 649 } 650 651 /*@C 652 PetscStrchr - Locates first occurance of a character in a string 653 654 Not Collective 655 656 Input Parameters: 657 + a - pointer to string 658 - b - character 659 660 Output Parameter: 661 . c - location of occurance, NULL if not found 662 663 Level: intermediate 664 665 Notes: 666 Not for use in Fortran 667 668 @*/ 669 PetscErrorCode PetscStrchr(const char a[],char b,char *c[]) 670 { 671 PetscFunctionBegin; 672 *c = (char*)strchr(a,b); 673 PetscFunctionReturn(0); 674 } 675 676 /*@C 677 PetscStrrchr - Locates one location past the last occurance of a character in a string, 678 if the character is not found then returns entire string 679 680 Not Collective 681 682 Input Parameters: 683 + a - pointer to string 684 - b - character 685 686 Output Parameter: 687 . tmp - location of occurance, a if not found 688 689 Level: intermediate 690 691 Notes: 692 Not for use in Fortran 693 694 @*/ 695 PetscErrorCode PetscStrrchr(const char a[],char b,char *tmp[]) 696 { 697 PetscFunctionBegin; 698 *tmp = (char*)strrchr(a,b); 699 if (!*tmp) *tmp = (char*)a; 700 else *tmp = *tmp + 1; 701 PetscFunctionReturn(0); 702 } 703 704 /*@C 705 PetscStrtolower - Converts string to lower case 706 707 Not Collective 708 709 Input Parameters: 710 . a - pointer to string 711 712 Level: intermediate 713 714 Notes: 715 Not for use in Fortran 716 717 @*/ 718 PetscErrorCode PetscStrtolower(char a[]) 719 { 720 PetscFunctionBegin; 721 while (*a) { 722 if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A'; 723 a++; 724 } 725 PetscFunctionReturn(0); 726 } 727 728 /*@C 729 PetscStrtoupper - Converts string to upper case 730 731 Not Collective 732 733 Input Parameters: 734 . a - pointer to string 735 736 Level: intermediate 737 738 Notes: 739 Not for use in Fortran 740 741 @*/ 742 PetscErrorCode PetscStrtoupper(char a[]) 743 { 744 PetscFunctionBegin; 745 while (*a) { 746 if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a'; 747 a++; 748 } 749 PetscFunctionReturn(0); 750 } 751 752 /*@C 753 PetscStrendswith - Determines if a string ends with a certain string 754 755 Not Collective 756 757 Input Parameters: 758 + a - pointer to string 759 - b - string to endwith 760 761 Output Parameter: 762 . flg - PETSC_TRUE or PETSC_FALSE 763 764 Notes: 765 Not for use in Fortran 766 767 Level: intermediate 768 769 @*/ 770 PetscErrorCode PetscStrendswith(const char a[],const char b[],PetscBool *flg) 771 { 772 char *test; 773 PetscErrorCode ierr; 774 size_t na,nb; 775 776 PetscFunctionBegin; 777 *flg = PETSC_FALSE; 778 ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr); 779 if (test) { 780 ierr = PetscStrlen(a,&na);CHKERRQ(ierr); 781 ierr = PetscStrlen(b,&nb);CHKERRQ(ierr); 782 if (a+na-nb == test) *flg = PETSC_TRUE; 783 } 784 PetscFunctionReturn(0); 785 } 786 787 /*@C 788 PetscStrbeginswith - Determines if a string begins with a certain string 789 790 Not Collective 791 792 Input Parameters: 793 + a - pointer to string 794 - b - string to begin with 795 796 Output Parameter: 797 . flg - PETSC_TRUE or PETSC_FALSE 798 799 Notes: 800 Not for use in Fortran 801 802 Level: intermediate 803 804 .seealso: PetscStrendswithwhich(), PetscStrendswith(), PetscStrtoupper, PetscStrtolower(), PetscStrrchr(), PetscStrchr(), 805 PetscStrncmp(), PetscStrlen(), PetscStrncmp(), PetscStrcmp() 806 807 @*/ 808 PetscErrorCode PetscStrbeginswith(const char a[],const char b[],PetscBool *flg) 809 { 810 char *test; 811 PetscErrorCode ierr; 812 813 PetscFunctionBegin; 814 *flg = PETSC_FALSE; 815 ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr); 816 if (test && (test == a)) *flg = PETSC_TRUE; 817 PetscFunctionReturn(0); 818 } 819 820 821 /*@C 822 PetscStrendswithwhich - Determines if a string ends with one of several possible strings 823 824 Not Collective 825 826 Input Parameters: 827 + a - pointer to string 828 - bs - strings to endwith (last entry must be null) 829 830 Output Parameter: 831 . cnt - the index of the string it ends with or 1+the last possible index 832 833 Notes: 834 Not for use in Fortran 835 836 Level: intermediate 837 838 @*/ 839 PetscErrorCode PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt) 840 { 841 PetscBool flg; 842 PetscErrorCode ierr; 843 844 PetscFunctionBegin; 845 *cnt = 0; 846 while (bs[*cnt]) { 847 ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr); 848 if (flg) PetscFunctionReturn(0); 849 *cnt += 1; 850 } 851 PetscFunctionReturn(0); 852 } 853 854 /*@C 855 PetscStrrstr - Locates last occurance of string in another string 856 857 Not Collective 858 859 Input Parameters: 860 + a - pointer to string 861 - b - string to find 862 863 Output Parameter: 864 . tmp - location of occurance 865 866 Notes: 867 Not for use in Fortran 868 869 Level: intermediate 870 871 @*/ 872 PetscErrorCode PetscStrrstr(const char a[],const char b[],char *tmp[]) 873 { 874 const char *stmp = a, *ltmp = 0; 875 876 PetscFunctionBegin; 877 while (stmp) { 878 stmp = (char*)strstr(stmp,b); 879 if (stmp) {ltmp = stmp;stmp++;} 880 } 881 *tmp = (char*)ltmp; 882 PetscFunctionReturn(0); 883 } 884 885 /*@C 886 PetscStrstr - Locates first occurance of string in another string 887 888 Not Collective 889 890 Input Parameters: 891 + haystack - string to search 892 - needle - string to find 893 894 Output Parameter: 895 . tmp - location of occurance, is a NULL if the string is not found 896 897 Notes: 898 Not for use in Fortran 899 900 Level: intermediate 901 902 @*/ 903 PetscErrorCode PetscStrstr(const char haystack[],const char needle[],char *tmp[]) 904 { 905 PetscFunctionBegin; 906 *tmp = (char*)strstr(haystack,needle); 907 PetscFunctionReturn(0); 908 } 909 910 struct _p_PetscToken {char token;char *array;char *current;}; 911 912 /*@C 913 PetscTokenFind - Locates next "token" in a string 914 915 Not Collective 916 917 Input Parameters: 918 . a - pointer to token 919 920 Output Parameter: 921 . result - location of occurance, NULL if not found 922 923 Notes: 924 925 This version is different from the system version in that 926 it allows you to pass a read-only string into the function. 927 928 This version also treats all characters etc. inside a double quote " 929 as a single token. 930 931 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 932 second will return a null terminated y 933 934 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 935 936 Not for use in Fortran 937 938 Level: intermediate 939 940 941 .seealso: PetscTokenCreate(), PetscTokenDestroy() 942 @*/ 943 PetscErrorCode PetscTokenFind(PetscToken a,char *result[]) 944 { 945 char *ptr = a->current,token; 946 947 PetscFunctionBegin; 948 *result = a->current; 949 if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);} 950 token = a->token; 951 if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;} 952 while (ptr) { 953 if (*ptr == token) { 954 *ptr++ = 0; 955 while (*ptr == a->token) ptr++; 956 a->current = ptr; 957 break; 958 } 959 if (!*ptr) { 960 a->current = 0; 961 break; 962 } 963 ptr++; 964 } 965 PetscFunctionReturn(0); 966 } 967 968 /*@C 969 PetscTokenCreate - Creates a PetscToken used to find tokens in a string 970 971 Not Collective 972 973 Input Parameters: 974 + string - the string to look in 975 - b - the separator character 976 977 Output Parameter: 978 . t- the token object 979 980 Notes: 981 982 This version is different from the system version in that 983 it allows you to pass a read-only string into the function. 984 985 Not for use in Fortran 986 987 Level: intermediate 988 989 .seealso: PetscTokenFind(), PetscTokenDestroy() 990 @*/ 991 PetscErrorCode PetscTokenCreate(const char a[],const char b,PetscToken *t) 992 { 993 PetscErrorCode ierr; 994 995 PetscFunctionBegin; 996 ierr = PetscNew(t);CHKERRQ(ierr); 997 ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr); 998 999 (*t)->current = (*t)->array; 1000 (*t)->token = b; 1001 PetscFunctionReturn(0); 1002 } 1003 1004 /*@C 1005 PetscTokenDestroy - Destroys a PetscToken 1006 1007 Not Collective 1008 1009 Input Parameters: 1010 . a - pointer to token 1011 1012 Level: intermediate 1013 1014 Notes: 1015 Not for use in Fortran 1016 1017 .seealso: PetscTokenCreate(), PetscTokenFind() 1018 @*/ 1019 PetscErrorCode PetscTokenDestroy(PetscToken *a) 1020 { 1021 PetscErrorCode ierr; 1022 1023 PetscFunctionBegin; 1024 if (!*a) PetscFunctionReturn(0); 1025 ierr = PetscFree((*a)->array);CHKERRQ(ierr); 1026 ierr = PetscFree(*a);CHKERRQ(ierr); 1027 PetscFunctionReturn(0); 1028 } 1029 1030 /*@C 1031 PetscStrInList - search string in character-delimited list 1032 1033 Not Collective 1034 1035 Input Parameters: 1036 + str - the string to look for 1037 . list - the list to search in 1038 - sep - the separator character 1039 1040 Output Parameter: 1041 . found - whether str is in list 1042 1043 Level: intermediate 1044 1045 Notes: 1046 Not for use in Fortran 1047 1048 .seealso: PetscTokenCreate(), PetscTokenFind(), PetscStrcmp() 1049 @*/ 1050 PetscErrorCode PetscStrInList(const char str[],const char list[],char sep,PetscBool *found) 1051 { 1052 PetscToken token; 1053 char *item; 1054 PetscErrorCode ierr; 1055 1056 PetscFunctionBegin; 1057 *found = PETSC_FALSE; 1058 ierr = PetscTokenCreate(list,sep,&token);CHKERRQ(ierr); 1059 ierr = PetscTokenFind(token,&item);CHKERRQ(ierr); 1060 while (item) { 1061 ierr = PetscStrcmp(str,item,found);CHKERRQ(ierr); 1062 if (*found) break; 1063 ierr = PetscTokenFind(token,&item);CHKERRQ(ierr); 1064 } 1065 ierr = PetscTokenDestroy(&token);CHKERRQ(ierr); 1066 PetscFunctionReturn(0); 1067 } 1068 1069 /*@C 1070 PetscGetPetscDir - Gets the directory PETSc is installed in 1071 1072 Not Collective 1073 1074 Output Parameter: 1075 . dir - the directory 1076 1077 Level: developer 1078 1079 Notes: 1080 Not for use in Fortran 1081 1082 @*/ 1083 PetscErrorCode PetscGetPetscDir(const char *dir[]) 1084 { 1085 PetscFunctionBegin; 1086 *dir = PETSC_DIR; 1087 PetscFunctionReturn(0); 1088 } 1089 1090 /*@C 1091 PetscStrreplace - Replaces substrings in string with other substrings 1092 1093 Not Collective 1094 1095 Input Parameters: 1096 + comm - MPI_Comm of processors that are processing the string 1097 . aa - the string to look in 1098 . b - the resulting copy of a with replaced strings (b can be the same as a) 1099 - len - the length of b 1100 1101 Notes: 1102 Replaces ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY}, 1103 ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values 1104 as well as any environmental variables. 1105 1106 PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what 1107 PETSc was built with and do not use environmental variables. 1108 1109 Not for use in Fortran 1110 1111 Level: intermediate 1112 1113 @*/ 1114 PetscErrorCode PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len) 1115 { 1116 PetscErrorCode ierr; 1117 int i = 0; 1118 size_t l,l1,l2,l3; 1119 char *work,*par,*epar,env[1024],*tfree,*a = (char*)aa; 1120 const char *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0}; 1121 char *r[] = {0,0,0,0,0,0,0,0,0}; 1122 PetscBool flag; 1123 1124 PetscFunctionBegin; 1125 if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull"); 1126 if (aa == b) { 1127 ierr = PetscStrallocpy(aa,(char**)&a);CHKERRQ(ierr); 1128 } 1129 ierr = PetscMalloc1(len,&work);CHKERRQ(ierr); 1130 1131 /* get values for replaced variables */ 1132 ierr = PetscStrallocpy(PETSC_ARCH,&r[0]);CHKERRQ(ierr); 1133 ierr = PetscStrallocpy(PETSC_DIR,&r[1]);CHKERRQ(ierr); 1134 ierr = PetscStrallocpy(PETSC_LIB_DIR,&r[2]);CHKERRQ(ierr); 1135 ierr = PetscMalloc1(256,&r[3]);CHKERRQ(ierr); 1136 ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[4]);CHKERRQ(ierr); 1137 ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[5]);CHKERRQ(ierr); 1138 ierr = PetscMalloc1(256,&r[6]);CHKERRQ(ierr); 1139 ierr = PetscMalloc1(256,&r[7]);CHKERRQ(ierr); 1140 ierr = PetscGetDisplay(r[3],256);CHKERRQ(ierr); 1141 ierr = PetscGetHomeDirectory(r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 1142 ierr = PetscGetWorkingDirectory(r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 1143 ierr = PetscGetUserName(r[6],256);CHKERRQ(ierr); 1144 ierr = PetscGetHostName(r[7],256);CHKERRQ(ierr); 1145 1146 /* replace that are in environment */ 1147 ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr); 1148 if (flag) { 1149 ierr = PetscFree(r[2]);CHKERRQ(ierr); 1150 ierr = PetscStrallocpy(env,&r[2]);CHKERRQ(ierr); 1151 } 1152 1153 /* replace the requested strings */ 1154 ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr); 1155 while (s[i]) { 1156 ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr); 1157 ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr); 1158 while (par) { 1159 *par = 0; 1160 par += l; 1161 1162 ierr = PetscStrlen(b,&l1);CHKERRQ(ierr); 1163 ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr); 1164 ierr = PetscStrlen(par,&l3);CHKERRQ(ierr); 1165 if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values"); 1166 ierr = PetscStrcpy(work,b);CHKERRQ(ierr); 1167 ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr); 1168 ierr = PetscStrcat(work,par);CHKERRQ(ierr); 1169 ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr); 1170 ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr); 1171 } 1172 i++; 1173 } 1174 i = 0; 1175 while (r[i]) { 1176 tfree = (char*)r[i]; 1177 ierr = PetscFree(tfree);CHKERRQ(ierr); 1178 i++; 1179 } 1180 1181 /* look for any other ${xxx} strings to replace from environmental variables */ 1182 ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr); 1183 while (par) { 1184 *par = 0; 1185 par += 2; 1186 ierr = PetscStrcpy(work,b);CHKERRQ(ierr); 1187 ierr = PetscStrstr(par,"}",&epar);CHKERRQ(ierr); 1188 *epar = 0; 1189 epar += 1; 1190 ierr = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr); 1191 if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par); 1192 ierr = PetscStrcat(work,env);CHKERRQ(ierr); 1193 ierr = PetscStrcat(work,epar);CHKERRQ(ierr); 1194 ierr = PetscStrcpy(b,work);CHKERRQ(ierr); 1195 ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr); 1196 } 1197 ierr = PetscFree(work);CHKERRQ(ierr); 1198 if (aa == b) { 1199 ierr = PetscFree(a);CHKERRQ(ierr); 1200 } 1201 PetscFunctionReturn(0); 1202 } 1203 1204 /*@C 1205 PetscEListFind - searches list of strings for given string, using case insensitive matching 1206 1207 Not Collective 1208 1209 Input Parameters: 1210 + n - number of strings in 1211 . list - list of strings to search 1212 - str - string to look for, empty string "" accepts default (first entry in list) 1213 1214 Output Parameters: 1215 + value - index of matching string (if found) 1216 - found - boolean indicating whether string was found (can be NULL) 1217 1218 Notes: 1219 Not for use in Fortran 1220 1221 Level: advanced 1222 @*/ 1223 PetscErrorCode PetscEListFind(PetscInt n,const char *const *list,const char *str,PetscInt *value,PetscBool *found) 1224 { 1225 PetscErrorCode ierr; 1226 PetscBool matched; 1227 PetscInt i; 1228 1229 PetscFunctionBegin; 1230 if (found) *found = PETSC_FALSE; 1231 for (i=0; i<n; i++) { 1232 ierr = PetscStrcasecmp(str,list[i],&matched);CHKERRQ(ierr); 1233 if (matched || !str[0]) { 1234 if (found) *found = PETSC_TRUE; 1235 *value = i; 1236 break; 1237 } 1238 } 1239 PetscFunctionReturn(0); 1240 } 1241 1242 /*@C 1243 PetscEnumFind - searches enum list of strings for given string, using case insensitive matching 1244 1245 Not Collective 1246 1247 Input Parameters: 1248 + enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL 1249 - str - string to look for 1250 1251 Output Parameters: 1252 + value - index of matching string (if found) 1253 - found - boolean indicating whether string was found (can be NULL) 1254 1255 Notes: 1256 Not for use in Fortran 1257 1258 Level: advanced 1259 @*/ 1260 PetscErrorCode PetscEnumFind(const char *const *enumlist,const char *str,PetscEnum *value,PetscBool *found) 1261 { 1262 PetscErrorCode ierr; 1263 PetscInt n = 0,evalue; 1264 PetscBool efound; 1265 1266 PetscFunctionBegin; 1267 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"); 1268 if (n < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix"); 1269 n -= 3; /* drop enum name, prefix, and null termination */ 1270 ierr = PetscEListFind(n,enumlist,str,&evalue,&efound);CHKERRQ(ierr); 1271 if (efound) *value = (PetscEnum)evalue; 1272 if (found) *found = efound; 1273 PetscFunctionReturn(0); 1274 } 1275