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> 11 #endif 12 #if defined(PETSC_HAVE_STRINGS_H) 13 #include <strings.h> 14 #endif 15 16 #undef __FUNCT__ 17 #define __FUNCT__ "PetscStrToArray" 18 /*@C 19 PetscStrToArray - Seperates a string by its spaces and creates an array of strings 20 21 Not Collective 22 23 Input Parameters: 24 . s - pointer to string 25 26 Output Parameter: 27 + argc - the number of entries in the array 28 - args - an array of the entries with a null at the end 29 30 Level: intermediate 31 32 Notes: this may be called before PetscInitialize() or after PetscFinalize() 33 34 Not for use in Fortran 35 36 Developer Notes: Using raw malloc() and does not call error handlers since this may be used before PETSc is initialized. Used 37 to generate argc, args arguments passed to MPI_Init() 38 39 .seealso: PetscStrToArrayDestroy(), PetscToken, PetscTokenCreate() 40 41 @*/ 42 PetscErrorCode PetscStrToArray(const char s[],int *argc,char ***args) 43 { 44 int i,n,*lens,cnt = 0; 45 PetscBool flg = PETSC_FALSE; 46 47 n = strlen(s); 48 *argc = 0; 49 for (i=0; i<n; i++) { 50 if (s[i] != ' ') break; 51 } 52 for (;i<n+1; i++) { 53 if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;} 54 else if (s[i] != ' ') {flg = PETSC_FALSE;} 55 } 56 (*args) = (char **) malloc(((*argc)+1)*sizeof(char**)); if (!*args) return PETSC_ERR_MEM; 57 lens = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM; 58 for (i=0; i<*argc; i++) lens[i] = 0; 59 60 *argc = 0; 61 for (i=0; i<n; i++) { 62 if (s[i] != ' ') break; 63 } 64 for (;i<n+1; i++) { 65 if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;} 66 else if (s[i] != ' ') {lens[*argc]++;flg = PETSC_FALSE;} 67 } 68 69 for (i=0; i<*argc; i++) { 70 (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char)); if (!(*args)[i]) return PETSC_ERR_MEM; 71 } 72 (*args)[*argc] = 0; 73 74 *argc = 0; 75 for (i=0; i<n; i++) { 76 if (s[i] != ' ') break; 77 } 78 for (;i<n+1; i++) { 79 if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;} 80 else if (s[i] != ' ' && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;} 81 } 82 return 0; 83 } 84 85 #undef __FUNCT__ 86 #define __FUNCT__ "PetscStrToArrayDestroy" 87 /*@C 88 PetscStrToArrayDestroy - Frees array created with PetscStrToArray(). 89 90 Not Collective 91 92 Output Parameters: 93 + argc - the number of arguments 94 - args - the array of arguments 95 96 Level: intermediate 97 98 Concepts: command line arguments 99 100 Notes: This may be called before PetscInitialize() or after PetscFinalize() 101 102 Not for use in Fortran 103 104 .seealso: PetscStrToArray() 105 106 @*/ 107 PetscErrorCode PetscStrToArrayDestroy(int argc,char **args) 108 { 109 PetscInt i; 110 111 for (i=0; i<argc; i++) { 112 free(args[i]); 113 } 114 free(args); 115 return 0; 116 } 117 118 #undef __FUNCT__ 119 #define __FUNCT__ "PetscStrlen" 120 /*@C 121 PetscStrlen - Gets length of a string 122 123 Not Collective 124 125 Input Parameters: 126 . s - pointer to string 127 128 Output Parameter: 129 . len - length in bytes 130 131 Level: intermediate 132 133 Note: 134 This routine is analogous to strlen(). 135 136 Null string returns a length of zero 137 138 Not for use in Fortran 139 140 Concepts: string length 141 142 @*/ 143 PetscErrorCode PetscStrlen(const char s[],size_t *len) 144 { 145 PetscFunctionBegin; 146 if (!s) { 147 *len = 0; 148 } else { 149 *len = strlen(s); 150 } 151 PetscFunctionReturn(0); 152 } 153 154 #undef __FUNCT__ 155 #define __FUNCT__ "PetscStrallocpy" 156 /*@C 157 PetscStrallocpy - Allocates space to hold a copy of a string then copies the string 158 159 Not Collective 160 161 Input Parameters: 162 . s - pointer to string 163 164 Output Parameter: 165 . t - the copied string 166 167 Level: intermediate 168 169 Note: 170 Null string returns a new null string 171 172 Not for use in Fortran 173 174 Concepts: string copy 175 176 @*/ 177 PetscErrorCode PetscStrallocpy(const char s[],char *t[]) 178 { 179 PetscErrorCode ierr; 180 size_t len; 181 char *tmp = 0; 182 183 PetscFunctionBegin; 184 if (s) { 185 ierr = PetscStrlen(s,&len);CHKERRQ(ierr); 186 ierr = PetscMalloc((1+len)*sizeof(char),&tmp);CHKERRQ(ierr); 187 ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr); 188 } 189 *t = tmp; 190 PetscFunctionReturn(0); 191 } 192 193 #undef __FUNCT__ 194 #define __FUNCT__ "PetscStrArrayallocpy" 195 /*@C 196 PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings 197 198 Not Collective 199 200 Input Parameters: 201 . s - pointer to array of strings (final string is a null) 202 203 Output Parameter: 204 . t - the copied array string 205 206 Level: intermediate 207 208 Note: 209 Not for use in Fortran 210 211 Concepts: string copy 212 213 .seealso: PetscStrallocpy() PetscStrArrayDestroy() 214 215 @*/ 216 PetscErrorCode PetscStrArrayallocpy(const char *const*list,char ***t) 217 { 218 PetscErrorCode ierr; 219 PetscInt i,n = 0; 220 221 PetscFunctionBegin; 222 while (list[n++]) ; 223 ierr = PetscMalloc((n+1)*sizeof(char**),t);CHKERRQ(ierr); 224 for (i=0; i<n; i++) { 225 ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr); 226 } 227 (*t)[n] = PETSC_NULL; 228 PetscFunctionReturn(0); 229 } 230 231 #undef __FUNCT__ 232 #define __FUNCT__ "PetscStrArrayDestroy" 233 /*@C 234 PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy(). 235 236 Not Collective 237 238 Output Parameters: 239 . list - array of strings 240 241 Level: intermediate 242 243 Concepts: command line arguments 244 245 Notes: Not for use in Fortran 246 247 .seealso: PetscStrArrayallocpy() 248 249 @*/ 250 PetscErrorCode PetscStrArrayDestroy(char **list) 251 { 252 PetscInt n = 0; 253 PetscErrorCode ierr; 254 255 while (list[n]) { 256 ierr = PetscFree(list[n]);CHKERRQ(ierr); 257 n++; 258 } 259 ierr = PetscFree(list);CHKERRQ(ierr); 260 return 0; 261 } 262 263 #undef __FUNCT__ 264 #define __FUNCT__ "PetscStrcpy" 265 /*@C 266 PetscStrcpy - Copies a string 267 268 Not Collective 269 270 Input Parameters: 271 . t - pointer to string 272 273 Output Parameter: 274 . s - the copied string 275 276 Level: intermediate 277 278 Notes: 279 Null string returns a string starting with zero 280 281 Not for use in Fortran 282 283 Concepts: string copy 284 285 .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat() 286 287 @*/ 288 289 PetscErrorCode PetscStrcpy(char s[],const char t[]) 290 { 291 PetscFunctionBegin; 292 if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer"); 293 if (t) {strcpy(s,t);} 294 else if (s) {s[0] = 0;} 295 PetscFunctionReturn(0); 296 } 297 298 #undef __FUNCT__ 299 #define __FUNCT__ "PetscStrncpy" 300 /*@C 301 PetscStrncpy - Copies a string up to a certain length 302 303 Not Collective 304 305 Input Parameters: 306 + t - pointer to string 307 - n - the length to copy 308 309 Output Parameter: 310 . s - the copied string 311 312 Level: intermediate 313 314 Note: 315 Null string returns a string starting with zero 316 317 Concepts: string copy 318 319 .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat() 320 321 @*/ 322 PetscErrorCode PetscStrncpy(char s[],const char t[],size_t n) 323 { 324 PetscFunctionBegin; 325 if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer"); 326 if (t) {strncpy(s,t,n);} 327 else if (s) {s[0] = 0;} 328 PetscFunctionReturn(0); 329 } 330 331 #undef __FUNCT__ 332 #define __FUNCT__ "PetscStrcat" 333 /*@C 334 PetscStrcat - Concatenates a string onto a given string 335 336 Not Collective 337 338 Input Parameters: 339 + s - string to be added to 340 - t - pointer to string to be added to end 341 342 Level: intermediate 343 344 Notes: Not for use in Fortran 345 346 Concepts: string copy 347 348 .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat() 349 350 @*/ 351 PetscErrorCode PetscStrcat(char s[],const char t[]) 352 { 353 PetscFunctionBegin; 354 if (!t) PetscFunctionReturn(0); 355 strcat(s,t); 356 PetscFunctionReturn(0); 357 } 358 359 #undef __FUNCT__ 360 #define __FUNCT__ "PetscStrncat" 361 /*@C 362 PetscStrncat - Concatenates a string onto a given string, up to a given length 363 364 Not Collective 365 366 Input Parameters: 367 + s - pointer to string to be added to end 368 . t - string to be added to 369 . n - maximum length to copy 370 371 Level: intermediate 372 373 Notes: Not for use in Fortran 374 375 Concepts: string copy 376 377 .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat() 378 379 @*/ 380 PetscErrorCode PetscStrncat(char s[],const char t[],size_t n) 381 { 382 PetscFunctionBegin; 383 strncat(s,t,n); 384 PetscFunctionReturn(0); 385 } 386 387 #undef __FUNCT__ 388 #define __FUNCT__ "PetscStrcmp" 389 /*@C 390 PetscStrcmp - Compares two strings, 391 392 Not Collective 393 394 Input Parameters: 395 + a - pointer to string first string 396 - b - pointer to second string 397 398 Output Parameter: 399 . flg - PETSC_TRUE if the two strings are equal 400 401 Level: intermediate 402 403 Notes: Not for use in Fortran 404 405 .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp() 406 407 @*/ 408 PetscErrorCode PetscStrcmp(const char a[],const char b[],PetscBool *flg) 409 { 410 int c; 411 412 PetscFunctionBegin; 413 if (!a && !b) { 414 *flg = PETSC_TRUE; 415 } else if (!a || !b) { 416 *flg = PETSC_FALSE; 417 } else { 418 c = strcmp(a,b); 419 if (c) *flg = PETSC_FALSE; 420 else *flg = PETSC_TRUE; 421 } 422 PetscFunctionReturn(0); 423 } 424 425 #undef __FUNCT__ 426 #define __FUNCT__ "PetscStrgrt" 427 /*@C 428 PetscStrgrt - If first string is greater than the second 429 430 Not Collective 431 432 Input Parameters: 433 + a - pointer to first string 434 - b - pointer to second string 435 436 Output Parameter: 437 . flg - if the first string is greater 438 439 Notes: 440 Null arguments are ok, a null string is considered smaller than 441 all others 442 443 Not for use in Fortran 444 445 Level: intermediate 446 447 .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp() 448 449 @*/ 450 PetscErrorCode PetscStrgrt(const char a[],const char b[],PetscBool *t) 451 { 452 int c; 453 454 PetscFunctionBegin; 455 if (!a && !b) { 456 *t = PETSC_FALSE; 457 } else if (a && !b) { 458 *t = PETSC_TRUE; 459 } else if (!a && b) { 460 *t = PETSC_FALSE; 461 } else { 462 c = strcmp(a,b); 463 if (c > 0) *t = PETSC_TRUE; 464 else *t = PETSC_FALSE; 465 } 466 PetscFunctionReturn(0); 467 } 468 469 #undef __FUNCT__ 470 #define __FUNCT__ "PetscStrcasecmp" 471 /*@C 472 PetscStrcasecmp - Returns true if the two strings are the same 473 except possibly for case. 474 475 Not Collective 476 477 Input Parameters: 478 + a - pointer to first string 479 - b - pointer to second string 480 481 Output Parameter: 482 . flg - if the two strings are the same 483 484 Notes: 485 Null arguments are ok 486 487 Not for use in Fortran 488 489 Level: intermediate 490 491 .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt() 492 493 @*/ 494 PetscErrorCode PetscStrcasecmp(const char a[],const char b[],PetscBool *t) 495 { 496 int c; 497 498 PetscFunctionBegin; 499 if (!a && !b) c = 0; 500 else if (!a || !b) c = 1; 501 #if defined(PETSC_HAVE_STRCASECMP) 502 else c = strcasecmp(a,b); 503 #elif defined(PETSC_HAVE_STRICMP) 504 else c = stricmp(a,b); 505 #else 506 else { 507 char *aa,*bb; 508 PetscErrorCode ierr; 509 ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr); 510 ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr); 511 ierr = PetscStrtolower(aa);CHKERRQ(ierr); 512 ierr = PetscStrtolower(bb);CHKERRQ(ierr); 513 ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr); 514 ierr = PetscFree(aa);CHKERRQ(ierr); 515 ierr = PetscFree(bb);CHKERRQ(ierr); 516 PetscFunctionReturn(0); 517 } 518 #endif 519 if (!c) *t = PETSC_TRUE; 520 else *t = PETSC_FALSE; 521 PetscFunctionReturn(0); 522 } 523 524 525 526 #undef __FUNCT__ 527 #define __FUNCT__ "PetscStrncmp" 528 /*@C 529 PetscStrncmp - Compares two strings, up to a certain length 530 531 Not Collective 532 533 Input Parameters: 534 + a - pointer to first string 535 . b - pointer to second string 536 - n - length to compare up to 537 538 Output Parameter: 539 . t - if the two strings are equal 540 541 Level: intermediate 542 543 Notes: Not for use in Fortran 544 545 .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp() 546 547 @*/ 548 PetscErrorCode PetscStrncmp(const char a[],const char b[],size_t n,PetscBool *t) 549 { 550 int c; 551 552 PetscFunctionBegin; 553 c = strncmp(a,b,n); 554 if (!c) *t = PETSC_TRUE; 555 else *t = PETSC_FALSE; 556 PetscFunctionReturn(0); 557 } 558 559 #undef __FUNCT__ 560 #define __FUNCT__ "PetscStrchr" 561 /*@C 562 PetscStrchr - Locates first occurance of a character in a string 563 564 Not Collective 565 566 Input Parameters: 567 + a - pointer to string 568 - b - character 569 570 Output Parameter: 571 . c - location of occurance, PETSC_NULL if not found 572 573 Level: intermediate 574 575 Notes: Not for use in Fortran 576 577 @*/ 578 PetscErrorCode PetscStrchr(const char a[],char b,char *c[]) 579 { 580 PetscFunctionBegin; 581 *c = (char *)strchr(a,b); 582 PetscFunctionReturn(0); 583 } 584 585 #undef __FUNCT__ 586 #define __FUNCT__ "PetscStrrchr" 587 /*@C 588 PetscStrrchr - Locates one location past the last occurance of a character in a string, 589 if the character is not found then returns entire string 590 591 Not Collective 592 593 Input Parameters: 594 + a - pointer to string 595 - b - character 596 597 Output Parameter: 598 . tmp - location of occurance, a if not found 599 600 Level: intermediate 601 602 Notes: Not for use in Fortran 603 604 @*/ 605 PetscErrorCode PetscStrrchr(const char a[],char b,char *tmp[]) 606 { 607 PetscFunctionBegin; 608 *tmp = (char *)strrchr(a,b); 609 if (!*tmp) *tmp = (char*)a; else *tmp = *tmp + 1; 610 PetscFunctionReturn(0); 611 } 612 613 #undef __FUNCT__ 614 #define __FUNCT__ "PetscStrtolower" 615 /*@C 616 PetscStrtolower - Converts string to lower case 617 618 Not Collective 619 620 Input Parameters: 621 . a - pointer to string 622 623 Level: intermediate 624 625 Notes: Not for use in Fortran 626 627 @*/ 628 PetscErrorCode PetscStrtolower(char a[]) 629 { 630 PetscFunctionBegin; 631 while (*a) { 632 if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A'; 633 a++; 634 } 635 PetscFunctionReturn(0); 636 } 637 638 #undef __FUNCT__ 639 #define __FUNCT__ "PetscStrendswith" 640 /*@C 641 PetscStrendswith - Determines if a string ends with a certain string 642 643 Not Collective 644 645 Input Parameters: 646 + a - pointer to string 647 - b - string to endwith 648 649 Output Parameter: 650 . flg - PETSC_TRUE or PETSC_FALSE 651 652 Notes: Not for use in Fortran 653 654 Level: intermediate 655 656 @*/ 657 PetscErrorCode PetscStrendswith(const char a[],const char b[],PetscBool *flg) 658 { 659 char *test; 660 PetscErrorCode ierr; 661 size_t na,nb; 662 663 PetscFunctionBegin; 664 *flg = PETSC_FALSE; 665 ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr); 666 if (test) { 667 ierr = PetscStrlen(a,&na);CHKERRQ(ierr); 668 ierr = PetscStrlen(b,&nb);CHKERRQ(ierr); 669 if (a+na-nb == test) *flg = PETSC_TRUE; 670 } 671 PetscFunctionReturn(0); 672 } 673 674 #undef __FUNCT__ 675 #define __FUNCT__ "PetscStrendswithwhich" 676 /*@C 677 PetscStrendswithwhich - Determines if a string ends with one of several possible strings 678 679 Not Collective 680 681 Input Parameters: 682 + a - pointer to string 683 - bs - strings to endwith (last entry must be null) 684 685 Output Parameter: 686 . cnt - the index of the string it ends with or 1+the last possible index 687 688 Notes: Not for use in Fortran 689 690 Level: intermediate 691 692 @*/ 693 PetscErrorCode PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt) 694 { 695 PetscBool flg; 696 PetscErrorCode ierr; 697 698 PetscFunctionBegin; 699 *cnt = 0; 700 while (bs[*cnt]) { 701 ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr); 702 if (flg) PetscFunctionReturn(0); 703 *cnt += 1; 704 } 705 PetscFunctionReturn(0); 706 } 707 708 #undef __FUNCT__ 709 #define __FUNCT__ "PetscStrrstr" 710 /*@C 711 PetscStrrstr - Locates last occurance of string in another string 712 713 Not Collective 714 715 Input Parameters: 716 + a - pointer to string 717 - b - string to find 718 719 Output Parameter: 720 . tmp - location of occurance 721 722 Notes: Not for use in Fortran 723 724 Level: intermediate 725 726 @*/ 727 PetscErrorCode PetscStrrstr(const char a[],const char b[],char *tmp[]) 728 { 729 const char *stmp = a, *ltmp = 0; 730 731 PetscFunctionBegin; 732 while (stmp) { 733 stmp = (char *)strstr(stmp,b); 734 if (stmp) {ltmp = stmp;stmp++;} 735 } 736 *tmp = (char *)ltmp; 737 PetscFunctionReturn(0); 738 } 739 740 #undef __FUNCT__ 741 #define __FUNCT__ "PetscStrstr" 742 /*@C 743 PetscStrstr - Locates first occurance of string in another string 744 745 Not Collective 746 747 Input Parameters: 748 + haystack - string to search 749 - needle - string to find 750 751 Output Parameter: 752 . tmp - location of occurance, is a PETSC_NULL if the string is not found 753 754 Notes: Not for use in Fortran 755 756 Level: intermediate 757 758 @*/ 759 PetscErrorCode PetscStrstr(const char haystack[],const char needle[],char *tmp[]) 760 { 761 PetscFunctionBegin; 762 *tmp = (char *)strstr(haystack,needle); 763 PetscFunctionReturn(0); 764 } 765 766 struct _p_PetscToken {char token;char *array;char *current;}; 767 768 #undef __FUNCT__ 769 #define __FUNCT__ "PetscTokenFind" 770 /*@C 771 PetscTokenFind - Locates next "token" in a string 772 773 Not Collective 774 775 Input Parameters: 776 . a - pointer to token 777 778 Output Parameter: 779 . result - location of occurance, PETSC_NULL if not found 780 781 Notes: 782 783 This version is different from the system version in that 784 it allows you to pass a read-only string into the function. 785 786 This version also treats all characters etc. inside a double quote " 787 as a single token. 788 789 Not for use in Fortran 790 791 Level: intermediate 792 793 794 .seealso: PetscTokenCreate(), PetscTokenDestroy() 795 @*/ 796 PetscErrorCode PetscTokenFind(PetscToken a,char *result[]) 797 { 798 char *ptr = a->current,token; 799 800 PetscFunctionBegin; 801 *result = a->current; 802 if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);} 803 token = a->token; 804 if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;} 805 while (ptr) { 806 if (*ptr == token) { 807 *ptr++ = 0; 808 while (*ptr == a->token) ptr++; 809 a->current = ptr; 810 break; 811 } 812 if (!*ptr) { 813 a->current = 0; 814 break; 815 } 816 ptr++; 817 } 818 PetscFunctionReturn(0); 819 } 820 821 #undef __FUNCT__ 822 #define __FUNCT__ "PetscTokenCreate" 823 /*@C 824 PetscTokenCreate - Creates a PetscToken used to find tokens in a string 825 826 Not Collective 827 828 Input Parameters: 829 + string - the string to look in 830 - token - the character to look for 831 832 Output Parameter: 833 . a - pointer to token 834 835 Notes: 836 837 This version is different from the system version in that 838 it allows you to pass a read-only string into the function. 839 840 Not for use in Fortran 841 842 Level: intermediate 843 844 .seealso: PetscTokenFind(), PetscTokenDestroy() 845 @*/ 846 PetscErrorCode PetscTokenCreate(const char a[],const char b,PetscToken *t) 847 { 848 PetscErrorCode ierr; 849 850 PetscFunctionBegin; 851 ierr = PetscNew(struct _p_PetscToken,t);CHKERRQ(ierr); 852 ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr); 853 (*t)->current = (*t)->array; 854 (*t)->token = b; 855 PetscFunctionReturn(0); 856 } 857 858 #undef __FUNCT__ 859 #define __FUNCT__ "PetscTokenDestroy" 860 /*@C 861 PetscTokenDestroy - Destroys a PetscToken 862 863 Not Collective 864 865 Input Parameters: 866 . a - pointer to token 867 868 Level: intermediate 869 870 Notes: Not for use in Fortran 871 872 .seealso: PetscTokenCreate(), PetscTokenFind() 873 @*/ 874 PetscErrorCode PetscTokenDestroy(PetscToken *a) 875 { 876 PetscErrorCode ierr; 877 878 PetscFunctionBegin; 879 if (!*a) PetscFunctionReturn(0); 880 ierr = PetscFree((*a)->array);CHKERRQ(ierr); 881 ierr = PetscFree(*a);CHKERRQ(ierr); 882 PetscFunctionReturn(0); 883 } 884 885 886 #undef __FUNCT__ 887 #define __FUNCT__ "PetscGetPetscDir" 888 /*@C 889 PetscGetPetscDir - Gets the directory PETSc is installed in 890 891 Not Collective 892 893 Output Parameter: 894 . dir - the directory 895 896 Level: developer 897 898 Notes: Not for use in Fortran 899 900 @*/ 901 PetscErrorCode PetscGetPetscDir(const char *dir[]) 902 { 903 PetscFunctionBegin; 904 *dir = PETSC_DIR; 905 PetscFunctionReturn(0); 906 } 907 908 #undef __FUNCT__ 909 #define __FUNCT__ "PetscStrreplace" 910 /*@C 911 PetscStrreplace - Replaces substrings in string with other substrings 912 913 Not Collective 914 915 Input Parameters: 916 + comm - MPI_Comm of processors that are processing the string 917 . aa - the string to look in 918 . b - the resulting copy of a with replaced strings (b can be the same as a) 919 - len - the length of b 920 921 Notes: 922 Replaces ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY}, 923 ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values 924 as well as any environmental variables. 925 926 PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what 927 PETSc was built with and do not use environmental variables. 928 929 Not for use in Fortran 930 931 Level: intermediate 932 933 @*/ 934 PetscErrorCode PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len) 935 { 936 PetscErrorCode ierr; 937 int i = 0; 938 size_t l,l1,l2,l3; 939 char *work,*par,*epar,env[1024],*tfree,*a = (char*)aa; 940 const char *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0}; 941 const char *r[] = {0,0,0,0,0,0,0,0,0}; 942 PetscBool flag; 943 944 PetscFunctionBegin; 945 if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull"); 946 if (aa == b) { 947 ierr = PetscStrallocpy(aa,(char **)&a);CHKERRQ(ierr); 948 } 949 ierr = PetscMalloc(len*sizeof(char*),&work);CHKERRQ(ierr); 950 951 /* get values for replaced variables */ 952 ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr); 953 ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr); 954 ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr); 955 ierr = PetscMalloc(256*sizeof(char),&r[3]);CHKERRQ(ierr); 956 ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[4]);CHKERRQ(ierr); 957 ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[5]);CHKERRQ(ierr); 958 ierr = PetscMalloc(256*sizeof(char),&r[6]);CHKERRQ(ierr); 959 ierr = PetscMalloc(256*sizeof(char),&r[7]);CHKERRQ(ierr); 960 ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr); 961 ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 962 ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 963 ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr); 964 ierr = PetscGetHostName((char*)r[7],256);CHKERRQ(ierr); 965 966 /* replace that are in environment */ 967 ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr); 968 if (flag) { 969 ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr); 970 } 971 972 /* replace the requested strings */ 973 ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr); 974 while (s[i]) { 975 ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr); 976 ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr); 977 while (par) { 978 *par = 0; 979 par += l; 980 981 ierr = PetscStrlen(b,&l1);CHKERRQ(ierr); 982 ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr); 983 ierr = PetscStrlen(par,&l3);CHKERRQ(ierr); 984 if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values"); 985 ierr = PetscStrcpy(work,b);CHKERRQ(ierr); 986 ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr); 987 ierr = PetscStrcat(work,par);CHKERRQ(ierr); 988 ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr); 989 ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr); 990 } 991 i++; 992 } 993 i = 0; 994 while (r[i]) { 995 tfree = (char*)r[i]; 996 ierr = PetscFree(tfree);CHKERRQ(ierr); 997 i++; 998 } 999 1000 /* look for any other ${xxx} strings to replace from environmental variables */ 1001 ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr); 1002 while (par) { 1003 *par = 0; 1004 par += 2; 1005 ierr = PetscStrcpy(work,b);CHKERRQ(ierr); 1006 ierr = PetscStrstr(par,"}",&epar);CHKERRQ(ierr); 1007 *epar = 0; 1008 epar += 1; 1009 ierr = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr); 1010 if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par); 1011 ierr = PetscStrcat(work,env);CHKERRQ(ierr); 1012 ierr = PetscStrcat(work,epar);CHKERRQ(ierr); 1013 ierr = PetscStrcpy(b,work);CHKERRQ(ierr); 1014 ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr); 1015 } 1016 ierr = PetscFree(work);CHKERRQ(ierr); 1017 if (aa == b) { 1018 ierr = PetscFree(a);CHKERRQ(ierr); 1019 } 1020 PetscFunctionReturn(0); 1021 } 1022 1023 1024