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