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