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