xref: /petsc/src/sys/utils/str.c (revision 80b92c666e37eeafd75245d5494809ce5f79eeac)
1e5c89e4eSSatish Balay /*
2e5c89e4eSSatish Balay     We define the string operations here. The reason we just do not use
3e5c89e4eSSatish Balay   the standard string routines in the PETSc code is that on some machines
4e5c89e4eSSatish Balay   they are broken or have the wrong prototypes.
5e5c89e4eSSatish Balay 
6e5c89e4eSSatish Balay */
75f80ce2aSJacob Faibussowitsch #include <petsc/private/petscimpl.h> /*I  "petscsys.h"   I*/
83964eb88SJed Brown #if defined(PETSC_HAVE_STRINGS_H)
93964eb88SJed Brown #  include <strings.h>          /* strcasecmp */
103964eb88SJed Brown #endif
113964eb88SJed Brown 
123c311c98SBarry Smith /*@C
1351a1f156SVaclav Hapla    PetscStrToArray - Separates a string by a character (for example ' ' or '\n') and creates an array of strings
143c311c98SBarry Smith 
153c311c98SBarry Smith    Not Collective
163c311c98SBarry Smith 
173c311c98SBarry Smith    Input Parameters:
18d67fe73bSBarry Smith +  s - pointer to string
1951a1f156SVaclav Hapla -  sp - separator character
203c311c98SBarry Smith 
21d8d19677SJose E. Roman    Output Parameters:
223c311c98SBarry Smith +   argc - the number of entries in the array
233c311c98SBarry Smith -   args - an array of the entries with a null at the end
243c311c98SBarry Smith 
253c311c98SBarry Smith    Level: intermediate
263c311c98SBarry Smith 
2795452b02SPatrick Sanan    Notes:
2895452b02SPatrick Sanan     this may be called before PetscInitialize() or after PetscFinalize()
293c311c98SBarry Smith 
306f013253SBarry Smith    Not for use in Fortran
316f013253SBarry Smith 
3295452b02SPatrick Sanan    Developer Notes:
3395452b02SPatrick Sanan     Using raw malloc() and does not call error handlers since this may be used before PETSc is initialized. Used
34b4cd4cebSBarry Smith      to generate argc, args arguments passed to MPI_Init()
35301d30feSBarry Smith 
36db781477SPatrick Sanan .seealso: `PetscStrToArrayDestroy()`, `PetscToken`, `PetscTokenCreate()`
373c311c98SBarry Smith 
383c311c98SBarry Smith @*/
39d67fe73bSBarry Smith PetscErrorCode PetscStrToArray(const char s[], char sp, int *argc, char ***args)
403c311c98SBarry Smith {
41c3bcdc7eSBarry Smith   int       i,j,n,*lens,cnt = 0;
42ace3abfcSBarry Smith   PetscBool flg = PETSC_FALSE;
433c311c98SBarry Smith 
4440a7e1efSBarry Smith   if (!s) n = 0;
4540a7e1efSBarry Smith   else    n = strlen(s);
463c311c98SBarry Smith   *argc = 0;
4761528463SBarry Smith   *args = NULL;
48acf7dc08SSatish Balay   for (; n>0; n--) {   /* remove separator chars at the end - and will empty the string if all chars are separator chars */
49acf7dc08SSatish Balay     if (s[n-1] != sp) break;
50acf7dc08SSatish Balay   }
515f80ce2aSJacob Faibussowitsch   if (!n) return 0;
523c311c98SBarry Smith   for (i=0; i<n; i++) {
53d67fe73bSBarry Smith     if (s[i] != sp) break;
543c311c98SBarry Smith   }
553c311c98SBarry Smith   for (;i<n+1; i++) {
56d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
57d67fe73bSBarry Smith     else if (s[i] != sp) {flg = PETSC_FALSE;}
583c311c98SBarry Smith   }
59a2ea699eSBarry Smith   (*args) = (char**) malloc(((*argc)+1)*sizeof(char*)); if (!*args) return PETSC_ERR_MEM;
6053e6e2c4SHong Zhang   lens    = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM;
613c311c98SBarry Smith   for (i=0; i<*argc; i++) lens[i] = 0;
623c311c98SBarry Smith 
633c311c98SBarry Smith   *argc = 0;
643c311c98SBarry Smith   for (i=0; i<n; i++) {
65d67fe73bSBarry Smith     if (s[i] != sp) break;
663c311c98SBarry Smith   }
677dd9f305SSatish Balay   for (;i<n+1; i++) {
68d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
69d67fe73bSBarry Smith     else if (s[i] != sp) {lens[*argc]++;flg = PETSC_FALSE;}
703c311c98SBarry Smith   }
713c311c98SBarry Smith 
723c311c98SBarry Smith   for (i=0; i<*argc; i++) {
73c3bcdc7eSBarry Smith     (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char));
74c3bcdc7eSBarry Smith     if (!(*args)[i]) {
75c3bcdc7eSBarry Smith       free(lens);
76c3bcdc7eSBarry Smith       for (j=0; j<i; j++) free((*args)[j]);
77c3bcdc7eSBarry Smith       free(*args);
78c3bcdc7eSBarry Smith       return PETSC_ERR_MEM;
79c3bcdc7eSBarry Smith     }
803c311c98SBarry Smith   }
81a2ea699eSBarry Smith   free(lens);
8202c9f0b5SLisandro Dalcin   (*args)[*argc] = NULL;
833c311c98SBarry Smith 
843c311c98SBarry Smith   *argc = 0;
853c311c98SBarry Smith   for (i=0; i<n; i++) {
86d67fe73bSBarry Smith     if (s[i] != sp) break;
873c311c98SBarry Smith   }
883c311c98SBarry Smith   for (;i<n+1; i++) {
89d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
90d67fe73bSBarry Smith     else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;}
913c311c98SBarry Smith   }
923c311c98SBarry Smith   return 0;
933c311c98SBarry Smith }
943c311c98SBarry Smith 
95301d30feSBarry Smith /*@C
96301d30feSBarry Smith    PetscStrToArrayDestroy - Frees array created with PetscStrToArray().
97301d30feSBarry Smith 
98301d30feSBarry Smith    Not Collective
99301d30feSBarry Smith 
100301d30feSBarry Smith    Output Parameters:
101301d30feSBarry Smith +  argc - the number of arguments
102301d30feSBarry Smith -  args - the array of arguments
103301d30feSBarry Smith 
104301d30feSBarry Smith    Level: intermediate
105301d30feSBarry Smith 
10695452b02SPatrick Sanan    Notes:
10795452b02SPatrick Sanan     This may be called before PetscInitialize() or after PetscFinalize()
108301d30feSBarry Smith 
1096f013253SBarry Smith    Not for use in Fortran
1106f013253SBarry Smith 
111db781477SPatrick Sanan .seealso: `PetscStrToArray()`
112301d30feSBarry Smith 
113301d30feSBarry Smith @*/
1147087cfbeSBarry Smith PetscErrorCode PetscStrToArrayDestroy(int argc, char **args)
115301d30feSBarry Smith {
1165f80ce2aSJacob Faibussowitsch   for (int i = 0; i < argc; ++i) free(args[i]);
117a297a907SKarl Rupp   if (args) free(args);
118301d30feSBarry Smith   return 0;
119301d30feSBarry Smith }
120301d30feSBarry Smith 
121e5c89e4eSSatish Balay /*@C
122e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
123e5c89e4eSSatish Balay 
124e5c89e4eSSatish Balay    Not Collective
125e5c89e4eSSatish Balay 
126e5c89e4eSSatish Balay    Input Parameters:
127e5c89e4eSSatish Balay .  s - pointer to string
128e5c89e4eSSatish Balay 
129e5c89e4eSSatish Balay    Output Parameter:
130e5c89e4eSSatish Balay .  len - length in bytes
131e5c89e4eSSatish Balay 
132e5c89e4eSSatish Balay    Level: intermediate
133e5c89e4eSSatish Balay 
134e5c89e4eSSatish Balay    Note:
135e5c89e4eSSatish Balay    This routine is analogous to strlen().
136e5c89e4eSSatish Balay 
137e5c89e4eSSatish Balay    Null string returns a length of zero
138e5c89e4eSSatish Balay 
1396f013253SBarry Smith    Not for use in Fortran
1406f013253SBarry Smith 
141e5c89e4eSSatish Balay @*/
1427087cfbeSBarry Smith PetscErrorCode PetscStrlen(const char s[], size_t *len)
143e5c89e4eSSatish Balay {
144e5c89e4eSSatish Balay   PetscFunctionBegin;
1455f80ce2aSJacob Faibussowitsch   *len = s ? strlen(s) : 0;
146e5c89e4eSSatish Balay   PetscFunctionReturn(0);
147e5c89e4eSSatish Balay }
148e5c89e4eSSatish Balay 
149e5c89e4eSSatish Balay /*@C
150e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
151e5c89e4eSSatish Balay 
152e5c89e4eSSatish Balay    Not Collective
153e5c89e4eSSatish Balay 
154e5c89e4eSSatish Balay    Input Parameters:
155e5c89e4eSSatish Balay .  s - pointer to string
156e5c89e4eSSatish Balay 
157e5c89e4eSSatish Balay    Output Parameter:
158e5c89e4eSSatish Balay .  t - the copied string
159e5c89e4eSSatish Balay 
160e5c89e4eSSatish Balay    Level: intermediate
161e5c89e4eSSatish Balay 
162e5c89e4eSSatish Balay    Note:
163e5c89e4eSSatish Balay       Null string returns a new null string
164e5c89e4eSSatish Balay 
1656f013253SBarry Smith       Not for use in Fortran
1666f013253SBarry Smith 
1670ecf5a55SBarry Smith       Warning: If t has previously been allocated then that memory is lost, you may need to PetscFree()
1680ecf5a55SBarry Smith       the array before calling this routine.
1690ecf5a55SBarry Smith 
170db781477SPatrick Sanan .seealso: `PetscStrArrayallocpy()`, `PetscStrcpy()`, `PetscStrNArrayallocpy()`
1710ecf5a55SBarry Smith 
172e5c89e4eSSatish Balay @*/
1737087cfbeSBarry Smith PetscErrorCode PetscStrallocpy(const char s[], char *t[])
174e5c89e4eSSatish Balay {
17502c9f0b5SLisandro Dalcin   char *tmp = NULL;
176e5c89e4eSSatish Balay 
177e5c89e4eSSatish Balay   PetscFunctionBegin;
178e5c89e4eSSatish Balay   if (s) {
1795f80ce2aSJacob Faibussowitsch     size_t len;
1805f80ce2aSJacob Faibussowitsch 
1819566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(s,&len));
1829566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(1+len,&tmp));
1839566063dSJacob Faibussowitsch     PetscCall(PetscStrcpy(tmp,s));
184e5c89e4eSSatish Balay   }
18571573d7dSBarry Smith   *t = tmp;
186e5c89e4eSSatish Balay   PetscFunctionReturn(0);
187e5c89e4eSSatish Balay }
188e5c89e4eSSatish Balay 
18947340559SBarry Smith /*@C
19047340559SBarry Smith    PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
19147340559SBarry Smith 
19247340559SBarry Smith    Not Collective
19347340559SBarry Smith 
19447340559SBarry Smith    Input Parameters:
19547340559SBarry Smith .  s - pointer to array of strings (final string is a null)
19647340559SBarry Smith 
19747340559SBarry Smith    Output Parameter:
19847340559SBarry Smith .  t - the copied array string
19947340559SBarry Smith 
20047340559SBarry Smith    Level: intermediate
20147340559SBarry Smith 
20247340559SBarry Smith    Note:
20347340559SBarry Smith       Not for use in Fortran
20447340559SBarry Smith 
2050ecf5a55SBarry Smith       Warning: If t has previously been allocated then that memory is lost, you may need to PetscStrArrayDestroy()
2060ecf5a55SBarry Smith       the array before calling this routine.
2070ecf5a55SBarry Smith 
208db781477SPatrick Sanan .seealso: `PetscStrallocpy()`, `PetscStrArrayDestroy()`, `PetscStrNArrayallocpy()`
20947340559SBarry Smith 
21047340559SBarry Smith @*/
21147340559SBarry Smith PetscErrorCode PetscStrArrayallocpy(const char *const *list, char ***t)
21247340559SBarry Smith {
2135f80ce2aSJacob Faibussowitsch   PetscInt n = 0;
21447340559SBarry Smith 
21547340559SBarry Smith   PetscFunctionBegin;
21647340559SBarry Smith   while (list[n++]) ;
2179566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n+1,t));
2189566063dSJacob Faibussowitsch   for (PetscInt i=0; i<n; i++) PetscCall(PetscStrallocpy(list[i],(*t)+i));
2190298fd71SBarry Smith   (*t)[n] = NULL;
22047340559SBarry Smith   PetscFunctionReturn(0);
22147340559SBarry Smith }
22247340559SBarry Smith 
22347340559SBarry Smith /*@C
22447340559SBarry Smith    PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
22547340559SBarry Smith 
22647340559SBarry Smith    Not Collective
22747340559SBarry Smith 
22847340559SBarry Smith    Output Parameters:
22947340559SBarry Smith .   list - array of strings
23047340559SBarry Smith 
23147340559SBarry Smith    Level: intermediate
23247340559SBarry Smith 
23395452b02SPatrick Sanan    Notes:
23495452b02SPatrick Sanan     Not for use in Fortran
23547340559SBarry Smith 
236db781477SPatrick Sanan .seealso: `PetscStrArrayallocpy()`
23747340559SBarry Smith 
23847340559SBarry Smith @*/
2396fed8037SJed Brown PetscErrorCode PetscStrArrayDestroy(char ***list)
24047340559SBarry Smith {
24147340559SBarry Smith   PetscInt n = 0;
24247340559SBarry Smith 
2436fed8037SJed Brown   PetscFunctionBegin;
2446fed8037SJed Brown   if (!*list) PetscFunctionReturn(0);
2456fed8037SJed Brown   while ((*list)[n]) {
2469566063dSJacob Faibussowitsch     PetscCall(PetscFree((*list)[n]));
2475f80ce2aSJacob Faibussowitsch     ++n;
24847340559SBarry Smith   }
2499566063dSJacob Faibussowitsch   PetscCall(PetscFree(*list));
2506fed8037SJed Brown   PetscFunctionReturn(0);
25147340559SBarry Smith }
25247340559SBarry Smith 
2536991f827SBarry Smith /*@C
2546991f827SBarry Smith    PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
2556991f827SBarry Smith 
2566991f827SBarry Smith    Not Collective
2576991f827SBarry Smith 
2586991f827SBarry Smith    Input Parameters:
2596991f827SBarry Smith +  n - the number of string entries
2606991f827SBarry Smith -  s - pointer to array of strings
2616991f827SBarry Smith 
2626991f827SBarry Smith    Output Parameter:
2636991f827SBarry Smith .  t - the copied array string
2646991f827SBarry Smith 
2656991f827SBarry Smith    Level: intermediate
2666991f827SBarry Smith 
2676991f827SBarry Smith    Note:
2686991f827SBarry Smith       Not for use in Fortran
2696991f827SBarry Smith 
270db781477SPatrick Sanan .seealso: `PetscStrallocpy()`, `PetscStrArrayallocpy()`, `PetscStrNArrayDestroy()`
2716991f827SBarry Smith 
2726991f827SBarry Smith @*/
2736991f827SBarry Smith PetscErrorCode PetscStrNArrayallocpy(PetscInt n, const char *const *list, char ***t)
2746991f827SBarry Smith {
2756991f827SBarry Smith   PetscFunctionBegin;
2769566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n,t));
2779566063dSJacob Faibussowitsch   for (PetscInt i=0; i<n; i++) PetscCall(PetscStrallocpy(list[i],(*t)+i));
2786991f827SBarry Smith   PetscFunctionReturn(0);
2796991f827SBarry Smith }
2806991f827SBarry Smith 
2816991f827SBarry Smith /*@C
2826991f827SBarry Smith    PetscStrNArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
2836991f827SBarry Smith 
2846991f827SBarry Smith    Not Collective
2856991f827SBarry Smith 
2866991f827SBarry Smith    Output Parameters:
2876991f827SBarry Smith +   n - number of string entries
2886991f827SBarry Smith -   list - array of strings
2896991f827SBarry Smith 
2906991f827SBarry Smith    Level: intermediate
2916991f827SBarry Smith 
29295452b02SPatrick Sanan    Notes:
29395452b02SPatrick Sanan     Not for use in Fortran
2946991f827SBarry Smith 
295db781477SPatrick Sanan .seealso: `PetscStrArrayallocpy()`
2966991f827SBarry Smith 
2976991f827SBarry Smith @*/
2986991f827SBarry Smith PetscErrorCode PetscStrNArrayDestroy(PetscInt n, char ***list)
2996991f827SBarry Smith {
3006991f827SBarry Smith   PetscFunctionBegin;
3016991f827SBarry Smith   if (!*list) PetscFunctionReturn(0);
3029566063dSJacob Faibussowitsch   for (PetscInt i=0; i<n; i++) PetscCall(PetscFree((*list)[i]));
3039566063dSJacob Faibussowitsch   PetscCall(PetscFree(*list));
3046991f827SBarry Smith   PetscFunctionReturn(0);
3056991f827SBarry Smith }
3066991f827SBarry Smith 
307e5c89e4eSSatish Balay /*@C
308e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
309e5c89e4eSSatish Balay 
310e5c89e4eSSatish Balay    Not Collective
311e5c89e4eSSatish Balay 
312e5c89e4eSSatish Balay    Input Parameters:
313e5c89e4eSSatish Balay .  t - pointer to string
314e5c89e4eSSatish Balay 
315e5c89e4eSSatish Balay    Output Parameter:
316e5c89e4eSSatish Balay .  s - the copied string
317e5c89e4eSSatish Balay 
318e5c89e4eSSatish Balay    Level: intermediate
319e5c89e4eSSatish Balay 
3206f013253SBarry Smith    Notes:
321e5c89e4eSSatish Balay      Null string returns a string starting with zero
322e5c89e4eSSatish Balay 
3236f013253SBarry Smith      Not for use in Fortran
3246f013253SBarry Smith 
3250ecf5a55SBarry Smith      It is recommended you use PetscStrncpy() instead of this routine
3260ecf5a55SBarry Smith 
327db781477SPatrick Sanan .seealso: `PetscStrncpy()`, `PetscStrcat()`, `PetscStrlcat()`
328e5c89e4eSSatish Balay 
329e5c89e4eSSatish Balay @*/
330acc6cc86SBarry Smith 
3317087cfbeSBarry Smith PetscErrorCode PetscStrcpy(char s[], const char t[])
332e5c89e4eSSatish Balay {
333e5c89e4eSSatish Balay   PetscFunctionBegin;
3345f80ce2aSJacob Faibussowitsch   if (t) {
3355f80ce2aSJacob Faibussowitsch     PetscValidCharPointer(s,1);
3365f80ce2aSJacob Faibussowitsch     PetscValidCharPointer(t,2);
3375f80ce2aSJacob Faibussowitsch     strcpy(s,t);
3385f80ce2aSJacob Faibussowitsch   } else if (s) s[0] = 0;
339e5c89e4eSSatish Balay   PetscFunctionReturn(0);
340e5c89e4eSSatish Balay }
341e5c89e4eSSatish Balay 
342e5c89e4eSSatish Balay /*@C
343e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
344e5c89e4eSSatish Balay 
345e5c89e4eSSatish Balay    Not Collective
346e5c89e4eSSatish Balay 
347e5c89e4eSSatish Balay    Input Parameters:
348e5c89e4eSSatish Balay +  t - pointer to string
349e5c89e4eSSatish Balay -  n - the length to copy
350e5c89e4eSSatish Balay 
351e5c89e4eSSatish Balay    Output Parameter:
352e5c89e4eSSatish Balay .  s - the copied string
353e5c89e4eSSatish Balay 
354e5c89e4eSSatish Balay    Level: intermediate
355e5c89e4eSSatish Balay 
356e5c89e4eSSatish Balay    Note:
357e5c89e4eSSatish Balay      Null string returns a string starting with zero
358e5c89e4eSSatish Balay 
359ff32304bSBarry Smith      If the string that is being copied is of length n or larger then the entire string is not
3601b6ef838SBarry Smith      copied and the final location of s is set to NULL. This is different then the behavior of
3611b6ef838SBarry Smith      strncpy() which leaves s non-terminated if there is not room for the entire string.
362ff32304bSBarry Smith 
36362a5de14SBarry Smith   Developers Note: Should this be PetscStrlcpy() to reflect its behavior which is like strlcpy() not strncpy()
36462a5de14SBarry Smith 
365db781477SPatrick Sanan .seealso: `PetscStrcpy()`, `PetscStrcat()`, `PetscStrlcat()`
366e5c89e4eSSatish Balay 
367e5c89e4eSSatish Balay @*/
3687087cfbeSBarry Smith PetscErrorCode PetscStrncpy(char s[], const char t[], size_t n)
369e5c89e4eSSatish Balay {
370e5c89e4eSSatish Balay   PetscFunctionBegin;
3715f80ce2aSJacob Faibussowitsch   if (s) PetscCheck(n,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Requires an output string of length at least 1 to hold the termination character");
372ff32304bSBarry Smith   if (t) {
3735f80ce2aSJacob Faibussowitsch     PetscValidCharPointer(s,1);
3748dc57659SBarry Smith     if (n > 1) {
3752c26941aSBarry Smith       strncpy(s,t,n-1);
376ff32304bSBarry Smith       s[n-1] = '\0';
3778dc57659SBarry Smith     } else {
3788dc57659SBarry Smith       s[0] = '\0';
3798dc57659SBarry Smith     }
380ff32304bSBarry Smith   } else if (s) s[0] = 0;
381e5c89e4eSSatish Balay   PetscFunctionReturn(0);
382e5c89e4eSSatish Balay }
383e5c89e4eSSatish Balay 
384e5c89e4eSSatish Balay /*@C
385e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
386e5c89e4eSSatish Balay 
387e5c89e4eSSatish Balay    Not Collective
388e5c89e4eSSatish Balay 
389e5c89e4eSSatish Balay    Input Parameters:
390e5e2177aSMatthew Knepley +  s - string to be added to
391e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
392e5c89e4eSSatish Balay 
393e5c89e4eSSatish Balay    Level: intermediate
394e5c89e4eSSatish Balay 
39595452b02SPatrick Sanan    Notes:
39695452b02SPatrick Sanan     Not for use in Fortran
3976f013253SBarry Smith 
3980ecf5a55SBarry Smith     It is recommended you use PetscStrlcat() instead of this routine
3990ecf5a55SBarry Smith 
400db781477SPatrick Sanan .seealso: `PetscStrcpy()`, `PetscStrncpy()`, `PetscStrlcat()`
401e5c89e4eSSatish Balay 
402e5c89e4eSSatish Balay @*/
4037087cfbeSBarry Smith PetscErrorCode PetscStrcat(char s[], const char t[])
404e5c89e4eSSatish Balay {
405e5c89e4eSSatish Balay   PetscFunctionBegin;
4069b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
4075f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(s,1);
4085f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(t,2);
409e5c89e4eSSatish Balay   strcat(s,t);
410e5c89e4eSSatish Balay   PetscFunctionReturn(0);
411e5c89e4eSSatish Balay }
412e5c89e4eSSatish Balay 
413e5c89e4eSSatish Balay /*@C
414a126751eSBarry Smith    PetscStrlcat - Concatenates a string onto a given string, up to a given length
415e5c89e4eSSatish Balay 
416e5c89e4eSSatish Balay    Not Collective
417e5c89e4eSSatish Balay 
418e5c89e4eSSatish Balay    Input Parameters:
419e0ffd71fSBarry Smith +  s - pointer to string to be added to at end
42072fa4726SStefano Zampini .  t - string to be added
42124a58d73SPatrick Sanan -  n - length of the original allocated string
422e5c89e4eSSatish Balay 
423e5c89e4eSSatish Balay    Level: intermediate
424e5c89e4eSSatish Balay 
42524a58d73SPatrick Sanan   Notes:
42624a58d73SPatrick Sanan   Not for use in Fortran
4276f013253SBarry Smith 
42824a58d73SPatrick Sanan   Unlike the system call strncat(), the length passed in is the length of the
42924a58d73SPatrick Sanan   original allocated space, not the length of the left-over space. This is
43024a58d73SPatrick Sanan   similar to the BSD system call strlcat().
431153a8027SBarry Smith 
432db781477SPatrick Sanan .seealso: `PetscStrcpy()`, `PetscStrncpy()`, `PetscStrcat()`
433e5c89e4eSSatish Balay 
434e5c89e4eSSatish Balay @*/
435a126751eSBarry Smith PetscErrorCode PetscStrlcat(char s[], const char t[], size_t n)
436e5c89e4eSSatish Balay {
437153a8027SBarry Smith   size_t len;
438153a8027SBarry Smith 
439e5c89e4eSSatish Balay   PetscFunctionBegin;
440e0ffd71fSBarry Smith   if (!t) PetscFunctionReturn(0);
4415f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(s,1);
4425f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(t,2);
4435f80ce2aSJacob Faibussowitsch   PetscCheck(n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"String buffer length must be positive");
4449566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(t,&len));
445153a8027SBarry Smith   strncat(s,t,n - len);
446681eeb0aSBarry Smith   s[n-1] = 0;
447e5c89e4eSSatish Balay   PetscFunctionReturn(0);
448e5c89e4eSSatish Balay }
449e5c89e4eSSatish Balay 
450573b0fb4SBarry Smith void PetscStrcmpNoError(const char a[], const char b[], PetscBool *flg)
451573b0fb4SBarry Smith {
452573b0fb4SBarry Smith   if (!a && !b)      *flg = PETSC_TRUE;
453573b0fb4SBarry Smith   else if (!a || !b) *flg = PETSC_FALSE;
4545f80ce2aSJacob Faibussowitsch   else *flg = strcmp(a,b) ? PETSC_FALSE : PETSC_TRUE;
455573b0fb4SBarry Smith }
456573b0fb4SBarry Smith 
457e5c89e4eSSatish Balay /*@C
458*80b92c66SBarry Smith    PetscBasename - returns a pointer to the last entry of a / seperated directory path
459*80b92c66SBarry Smith 
460*80b92c66SBarry Smith    Not Collective
461*80b92c66SBarry Smith 
462*80b92c66SBarry Smith    Input Parameter:
463*80b92c66SBarry Smith .  a - pointer to string
464*80b92c66SBarry Smith 
465*80b92c66SBarry Smith    Level: intermediate
466*80b92c66SBarry Smith 
467*80b92c66SBarry Smith    Notes:
468*80b92c66SBarry Smith     Not for use in Fortran
469*80b92c66SBarry Smith 
470*80b92c66SBarry Smith .seealso: `PetscStrgrt()`, `PetscStrncmp()`, `PetscStrcasecmp()`, `PetscStrrchr()`,`PetscStrcmp()`,`PetscStrstr()`,
471*80b92c66SBarry Smith           `PetscTokenCreate()`, `PetscStrToArray()`, `PetscStrInList()`
472*80b92c66SBarry Smith @*/
473*80b92c66SBarry Smith const char *PetscBasename(const char a[])
474*80b92c66SBarry Smith {
475*80b92c66SBarry Smith   const          char *ptr;
476*80b92c66SBarry Smith 
477*80b92c66SBarry Smith   if (PetscStrrchr(a,'/',(char **)&ptr)) ptr = NULL;
478*80b92c66SBarry Smith   return ptr;
479*80b92c66SBarry Smith }
480*80b92c66SBarry Smith 
481*80b92c66SBarry Smith /*@C
482e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
483e5c89e4eSSatish Balay 
484e5c89e4eSSatish Balay    Not Collective
485e5c89e4eSSatish Balay 
486e5c89e4eSSatish Balay    Input Parameters:
487e5c89e4eSSatish Balay +  a - pointer to string first string
488e5c89e4eSSatish Balay -  b - pointer to second string
489e5c89e4eSSatish Balay 
490e5c89e4eSSatish Balay    Output Parameter:
4918c74ee41SBarry Smith .  flg - PETSC_TRUE if the two strings are equal
492e5c89e4eSSatish Balay 
493e5c89e4eSSatish Balay    Level: intermediate
494e5c89e4eSSatish Balay 
49595452b02SPatrick Sanan    Notes:
49695452b02SPatrick Sanan     Not for use in Fortran
4976f013253SBarry Smith 
498db781477SPatrick Sanan .seealso: `PetscStrgrt()`, `PetscStrncmp()`, `PetscStrcasecmp()`
499e5c89e4eSSatish Balay @*/
5007087cfbeSBarry Smith PetscErrorCode  PetscStrcmp(const char a[],const char b[],PetscBool *flg)
501e5c89e4eSSatish Balay {
502e5c89e4eSSatish Balay   PetscFunctionBegin;
5035f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(flg,3);
504a297a907SKarl Rupp   if (!a && !b)      *flg = PETSC_TRUE;
505a297a907SKarl Rupp   else if (!a || !b) *flg = PETSC_FALSE;
506b45e3bf4SStefano Zampini   else               *flg = (PetscBool)!strcmp(a,b);
507e5c89e4eSSatish Balay   PetscFunctionReturn(0);
508e5c89e4eSSatish Balay }
509e5c89e4eSSatish Balay 
510e5c89e4eSSatish Balay /*@C
511e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
512e5c89e4eSSatish Balay 
513e5c89e4eSSatish Balay    Not Collective
514e5c89e4eSSatish Balay 
515e5c89e4eSSatish Balay    Input Parameters:
516e5c89e4eSSatish Balay +  a - pointer to first string
517e5c89e4eSSatish Balay -  b - pointer to second string
518e5c89e4eSSatish Balay 
519e5c89e4eSSatish Balay    Output Parameter:
520e5c89e4eSSatish Balay .  flg - if the first string is greater
521e5c89e4eSSatish Balay 
522e5c89e4eSSatish Balay    Notes:
523e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
524e5c89e4eSSatish Balay     all others
525e5c89e4eSSatish Balay 
5266f013253SBarry Smith    Not for use in Fortran
5276f013253SBarry Smith 
528e5c89e4eSSatish Balay    Level: intermediate
529e5c89e4eSSatish Balay 
530db781477SPatrick Sanan .seealso: `PetscStrcmp()`, `PetscStrncmp()`, `PetscStrcasecmp()`
531e5c89e4eSSatish Balay 
532e5c89e4eSSatish Balay @*/
5337087cfbeSBarry Smith PetscErrorCode PetscStrgrt(const char a[], const char b[], PetscBool *t)
534e5c89e4eSSatish Balay {
535e5c89e4eSSatish Balay   PetscFunctionBegin;
5365f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(t,3);
537a297a907SKarl Rupp   if (!a && !b)     *t = PETSC_FALSE;
538a297a907SKarl Rupp   else if (a && !b) *t = PETSC_TRUE;
539a297a907SKarl Rupp   else if (!a && b) *t = PETSC_FALSE;
540a297a907SKarl Rupp   else {
5415f80ce2aSJacob Faibussowitsch     PetscValidCharPointer(a,1);
5425f80ce2aSJacob Faibussowitsch     PetscValidCharPointer(b,2);
5435f80ce2aSJacob Faibussowitsch     *t = strcmp(a,b) > 0 ? PETSC_TRUE : PETSC_FALSE;
544e5c89e4eSSatish Balay   }
545e5c89e4eSSatish Balay   PetscFunctionReturn(0);
546e5c89e4eSSatish Balay }
547e5c89e4eSSatish Balay 
548e5c89e4eSSatish Balay /*@C
549e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
550e5c89e4eSSatish Balay      except possibly for case.
551e5c89e4eSSatish Balay 
552e5c89e4eSSatish Balay    Not Collective
553e5c89e4eSSatish Balay 
554e5c89e4eSSatish Balay    Input Parameters:
555e5c89e4eSSatish Balay +  a - pointer to first string
556e5c89e4eSSatish Balay -  b - pointer to second string
557e5c89e4eSSatish Balay 
558e5c89e4eSSatish Balay    Output Parameter:
559e5c89e4eSSatish Balay .  flg - if the two strings are the same
560e5c89e4eSSatish Balay 
561e5c89e4eSSatish Balay    Notes:
562e5c89e4eSSatish Balay     Null arguments are ok
563e5c89e4eSSatish Balay 
5646f013253SBarry Smith    Not for use in Fortran
5656f013253SBarry Smith 
566e5c89e4eSSatish Balay    Level: intermediate
567e5c89e4eSSatish Balay 
568db781477SPatrick Sanan .seealso: `PetscStrcmp()`, `PetscStrncmp()`, `PetscStrgrt()`
569e5c89e4eSSatish Balay 
570e5c89e4eSSatish Balay @*/
5717087cfbeSBarry Smith PetscErrorCode PetscStrcasecmp(const char a[], const char b[], PetscBool *t)
572e5c89e4eSSatish Balay {
573e5c89e4eSSatish Balay   int c;
574e5c89e4eSSatish Balay 
575e5c89e4eSSatish Balay   PetscFunctionBegin;
5765f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(t,3);
577e5c89e4eSSatish Balay   if (!a && !b)      c = 0;
578e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
57932b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
58032b366c8SSatish Balay   else c = strcasecmp(a,b);
58132b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
582e5c89e4eSSatish Balay   else c = stricmp(a,b);
583e5c89e4eSSatish Balay #else
58432b366c8SSatish Balay   else {
58532b366c8SSatish Balay     char           *aa,*bb;
5869566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(a,&aa));
5879566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(b,&bb));
5889566063dSJacob Faibussowitsch     PetscCall(PetscStrtolower(aa));
5899566063dSJacob Faibussowitsch     PetscCall(PetscStrtolower(bb));
5909566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(aa,bb,t));
5919566063dSJacob Faibussowitsch     PetscCall(PetscFree(aa));
5929566063dSJacob Faibussowitsch     PetscCall(PetscFree(bb));
59332b366c8SSatish Balay     PetscFunctionReturn(0);
59432b366c8SSatish Balay   }
595e5c89e4eSSatish Balay #endif
5965f80ce2aSJacob Faibussowitsch   *t = c ? PETSC_FALSE : PETSC_TRUE;
597e5c89e4eSSatish Balay   PetscFunctionReturn(0);
598e5c89e4eSSatish Balay }
599e5c89e4eSSatish Balay 
600e5c89e4eSSatish Balay /*@C
601e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
602e5c89e4eSSatish Balay 
603e5c89e4eSSatish Balay    Not Collective
604e5c89e4eSSatish Balay 
605e5c89e4eSSatish Balay    Input Parameters:
606e5c89e4eSSatish Balay +  a - pointer to first string
607e5c89e4eSSatish Balay .  b - pointer to second string
608e5c89e4eSSatish Balay -  n - length to compare up to
609e5c89e4eSSatish Balay 
610e5c89e4eSSatish Balay    Output Parameter:
611e5c89e4eSSatish Balay .  t - if the two strings are equal
612e5c89e4eSSatish Balay 
613e5c89e4eSSatish Balay    Level: intermediate
614e5c89e4eSSatish Balay 
61595452b02SPatrick Sanan    Notes:
61695452b02SPatrick Sanan     Not for use in Fortran
6176f013253SBarry Smith 
618db781477SPatrick Sanan .seealso: `PetscStrgrt()`, `PetscStrcmp()`, `PetscStrcasecmp()`
619e5c89e4eSSatish Balay 
620e5c89e4eSSatish Balay @*/
6217087cfbeSBarry Smith PetscErrorCode PetscStrncmp(const char a[], const char b[], size_t n, PetscBool *t)
622e5c89e4eSSatish Balay {
623e5c89e4eSSatish Balay   PetscFunctionBegin;
6245f80ce2aSJacob Faibussowitsch   if (n) {
6255f80ce2aSJacob Faibussowitsch     PetscValidCharPointer(a,1);
6265f80ce2aSJacob Faibussowitsch     PetscValidCharPointer(b,2);
6275f80ce2aSJacob Faibussowitsch   }
6285f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(t,4);
6295f80ce2aSJacob Faibussowitsch   *t = strncmp(a,b,n) ? PETSC_FALSE : PETSC_TRUE;
630e5c89e4eSSatish Balay   PetscFunctionReturn(0);
631e5c89e4eSSatish Balay }
632e5c89e4eSSatish Balay 
633e5c89e4eSSatish Balay /*@C
634a5b23f4aSJose E. Roman    PetscStrchr - Locates first occurrence of a character in a string
635e5c89e4eSSatish Balay 
636e5c89e4eSSatish Balay    Not Collective
637e5c89e4eSSatish Balay 
638e5c89e4eSSatish Balay    Input Parameters:
639e5c89e4eSSatish Balay +  a - pointer to string
640e5c89e4eSSatish Balay -  b - character
641e5c89e4eSSatish Balay 
642e5c89e4eSSatish Balay    Output Parameter:
643a5b23f4aSJose E. Roman .  c - location of occurrence, NULL if not found
644e5c89e4eSSatish Balay 
645e5c89e4eSSatish Balay    Level: intermediate
646e5c89e4eSSatish Balay 
64795452b02SPatrick Sanan    Notes:
64895452b02SPatrick Sanan     Not for use in Fortran
6496f013253SBarry Smith 
650e5c89e4eSSatish Balay @*/
6517087cfbeSBarry Smith PetscErrorCode PetscStrchr(const char a[], char b, char *c[])
652e5c89e4eSSatish Balay {
653e5c89e4eSSatish Balay   PetscFunctionBegin;
6545f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(a,1);
6555f80ce2aSJacob Faibussowitsch   PetscValidPointer(c,3);
656e5c89e4eSSatish Balay   *c = (char*)strchr(a,b);
657e5c89e4eSSatish Balay   PetscFunctionReturn(0);
658e5c89e4eSSatish Balay }
659e5c89e4eSSatish Balay 
660e5c89e4eSSatish Balay /*@C
661a5b23f4aSJose E. Roman    PetscStrrchr - Locates one location past the last occurrence of a character in a string,
662e5c89e4eSSatish Balay       if the character is not found then returns entire string
663e5c89e4eSSatish Balay 
664e5c89e4eSSatish Balay    Not Collective
665e5c89e4eSSatish Balay 
666e5c89e4eSSatish Balay    Input Parameters:
667e5c89e4eSSatish Balay +  a - pointer to string
668e5c89e4eSSatish Balay -  b - character
669e5c89e4eSSatish Balay 
670e5c89e4eSSatish Balay    Output Parameter:
671a5b23f4aSJose E. Roman .  tmp - location of occurrence, a if not found
672e5c89e4eSSatish Balay 
673e5c89e4eSSatish Balay    Level: intermediate
674e5c89e4eSSatish Balay 
67595452b02SPatrick Sanan    Notes:
67695452b02SPatrick Sanan     Not for use in Fortran
6776f013253SBarry Smith 
678e5c89e4eSSatish Balay @*/
6797087cfbeSBarry Smith PetscErrorCode PetscStrrchr(const char a[], char b, char *tmp[])
680e5c89e4eSSatish Balay {
681e5c89e4eSSatish Balay   PetscFunctionBegin;
6825f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(a,1);
6835f80ce2aSJacob Faibussowitsch   PetscValidPointer(tmp,3);
684e5c89e4eSSatish Balay   *tmp = (char*)strrchr(a,b);
685a297a907SKarl Rupp   if (!*tmp) *tmp = (char*)a;
686a297a907SKarl Rupp   else *tmp = *tmp + 1;
687e5c89e4eSSatish Balay   PetscFunctionReturn(0);
688e5c89e4eSSatish Balay }
689e5c89e4eSSatish Balay 
690e5c89e4eSSatish Balay /*@C
691e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
692e5c89e4eSSatish Balay 
693e5c89e4eSSatish Balay    Not Collective
694e5c89e4eSSatish Balay 
695e5c89e4eSSatish Balay    Input Parameters:
696e5c89e4eSSatish Balay .  a - pointer to string
697e5c89e4eSSatish Balay 
698e5c89e4eSSatish Balay    Level: intermediate
699e5c89e4eSSatish Balay 
70095452b02SPatrick Sanan    Notes:
70195452b02SPatrick Sanan     Not for use in Fortran
7026f013253SBarry Smith 
703e5c89e4eSSatish Balay @*/
7047087cfbeSBarry Smith PetscErrorCode PetscStrtolower(char a[])
705e5c89e4eSSatish Balay {
706e5c89e4eSSatish Balay   PetscFunctionBegin;
7075f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(a,1);
708e5c89e4eSSatish Balay   while (*a) {
709e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
710e5c89e4eSSatish Balay     a++;
711e5c89e4eSSatish Balay   }
712e5c89e4eSSatish Balay   PetscFunctionReturn(0);
713e5c89e4eSSatish Balay }
714e5c89e4eSSatish Balay 
7152f234a98SBarry Smith /*@C
7166e3a5469SBarry Smith    PetscStrtoupper - Converts string to upper case
7172f234a98SBarry Smith 
7182f234a98SBarry Smith    Not Collective
7192f234a98SBarry Smith 
7202f234a98SBarry Smith    Input Parameters:
7212f234a98SBarry Smith .  a - pointer to string
7222f234a98SBarry Smith 
7232f234a98SBarry Smith    Level: intermediate
7242f234a98SBarry Smith 
72595452b02SPatrick Sanan    Notes:
72695452b02SPatrick Sanan     Not for use in Fortran
7272f234a98SBarry Smith 
7282f234a98SBarry Smith @*/
7292f234a98SBarry Smith PetscErrorCode PetscStrtoupper(char a[])
7302f234a98SBarry Smith {
7312f234a98SBarry Smith   PetscFunctionBegin;
7325f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(a,1);
7332f234a98SBarry Smith   while (*a) {
7342f234a98SBarry Smith     if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a';
7352f234a98SBarry Smith     a++;
7362f234a98SBarry Smith   }
7372f234a98SBarry Smith   PetscFunctionReturn(0);
7382f234a98SBarry Smith }
7392f234a98SBarry Smith 
7407ba3a57cSBarry Smith /*@C
7417ba3a57cSBarry Smith    PetscStrendswith - Determines if a string ends with a certain string
7421d1a0024SBarry Smith 
7437ba3a57cSBarry Smith    Not Collective
7447ba3a57cSBarry Smith 
7457ba3a57cSBarry Smith    Input Parameters:
7467ba3a57cSBarry Smith +  a - pointer to string
7477ba3a57cSBarry Smith -  b - string to endwith
7487ba3a57cSBarry Smith 
7497ba3a57cSBarry Smith    Output Parameter:
7507ba3a57cSBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
7517ba3a57cSBarry Smith 
75295452b02SPatrick Sanan    Notes:
75395452b02SPatrick Sanan     Not for use in Fortran
7547ba3a57cSBarry Smith 
7557ba3a57cSBarry Smith    Level: intermediate
7567ba3a57cSBarry Smith 
7577ba3a57cSBarry Smith @*/
7587ba3a57cSBarry Smith PetscErrorCode PetscStrendswith(const char a[], const char b[], PetscBool *flg)
7597ba3a57cSBarry Smith {
7607ba3a57cSBarry Smith   char *test;
7617ba3a57cSBarry Smith 
7627ba3a57cSBarry Smith   PetscFunctionBegin;
7635f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(flg,3);
7647ba3a57cSBarry Smith   *flg = PETSC_FALSE;
7659566063dSJacob Faibussowitsch   PetscCall(PetscStrrstr(a,b,&test));
7667ba3a57cSBarry Smith   if (test) {
7675f80ce2aSJacob Faibussowitsch     size_t na,nb;
7685f80ce2aSJacob Faibussowitsch 
7699566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(a,&na));
7709566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(b,&nb));
7717ba3a57cSBarry Smith     if (a+na-nb == test) *flg = PETSC_TRUE;
7727ba3a57cSBarry Smith   }
7737ba3a57cSBarry Smith   PetscFunctionReturn(0);
7747ba3a57cSBarry Smith }
7757ba3a57cSBarry Smith 
7762c9581d2SBarry Smith /*@C
7772c9581d2SBarry Smith    PetscStrbeginswith - Determines if a string begins with a certain string
7782c9581d2SBarry Smith 
7792c9581d2SBarry Smith    Not Collective
7802c9581d2SBarry Smith 
7812c9581d2SBarry Smith    Input Parameters:
7822c9581d2SBarry Smith +  a - pointer to string
7832c9581d2SBarry Smith -  b - string to begin with
7842c9581d2SBarry Smith 
7852c9581d2SBarry Smith    Output Parameter:
7862c9581d2SBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
7872c9581d2SBarry Smith 
78895452b02SPatrick Sanan    Notes:
78995452b02SPatrick Sanan     Not for use in Fortran
7902c9581d2SBarry Smith 
7912c9581d2SBarry Smith    Level: intermediate
7922c9581d2SBarry Smith 
793db781477SPatrick Sanan .seealso: `PetscStrendswithwhich()`, `PetscStrendswith()`, `PetscStrtoupper`, `PetscStrtolower()`, `PetscStrrchr()`, `PetscStrchr()`,
794db781477SPatrick Sanan           `PetscStrncmp()`, `PetscStrlen()`, `PetscStrncmp()`, `PetscStrcmp()`
7956e3a5469SBarry Smith 
7962c9581d2SBarry Smith @*/
7972c9581d2SBarry Smith PetscErrorCode PetscStrbeginswith(const char a[], const char b[], PetscBool *flg)
7982c9581d2SBarry Smith {
7992c9581d2SBarry Smith   char *test;
8002c9581d2SBarry Smith 
8012c9581d2SBarry Smith   PetscFunctionBegin;
8025f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(a,1);
8035f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(b,2);
8045f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(flg,3);
8052c9581d2SBarry Smith   *flg = PETSC_FALSE;
8069566063dSJacob Faibussowitsch   PetscCall(PetscStrrstr(a,b,&test));
807a297a907SKarl Rupp   if (test && (test == a)) *flg = PETSC_TRUE;
8082c9581d2SBarry Smith   PetscFunctionReturn(0);
8092c9581d2SBarry Smith }
8102c9581d2SBarry Smith 
8117ba3a57cSBarry Smith /*@C
8127ba3a57cSBarry Smith    PetscStrendswithwhich - Determines if a string ends with one of several possible strings
8137ba3a57cSBarry Smith 
8147ba3a57cSBarry Smith    Not Collective
8157ba3a57cSBarry Smith 
8167ba3a57cSBarry Smith    Input Parameters:
8177ba3a57cSBarry Smith +  a - pointer to string
818fa4b66f2SVaclav Hapla -  bs - strings to end with (last entry must be NULL)
8197ba3a57cSBarry Smith 
8207ba3a57cSBarry Smith    Output Parameter:
821fa4b66f2SVaclav Hapla .  cnt - the index of the string it ends with or the index of NULL
8227ba3a57cSBarry Smith 
82395452b02SPatrick Sanan    Notes:
82495452b02SPatrick Sanan     Not for use in Fortran
8257ba3a57cSBarry Smith 
8267ba3a57cSBarry Smith    Level: intermediate
8277ba3a57cSBarry Smith 
8287ba3a57cSBarry Smith @*/
8297ba3a57cSBarry Smith PetscErrorCode PetscStrendswithwhich(const char a[], const char *const *bs, PetscInt *cnt)
8307ba3a57cSBarry Smith {
8317ba3a57cSBarry Smith   PetscFunctionBegin;
8325f80ce2aSJacob Faibussowitsch   PetscValidPointer(bs,2);
8335f80ce2aSJacob Faibussowitsch   PetscValidIntPointer(cnt,3);
8347ba3a57cSBarry Smith   *cnt = 0;
8357ba3a57cSBarry Smith   while (bs[*cnt]) {
8365f80ce2aSJacob Faibussowitsch     PetscBool flg;
8375f80ce2aSJacob Faibussowitsch 
8389566063dSJacob Faibussowitsch     PetscCall(PetscStrendswith(a,bs[*cnt],&flg));
8397ba3a57cSBarry Smith     if (flg) PetscFunctionReturn(0);
8405f80ce2aSJacob Faibussowitsch     ++(*cnt);
8417ba3a57cSBarry Smith   }
8427ba3a57cSBarry Smith   PetscFunctionReturn(0);
8437ba3a57cSBarry Smith }
8447ba3a57cSBarry Smith 
8457ba3a57cSBarry Smith /*@C
846a5b23f4aSJose E. Roman    PetscStrrstr - Locates last occurrence of string in another string
8477ba3a57cSBarry Smith 
8487ba3a57cSBarry Smith    Not Collective
8497ba3a57cSBarry Smith 
8507ba3a57cSBarry Smith    Input Parameters:
8517ba3a57cSBarry Smith +  a - pointer to string
8527ba3a57cSBarry Smith -  b - string to find
8537ba3a57cSBarry Smith 
8547ba3a57cSBarry Smith    Output Parameter:
855a5b23f4aSJose E. Roman .  tmp - location of occurrence
8567ba3a57cSBarry Smith 
85795452b02SPatrick Sanan    Notes:
85895452b02SPatrick Sanan     Not for use in Fortran
8597ba3a57cSBarry Smith 
8607ba3a57cSBarry Smith    Level: intermediate
8617ba3a57cSBarry Smith 
8627ba3a57cSBarry Smith @*/
8637ba3a57cSBarry Smith PetscErrorCode PetscStrrstr(const char a[], const char b[], char *tmp[])
8647ba3a57cSBarry Smith {
8655f80ce2aSJacob Faibussowitsch   const char *ltmp = NULL;
8667ba3a57cSBarry Smith 
8677ba3a57cSBarry Smith   PetscFunctionBegin;
8685f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(a,1);
8695f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(b,2);
8705f80ce2aSJacob Faibussowitsch   PetscValidPointer(tmp,3);
8715f80ce2aSJacob Faibussowitsch   while (a) {
8725f80ce2aSJacob Faibussowitsch     a = (char*)strstr(a,b);
8735f80ce2aSJacob Faibussowitsch     if (a) ltmp = a++;
8747ba3a57cSBarry Smith   }
8757ba3a57cSBarry Smith   *tmp = (char*)ltmp;
8767ba3a57cSBarry Smith   PetscFunctionReturn(0);
8777ba3a57cSBarry Smith }
8787ba3a57cSBarry Smith 
8797ba3a57cSBarry Smith /*@C
880a5b23f4aSJose E. Roman    PetscStrstr - Locates first occurrence of string in another string
8817ba3a57cSBarry Smith 
8827ba3a57cSBarry Smith    Not Collective
8837ba3a57cSBarry Smith 
8847ba3a57cSBarry Smith    Input Parameters:
885160f4796SJed Brown +  haystack - string to search
886160f4796SJed Brown -  needle - string to find
8877ba3a57cSBarry Smith 
8887ba3a57cSBarry Smith    Output Parameter:
889a5b23f4aSJose E. Roman .  tmp - location of occurrence, is a NULL if the string is not found
8907ba3a57cSBarry Smith 
89195452b02SPatrick Sanan    Notes:
89295452b02SPatrick Sanan     Not for use in Fortran
8937ba3a57cSBarry Smith 
8947ba3a57cSBarry Smith    Level: intermediate
8957ba3a57cSBarry Smith 
8967ba3a57cSBarry Smith @*/
897160f4796SJed Brown PetscErrorCode PetscStrstr(const char haystack[],const char needle[],char *tmp[])
8987ba3a57cSBarry Smith {
8997ba3a57cSBarry Smith   PetscFunctionBegin;
9005f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(haystack,1);
9015f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(needle,2);
9025f80ce2aSJacob Faibussowitsch   PetscValidPointer(tmp,3);
903160f4796SJed Brown   *tmp = (char*)strstr(haystack,needle);
9047ba3a57cSBarry Smith   PetscFunctionReturn(0);
9057ba3a57cSBarry Smith }
9067ba3a57cSBarry Smith 
9077ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
9081d1a0024SBarry Smith 
909e5c89e4eSSatish Balay /*@C
910e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
911e5c89e4eSSatish Balay 
912e5c89e4eSSatish Balay    Not Collective
913e5c89e4eSSatish Balay 
914e5c89e4eSSatish Balay    Input Parameters:
915e5c89e4eSSatish Balay .  a - pointer to token
916e5c89e4eSSatish Balay 
917e5c89e4eSSatish Balay    Output Parameter:
918a5b23f4aSJose E. Roman .  result - location of occurrence, NULL if not found
919e5c89e4eSSatish Balay 
920e5c89e4eSSatish Balay    Notes:
921e5c89e4eSSatish Balay 
922e5c89e4eSSatish Balay      This version is different from the system version in that
923e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
924e5c89e4eSSatish Balay 
9254704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
9264704e885SBarry Smith    as a single token.
9274704e885SBarry Smith 
9283a9c465aSBarry Smith      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
9293a9c465aSBarry Smith    second will return a null terminated y
9303a9c465aSBarry Smith 
9313a9c465aSBarry Smith      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
9323a9c465aSBarry Smith 
9336f013253SBarry Smith     Not for use in Fortran
9346f013253SBarry Smith 
935e5c89e4eSSatish Balay    Level: intermediate
936e5c89e4eSSatish Balay 
937db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenDestroy()`
938e5c89e4eSSatish Balay @*/
9397087cfbeSBarry Smith PetscErrorCode PetscTokenFind(PetscToken a, char *result[])
940e5c89e4eSSatish Balay {
9415f80ce2aSJacob Faibussowitsch   char *ptr,token;
942e5c89e4eSSatish Balay 
943e5c89e4eSSatish Balay   PetscFunctionBegin;
9445f80ce2aSJacob Faibussowitsch   PetscValidPointer(a,1);
9455f80ce2aSJacob Faibussowitsch   PetscValidPointer(result,2);
9465f80ce2aSJacob Faibussowitsch   *result = ptr = a->current;
94702c9f0b5SLisandro Dalcin   if (ptr && !*ptr) {*result = NULL; PetscFunctionReturn(0);}
9484704e885SBarry Smith   token = a->token;
94990fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
950e5c89e4eSSatish Balay   while (ptr) {
9514704e885SBarry Smith     if (*ptr == token) {
952e5c89e4eSSatish Balay       *ptr++ = 0;
953e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
954e5c89e4eSSatish Balay       a->current = ptr;
955e5c89e4eSSatish Balay       break;
956e5c89e4eSSatish Balay     }
957e5c89e4eSSatish Balay     if (!*ptr) {
95802c9f0b5SLisandro Dalcin       a->current = NULL;
959e5c89e4eSSatish Balay       break;
960e5c89e4eSSatish Balay     }
961e5c89e4eSSatish Balay     ptr++;
962e5c89e4eSSatish Balay   }
963e5c89e4eSSatish Balay   PetscFunctionReturn(0);
964e5c89e4eSSatish Balay }
965e5c89e4eSSatish Balay 
966e5c89e4eSSatish Balay /*@C
967e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
968e5c89e4eSSatish Balay 
969e5c89e4eSSatish Balay    Not Collective
970e5c89e4eSSatish Balay 
971e5c89e4eSSatish Balay    Input Parameters:
972e5c89e4eSSatish Balay +  string - the string to look in
9733a9c465aSBarry Smith -  b - the separator character
974e5c89e4eSSatish Balay 
975e5c89e4eSSatish Balay    Output Parameter:
9763a9c465aSBarry Smith .  t- the token object
977e5c89e4eSSatish Balay 
978e5c89e4eSSatish Balay    Notes:
979e5c89e4eSSatish Balay 
980e5c89e4eSSatish Balay      This version is different from the system version in that
981e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
982e5c89e4eSSatish Balay 
9836f013253SBarry Smith     Not for use in Fortran
9846f013253SBarry Smith 
985e5c89e4eSSatish Balay    Level: intermediate
986e5c89e4eSSatish Balay 
987db781477SPatrick Sanan .seealso: `PetscTokenFind()`, `PetscTokenDestroy()`
988e5c89e4eSSatish Balay @*/
9897087cfbeSBarry Smith PetscErrorCode PetscTokenCreate(const char a[], const char b, PetscToken *t)
990e5c89e4eSSatish Balay {
991e5c89e4eSSatish Balay   PetscFunctionBegin;
9925f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(a,1);
9935f80ce2aSJacob Faibussowitsch   PetscValidPointer(t,3);
9949566063dSJacob Faibussowitsch   PetscCall(PetscNew(t));
9959566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(a,&(*t)->array));
996a297a907SKarl Rupp 
997e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
998e5c89e4eSSatish Balay   (*t)->token   = b;
999e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1000e5c89e4eSSatish Balay }
1001e5c89e4eSSatish Balay 
1002e5c89e4eSSatish Balay /*@C
1003e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
1004e5c89e4eSSatish Balay 
1005e5c89e4eSSatish Balay    Not Collective
1006e5c89e4eSSatish Balay 
1007e5c89e4eSSatish Balay    Input Parameters:
1008e5c89e4eSSatish Balay .  a - pointer to token
1009e5c89e4eSSatish Balay 
1010e5c89e4eSSatish Balay    Level: intermediate
1011e5c89e4eSSatish Balay 
101295452b02SPatrick Sanan    Notes:
101395452b02SPatrick Sanan     Not for use in Fortran
10146f013253SBarry Smith 
1015db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenFind()`
1016e5c89e4eSSatish Balay @*/
10178c74ee41SBarry Smith PetscErrorCode PetscTokenDestroy(PetscToken *a)
1018e5c89e4eSSatish Balay {
1019e5c89e4eSSatish Balay   PetscFunctionBegin;
10208c74ee41SBarry Smith   if (!*a) PetscFunctionReturn(0);
10219566063dSJacob Faibussowitsch   PetscCall(PetscFree((*a)->array));
10229566063dSJacob Faibussowitsch   PetscCall(PetscFree(*a));
1023e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1024e5c89e4eSSatish Balay }
1025e5c89e4eSSatish Balay 
10268e81d068SLisandro Dalcin /*@C
10278e81d068SLisandro Dalcin    PetscStrInList - search string in character-delimited list
10288e81d068SLisandro Dalcin 
10298e81d068SLisandro Dalcin    Not Collective
10308e81d068SLisandro Dalcin 
10318e81d068SLisandro Dalcin    Input Parameters:
10328e81d068SLisandro Dalcin +  str - the string to look for
10338e81d068SLisandro Dalcin .  list - the list to search in
10348e81d068SLisandro Dalcin -  sep - the separator character
10358e81d068SLisandro Dalcin 
10368e81d068SLisandro Dalcin    Output Parameter:
10378e81d068SLisandro Dalcin .  found - whether str is in list
10388e81d068SLisandro Dalcin 
10398e81d068SLisandro Dalcin    Level: intermediate
10408e81d068SLisandro Dalcin 
104195452b02SPatrick Sanan    Notes:
104295452b02SPatrick Sanan     Not for use in Fortran
10438e81d068SLisandro Dalcin 
1044db781477SPatrick Sanan .seealso: `PetscTokenCreate()`, `PetscTokenFind()`, `PetscStrcmp()`
10458e81d068SLisandro Dalcin @*/
10468e81d068SLisandro Dalcin PetscErrorCode PetscStrInList(const char str[], const char list[], char sep, PetscBool *found)
10478e81d068SLisandro Dalcin {
10488e81d068SLisandro Dalcin   PetscToken  token;
10498e81d068SLisandro Dalcin   char       *item;
10508e81d068SLisandro Dalcin 
10518e81d068SLisandro Dalcin   PetscFunctionBegin;
10525f80ce2aSJacob Faibussowitsch   PetscValidBoolPointer(found,4);
10538e81d068SLisandro Dalcin   *found = PETSC_FALSE;
10549566063dSJacob Faibussowitsch   PetscCall(PetscTokenCreate(list,sep,&token));
10559566063dSJacob Faibussowitsch   PetscCall(PetscTokenFind(token,&item));
10568e81d068SLisandro Dalcin   while (item) {
10579566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(str,item,found));
10588e81d068SLisandro Dalcin     if (*found) break;
10599566063dSJacob Faibussowitsch     PetscCall(PetscTokenFind(token,&item));
10608e81d068SLisandro Dalcin   }
10619566063dSJacob Faibussowitsch   PetscCall(PetscTokenDestroy(&token));
10628e81d068SLisandro Dalcin   PetscFunctionReturn(0);
10638e81d068SLisandro Dalcin }
1064e5c89e4eSSatish Balay 
1065e5c89e4eSSatish Balay /*@C
1066e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
1067e5c89e4eSSatish Balay 
1068e5c89e4eSSatish Balay    Not Collective
1069e5c89e4eSSatish Balay 
1070e5c89e4eSSatish Balay    Output Parameter:
1071e5c89e4eSSatish Balay .  dir - the directory
1072e5c89e4eSSatish Balay 
1073e5c89e4eSSatish Balay    Level: developer
1074e5c89e4eSSatish Balay 
107595452b02SPatrick Sanan    Notes:
107695452b02SPatrick Sanan     Not for use in Fortran
10776f013253SBarry Smith 
1078e5c89e4eSSatish Balay @*/
10797087cfbeSBarry Smith PetscErrorCode PetscGetPetscDir(const char *dir[])
1080e5c89e4eSSatish Balay {
1081e5c89e4eSSatish Balay   PetscFunctionBegin;
10825f80ce2aSJacob Faibussowitsch   PetscValidPointer(dir,1);
1083e5c89e4eSSatish Balay   *dir = PETSC_DIR;
1084e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1085e5c89e4eSSatish Balay }
1086e5c89e4eSSatish Balay 
1087e5c89e4eSSatish Balay /*@C
1088e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
1089e5c89e4eSSatish Balay 
1090e5c89e4eSSatish Balay    Not Collective
1091e5c89e4eSSatish Balay 
1092e5c89e4eSSatish Balay    Input Parameters:
1093e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
109471573d7dSBarry Smith .   aa - the string to look in
1095d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
1096e5c89e4eSSatish Balay -   len - the length of b
1097e5c89e4eSSatish Balay 
1098e5c89e4eSSatish Balay    Notes:
1099e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
1100d5649816SBarry Smith       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
1101e5c89e4eSSatish Balay       as well as any environmental variables.
1102e5c89e4eSSatish Balay 
11036f013253SBarry Smith       PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
1104acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
1105acc6cc86SBarry Smith 
11066f013253SBarry Smith       Not for use in Fortran
11076f013253SBarry Smith 
1108e5c89e4eSSatish Balay    Level: intermediate
1109e5c89e4eSSatish Balay 
1110e5c89e4eSSatish Balay @*/
11117087cfbeSBarry Smith PetscErrorCode PetscStrreplace(MPI_Comm comm, const char aa[], char b[], size_t len)
1112e5c89e4eSSatish Balay {
1113e5c89e4eSSatish Balay   int            i = 0;
1114e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
111571573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
111602c9f0b5SLisandro Dalcin   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",NULL};
111702c9f0b5SLisandro Dalcin   char           *r[] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
1118ace3abfcSBarry Smith   PetscBool      flag;
1119589a23caSBarry Smith   static size_t  DISPLAY_LENGTH = 265,USER_LENGTH = 256, HOST_LENGTH = 256;
1120e5c89e4eSSatish Balay 
1121e5c89e4eSSatish Balay   PetscFunctionBegin;
11225f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(aa,2);
11235f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(b,3);
11249566063dSJacob Faibussowitsch   if (aa == b) PetscCall(PetscStrallocpy(aa,(char**)&a));
11259566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(len,&work));
1126e5c89e4eSSatish Balay 
1127e5c89e4eSSatish Balay   /* get values for replaced variables */
11289566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(PETSC_ARCH,&r[0]));
11299566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(PETSC_DIR,&r[1]));
11309566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(PETSC_LIB_DIR,&r[2]));
11319566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(DISPLAY_LENGTH,&r[3]));
11329566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN,&r[4]));
11339566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(PETSC_MAX_PATH_LEN,&r[5]));
11349566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(USER_LENGTH,&r[6]));
11359566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(HOST_LENGTH,&r[7]));
11369566063dSJacob Faibussowitsch   PetscCall(PetscGetDisplay(r[3],DISPLAY_LENGTH));
11379566063dSJacob Faibussowitsch   PetscCall(PetscGetHomeDirectory(r[4],PETSC_MAX_PATH_LEN));
11389566063dSJacob Faibussowitsch   PetscCall(PetscGetWorkingDirectory(r[5],PETSC_MAX_PATH_LEN));
11399566063dSJacob Faibussowitsch   PetscCall(PetscGetUserName(r[6],USER_LENGTH));
11409566063dSJacob Faibussowitsch   PetscCall(PetscGetHostName(r[7],HOST_LENGTH));
1141487e5849SBarry Smith 
1142487e5849SBarry Smith   /* replace that are in environment */
11439566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,sizeof(env),&flag));
1144487e5849SBarry Smith   if (flag) {
11459566063dSJacob Faibussowitsch     PetscCall(PetscFree(r[2]));
11469566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(env,&r[2]));
1147487e5849SBarry Smith   }
1148e5c89e4eSSatish Balay 
1149e5c89e4eSSatish Balay   /* replace the requested strings */
11509566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(b,a,len));
1151e5c89e4eSSatish Balay   while (s[i]) {
11529566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(s[i],&l));
11539566063dSJacob Faibussowitsch     PetscCall(PetscStrstr(b,s[i],&par));
1154e5c89e4eSSatish Balay     while (par) {
1155e5c89e4eSSatish Balay       *par = 0;
1156e5c89e4eSSatish Balay       par += l;
1157e5c89e4eSSatish Balay 
11589566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(b,&l1));
11599566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(r[i],&l2));
11609566063dSJacob Faibussowitsch       PetscCall(PetscStrlen(par,&l3));
1161cc73adaaSBarry Smith       PetscCheck(l1 + l2 + l3 < len,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
11629566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(work,b,len));
11639566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(work,r[i],len));
11649566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(work,par,len));
11659566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(b,work,len));
11669566063dSJacob Faibussowitsch       PetscCall(PetscStrstr(b,s[i],&par));
1167e5c89e4eSSatish Balay     }
1168e5c89e4eSSatish Balay     i++;
1169e5c89e4eSSatish Balay   }
1170487e5849SBarry Smith   i = 0;
1171487e5849SBarry Smith   while (r[i]) {
1172e5c89e4eSSatish Balay     tfree = (char*)r[i];
11739566063dSJacob Faibussowitsch     PetscCall(PetscFree(tfree));
1174487e5849SBarry Smith     i++;
1175e5c89e4eSSatish Balay   }
1176e5c89e4eSSatish Balay 
1177e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
11789566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(b,"${",&par));
1179e5c89e4eSSatish Balay   while (par) {
1180e5c89e4eSSatish Balay     *par  = 0;
1181e5c89e4eSSatish Balay     par  += 2;
11829566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(work,b,len));
11839566063dSJacob Faibussowitsch     PetscCall(PetscStrstr(par,"}",&epar));
1184e5c89e4eSSatish Balay     *epar = 0;
1185e5c89e4eSSatish Balay     epar += 1;
11869566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetenv(comm,par,env,sizeof(env),&flag));
118728b400f6SJacob Faibussowitsch     PetscCheck(flag,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
11889566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(work,env,len));
11899566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(work,epar,len));
11909566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(b,work,len));
11919566063dSJacob Faibussowitsch     PetscCall(PetscStrstr(b,"${",&par));
1192e5c89e4eSSatish Balay   }
11939566063dSJacob Faibussowitsch   PetscCall(PetscFree(work));
11949566063dSJacob Faibussowitsch   if (aa == b) PetscCall(PetscFree(a));
1195e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1196e5c89e4eSSatish Balay }
1197e5c89e4eSSatish Balay 
1198a53986e1SJed Brown /*@C
1199a53986e1SJed Brown    PetscEListFind - searches list of strings for given string, using case insensitive matching
1200e5c89e4eSSatish Balay 
1201a53986e1SJed Brown    Not Collective
1202a53986e1SJed Brown 
1203a53986e1SJed Brown    Input Parameters:
1204a53986e1SJed Brown +  n - number of strings in
1205a53986e1SJed Brown .  list - list of strings to search
1206a53986e1SJed Brown -  str - string to look for, empty string "" accepts default (first entry in list)
1207a53986e1SJed Brown 
1208a53986e1SJed Brown    Output Parameters:
1209a53986e1SJed Brown +  value - index of matching string (if found)
1210a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1211a53986e1SJed Brown 
1212a53986e1SJed Brown    Notes:
1213a53986e1SJed Brown    Not for use in Fortran
1214a53986e1SJed Brown 
1215a53986e1SJed Brown    Level: advanced
1216a53986e1SJed Brown @*/
1217a53986e1SJed Brown PetscErrorCode PetscEListFind(PetscInt n, const char *const *list, const char *str, PetscInt *value, PetscBool *found)
1218a53986e1SJed Brown {
1219a53986e1SJed Brown   PetscFunctionBegin;
12205f80ce2aSJacob Faibussowitsch   if (found) {
12215f80ce2aSJacob Faibussowitsch     PetscValidBoolPointer(found,5);
12225f80ce2aSJacob Faibussowitsch     *found = PETSC_FALSE;
12235f80ce2aSJacob Faibussowitsch   }
12245f80ce2aSJacob Faibussowitsch   for (PetscInt i = 0; i < n; ++i) {
12255f80ce2aSJacob Faibussowitsch     PetscBool matched;
12265f80ce2aSJacob Faibussowitsch 
12279566063dSJacob Faibussowitsch     PetscCall(PetscStrcasecmp(str,list[i],&matched));
1228a53986e1SJed Brown     if (matched || !str[0]) {
1229a53986e1SJed Brown       if (found) *found = PETSC_TRUE;
1230a53986e1SJed Brown       *value = i;
1231a53986e1SJed Brown       break;
1232a53986e1SJed Brown     }
1233a53986e1SJed Brown   }
1234a53986e1SJed Brown   PetscFunctionReturn(0);
1235a53986e1SJed Brown }
1236a53986e1SJed Brown 
1237a53986e1SJed Brown /*@C
12388e81d068SLisandro Dalcin    PetscEnumFind - searches enum list of strings for given string, using case insensitive matching
1239a53986e1SJed Brown 
1240a53986e1SJed Brown    Not Collective
1241a53986e1SJed Brown 
1242a53986e1SJed Brown    Input Parameters:
1243a53986e1SJed Brown +  enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL
1244a53986e1SJed Brown -  str - string to look for
1245a53986e1SJed Brown 
1246a53986e1SJed Brown    Output Parameters:
1247a53986e1SJed Brown +  value - index of matching string (if found)
1248a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1249a53986e1SJed Brown 
1250a53986e1SJed Brown    Notes:
1251a53986e1SJed Brown    Not for use in Fortran
1252a53986e1SJed Brown 
1253a53986e1SJed Brown    Level: advanced
1254a53986e1SJed Brown @*/
1255a53986e1SJed Brown PetscErrorCode PetscEnumFind(const char *const *enumlist, const char *str, PetscEnum *value, PetscBool *found)
1256a53986e1SJed Brown {
1257d05ba7d2SLisandro Dalcin   PetscInt  n = 0,evalue;
1258a53986e1SJed Brown   PetscBool efound;
1259a53986e1SJed Brown 
1260a53986e1SJed Brown   PetscFunctionBegin;
12615f80ce2aSJacob Faibussowitsch   PetscValidPointer(enumlist,1);
12625f80ce2aSJacob Faibussowitsch   while (enumlist[n++]) PetscCheck(n <= 50,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
12635f80ce2aSJacob Faibussowitsch   PetscCheck(n >= 3,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
1264a53986e1SJed Brown   n -= 3; /* drop enum name, prefix, and null termination */
12659566063dSJacob Faibussowitsch   PetscCall(PetscEListFind(n,enumlist,str,&evalue,&efound));
12665f80ce2aSJacob Faibussowitsch   if (efound) {
12675f80ce2aSJacob Faibussowitsch     PetscValidPointer(value,3);
12685f80ce2aSJacob Faibussowitsch     *value = (PetscEnum)evalue;
12695f80ce2aSJacob Faibussowitsch   }
12705f80ce2aSJacob Faibussowitsch   if (found) {
12715f80ce2aSJacob Faibussowitsch     PetscValidBoolPointer(found,4);
12725f80ce2aSJacob Faibussowitsch     *found = efound;
12735f80ce2aSJacob Faibussowitsch   }
1274a53986e1SJed Brown   PetscFunctionReturn(0);
1275a53986e1SJed Brown }
1276