Actual source code: str.c
1: /*
2: We define the string operations here. The reason we just do not use
3: the standard string routines in the PETSc code is that on some machines
4: they are broken or have the wrong prototypes.
6: */
7: #include <petsc/private/petscimpl.h>
8: #if defined(PETSC_HAVE_STRINGS_H)
9: # include <strings.h> /* strcasecmp */
10: #endif
12: /*@C
13: PetscStrToArray - Separates a string by a character (for example ' ' or '\n') and creates an array of strings
15: Not Collective
17: Input Parameters:
18: + s - pointer to string
19: - sp - separator character
21: Output Parameters:
22: + argc - the number of entries in the array
23: - args - an array of the entries with a null at the end
25: Level: intermediate
27: Notes:
28: this may be called before PetscInitialize() or after PetscFinalize()
30: Not for use in Fortran
32: Developer Notes:
33: Using raw malloc() and does not call error handlers since this may be used before PETSc is initialized. Used
34: to generate argc, args arguments passed to MPI_Init()
36: .seealso: PetscStrToArrayDestroy(), PetscToken, PetscTokenCreate()
38: @*/
39: PetscErrorCode PetscStrToArray(const char s[], char sp, int *argc, char ***args)
40: {
41: int i,j,n,*lens,cnt = 0;
42: PetscBool flg = PETSC_FALSE;
44: if (!s) n = 0;
45: else n = strlen(s);
46: *argc = 0;
47: *args = NULL;
48: for (; n>0; n--) { /* remove separator chars at the end - and will empty the string if all chars are separator chars */
49: if (s[n-1] != sp) break;
50: }
51: if (!n) return 0;
52: for (i=0; i<n; i++) {
53: if (s[i] != sp) break;
54: }
55: for (;i<n+1; i++) {
56: if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
57: else if (s[i] != sp) {flg = PETSC_FALSE;}
58: }
59: (*args) = (char**) malloc(((*argc)+1)*sizeof(char*)); if (!*args) return PETSC_ERR_MEM;
60: lens = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM;
61: for (i=0; i<*argc; i++) lens[i] = 0;
63: *argc = 0;
64: for (i=0; i<n; i++) {
65: if (s[i] != sp) break;
66: }
67: for (;i<n+1; i++) {
68: if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
69: else if (s[i] != sp) {lens[*argc]++;flg = PETSC_FALSE;}
70: }
72: for (i=0; i<*argc; i++) {
73: (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char));
74: if (!(*args)[i]) {
75: free(lens);
76: for (j=0; j<i; j++) free((*args)[j]);
77: free(*args);
78: return PETSC_ERR_MEM;
79: }
80: }
81: free(lens);
82: (*args)[*argc] = NULL;
84: *argc = 0;
85: for (i=0; i<n; i++) {
86: if (s[i] != sp) break;
87: }
88: for (;i<n+1; i++) {
89: if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
90: else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;}
91: }
92: return 0;
93: }
95: /*@C
96: PetscStrToArrayDestroy - Frees array created with PetscStrToArray().
98: Not Collective
100: Output Parameters:
101: + argc - the number of arguments
102: - args - the array of arguments
104: Level: intermediate
106: Notes:
107: This may be called before PetscInitialize() or after PetscFinalize()
109: Not for use in Fortran
111: .seealso: PetscStrToArray()
113: @*/
114: PetscErrorCode PetscStrToArrayDestroy(int argc, char **args)
115: {
116: for (int i = 0; i < argc; ++i) free(args[i]);
117: if (args) free(args);
118: return 0;
119: }
121: /*@C
122: PetscStrlen - Gets length of a string
124: Not Collective
126: Input Parameters:
127: . s - pointer to string
129: Output Parameter:
130: . len - length in bytes
132: Level: intermediate
134: Note:
135: This routine is analogous to strlen().
137: Null string returns a length of zero
139: Not for use in Fortran
141: @*/
142: PetscErrorCode PetscStrlen(const char s[], size_t *len)
143: {
144: *len = s ? strlen(s) : 0;
145: return 0;
146: }
148: /*@C
149: PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
151: Not Collective
153: Input Parameters:
154: . s - pointer to string
156: Output Parameter:
157: . t - the copied string
159: Level: intermediate
161: Note:
162: Null string returns a new null string
164: Not for use in Fortran
166: Warning: If t has previously been allocated then that memory is lost, you may need to PetscFree()
167: the array before calling this routine.
169: .seealso: PetscStrArrayallocpy(), PetscStrcpy(), PetscStrNArrayallocpy()
171: @*/
172: PetscErrorCode PetscStrallocpy(const char s[], char *t[])
173: {
174: char *tmp = NULL;
176: if (s) {
177: size_t len;
179: PetscStrlen(s,&len);
180: PetscMalloc1(1+len,&tmp);
181: PetscStrcpy(tmp,s);
182: }
183: *t = tmp;
184: return 0;
185: }
187: /*@C
188: PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
190: Not Collective
192: Input Parameters:
193: . s - pointer to array of strings (final string is a null)
195: Output Parameter:
196: . t - the copied array string
198: Level: intermediate
200: Note:
201: Not for use in Fortran
203: Warning: If t has previously been allocated then that memory is lost, you may need to PetscStrArrayDestroy()
204: the array before calling this routine.
206: .seealso: PetscStrallocpy(), PetscStrArrayDestroy(), PetscStrNArrayallocpy()
208: @*/
209: PetscErrorCode PetscStrArrayallocpy(const char *const *list, char ***t)
210: {
211: PetscInt n = 0;
213: while (list[n++]) ;
214: PetscMalloc1(n+1,t);
215: for (PetscInt i=0; i<n; i++) PetscStrallocpy(list[i],(*t)+i);
216: (*t)[n] = NULL;
217: return 0;
218: }
220: /*@C
221: PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
223: Not Collective
225: Output Parameters:
226: . list - array of strings
228: Level: intermediate
230: Notes:
231: Not for use in Fortran
233: .seealso: PetscStrArrayallocpy()
235: @*/
236: PetscErrorCode PetscStrArrayDestroy(char ***list)
237: {
238: PetscInt n = 0;
240: if (!*list) return 0;
241: while ((*list)[n]) {
242: PetscFree((*list)[n]);
243: ++n;
244: }
245: PetscFree(*list);
246: return 0;
247: }
249: /*@C
250: PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
252: Not Collective
254: Input Parameters:
255: + n - the number of string entries
256: - s - pointer to array of strings
258: Output Parameter:
259: . t - the copied array string
261: Level: intermediate
263: Note:
264: Not for use in Fortran
266: .seealso: PetscStrallocpy(), PetscStrArrayallocpy(), PetscStrNArrayDestroy()
268: @*/
269: PetscErrorCode PetscStrNArrayallocpy(PetscInt n, const char *const *list, char ***t)
270: {
271: PetscMalloc1(n,t);
272: for (PetscInt i=0; i<n; i++) PetscStrallocpy(list[i],(*t)+i);
273: return 0;
274: }
276: /*@C
277: PetscStrNArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
279: Not Collective
281: Output Parameters:
282: + n - number of string entries
283: - list - array of strings
285: Level: intermediate
287: Notes:
288: Not for use in Fortran
290: .seealso: PetscStrArrayallocpy()
292: @*/
293: PetscErrorCode PetscStrNArrayDestroy(PetscInt n, char ***list)
294: {
295: if (!*list) return 0;
296: for (PetscInt i=0; i<n; i++) PetscFree((*list)[i]);
297: PetscFree(*list);
298: return 0;
299: }
301: /*@C
302: PetscStrcpy - Copies a string
304: Not Collective
306: Input Parameters:
307: . t - pointer to string
309: Output Parameter:
310: . s - the copied string
312: Level: intermediate
314: Notes:
315: Null string returns a string starting with zero
317: Not for use in Fortran
319: It is recommended you use PetscStrncpy() instead of this routine
321: .seealso: PetscStrncpy(), PetscStrcat(), PetscStrlcat()
323: @*/
325: PetscErrorCode PetscStrcpy(char s[], const char t[])
326: {
327: if (t) {
330: strcpy(s,t);
331: } else if (s) s[0] = 0;
332: return 0;
333: }
335: /*@C
336: PetscStrncpy - Copies a string up to a certain length
338: Not Collective
340: Input Parameters:
341: + t - pointer to string
342: - n - the length to copy
344: Output Parameter:
345: . s - the copied string
347: Level: intermediate
349: Note:
350: Null string returns a string starting with zero
352: If the string that is being copied is of length n or larger then the entire string is not
353: copied and the final location of s is set to NULL. This is different then the behavior of
354: strncpy() which leaves s non-terminated if there is not room for the entire string.
356: Developers Note: Should this be PetscStrlcpy() to reflect its behavior which is like strlcpy() not strncpy()
358: .seealso: PetscStrcpy(), PetscStrcat(), PetscStrlcat()
360: @*/
361: PetscErrorCode PetscStrncpy(char s[], const char t[], size_t n)
362: {
364: if (t) {
366: if (n > 1) {
367: strncpy(s,t,n-1);
368: s[n-1] = '\0';
369: } else {
370: s[0] = '\0';
371: }
372: } else if (s) s[0] = 0;
373: return 0;
374: }
376: /*@C
377: PetscStrcat - Concatenates a string onto a given string
379: Not Collective
381: Input Parameters:
382: + s - string to be added to
383: - t - pointer to string to be added to end
385: Level: intermediate
387: Notes:
388: Not for use in Fortran
390: It is recommended you use PetscStrlcat() instead of this routine
392: .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrlcat()
394: @*/
395: PetscErrorCode PetscStrcat(char s[], const char t[])
396: {
397: if (!t) return 0;
400: strcat(s,t);
401: return 0;
402: }
404: /*@C
405: PetscStrlcat - Concatenates a string onto a given string, up to a given length
407: Not Collective
409: Input Parameters:
410: + s - pointer to string to be added to at end
411: . t - string to be added
412: - n - length of the original allocated string
414: Level: intermediate
416: Notes:
417: Not for use in Fortran
419: Unlike the system call strncat(), the length passed in is the length of the
420: original allocated space, not the length of the left-over space. This is
421: similar to the BSD system call strlcat().
423: .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
425: @*/
426: PetscErrorCode PetscStrlcat(char s[], const char t[], size_t n)
427: {
428: size_t len;
430: if (!t) return 0;
434: PetscStrlen(t,&len);
435: strncat(s,t,n - len);
436: s[n-1] = 0;
437: return 0;
438: }
440: void PetscStrcmpNoError(const char a[], const char b[], PetscBool *flg)
441: {
442: if (!a && !b) *flg = PETSC_TRUE;
443: else if (!a || !b) *flg = PETSC_FALSE;
444: else *flg = strcmp(a,b) ? PETSC_FALSE : PETSC_TRUE;
445: }
447: /*@C
448: PetscStrcmp - Compares two strings,
450: Not Collective
452: Input Parameters:
453: + a - pointer to string first string
454: - b - pointer to second string
456: Output Parameter:
457: . flg - PETSC_TRUE if the two strings are equal
459: Level: intermediate
461: Notes:
462: Not for use in Fortran
464: .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
465: @*/
466: PetscErrorCode PetscStrcmp(const char a[],const char b[],PetscBool *flg)
467: {
469: if (!a && !b) *flg = PETSC_TRUE;
470: else if (!a || !b) *flg = PETSC_FALSE;
471: else *flg = (PetscBool)!strcmp(a,b);
472: return 0;
473: }
475: /*@C
476: PetscStrgrt - If first string is greater than the second
478: Not Collective
480: Input Parameters:
481: + a - pointer to first string
482: - b - pointer to second string
484: Output Parameter:
485: . flg - if the first string is greater
487: Notes:
488: Null arguments are ok, a null string is considered smaller than
489: all others
491: Not for use in Fortran
493: Level: intermediate
495: .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
497: @*/
498: PetscErrorCode PetscStrgrt(const char a[], const char b[], PetscBool *t)
499: {
501: if (!a && !b) *t = PETSC_FALSE;
502: else if (a && !b) *t = PETSC_TRUE;
503: else if (!a && b) *t = PETSC_FALSE;
504: else {
507: *t = strcmp(a,b) > 0 ? PETSC_TRUE : PETSC_FALSE;
508: }
509: return 0;
510: }
512: /*@C
513: PetscStrcasecmp - Returns true if the two strings are the same
514: except possibly for case.
516: Not Collective
518: Input Parameters:
519: + a - pointer to first string
520: - b - pointer to second string
522: Output Parameter:
523: . flg - if the two strings are the same
525: Notes:
526: Null arguments are ok
528: Not for use in Fortran
530: Level: intermediate
532: .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
534: @*/
535: PetscErrorCode PetscStrcasecmp(const char a[], const char b[], PetscBool *t)
536: {
537: int c;
540: if (!a && !b) c = 0;
541: else if (!a || !b) c = 1;
542: #if defined(PETSC_HAVE_STRCASECMP)
543: else c = strcasecmp(a,b);
544: #elif defined(PETSC_HAVE_STRICMP)
545: else c = stricmp(a,b);
546: #else
547: else {
548: char *aa,*bb;
549: PetscStrallocpy(a,&aa);
550: PetscStrallocpy(b,&bb);
551: PetscStrtolower(aa);
552: PetscStrtolower(bb);
553: PetscStrcmp(aa,bb,t);
554: PetscFree(aa);
555: PetscFree(bb);
556: return 0;
557: }
558: #endif
559: *t = c ? PETSC_FALSE : PETSC_TRUE;
560: return 0;
561: }
563: /*@C
564: PetscStrncmp - Compares two strings, up to a certain length
566: Not Collective
568: Input Parameters:
569: + a - pointer to first string
570: . b - pointer to second string
571: - n - length to compare up to
573: Output Parameter:
574: . t - if the two strings are equal
576: Level: intermediate
578: Notes:
579: Not for use in Fortran
581: .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
583: @*/
584: PetscErrorCode PetscStrncmp(const char a[], const char b[], size_t n, PetscBool *t)
585: {
586: if (n) {
589: }
591: *t = strncmp(a,b,n) ? PETSC_FALSE : PETSC_TRUE;
592: return 0;
593: }
595: /*@C
596: PetscStrchr - Locates first occurrence of a character in a string
598: Not Collective
600: Input Parameters:
601: + a - pointer to string
602: - b - character
604: Output Parameter:
605: . c - location of occurrence, NULL if not found
607: Level: intermediate
609: Notes:
610: Not for use in Fortran
612: @*/
613: PetscErrorCode PetscStrchr(const char a[], char b, char *c[])
614: {
617: *c = (char*)strchr(a,b);
618: return 0;
619: }
621: /*@C
622: PetscStrrchr - Locates one location past the last occurrence of a character in a string,
623: if the character is not found then returns entire string
625: Not Collective
627: Input Parameters:
628: + a - pointer to string
629: - b - character
631: Output Parameter:
632: . tmp - location of occurrence, a if not found
634: Level: intermediate
636: Notes:
637: Not for use in Fortran
639: @*/
640: PetscErrorCode PetscStrrchr(const char a[], char b, char *tmp[])
641: {
644: *tmp = (char*)strrchr(a,b);
645: if (!*tmp) *tmp = (char*)a;
646: else *tmp = *tmp + 1;
647: return 0;
648: }
650: /*@C
651: PetscStrtolower - Converts string to lower case
653: Not Collective
655: Input Parameters:
656: . a - pointer to string
658: Level: intermediate
660: Notes:
661: Not for use in Fortran
663: @*/
664: PetscErrorCode PetscStrtolower(char a[])
665: {
667: while (*a) {
668: if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
669: a++;
670: }
671: return 0;
672: }
674: /*@C
675: PetscStrtoupper - Converts string to upper case
677: Not Collective
679: Input Parameters:
680: . a - pointer to string
682: Level: intermediate
684: Notes:
685: Not for use in Fortran
687: @*/
688: PetscErrorCode PetscStrtoupper(char a[])
689: {
691: while (*a) {
692: if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a';
693: a++;
694: }
695: return 0;
696: }
698: /*@C
699: PetscStrendswith - Determines if a string ends with a certain string
701: Not Collective
703: Input Parameters:
704: + a - pointer to string
705: - b - string to endwith
707: Output Parameter:
708: . flg - PETSC_TRUE or PETSC_FALSE
710: Notes:
711: Not for use in Fortran
713: Level: intermediate
715: @*/
716: PetscErrorCode PetscStrendswith(const char a[], const char b[], PetscBool *flg)
717: {
718: char *test;
721: *flg = PETSC_FALSE;
722: PetscStrrstr(a,b,&test);
723: if (test) {
724: size_t na,nb;
726: PetscStrlen(a,&na);
727: PetscStrlen(b,&nb);
728: if (a+na-nb == test) *flg = PETSC_TRUE;
729: }
730: return 0;
731: }
733: /*@C
734: PetscStrbeginswith - Determines if a string begins with a certain string
736: Not Collective
738: Input Parameters:
739: + a - pointer to string
740: - b - string to begin with
742: Output Parameter:
743: . flg - PETSC_TRUE or PETSC_FALSE
745: Notes:
746: Not for use in Fortran
748: Level: intermediate
750: .seealso: PetscStrendswithwhich(), PetscStrendswith(), PetscStrtoupper, PetscStrtolower(), PetscStrrchr(), PetscStrchr(),
751: PetscStrncmp(), PetscStrlen(), PetscStrncmp(), PetscStrcmp()
753: @*/
754: PetscErrorCode PetscStrbeginswith(const char a[], const char b[], PetscBool *flg)
755: {
756: char *test;
761: *flg = PETSC_FALSE;
762: PetscStrrstr(a,b,&test);
763: if (test && (test == a)) *flg = PETSC_TRUE;
764: return 0;
765: }
767: /*@C
768: PetscStrendswithwhich - Determines if a string ends with one of several possible strings
770: Not Collective
772: Input Parameters:
773: + a - pointer to string
774: - bs - strings to end with (last entry must be NULL)
776: Output Parameter:
777: . cnt - the index of the string it ends with or the index of NULL
779: Notes:
780: Not for use in Fortran
782: Level: intermediate
784: @*/
785: PetscErrorCode PetscStrendswithwhich(const char a[], const char *const *bs, PetscInt *cnt)
786: {
789: *cnt = 0;
790: while (bs[*cnt]) {
791: PetscBool flg;
793: PetscStrendswith(a,bs[*cnt],&flg);
794: if (flg) return 0;
795: ++(*cnt);
796: }
797: return 0;
798: }
800: /*@C
801: PetscStrrstr - Locates last occurrence of string in another string
803: Not Collective
805: Input Parameters:
806: + a - pointer to string
807: - b - string to find
809: Output Parameter:
810: . tmp - location of occurrence
812: Notes:
813: Not for use in Fortran
815: Level: intermediate
817: @*/
818: PetscErrorCode PetscStrrstr(const char a[], const char b[], char *tmp[])
819: {
820: const char *ltmp = NULL;
825: while (a) {
826: a = (char*)strstr(a,b);
827: if (a) ltmp = a++;
828: }
829: *tmp = (char*)ltmp;
830: return 0;
831: }
833: /*@C
834: PetscStrstr - Locates first occurrence of string in another string
836: Not Collective
838: Input Parameters:
839: + haystack - string to search
840: - needle - string to find
842: Output Parameter:
843: . tmp - location of occurrence, is a NULL if the string is not found
845: Notes:
846: Not for use in Fortran
848: Level: intermediate
850: @*/
851: PetscErrorCode PetscStrstr(const char haystack[],const char needle[],char *tmp[])
852: {
856: *tmp = (char*)strstr(haystack,needle);
857: return 0;
858: }
860: struct _p_PetscToken {char token;char *array;char *current;};
862: /*@C
863: PetscTokenFind - Locates next "token" in a string
865: Not Collective
867: Input Parameters:
868: . a - pointer to token
870: Output Parameter:
871: . result - location of occurrence, NULL if not found
873: Notes:
875: This version is different from the system version in that
876: it allows you to pass a read-only string into the function.
878: This version also treats all characters etc. inside a double quote "
879: as a single token.
881: For example if the separator character is + and the string is xxxx+y then the first fine will return a pointer to a null terminated xxxx and the
882: second will return a null terminated y
884: If the separator character is + and the string is xxxx then the first and only token found will be a pointer to a null terminated xxxx
886: Not for use in Fortran
888: Level: intermediate
890: .seealso: PetscTokenCreate(), PetscTokenDestroy()
891: @*/
892: PetscErrorCode PetscTokenFind(PetscToken a, char *result[])
893: {
894: char *ptr,token;
898: *result = ptr = a->current;
899: if (ptr && !*ptr) {*result = NULL; return 0;}
900: token = a->token;
901: if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
902: while (ptr) {
903: if (*ptr == token) {
904: *ptr++ = 0;
905: while (*ptr == a->token) ptr++;
906: a->current = ptr;
907: break;
908: }
909: if (!*ptr) {
910: a->current = NULL;
911: break;
912: }
913: ptr++;
914: }
915: return 0;
916: }
918: /*@C
919: PetscTokenCreate - Creates a PetscToken used to find tokens in a string
921: Not Collective
923: Input Parameters:
924: + string - the string to look in
925: - b - the separator character
927: Output Parameter:
928: . t- the token object
930: Notes:
932: This version is different from the system version in that
933: it allows you to pass a read-only string into the function.
935: Not for use in Fortran
937: Level: intermediate
939: .seealso: PetscTokenFind(), PetscTokenDestroy()
940: @*/
941: PetscErrorCode PetscTokenCreate(const char a[], const char b, PetscToken *t)
942: {
945: PetscNew(t);
946: PetscStrallocpy(a,&(*t)->array);
948: (*t)->current = (*t)->array;
949: (*t)->token = b;
950: return 0;
951: }
953: /*@C
954: PetscTokenDestroy - Destroys a PetscToken
956: Not Collective
958: Input Parameters:
959: . a - pointer to token
961: Level: intermediate
963: Notes:
964: Not for use in Fortran
966: .seealso: PetscTokenCreate(), PetscTokenFind()
967: @*/
968: PetscErrorCode PetscTokenDestroy(PetscToken *a)
969: {
970: if (!*a) return 0;
971: PetscFree((*a)->array);
972: PetscFree(*a);
973: return 0;
974: }
976: /*@C
977: PetscStrInList - search string in character-delimited list
979: Not Collective
981: Input Parameters:
982: + str - the string to look for
983: . list - the list to search in
984: - sep - the separator character
986: Output Parameter:
987: . found - whether str is in list
989: Level: intermediate
991: Notes:
992: Not for use in Fortran
994: .seealso: PetscTokenCreate(), PetscTokenFind(), PetscStrcmp()
995: @*/
996: PetscErrorCode PetscStrInList(const char str[], const char list[], char sep, PetscBool *found)
997: {
998: PetscToken token;
999: char *item;
1002: *found = PETSC_FALSE;
1003: PetscTokenCreate(list,sep,&token);
1004: PetscTokenFind(token,&item);
1005: while (item) {
1006: PetscStrcmp(str,item,found);
1007: if (*found) break;
1008: PetscTokenFind(token,&item);
1009: }
1010: PetscTokenDestroy(&token);
1011: return 0;
1012: }
1014: /*@C
1015: PetscGetPetscDir - Gets the directory PETSc is installed in
1017: Not Collective
1019: Output Parameter:
1020: . dir - the directory
1022: Level: developer
1024: Notes:
1025: Not for use in Fortran
1027: @*/
1028: PetscErrorCode PetscGetPetscDir(const char *dir[])
1029: {
1031: *dir = PETSC_DIR;
1032: return 0;
1033: }
1035: /*@C
1036: PetscStrreplace - Replaces substrings in string with other substrings
1038: Not Collective
1040: Input Parameters:
1041: + comm - MPI_Comm of processors that are processing the string
1042: . aa - the string to look in
1043: . b - the resulting copy of a with replaced strings (b can be the same as a)
1044: - len - the length of b
1046: Notes:
1047: Replaces ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
1048: ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
1049: as well as any environmental variables.
1051: PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
1052: PETSc was built with and do not use environmental variables.
1054: Not for use in Fortran
1056: Level: intermediate
1058: @*/
1059: PetscErrorCode PetscStrreplace(MPI_Comm comm, const char aa[], char b[], size_t len)
1060: {
1061: int i = 0;
1062: size_t l,l1,l2,l3;
1063: char *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
1064: const char *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",NULL};
1065: char *r[] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
1066: PetscBool flag;
1067: static size_t DISPLAY_LENGTH = 265,USER_LENGTH = 256, HOST_LENGTH = 256;
1071: if (aa == b) PetscStrallocpy(aa,(char**)&a);
1072: PetscMalloc1(len,&work);
1074: /* get values for replaced variables */
1075: PetscStrallocpy(PETSC_ARCH,&r[0]);
1076: PetscStrallocpy(PETSC_DIR,&r[1]);
1077: PetscStrallocpy(PETSC_LIB_DIR,&r[2]);
1078: PetscMalloc1(DISPLAY_LENGTH,&r[3]);
1079: PetscMalloc1(PETSC_MAX_PATH_LEN,&r[4]);
1080: PetscMalloc1(PETSC_MAX_PATH_LEN,&r[5]);
1081: PetscMalloc1(USER_LENGTH,&r[6]);
1082: PetscMalloc1(HOST_LENGTH,&r[7]);
1083: PetscGetDisplay(r[3],DISPLAY_LENGTH);
1084: PetscGetHomeDirectory(r[4],PETSC_MAX_PATH_LEN);
1085: PetscGetWorkingDirectory(r[5],PETSC_MAX_PATH_LEN);
1086: PetscGetUserName(r[6],USER_LENGTH);
1087: PetscGetHostName(r[7],HOST_LENGTH);
1089: /* replace that are in environment */
1090: PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,sizeof(env),&flag);
1091: if (flag) {
1092: PetscFree(r[2]);
1093: PetscStrallocpy(env,&r[2]);
1094: }
1096: /* replace the requested strings */
1097: PetscStrncpy(b,a,len);
1098: while (s[i]) {
1099: PetscStrlen(s[i],&l);
1100: PetscStrstr(b,s[i],&par);
1101: while (par) {
1102: *par = 0;
1103: par += l;
1105: PetscStrlen(b,&l1);
1106: PetscStrlen(r[i],&l2);
1107: PetscStrlen(par,&l3);
1109: PetscStrncpy(work,b,len);
1110: PetscStrlcat(work,r[i],len);
1111: PetscStrlcat(work,par,len);
1112: PetscStrncpy(b,work,len);
1113: PetscStrstr(b,s[i],&par);
1114: }
1115: i++;
1116: }
1117: i = 0;
1118: while (r[i]) {
1119: tfree = (char*)r[i];
1120: PetscFree(tfree);
1121: i++;
1122: }
1124: /* look for any other ${xxx} strings to replace from environmental variables */
1125: PetscStrstr(b,"${",&par);
1126: while (par) {
1127: *par = 0;
1128: par += 2;
1129: PetscStrncpy(work,b,len);
1130: PetscStrstr(par,"}",&epar);
1131: *epar = 0;
1132: epar += 1;
1133: PetscOptionsGetenv(comm,par,env,sizeof(env),&flag);
1135: PetscStrlcat(work,env,len);
1136: PetscStrlcat(work,epar,len);
1137: PetscStrncpy(b,work,len);
1138: PetscStrstr(b,"${",&par);
1139: }
1140: PetscFree(work);
1141: if (aa == b) PetscFree(a);
1142: return 0;
1143: }
1145: /*@C
1146: PetscEListFind - searches list of strings for given string, using case insensitive matching
1148: Not Collective
1150: Input Parameters:
1151: + n - number of strings in
1152: . list - list of strings to search
1153: - str - string to look for, empty string "" accepts default (first entry in list)
1155: Output Parameters:
1156: + value - index of matching string (if found)
1157: - found - boolean indicating whether string was found (can be NULL)
1159: Notes:
1160: Not for use in Fortran
1162: Level: advanced
1163: @*/
1164: PetscErrorCode PetscEListFind(PetscInt n, const char *const *list, const char *str, PetscInt *value, PetscBool *found)
1165: {
1166: if (found) {
1168: *found = PETSC_FALSE;
1169: }
1170: for (PetscInt i = 0; i < n; ++i) {
1171: PetscBool matched;
1173: PetscStrcasecmp(str,list[i],&matched);
1174: if (matched || !str[0]) {
1175: if (found) *found = PETSC_TRUE;
1176: *value = i;
1177: break;
1178: }
1179: }
1180: return 0;
1181: }
1183: /*@C
1184: PetscEnumFind - searches enum list of strings for given string, using case insensitive matching
1186: Not Collective
1188: Input Parameters:
1189: + enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL
1190: - str - string to look for
1192: Output Parameters:
1193: + value - index of matching string (if found)
1194: - found - boolean indicating whether string was found (can be NULL)
1196: Notes:
1197: Not for use in Fortran
1199: Level: advanced
1200: @*/
1201: PetscErrorCode PetscEnumFind(const char *const *enumlist, const char *str, PetscEnum *value, PetscBool *found)
1202: {
1203: PetscInt n = 0,evalue;
1204: PetscBool efound;
1209: n -= 3; /* drop enum name, prefix, and null termination */
1210: PetscEListFind(n,enumlist,str,&evalue,&efound);
1211: if (efound) {
1213: *value = (PetscEnum)evalue;
1214: }
1215: if (found) {
1217: *found = efound;
1218: }
1219: return 0;
1220: }