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