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