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