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