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