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