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