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