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