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