1 2 /* 3 We define the string operations here. The reason we just do not use 4 the standard string routines in the PETSc code is that on some machines 5 they are broken or have the wrong prototypes. 6 7 */ 8 #include <petscsys.h> /*I "petscsys.h" I*/ 9 #if defined(PETSC_HAVE_STRING_H) 10 #include <string.h> /* strstr */ 11 #endif 12 #if defined(PETSC_HAVE_STRINGS_H) 13 # include <strings.h> /* strcasecmp */ 14 #endif 15 16 /*@C 17 PetscStrToArray - Separates a string by a charactor (for example ' ' or '\n') and creates an array of strings 18 19 Not Collective 20 21 Input Parameters: 22 + s - pointer to string 23 - sp - separator charactor 24 25 Output Parameter: 26 + argc - the number of entries in the array 27 - args - an array of the entries with a null at the end 28 29 Level: intermediate 30 31 Notes: 32 this may be called before PetscInitialize() or after PetscFinalize() 33 34 Not for use in Fortran 35 36 Developer Notes: 37 Using raw malloc() and does not call error handlers since this may be used before PETSc is initialized. Used 38 to generate argc, args arguments passed to MPI_Init() 39 40 .seealso: PetscStrToArrayDestroy(), PetscToken, PetscTokenCreate() 41 42 @*/ 43 PetscErrorCode PetscStrToArray(const char s[],char sp,int *argc,char ***args) 44 { 45 int i,j,n,*lens,cnt = 0; 46 PetscBool flg = PETSC_FALSE; 47 48 if (!s) n = 0; 49 else n = strlen(s); 50 *argc = 0; 51 *args = NULL; 52 for (; n>0; n--) { /* remove separator chars at the end - and will empty the string if all chars are separator chars */ 53 if (s[n-1] != sp) break; 54 } 55 if (!n) { 56 return(0); 57 } 58 for (i=0; i<n; i++) { 59 if (s[i] != sp) break; 60 } 61 for (;i<n+1; i++) { 62 if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;} 63 else if (s[i] != sp) {flg = PETSC_FALSE;} 64 } 65 (*args) = (char**) malloc(((*argc)+1)*sizeof(char*)); if (!*args) return PETSC_ERR_MEM; 66 lens = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM; 67 for (i=0; i<*argc; i++) lens[i] = 0; 68 69 *argc = 0; 70 for (i=0; i<n; i++) { 71 if (s[i] != sp) break; 72 } 73 for (;i<n+1; i++) { 74 if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;} 75 else if (s[i] != sp) {lens[*argc]++;flg = PETSC_FALSE;} 76 } 77 78 for (i=0; i<*argc; i++) { 79 (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char)); 80 if (!(*args)[i]) { 81 free(lens); 82 for (j=0; j<i; j++) free((*args)[j]); 83 free(*args); 84 return PETSC_ERR_MEM; 85 } 86 } 87 free(lens); 88 (*args)[*argc] = 0; 89 90 *argc = 0; 91 for (i=0; i<n; i++) { 92 if (s[i] != sp) break; 93 } 94 for (;i<n+1; i++) { 95 if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;} 96 else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;} 97 } 98 return 0; 99 } 100 101 /*@C 102 PetscStrToArrayDestroy - Frees array created with PetscStrToArray(). 103 104 Not Collective 105 106 Output Parameters: 107 + argc - the number of arguments 108 - args - the array of arguments 109 110 Level: intermediate 111 112 Notes: 113 This may be called before PetscInitialize() or after PetscFinalize() 114 115 Not for use in Fortran 116 117 .seealso: PetscStrToArray() 118 119 @*/ 120 PetscErrorCode PetscStrToArrayDestroy(int argc,char **args) 121 { 122 PetscInt i; 123 124 for (i=0; i<argc; i++) free(args[i]); 125 if (args) free(args); 126 return 0; 127 } 128 129 /*@C 130 PetscStrlen - Gets length of a string 131 132 Not Collective 133 134 Input Parameters: 135 . s - pointer to string 136 137 Output Parameter: 138 . len - length in bytes 139 140 Level: intermediate 141 142 Note: 143 This routine is analogous to strlen(). 144 145 Null string returns a length of zero 146 147 Not for use in Fortran 148 149 @*/ 150 PetscErrorCode PetscStrlen(const char s[],size_t *len) 151 { 152 PetscFunctionBegin; 153 if (!s) *len = 0; 154 else *len = strlen(s); 155 PetscFunctionReturn(0); 156 } 157 158 /*@C 159 PetscStrallocpy - Allocates space to hold a copy of a string then copies the string 160 161 Not Collective 162 163 Input Parameters: 164 . s - pointer to string 165 166 Output Parameter: 167 . t - the copied string 168 169 Level: intermediate 170 171 Note: 172 Null string returns a new null string 173 174 Not for use in Fortran 175 176 @*/ 177 PetscErrorCode PetscStrallocpy(const char s[],char *t[]) 178 { 179 PetscErrorCode ierr; 180 size_t len; 181 char *tmp = 0; 182 183 PetscFunctionBegin; 184 if (s) { 185 ierr = PetscStrlen(s,&len);CHKERRQ(ierr); 186 ierr = PetscMalloc1(1+len,&tmp);CHKERRQ(ierr); 187 ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr); 188 } 189 *t = tmp; 190 PetscFunctionReturn(0); 191 } 192 193 /*@C 194 PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings 195 196 Not Collective 197 198 Input Parameters: 199 . s - pointer to array of strings (final string is a null) 200 201 Output Parameter: 202 . t - the copied array string 203 204 Level: intermediate 205 206 Note: 207 Not for use in Fortran 208 209 .seealso: PetscStrallocpy() PetscStrArrayDestroy() 210 211 @*/ 212 PetscErrorCode PetscStrArrayallocpy(const char *const *list,char ***t) 213 { 214 PetscErrorCode ierr; 215 PetscInt i,n = 0; 216 217 PetscFunctionBegin; 218 while (list[n++]) ; 219 ierr = PetscMalloc1(n+1,t);CHKERRQ(ierr); 220 for (i=0; i<n; i++) { 221 ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr); 222 } 223 (*t)[n] = NULL; 224 PetscFunctionReturn(0); 225 } 226 227 /*@C 228 PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy(). 229 230 Not Collective 231 232 Output Parameters: 233 . list - array of strings 234 235 Level: intermediate 236 237 Notes: 238 Not for use in Fortran 239 240 .seealso: PetscStrArrayallocpy() 241 242 @*/ 243 PetscErrorCode PetscStrArrayDestroy(char ***list) 244 { 245 PetscInt n = 0; 246 PetscErrorCode ierr; 247 248 PetscFunctionBegin; 249 if (!*list) PetscFunctionReturn(0); 250 while ((*list)[n]) { 251 ierr = PetscFree((*list)[n]);CHKERRQ(ierr); 252 n++; 253 } 254 ierr = PetscFree(*list);CHKERRQ(ierr); 255 PetscFunctionReturn(0); 256 } 257 258 /*@C 259 PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings 260 261 Not Collective 262 263 Input Parameters: 264 + n - the number of string entries 265 - s - pointer to array of strings 266 267 Output Parameter: 268 . t - the copied array string 269 270 Level: intermediate 271 272 Note: 273 Not for use in Fortran 274 275 .seealso: PetscStrallocpy() PetscStrArrayDestroy() 276 277 @*/ 278 PetscErrorCode PetscStrNArrayallocpy(PetscInt n,const char *const *list,char ***t) 279 { 280 PetscErrorCode ierr; 281 PetscInt i; 282 283 PetscFunctionBegin; 284 ierr = PetscMalloc1(n,t);CHKERRQ(ierr); 285 for (i=0; i<n; i++) { 286 ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr); 287 } 288 PetscFunctionReturn(0); 289 } 290 291 /*@C 292 PetscStrNArrayDestroy - Frees array of strings created with PetscStrArrayallocpy(). 293 294 Not Collective 295 296 Output Parameters: 297 + n - number of string entries 298 - list - array of strings 299 300 Level: intermediate 301 302 Notes: 303 Not for use in Fortran 304 305 .seealso: PetscStrArrayallocpy() 306 307 @*/ 308 PetscErrorCode PetscStrNArrayDestroy(PetscInt n,char ***list) 309 { 310 PetscErrorCode ierr; 311 PetscInt i; 312 313 PetscFunctionBegin; 314 if (!*list) PetscFunctionReturn(0); 315 for (i=0; i<n; i++){ 316 ierr = PetscFree((*list)[i]);CHKERRQ(ierr); 317 } 318 ierr = PetscFree(*list);CHKERRQ(ierr); 319 PetscFunctionReturn(0); 320 } 321 322 /*@C 323 PetscStrcpy - Copies a string 324 325 Not Collective 326 327 Input Parameters: 328 . t - pointer to string 329 330 Output Parameter: 331 . s - the copied string 332 333 Level: intermediate 334 335 Notes: 336 Null string returns a string starting with zero 337 338 Not for use in Fortran 339 340 .seealso: PetscStrncpy(), PetscStrcat(), PetscStrlcat() 341 342 @*/ 343 344 PetscErrorCode PetscStrcpy(char s[],const char t[]) 345 { 346 PetscFunctionBegin; 347 if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer"); 348 if (t) strcpy(s,t); 349 else if (s) s[0] = 0; 350 PetscFunctionReturn(0); 351 } 352 353 /*@C 354 PetscStrncpy - Copies a string up to a certain length 355 356 Not Collective 357 358 Input Parameters: 359 + t - pointer to string 360 - n - the length to copy 361 362 Output Parameter: 363 . s - the copied string 364 365 Level: intermediate 366 367 Note: 368 Null string returns a string starting with zero 369 370 If the string that is being copied is of length n or larger then the entire string is not 371 copied and the final location of s is set to NULL. This is different then the behavior of 372 strncpy() which leaves s non-terminated if there is not room for the entire string. 373 374 Developers Note: Should this be PetscStrlcpy() to reflect its behavior which is like strlcpy() not strncpy() 375 376 .seealso: PetscStrcpy(), PetscStrcat(), PetscStrlcat() 377 378 @*/ 379 PetscErrorCode PetscStrncpy(char s[],const char t[],size_t n) 380 { 381 PetscFunctionBegin; 382 if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer"); 383 if (s && !n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Requires an output string of length at least 1 to hold the termination character"); 384 if (t) { 385 if (n > 1) { 386 strncpy(s,t,n-1); 387 s[n-1] = '\0'; 388 } else { 389 s[0] = '\0'; 390 } 391 } else if (s) s[0] = 0; 392 PetscFunctionReturn(0); 393 } 394 395 /*@C 396 PetscStrcat - Concatenates a string onto a given string 397 398 Not Collective 399 400 Input Parameters: 401 + s - string to be added to 402 - t - pointer to string to be added to end 403 404 Level: intermediate 405 406 Notes: 407 Not for use in Fortran 408 409 .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrlcat() 410 411 @*/ 412 PetscErrorCode PetscStrcat(char s[],const char t[]) 413 { 414 PetscFunctionBegin; 415 if (!t) PetscFunctionReturn(0); 416 strcat(s,t); 417 PetscFunctionReturn(0); 418 } 419 420 /*@C 421 PetscStrlcat - Concatenates a string onto a given string, up to a given length 422 423 Not Collective 424 425 Input Parameters: 426 + s - pointer to string to be added to at end 427 . t - string to be added to 428 - n - length of the original allocated string 429 430 Level: intermediate 431 432 Notes: 433 Not for use in Fortran 434 435 Unlike the system call strncat(), the length passed in is the length of the 436 original allocated space, not the length of the left-over space. This is 437 similar to the BSD system call strlcat(). 438 439 .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat() 440 441 @*/ 442 PetscErrorCode PetscStrlcat(char s[],const char t[],size_t n) 443 { 444 size_t len; 445 PetscErrorCode ierr; 446 447 PetscFunctionBegin; 448 if (t && !n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"String buffer length must be positive"); 449 if (!t) PetscFunctionReturn(0); 450 ierr = PetscStrlen(t,&len);CHKERRQ(ierr); 451 strncat(s,t,n - len); 452 s[n-1] = 0; 453 PetscFunctionReturn(0); 454 } 455 456 void PetscStrcmpNoError(const char a[],const char b[],PetscBool *flg) 457 { 458 int c; 459 460 if (!a && !b) *flg = PETSC_TRUE; 461 else if (!a || !b) *flg = PETSC_FALSE; 462 else { 463 c = strcmp(a,b); 464 if (c) *flg = PETSC_FALSE; 465 else *flg = PETSC_TRUE; 466 } 467 } 468 469 /*@C 470 PetscStrcmp - Compares two strings, 471 472 Not Collective 473 474 Input Parameters: 475 + a - pointer to string first string 476 - b - pointer to second string 477 478 Output Parameter: 479 . flg - PETSC_TRUE if the two strings are equal 480 481 Level: intermediate 482 483 Notes: 484 Not for use in Fortran 485 486 .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp() 487 488 @*/ 489 PetscErrorCode PetscStrcmp(const char a[],const char b[],PetscBool *flg) 490 { 491 int c; 492 493 PetscFunctionBegin; 494 if (!a && !b) *flg = PETSC_TRUE; 495 else if (!a || !b) *flg = PETSC_FALSE; 496 else { 497 c = strcmp(a,b); 498 if (c) *flg = PETSC_FALSE; 499 else *flg = PETSC_TRUE; 500 } 501 PetscFunctionReturn(0); 502 } 503 504 /*@C 505 PetscStrgrt - If first string is greater than the second 506 507 Not Collective 508 509 Input Parameters: 510 + a - pointer to first string 511 - b - pointer to second string 512 513 Output Parameter: 514 . flg - if the first string is greater 515 516 Notes: 517 Null arguments are ok, a null string is considered smaller than 518 all others 519 520 Not for use in Fortran 521 522 Level: intermediate 523 524 .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp() 525 526 @*/ 527 PetscErrorCode PetscStrgrt(const char a[],const char b[],PetscBool *t) 528 { 529 int c; 530 531 PetscFunctionBegin; 532 if (!a && !b) *t = PETSC_FALSE; 533 else if (a && !b) *t = PETSC_TRUE; 534 else if (!a && b) *t = PETSC_FALSE; 535 else { 536 c = strcmp(a,b); 537 if (c > 0) *t = PETSC_TRUE; 538 else *t = PETSC_FALSE; 539 } 540 PetscFunctionReturn(0); 541 } 542 543 /*@C 544 PetscStrcasecmp - Returns true if the two strings are the same 545 except possibly for case. 546 547 Not Collective 548 549 Input Parameters: 550 + a - pointer to first string 551 - b - pointer to second string 552 553 Output Parameter: 554 . flg - if the two strings are the same 555 556 Notes: 557 Null arguments are ok 558 559 Not for use in Fortran 560 561 Level: intermediate 562 563 .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt() 564 565 @*/ 566 PetscErrorCode PetscStrcasecmp(const char a[],const char b[],PetscBool *t) 567 { 568 int c; 569 570 PetscFunctionBegin; 571 if (!a && !b) c = 0; 572 else if (!a || !b) c = 1; 573 #if defined(PETSC_HAVE_STRCASECMP) 574 else c = strcasecmp(a,b); 575 #elif defined(PETSC_HAVE_STRICMP) 576 else c = stricmp(a,b); 577 #else 578 else { 579 char *aa,*bb; 580 PetscErrorCode ierr; 581 ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr); 582 ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr); 583 ierr = PetscStrtolower(aa);CHKERRQ(ierr); 584 ierr = PetscStrtolower(bb);CHKERRQ(ierr); 585 ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr); 586 ierr = PetscFree(aa);CHKERRQ(ierr); 587 ierr = PetscFree(bb);CHKERRQ(ierr); 588 PetscFunctionReturn(0); 589 } 590 #endif 591 if (!c) *t = PETSC_TRUE; 592 else *t = PETSC_FALSE; 593 PetscFunctionReturn(0); 594 } 595 596 597 598 /*@C 599 PetscStrncmp - Compares two strings, up to a certain length 600 601 Not Collective 602 603 Input Parameters: 604 + a - pointer to first string 605 . b - pointer to second string 606 - n - length to compare up to 607 608 Output Parameter: 609 . t - if the two strings are equal 610 611 Level: intermediate 612 613 Notes: 614 Not for use in Fortran 615 616 .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp() 617 618 @*/ 619 PetscErrorCode PetscStrncmp(const char a[],const char b[],size_t n,PetscBool *t) 620 { 621 int c; 622 623 PetscFunctionBegin; 624 c = strncmp(a,b,n); 625 if (!c) *t = PETSC_TRUE; 626 else *t = PETSC_FALSE; 627 PetscFunctionReturn(0); 628 } 629 630 /*@C 631 PetscStrchr - Locates first occurance of a character in a string 632 633 Not Collective 634 635 Input Parameters: 636 + a - pointer to string 637 - b - character 638 639 Output Parameter: 640 . c - location of occurance, NULL if not found 641 642 Level: intermediate 643 644 Notes: 645 Not for use in Fortran 646 647 @*/ 648 PetscErrorCode PetscStrchr(const char a[],char b,char *c[]) 649 { 650 PetscFunctionBegin; 651 *c = (char*)strchr(a,b); 652 PetscFunctionReturn(0); 653 } 654 655 /*@C 656 PetscStrrchr - Locates one location past the last occurance of a character in a string, 657 if the character is not found then returns entire string 658 659 Not Collective 660 661 Input Parameters: 662 + a - pointer to string 663 - b - character 664 665 Output Parameter: 666 . tmp - location of occurance, a if not found 667 668 Level: intermediate 669 670 Notes: 671 Not for use in Fortran 672 673 @*/ 674 PetscErrorCode PetscStrrchr(const char a[],char b,char *tmp[]) 675 { 676 PetscFunctionBegin; 677 *tmp = (char*)strrchr(a,b); 678 if (!*tmp) *tmp = (char*)a; 679 else *tmp = *tmp + 1; 680 PetscFunctionReturn(0); 681 } 682 683 /*@C 684 PetscStrtolower - Converts string to lower case 685 686 Not Collective 687 688 Input Parameters: 689 . a - pointer to string 690 691 Level: intermediate 692 693 Notes: 694 Not for use in Fortran 695 696 @*/ 697 PetscErrorCode PetscStrtolower(char a[]) 698 { 699 PetscFunctionBegin; 700 while (*a) { 701 if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A'; 702 a++; 703 } 704 PetscFunctionReturn(0); 705 } 706 707 /*@C 708 PetscStrtoupper - Converts string to upper case 709 710 Not Collective 711 712 Input Parameters: 713 . a - pointer to string 714 715 Level: intermediate 716 717 Notes: 718 Not for use in Fortran 719 720 @*/ 721 PetscErrorCode PetscStrtoupper(char a[]) 722 { 723 PetscFunctionBegin; 724 while (*a) { 725 if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a'; 726 a++; 727 } 728 PetscFunctionReturn(0); 729 } 730 731 /*@C 732 PetscStrendswith - Determines if a string ends with a certain string 733 734 Not Collective 735 736 Input Parameters: 737 + a - pointer to string 738 - b - string to endwith 739 740 Output Parameter: 741 . flg - PETSC_TRUE or PETSC_FALSE 742 743 Notes: 744 Not for use in Fortran 745 746 Level: intermediate 747 748 @*/ 749 PetscErrorCode PetscStrendswith(const char a[],const char b[],PetscBool *flg) 750 { 751 char *test; 752 PetscErrorCode ierr; 753 size_t na,nb; 754 755 PetscFunctionBegin; 756 *flg = PETSC_FALSE; 757 ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr); 758 if (test) { 759 ierr = PetscStrlen(a,&na);CHKERRQ(ierr); 760 ierr = PetscStrlen(b,&nb);CHKERRQ(ierr); 761 if (a+na-nb == test) *flg = PETSC_TRUE; 762 } 763 PetscFunctionReturn(0); 764 } 765 766 /*@C 767 PetscStrbeginswith - Determines if a string begins with a certain string 768 769 Not Collective 770 771 Input Parameters: 772 + a - pointer to string 773 - b - string to begin with 774 775 Output Parameter: 776 . flg - PETSC_TRUE or PETSC_FALSE 777 778 Notes: 779 Not for use in Fortran 780 781 Level: intermediate 782 783 .seealso: PetscStrendswithwhich(), PetscStrendswith(), PetscStrtoupper, PetscStrtolower(), PetscStrrchr(), PetscStrchr(), 784 PetscStrncmp(), PetscStrlen(), PetscStrncmp(), PetscStrcmp() 785 786 @*/ 787 PetscErrorCode PetscStrbeginswith(const char a[],const char b[],PetscBool *flg) 788 { 789 char *test; 790 PetscErrorCode ierr; 791 792 PetscFunctionBegin; 793 *flg = PETSC_FALSE; 794 ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr); 795 if (test && (test == a)) *flg = PETSC_TRUE; 796 PetscFunctionReturn(0); 797 } 798 799 800 /*@C 801 PetscStrendswithwhich - Determines if a string ends with one of several possible strings 802 803 Not Collective 804 805 Input Parameters: 806 + a - pointer to string 807 - bs - strings to endwith (last entry must be null) 808 809 Output Parameter: 810 . cnt - the index of the string it ends with or 1+the last possible index 811 812 Notes: 813 Not for use in Fortran 814 815 Level: intermediate 816 817 @*/ 818 PetscErrorCode PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt) 819 { 820 PetscBool flg; 821 PetscErrorCode ierr; 822 823 PetscFunctionBegin; 824 *cnt = 0; 825 while (bs[*cnt]) { 826 ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr); 827 if (flg) PetscFunctionReturn(0); 828 *cnt += 1; 829 } 830 PetscFunctionReturn(0); 831 } 832 833 /*@C 834 PetscStrrstr - Locates last occurance of string in another string 835 836 Not Collective 837 838 Input Parameters: 839 + a - pointer to string 840 - b - string to find 841 842 Output Parameter: 843 . tmp - location of occurance 844 845 Notes: 846 Not for use in Fortran 847 848 Level: intermediate 849 850 @*/ 851 PetscErrorCode PetscStrrstr(const char a[],const char b[],char *tmp[]) 852 { 853 const char *stmp = a, *ltmp = 0; 854 855 PetscFunctionBegin; 856 while (stmp) { 857 stmp = (char*)strstr(stmp,b); 858 if (stmp) {ltmp = stmp;stmp++;} 859 } 860 *tmp = (char*)ltmp; 861 PetscFunctionReturn(0); 862 } 863 864 /*@C 865 PetscStrstr - Locates first occurance of string in another string 866 867 Not Collective 868 869 Input Parameters: 870 + haystack - string to search 871 - needle - string to find 872 873 Output Parameter: 874 . tmp - location of occurance, is a NULL if the string is not found 875 876 Notes: 877 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: 994 Not for use in Fortran 995 996 .seealso: PetscTokenCreate(), PetscTokenFind() 997 @*/ 998 PetscErrorCode PetscTokenDestroy(PetscToken *a) 999 { 1000 PetscErrorCode ierr; 1001 1002 PetscFunctionBegin; 1003 if (!*a) PetscFunctionReturn(0); 1004 ierr = PetscFree((*a)->array);CHKERRQ(ierr); 1005 ierr = PetscFree(*a);CHKERRQ(ierr); 1006 PetscFunctionReturn(0); 1007 } 1008 1009 /*@C 1010 PetscStrInList - search string in character-delimited list 1011 1012 Not Collective 1013 1014 Input Parameters: 1015 + str - the string to look for 1016 . list - the list to search in 1017 - sep - the separator character 1018 1019 Output Parameter: 1020 . found - whether str is in list 1021 1022 Level: intermediate 1023 1024 Notes: 1025 Not for use in Fortran 1026 1027 .seealso: PetscTokenCreate(), PetscTokenFind(), PetscStrcmp() 1028 @*/ 1029 PetscErrorCode PetscStrInList(const char str[],const char list[],char sep,PetscBool *found) 1030 { 1031 PetscToken token; 1032 char *item; 1033 PetscErrorCode ierr; 1034 1035 PetscFunctionBegin; 1036 *found = PETSC_FALSE; 1037 ierr = PetscTokenCreate(list,sep,&token);CHKERRQ(ierr); 1038 ierr = PetscTokenFind(token,&item);CHKERRQ(ierr); 1039 while (item) { 1040 ierr = PetscStrcmp(str,item,found);CHKERRQ(ierr); 1041 if (*found) break; 1042 ierr = PetscTokenFind(token,&item);CHKERRQ(ierr); 1043 } 1044 ierr = PetscTokenDestroy(&token);CHKERRQ(ierr); 1045 PetscFunctionReturn(0); 1046 } 1047 1048 /*@C 1049 PetscGetPetscDir - Gets the directory PETSc is installed in 1050 1051 Not Collective 1052 1053 Output Parameter: 1054 . dir - the directory 1055 1056 Level: developer 1057 1058 Notes: 1059 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