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 1009 /*@C 1010 PetscGetPetscDir - Gets the directory PETSc is installed in 1011 1012 Not Collective 1013 1014 Output Parameter: 1015 . dir - the directory 1016 1017 Level: developer 1018 1019 Notes: Not for use in Fortran 1020 1021 @*/ 1022 PetscErrorCode PetscGetPetscDir(const char *dir[]) 1023 { 1024 PetscFunctionBegin; 1025 *dir = PETSC_DIR; 1026 PetscFunctionReturn(0); 1027 } 1028 1029 /*@C 1030 PetscStrreplace - Replaces substrings in string with other substrings 1031 1032 Not Collective 1033 1034 Input Parameters: 1035 + comm - MPI_Comm of processors that are processing the string 1036 . aa - the string to look in 1037 . b - the resulting copy of a with replaced strings (b can be the same as a) 1038 - len - the length of b 1039 1040 Notes: 1041 Replaces ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY}, 1042 ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values 1043 as well as any environmental variables. 1044 1045 PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what 1046 PETSc was built with and do not use environmental variables. 1047 1048 Not for use in Fortran 1049 1050 Level: intermediate 1051 1052 @*/ 1053 PetscErrorCode PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len) 1054 { 1055 PetscErrorCode ierr; 1056 int i = 0; 1057 size_t l,l1,l2,l3; 1058 char *work,*par,*epar,env[1024],*tfree,*a = (char*)aa; 1059 const char *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0}; 1060 char *r[] = {0,0,0,0,0,0,0,0,0}; 1061 PetscBool flag; 1062 1063 PetscFunctionBegin; 1064 if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull"); 1065 if (aa == b) { 1066 ierr = PetscStrallocpy(aa,(char**)&a);CHKERRQ(ierr); 1067 } 1068 ierr = PetscMalloc1(len,&work);CHKERRQ(ierr); 1069 1070 /* get values for replaced variables */ 1071 ierr = PetscStrallocpy(PETSC_ARCH,&r[0]);CHKERRQ(ierr); 1072 ierr = PetscStrallocpy(PETSC_DIR,&r[1]);CHKERRQ(ierr); 1073 ierr = PetscStrallocpy(PETSC_LIB_DIR,&r[2]);CHKERRQ(ierr); 1074 ierr = PetscMalloc1(256,&r[3]);CHKERRQ(ierr); 1075 ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[4]);CHKERRQ(ierr); 1076 ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[5]);CHKERRQ(ierr); 1077 ierr = PetscMalloc1(256,&r[6]);CHKERRQ(ierr); 1078 ierr = PetscMalloc1(256,&r[7]);CHKERRQ(ierr); 1079 ierr = PetscGetDisplay(r[3],256);CHKERRQ(ierr); 1080 ierr = PetscGetHomeDirectory(r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 1081 ierr = PetscGetWorkingDirectory(r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 1082 ierr = PetscGetUserName(r[6],256);CHKERRQ(ierr); 1083 ierr = PetscGetHostName(r[7],256);CHKERRQ(ierr); 1084 1085 /* replace that are in environment */ 1086 ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr); 1087 if (flag) { 1088 ierr = PetscFree(r[2]);CHKERRQ(ierr); 1089 ierr = PetscStrallocpy(env,&r[2]);CHKERRQ(ierr); 1090 } 1091 1092 /* replace the requested strings */ 1093 ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr); 1094 while (s[i]) { 1095 ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr); 1096 ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr); 1097 while (par) { 1098 *par = 0; 1099 par += l; 1100 1101 ierr = PetscStrlen(b,&l1);CHKERRQ(ierr); 1102 ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr); 1103 ierr = PetscStrlen(par,&l3);CHKERRQ(ierr); 1104 if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values"); 1105 ierr = PetscStrcpy(work,b);CHKERRQ(ierr); 1106 ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr); 1107 ierr = PetscStrcat(work,par);CHKERRQ(ierr); 1108 ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr); 1109 ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr); 1110 } 1111 i++; 1112 } 1113 i = 0; 1114 while (r[i]) { 1115 tfree = (char*)r[i]; 1116 ierr = PetscFree(tfree);CHKERRQ(ierr); 1117 i++; 1118 } 1119 1120 /* look for any other ${xxx} strings to replace from environmental variables */ 1121 ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr); 1122 while (par) { 1123 *par = 0; 1124 par += 2; 1125 ierr = PetscStrcpy(work,b);CHKERRQ(ierr); 1126 ierr = PetscStrstr(par,"}",&epar);CHKERRQ(ierr); 1127 *epar = 0; 1128 epar += 1; 1129 ierr = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr); 1130 if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par); 1131 ierr = PetscStrcat(work,env);CHKERRQ(ierr); 1132 ierr = PetscStrcat(work,epar);CHKERRQ(ierr); 1133 ierr = PetscStrcpy(b,work);CHKERRQ(ierr); 1134 ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr); 1135 } 1136 ierr = PetscFree(work);CHKERRQ(ierr); 1137 if (aa == b) { 1138 ierr = PetscFree(a);CHKERRQ(ierr); 1139 } 1140 PetscFunctionReturn(0); 1141 } 1142 1143 /*@C 1144 PetscEListFind - searches list of strings for given string, using case insensitive matching 1145 1146 Not Collective 1147 1148 Input Parameters: 1149 + n - number of strings in 1150 . list - list of strings to search 1151 - str - string to look for, empty string "" accepts default (first entry in list) 1152 1153 Output Parameters: 1154 + value - index of matching string (if found) 1155 - found - boolean indicating whether string was found (can be NULL) 1156 1157 Notes: 1158 Not for use in Fortran 1159 1160 Level: advanced 1161 @*/ 1162 PetscErrorCode PetscEListFind(PetscInt n,const char *const *list,const char *str,PetscInt *value,PetscBool *found) 1163 { 1164 PetscErrorCode ierr; 1165 PetscBool matched; 1166 PetscInt i; 1167 1168 PetscFunctionBegin; 1169 if (found) *found = PETSC_FALSE; 1170 for (i=0; i<n; i++) { 1171 ierr = PetscStrcasecmp(str,list[i],&matched);CHKERRQ(ierr); 1172 if (matched || !str[0]) { 1173 if (found) *found = PETSC_TRUE; 1174 *value = i; 1175 break; 1176 } 1177 } 1178 PetscFunctionReturn(0); 1179 } 1180 1181 /*@C 1182 PetscEListFind - searches enum list of strings for given string, using case insensitive matching 1183 1184 Not Collective 1185 1186 Input Parameters: 1187 + enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL 1188 - str - string to look for 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 PetscEnumFind(const char *const *enumlist,const char *str,PetscEnum *value,PetscBool *found) 1200 { 1201 PetscErrorCode ierr; 1202 PetscInt n = 0,evalue; 1203 PetscBool efound; 1204 1205 PetscFunctionBegin; 1206 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"); 1207 if (n < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix"); 1208 n -= 3; /* drop enum name, prefix, and null termination */ 1209 ierr = PetscEListFind(n,enumlist,str,&evalue,&efound);CHKERRQ(ierr); 1210 if (efound) *value = (PetscEnum)evalue; 1211 if (found) *found = efound; 1212 PetscFunctionReturn(0); 1213 } 1214