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) { 115 SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer"); 116 } 117 if (t) {strcpy(s,t);} 118 else if (s) {s[0] = 0;} 119 PetscFunctionReturn(0); 120 } 121 122 #undef __FUNCT__ 123 #define __FUNCT__ "PetscStrncpy" 124 /*@C 125 PetscStrncpy - Copies a string up to a certain length 126 127 Not Collective 128 129 Input Parameters: 130 + t - pointer to string 131 - n - the length to copy 132 133 Output Parameter: 134 . s - the copied string 135 136 Level: intermediate 137 138 Note: 139 Null string returns a string starting with zero 140 141 Concepts: string copy 142 143 .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat() 144 145 @*/ 146 PetscErrorCode PETSC_DLLEXPORT PetscStrncpy(char s[],const char t[],size_t n) 147 { 148 PetscFunctionBegin; 149 if (t && !s) { 150 SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer"); 151 } 152 if (t) {strncpy(s,t,n);} 153 else if (s) {s[0] = 0;} 154 PetscFunctionReturn(0); 155 } 156 157 #undef __FUNCT__ 158 #define __FUNCT__ "PetscStrcat" 159 /*@C 160 PetscStrcat - Concatenates a string onto a given string 161 162 Not Collective 163 164 Input Parameters: 165 + s - string to be added to 166 - t - pointer to string to be added to end 167 168 Level: intermediate 169 170 Concepts: string copy 171 172 .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat() 173 174 @*/ 175 PetscErrorCode PETSC_DLLEXPORT PetscStrcat(char s[],const char t[]) 176 { 177 PetscFunctionBegin; 178 if (!t) PetscFunctionReturn(0); 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 This version also treats all characters etc. inside a double quote " 468 as a single token. 469 470 Level: intermediate 471 472 .seealso: PetscTokenCreate(), PetscTokenDestroy() 473 @*/ 474 PetscErrorCode PETSC_DLLEXPORT PetscTokenFind(PetscToken a,char *result[]) 475 { 476 char *ptr = a->current,token; 477 478 PetscFunctionBegin; 479 *result = a->current; 480 if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);} 481 token = a->token; 482 if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;} 483 while (ptr) { 484 if (*ptr == token) { 485 *ptr++ = 0; 486 while (*ptr == a->token) ptr++; 487 a->current = ptr; 488 break; 489 } 490 if (!*ptr) { 491 a->current = 0; 492 break; 493 } 494 ptr++; 495 } 496 PetscFunctionReturn(0); 497 } 498 499 #undef __FUNCT__ 500 #define __FUNCT__ "PetscTokenCreate" 501 /*@C 502 PetscTokenCreate - Creates a PetscToken used to find tokens in a string 503 504 Not Collective 505 506 Input Parameters: 507 + string - the string to look in 508 - token - the character to look for 509 510 Output Parameter: 511 . a - pointer to token 512 513 Notes: 514 515 This version is different from the system version in that 516 it allows you to pass a read-only string into the function. 517 518 Level: intermediate 519 520 .seealso: PetscTokenFind(), PetscTokenDestroy() 521 @*/ 522 PetscErrorCode PETSC_DLLEXPORT PetscTokenCreate(const char a[],const char b,PetscToken *t) 523 { 524 PetscErrorCode ierr; 525 526 PetscFunctionBegin; 527 ierr = PetscNew(struct _p_PetscToken,t);CHKERRQ(ierr); 528 ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr); 529 (*t)->current = (*t)->array; 530 (*t)->token = b; 531 PetscFunctionReturn(0); 532 } 533 534 #undef __FUNCT__ 535 #define __FUNCT__ "PetscTokenDestroy" 536 /*@C 537 PetscTokenDestroy - Destroys a PetscToken 538 539 Not Collective 540 541 Input Parameters: 542 . a - pointer to token 543 544 Level: intermediate 545 546 .seealso: PetscTokenCreate(), PetscTokenFind() 547 @*/ 548 PetscErrorCode PETSC_DLLEXPORT PetscTokenDestroy(PetscToken a) 549 { 550 PetscErrorCode ierr; 551 552 PetscFunctionBegin; 553 ierr = PetscFree(a->array);CHKERRQ(ierr); 554 ierr = PetscFree(a);CHKERRQ(ierr); 555 PetscFunctionReturn(0); 556 } 557 558 #undef __FUNCT__ 559 #define __FUNCT__ "PetscStrrstr" 560 /*@C 561 PetscStrrstr - Locates last occurance of string in another string 562 563 Not Collective 564 565 Input Parameters: 566 + a - pointer to string 567 - b - string to find 568 569 Output Parameter: 570 . tmp - location of occurance 571 572 Level: intermediate 573 574 @*/ 575 PetscErrorCode PETSC_DLLEXPORT PetscStrrstr(const char a[],const char b[],char *tmp[]) 576 { 577 const char *stmp = a, *ltmp = 0; 578 579 PetscFunctionBegin; 580 while (stmp) { 581 stmp = (char *)strstr(stmp,b); 582 if (stmp) {ltmp = stmp;stmp++;} 583 } 584 *tmp = (char *)ltmp; 585 PetscFunctionReturn(0); 586 } 587 588 #undef __FUNCT__ 589 #define __FUNCT__ "PetscStrstr" 590 /*@C 591 PetscStrstr - Locates first occurance of string in another string 592 593 Not Collective 594 595 Input Parameters: 596 + a - pointer to string 597 - b - string to find 598 599 Output Parameter: 600 . tmp - location of occurance 601 602 Level: intermediate 603 604 @*/ 605 PetscErrorCode PETSC_DLLEXPORT PetscStrstr(const char a[],const char b[],char *tmp[]) 606 { 607 PetscFunctionBegin; 608 *tmp = (char *)strstr(a,b); 609 PetscFunctionReturn(0); 610 } 611 612 #undef __FUNCT__ 613 #define __FUNCT__ "PetscGetPetscDir" 614 /*@C 615 PetscGetPetscDir - Gets the directory PETSc is installed in 616 617 Not Collective 618 619 Output Parameter: 620 . dir - the directory 621 622 Level: developer 623 624 @*/ 625 PetscErrorCode PETSC_DLLEXPORT PetscGetPetscDir(const char *dir[]) 626 { 627 PetscFunctionBegin; 628 *dir = PETSC_DIR; 629 PetscFunctionReturn(0); 630 } 631 632 #undef __FUNCT__ 633 #define __FUNCT__ "PetscStrreplace" 634 /*@C 635 PetscStrreplace - Replaces substrings in string with other substrings 636 637 Not Collective 638 639 Input Parameters: 640 + comm - MPI_Comm of processors that are processing the string 641 . aa - the string to look in 642 . b - the resulting copy of a with replaced strings (b can be the same as a) 643 - len - the length of b 644 645 Notes: 646 Replaces ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY}, 647 ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME} with appropriate values 648 as well as any environmental variables. 649 650 Note: PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what 651 PETSc was built with and do not use environmental variables. 652 653 Level: intermediate 654 655 @*/ 656 PetscErrorCode PETSC_DLLEXPORT PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len) 657 { 658 PetscErrorCode ierr; 659 int i = 0; 660 size_t l,l1,l2,l3; 661 char *work,*par,*epar,env[1024],*tfree,*a = (char*)aa; 662 const char *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}",0}; 663 const char *r[] = {0,0,0,0,0,0,0,0}; 664 PetscTruth flag; 665 666 PetscFunctionBegin; 667 if (!a || !b) SETERRQ(PETSC_ERR_ARG_NULL,"a and b strings must be nonnull"); 668 if (aa == b) { 669 ierr = PetscStrallocpy(aa,(char **)&a);CHKERRQ(ierr); 670 } 671 ierr = PetscMalloc(len*sizeof(char*),&work);CHKERRQ(ierr); 672 673 /* get values for replaced variables */ 674 ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr); 675 ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr); 676 ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr); 677 ierr = PetscMalloc(256*sizeof(char),&r[3]);CHKERRQ(ierr); 678 ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[4]);CHKERRQ(ierr); 679 ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[5]);CHKERRQ(ierr); 680 ierr = PetscMalloc(256*sizeof(char),&r[6]);CHKERRQ(ierr); 681 ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr); 682 ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 683 ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 684 ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr); 685 686 /* replace that are in environment */ 687 ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr); 688 if (flag) { 689 ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr); 690 } 691 692 /* replace the requested strings */ 693 ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr); 694 while (s[i]) { 695 ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr); 696 ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr); 697 while (par) { 698 *par = 0; 699 par += l; 700 701 ierr = PetscStrlen(b,&l1);CHKERRQ(ierr); 702 ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr); 703 ierr = PetscStrlen(par,&l3);CHKERRQ(ierr); 704 if (l1 + l2 + l3 >= len) { 705 SETERRQ(PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values"); 706 } 707 ierr = PetscStrcpy(work,b);CHKERRQ(ierr); 708 ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr); 709 ierr = PetscStrcat(work,par);CHKERRQ(ierr); 710 ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr); 711 ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr); 712 } 713 i++; 714 } 715 i = 0; 716 while (r[i]) { 717 tfree = (char*)r[i]; 718 ierr = PetscFree(tfree);CHKERRQ(ierr); 719 i++; 720 } 721 722 /* look for any other ${xxx} strings to replace from environmental variables */ 723 ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr); 724 while (par) { 725 *par = 0; 726 par += 2; 727 ierr = PetscStrcpy(work,b);CHKERRQ(ierr); 728 ierr = PetscStrstr(par,"}",&epar);CHKERRQ(ierr); 729 *epar = 0; 730 epar += 1; 731 ierr = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr); 732 if (!flag) { 733 SETERRQ1(PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par); 734 } 735 ierr = PetscStrcat(work,env);CHKERRQ(ierr); 736 ierr = PetscStrcat(work,epar);CHKERRQ(ierr); 737 ierr = PetscStrcpy(b,work);CHKERRQ(ierr); 738 ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr); 739 } 740 ierr = PetscFree(work);CHKERRQ(ierr); 741 if (aa == b) { 742 ierr = PetscFree(a);CHKERRQ(ierr); 743 } 744 PetscFunctionReturn(0); 745 } 746 747 /*MC 748 PetscStrfree - Frees a string (if it is not null) 749 750 Not Collective 751 752 Synopsis: 753 PetscErrorCode PetscStrfree(char *s) 754 755 Input Parameter: 756 . s - pointer to string 757 758 Level: intermediate 759 760 Concepts: string free 761 762 .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat(), PetscStrallocpy() 763 764 M*/ 765