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