xref: /petsc/src/sys/utils/str.c (revision d8d19677bbccf95218448bee62e6b87f4513e133)
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 */
7c6db04a5SJed Brown #include <petscsys.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 
21*d8d19677SJose 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 
36b4cd4cebSBarry Smith .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   }
514996c5bdSBarry Smith   if (!n) {
524996c5bdSBarry Smith     return(0);
534996c5bdSBarry Smith   }
543c311c98SBarry Smith   for (i=0; i<n; i++) {
55d67fe73bSBarry Smith     if (s[i] != sp) break;
563c311c98SBarry Smith   }
573c311c98SBarry Smith   for (;i<n+1; i++) {
58d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
59d67fe73bSBarry Smith     else if (s[i] != sp) {flg = PETSC_FALSE;}
603c311c98SBarry Smith   }
61a2ea699eSBarry Smith   (*args) = (char**) malloc(((*argc)+1)*sizeof(char*)); if (!*args) return PETSC_ERR_MEM;
6253e6e2c4SHong Zhang   lens    = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM;
633c311c98SBarry Smith   for (i=0; i<*argc; i++) lens[i] = 0;
643c311c98SBarry Smith 
653c311c98SBarry Smith   *argc = 0;
663c311c98SBarry Smith   for (i=0; i<n; i++) {
67d67fe73bSBarry Smith     if (s[i] != sp) break;
683c311c98SBarry Smith   }
697dd9f305SSatish Balay   for (;i<n+1; i++) {
70d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
71d67fe73bSBarry Smith     else if (s[i] != sp) {lens[*argc]++;flg = PETSC_FALSE;}
723c311c98SBarry Smith   }
733c311c98SBarry Smith 
743c311c98SBarry Smith   for (i=0; i<*argc; i++) {
75c3bcdc7eSBarry Smith     (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char));
76c3bcdc7eSBarry Smith     if (!(*args)[i]) {
77c3bcdc7eSBarry Smith       free(lens);
78c3bcdc7eSBarry Smith       for (j=0; j<i; j++) free((*args)[j]);
79c3bcdc7eSBarry Smith       free(*args);
80c3bcdc7eSBarry Smith       return PETSC_ERR_MEM;
81c3bcdc7eSBarry Smith     }
823c311c98SBarry Smith   }
83a2ea699eSBarry Smith   free(lens);
8402c9f0b5SLisandro Dalcin   (*args)[*argc] = NULL;
853c311c98SBarry Smith 
863c311c98SBarry Smith   *argc = 0;
873c311c98SBarry Smith   for (i=0; i<n; i++) {
88d67fe73bSBarry Smith     if (s[i] != sp) break;
893c311c98SBarry Smith   }
903c311c98SBarry Smith   for (;i<n+1; i++) {
91d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
92d67fe73bSBarry Smith     else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;}
933c311c98SBarry Smith   }
943c311c98SBarry Smith   return 0;
953c311c98SBarry Smith }
963c311c98SBarry Smith 
97301d30feSBarry Smith /*@C
98301d30feSBarry Smith    PetscStrToArrayDestroy - Frees array created with PetscStrToArray().
99301d30feSBarry Smith 
100301d30feSBarry Smith    Not Collective
101301d30feSBarry Smith 
102301d30feSBarry Smith    Output Parameters:
103301d30feSBarry Smith +  argc - the number of arguments
104301d30feSBarry Smith -  args - the array of arguments
105301d30feSBarry Smith 
106301d30feSBarry Smith    Level: intermediate
107301d30feSBarry Smith 
10895452b02SPatrick Sanan    Notes:
10995452b02SPatrick Sanan     This may be called before PetscInitialize() or after PetscFinalize()
110301d30feSBarry Smith 
1116f013253SBarry Smith    Not for use in Fortran
1126f013253SBarry Smith 
113301d30feSBarry Smith .seealso: PetscStrToArray()
114301d30feSBarry Smith 
115301d30feSBarry Smith @*/
1167087cfbeSBarry Smith PetscErrorCode  PetscStrToArrayDestroy(int argc,char **args)
117301d30feSBarry Smith {
118301d30feSBarry Smith   PetscInt i;
119301d30feSBarry Smith 
120a297a907SKarl Rupp   for (i=0; i<argc; i++) free(args[i]);
121a297a907SKarl Rupp   if (args) free(args);
122301d30feSBarry Smith   return 0;
123301d30feSBarry Smith }
124301d30feSBarry Smith 
125e5c89e4eSSatish Balay /*@C
126e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
127e5c89e4eSSatish Balay 
128e5c89e4eSSatish Balay    Not Collective
129e5c89e4eSSatish Balay 
130e5c89e4eSSatish Balay    Input Parameters:
131e5c89e4eSSatish Balay .  s - pointer to string
132e5c89e4eSSatish Balay 
133e5c89e4eSSatish Balay    Output Parameter:
134e5c89e4eSSatish Balay .  len - length in bytes
135e5c89e4eSSatish Balay 
136e5c89e4eSSatish Balay    Level: intermediate
137e5c89e4eSSatish Balay 
138e5c89e4eSSatish Balay    Note:
139e5c89e4eSSatish Balay    This routine is analogous to strlen().
140e5c89e4eSSatish Balay 
141e5c89e4eSSatish Balay    Null string returns a length of zero
142e5c89e4eSSatish Balay 
1436f013253SBarry Smith    Not for use in Fortran
1446f013253SBarry Smith 
145e5c89e4eSSatish Balay @*/
1467087cfbeSBarry Smith PetscErrorCode  PetscStrlen(const char s[],size_t *len)
147e5c89e4eSSatish Balay {
148e5c89e4eSSatish Balay   PetscFunctionBegin;
149a297a907SKarl Rupp   if (!s) *len = 0;
150a297a907SKarl Rupp   else    *len = strlen(s);
151e5c89e4eSSatish Balay   PetscFunctionReturn(0);
152e5c89e4eSSatish Balay }
153e5c89e4eSSatish Balay 
154e5c89e4eSSatish Balay /*@C
155e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
156e5c89e4eSSatish Balay 
157e5c89e4eSSatish Balay    Not Collective
158e5c89e4eSSatish Balay 
159e5c89e4eSSatish Balay    Input Parameters:
160e5c89e4eSSatish Balay .  s - pointer to string
161e5c89e4eSSatish Balay 
162e5c89e4eSSatish Balay    Output Parameter:
163e5c89e4eSSatish Balay .  t - the copied string
164e5c89e4eSSatish Balay 
165e5c89e4eSSatish Balay    Level: intermediate
166e5c89e4eSSatish Balay 
167e5c89e4eSSatish Balay    Note:
168e5c89e4eSSatish Balay       Null string returns a new null string
169e5c89e4eSSatish Balay 
1706f013253SBarry Smith       Not for use in Fortran
1716f013253SBarry Smith 
1720ecf5a55SBarry Smith       Warning: If t has previously been allocated then that memory is lost, you may need to PetscFree()
1730ecf5a55SBarry Smith       the array before calling this routine.
1740ecf5a55SBarry Smith 
1750ecf5a55SBarry Smith .seealso: PetscStrArrayallocpy(), PetscStrcpy(), PetscStrNArrayallocpy()
1760ecf5a55SBarry Smith 
177e5c89e4eSSatish Balay @*/
1787087cfbeSBarry Smith PetscErrorCode  PetscStrallocpy(const char s[],char *t[])
179e5c89e4eSSatish Balay {
180e5c89e4eSSatish Balay   PetscErrorCode ierr;
181e5c89e4eSSatish Balay   size_t         len;
18202c9f0b5SLisandro Dalcin   char           *tmp = NULL;
183e5c89e4eSSatish Balay 
184e5c89e4eSSatish Balay   PetscFunctionBegin;
185e5c89e4eSSatish Balay   if (s) {
186e5c89e4eSSatish Balay     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
187854ce69bSBarry Smith     ierr = PetscMalloc1(1+len,&tmp);CHKERRQ(ierr);
18871573d7dSBarry Smith     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
189e5c89e4eSSatish Balay   }
19071573d7dSBarry Smith   *t = tmp;
191e5c89e4eSSatish Balay   PetscFunctionReturn(0);
192e5c89e4eSSatish Balay }
193e5c89e4eSSatish Balay 
19447340559SBarry Smith /*@C
19547340559SBarry Smith    PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
19647340559SBarry Smith 
19747340559SBarry Smith    Not Collective
19847340559SBarry Smith 
19947340559SBarry Smith    Input Parameters:
20047340559SBarry Smith .  s - pointer to array of strings (final string is a null)
20147340559SBarry Smith 
20247340559SBarry Smith    Output Parameter:
20347340559SBarry Smith .  t - the copied array string
20447340559SBarry Smith 
20547340559SBarry Smith    Level: intermediate
20647340559SBarry Smith 
20747340559SBarry Smith    Note:
20847340559SBarry Smith       Not for use in Fortran
20947340559SBarry Smith 
2100ecf5a55SBarry Smith       Warning: If t has previously been allocated then that memory is lost, you may need to PetscStrArrayDestroy()
2110ecf5a55SBarry Smith       the array before calling this routine.
2120ecf5a55SBarry Smith 
2130ecf5a55SBarry Smith .seealso: PetscStrallocpy(), PetscStrArrayDestroy(), PetscStrNArrayallocpy()
21447340559SBarry Smith 
21547340559SBarry Smith @*/
21647340559SBarry Smith PetscErrorCode  PetscStrArrayallocpy(const char *const *list,char ***t)
21747340559SBarry Smith {
21847340559SBarry Smith   PetscErrorCode ierr;
21947340559SBarry Smith   PetscInt       i,n = 0;
22047340559SBarry Smith 
22147340559SBarry Smith   PetscFunctionBegin;
22247340559SBarry Smith   while (list[n++]) ;
223854ce69bSBarry Smith   ierr = PetscMalloc1(n+1,t);CHKERRQ(ierr);
22447340559SBarry Smith   for (i=0; i<n; i++) {
22547340559SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
22647340559SBarry Smith   }
2270298fd71SBarry Smith   (*t)[n] = NULL;
22847340559SBarry Smith   PetscFunctionReturn(0);
22947340559SBarry Smith }
23047340559SBarry Smith 
23147340559SBarry Smith /*@C
23247340559SBarry Smith    PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
23347340559SBarry Smith 
23447340559SBarry Smith    Not Collective
23547340559SBarry Smith 
23647340559SBarry Smith    Output Parameters:
23747340559SBarry Smith .   list - array of strings
23847340559SBarry Smith 
23947340559SBarry Smith    Level: intermediate
24047340559SBarry Smith 
24195452b02SPatrick Sanan    Notes:
24295452b02SPatrick Sanan     Not for use in Fortran
24347340559SBarry Smith 
24447340559SBarry Smith .seealso: PetscStrArrayallocpy()
24547340559SBarry Smith 
24647340559SBarry Smith @*/
2476fed8037SJed Brown PetscErrorCode PetscStrArrayDestroy(char ***list)
24847340559SBarry Smith {
24947340559SBarry Smith   PetscInt       n = 0;
25047340559SBarry Smith   PetscErrorCode ierr;
25147340559SBarry Smith 
2526fed8037SJed Brown   PetscFunctionBegin;
2536fed8037SJed Brown   if (!*list) PetscFunctionReturn(0);
2546fed8037SJed Brown   while ((*list)[n]) {
2556fed8037SJed Brown     ierr = PetscFree((*list)[n]);CHKERRQ(ierr);
25647340559SBarry Smith     n++;
25747340559SBarry Smith   }
2586fed8037SJed Brown   ierr = PetscFree(*list);CHKERRQ(ierr);
2596fed8037SJed Brown   PetscFunctionReturn(0);
26047340559SBarry Smith }
26147340559SBarry Smith 
2626991f827SBarry Smith /*@C
2636991f827SBarry Smith    PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
2646991f827SBarry Smith 
2656991f827SBarry Smith    Not Collective
2666991f827SBarry Smith 
2676991f827SBarry Smith    Input Parameters:
2686991f827SBarry Smith +  n - the number of string entries
2696991f827SBarry Smith -  s - pointer to array of strings
2706991f827SBarry Smith 
2716991f827SBarry Smith    Output Parameter:
2726991f827SBarry Smith .  t - the copied array string
2736991f827SBarry Smith 
2746991f827SBarry Smith    Level: intermediate
2756991f827SBarry Smith 
2766991f827SBarry Smith    Note:
2776991f827SBarry Smith       Not for use in Fortran
2786991f827SBarry Smith 
2790ecf5a55SBarry Smith .seealso: PetscStrallocpy(), PetscStrArrayallocpy(), PetscStrNArrayDestroy()
2806991f827SBarry Smith 
2816991f827SBarry Smith @*/
2826991f827SBarry Smith PetscErrorCode  PetscStrNArrayallocpy(PetscInt n,const char *const *list,char ***t)
2836991f827SBarry Smith {
2846991f827SBarry Smith   PetscErrorCode ierr;
2856991f827SBarry Smith   PetscInt       i;
2866991f827SBarry Smith 
2876991f827SBarry Smith   PetscFunctionBegin;
2886991f827SBarry Smith   ierr = PetscMalloc1(n,t);CHKERRQ(ierr);
2896991f827SBarry Smith   for (i=0; i<n; i++) {
2906991f827SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
2916991f827SBarry Smith   }
2926991f827SBarry Smith   PetscFunctionReturn(0);
2936991f827SBarry Smith }
2946991f827SBarry Smith 
2956991f827SBarry Smith /*@C
2966991f827SBarry Smith    PetscStrNArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
2976991f827SBarry Smith 
2986991f827SBarry Smith    Not Collective
2996991f827SBarry Smith 
3006991f827SBarry Smith    Output Parameters:
3016991f827SBarry Smith +   n - number of string entries
3026991f827SBarry Smith -   list - array of strings
3036991f827SBarry Smith 
3046991f827SBarry Smith    Level: intermediate
3056991f827SBarry Smith 
30695452b02SPatrick Sanan    Notes:
30795452b02SPatrick Sanan     Not for use in Fortran
3086991f827SBarry Smith 
3096991f827SBarry Smith .seealso: PetscStrArrayallocpy()
3106991f827SBarry Smith 
3116991f827SBarry Smith @*/
3126991f827SBarry Smith PetscErrorCode PetscStrNArrayDestroy(PetscInt n,char ***list)
3136991f827SBarry Smith {
3146991f827SBarry Smith   PetscErrorCode ierr;
3156991f827SBarry Smith   PetscInt       i;
3166991f827SBarry Smith 
3176991f827SBarry Smith   PetscFunctionBegin;
3186991f827SBarry Smith   if (!*list) PetscFunctionReturn(0);
3196991f827SBarry Smith   for (i=0; i<n; i++) {
3206991f827SBarry Smith     ierr = PetscFree((*list)[i]);CHKERRQ(ierr);
3216991f827SBarry Smith   }
3226991f827SBarry Smith   ierr = PetscFree(*list);CHKERRQ(ierr);
3236991f827SBarry Smith   PetscFunctionReturn(0);
3246991f827SBarry Smith }
3256991f827SBarry Smith 
326e5c89e4eSSatish Balay /*@C
327e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
328e5c89e4eSSatish Balay 
329e5c89e4eSSatish Balay    Not Collective
330e5c89e4eSSatish Balay 
331e5c89e4eSSatish Balay    Input Parameters:
332e5c89e4eSSatish Balay .  t - pointer to string
333e5c89e4eSSatish Balay 
334e5c89e4eSSatish Balay    Output Parameter:
335e5c89e4eSSatish Balay .  s - the copied string
336e5c89e4eSSatish Balay 
337e5c89e4eSSatish Balay    Level: intermediate
338e5c89e4eSSatish Balay 
3396f013253SBarry Smith    Notes:
340e5c89e4eSSatish Balay      Null string returns a string starting with zero
341e5c89e4eSSatish Balay 
3426f013253SBarry Smith      Not for use in Fortran
3436f013253SBarry Smith 
3440ecf5a55SBarry Smith      It is recommended you use PetscStrncpy() instead of this routine
3450ecf5a55SBarry Smith 
346a126751eSBarry Smith .seealso: PetscStrncpy(), PetscStrcat(), PetscStrlcat()
347e5c89e4eSSatish Balay 
348e5c89e4eSSatish Balay @*/
349acc6cc86SBarry Smith 
3507087cfbeSBarry Smith PetscErrorCode  PetscStrcpy(char s[],const char t[])
351e5c89e4eSSatish Balay {
352e5c89e4eSSatish Balay   PetscFunctionBegin;
35317186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
354a297a907SKarl Rupp   if (t) strcpy(s,t);
355a297a907SKarl Rupp   else if (s) s[0] = 0;
356e5c89e4eSSatish Balay   PetscFunctionReturn(0);
357e5c89e4eSSatish Balay }
358e5c89e4eSSatish Balay 
359e5c89e4eSSatish Balay /*@C
360e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
361e5c89e4eSSatish Balay 
362e5c89e4eSSatish Balay    Not Collective
363e5c89e4eSSatish Balay 
364e5c89e4eSSatish Balay    Input Parameters:
365e5c89e4eSSatish Balay +  t - pointer to string
366e5c89e4eSSatish Balay -  n - the length to copy
367e5c89e4eSSatish Balay 
368e5c89e4eSSatish Balay    Output Parameter:
369e5c89e4eSSatish Balay .  s - the copied string
370e5c89e4eSSatish Balay 
371e5c89e4eSSatish Balay    Level: intermediate
372e5c89e4eSSatish Balay 
373e5c89e4eSSatish Balay    Note:
374e5c89e4eSSatish Balay      Null string returns a string starting with zero
375e5c89e4eSSatish Balay 
376ff32304bSBarry Smith      If the string that is being copied is of length n or larger then the entire string is not
3771b6ef838SBarry Smith      copied and the final location of s is set to NULL. This is different then the behavior of
3781b6ef838SBarry Smith      strncpy() which leaves s non-terminated if there is not room for the entire string.
379ff32304bSBarry Smith 
38062a5de14SBarry Smith   Developers Note: Should this be PetscStrlcpy() to reflect its behavior which is like strlcpy() not strncpy()
38162a5de14SBarry Smith 
382a126751eSBarry Smith .seealso: PetscStrcpy(), PetscStrcat(), PetscStrlcat()
383e5c89e4eSSatish Balay 
384e5c89e4eSSatish Balay @*/
3857087cfbeSBarry Smith PetscErrorCode  PetscStrncpy(char s[],const char t[],size_t n)
386e5c89e4eSSatish Balay {
387e5c89e4eSSatish Balay   PetscFunctionBegin;
38817186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
38962a5de14SBarry Smith   if (s && !n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Requires an output string of length at least 1 to hold the termination character");
390ff32304bSBarry Smith   if (t) {
3918dc57659SBarry Smith     if (n > 1) {
3922c26941aSBarry Smith       strncpy(s,t,n-1);
393ff32304bSBarry Smith       s[n-1] = '\0';
3948dc57659SBarry Smith     } else {
3958dc57659SBarry Smith       s[0] = '\0';
3968dc57659SBarry Smith     }
397ff32304bSBarry Smith   } else if (s) s[0] = 0;
398e5c89e4eSSatish Balay   PetscFunctionReturn(0);
399e5c89e4eSSatish Balay }
400e5c89e4eSSatish Balay 
401e5c89e4eSSatish Balay /*@C
402e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
403e5c89e4eSSatish Balay 
404e5c89e4eSSatish Balay    Not Collective
405e5c89e4eSSatish Balay 
406e5c89e4eSSatish Balay    Input Parameters:
407e5e2177aSMatthew Knepley +  s - string to be added to
408e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
409e5c89e4eSSatish Balay 
410e5c89e4eSSatish Balay    Level: intermediate
411e5c89e4eSSatish Balay 
41295452b02SPatrick Sanan    Notes:
41395452b02SPatrick Sanan     Not for use in Fortran
4146f013253SBarry Smith 
4150ecf5a55SBarry Smith     It is recommended you use PetscStrlcat() instead of this routine
4160ecf5a55SBarry Smith 
417a126751eSBarry Smith .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrlcat()
418e5c89e4eSSatish Balay 
419e5c89e4eSSatish Balay @*/
4207087cfbeSBarry Smith PetscErrorCode  PetscStrcat(char s[],const char t[])
421e5c89e4eSSatish Balay {
422e5c89e4eSSatish Balay   PetscFunctionBegin;
4239b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
424e5c89e4eSSatish Balay   strcat(s,t);
425e5c89e4eSSatish Balay   PetscFunctionReturn(0);
426e5c89e4eSSatish Balay }
427e5c89e4eSSatish Balay 
428e5c89e4eSSatish Balay /*@C
429a126751eSBarry Smith    PetscStrlcat - Concatenates a string onto a given string, up to a given length
430e5c89e4eSSatish Balay 
431e5c89e4eSSatish Balay    Not Collective
432e5c89e4eSSatish Balay 
433e5c89e4eSSatish Balay    Input Parameters:
434e0ffd71fSBarry Smith +  s - pointer to string to be added to at end
43572fa4726SStefano Zampini .  t - string to be added
43624a58d73SPatrick Sanan -  n - length of the original allocated string
437e5c89e4eSSatish Balay 
438e5c89e4eSSatish Balay    Level: intermediate
439e5c89e4eSSatish Balay 
44024a58d73SPatrick Sanan   Notes:
44124a58d73SPatrick Sanan   Not for use in Fortran
4426f013253SBarry Smith 
44324a58d73SPatrick Sanan   Unlike the system call strncat(), the length passed in is the length of the
44424a58d73SPatrick Sanan   original allocated space, not the length of the left-over space. This is
44524a58d73SPatrick Sanan   similar to the BSD system call strlcat().
446153a8027SBarry Smith 
447e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
448e5c89e4eSSatish Balay 
449e5c89e4eSSatish Balay @*/
450a126751eSBarry Smith PetscErrorCode  PetscStrlcat(char s[],const char t[],size_t n)
451e5c89e4eSSatish Balay {
452153a8027SBarry Smith   size_t         len;
453153a8027SBarry Smith   PetscErrorCode ierr;
454153a8027SBarry Smith 
455e5c89e4eSSatish Balay   PetscFunctionBegin;
456681eeb0aSBarry Smith   if (t && !n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"String buffer length must be positive");
457e0ffd71fSBarry Smith   if (!t) PetscFunctionReturn(0);
458153a8027SBarry Smith   ierr = PetscStrlen(t,&len);CHKERRQ(ierr);
459153a8027SBarry Smith   strncat(s,t,n - len);
460681eeb0aSBarry Smith   s[n-1] = 0;
461e5c89e4eSSatish Balay   PetscFunctionReturn(0);
462e5c89e4eSSatish Balay }
463e5c89e4eSSatish Balay 
464573b0fb4SBarry Smith void  PetscStrcmpNoError(const char a[],const char b[],PetscBool  *flg)
465573b0fb4SBarry Smith {
466573b0fb4SBarry Smith   int c;
467573b0fb4SBarry Smith 
468573b0fb4SBarry Smith   if (!a && !b)      *flg = PETSC_TRUE;
469573b0fb4SBarry Smith   else if (!a || !b) *flg = PETSC_FALSE;
470573b0fb4SBarry Smith   else {
471573b0fb4SBarry Smith     c = strcmp(a,b);
472573b0fb4SBarry Smith     if (c) *flg = PETSC_FALSE;
473573b0fb4SBarry Smith     else   *flg = PETSC_TRUE;
474573b0fb4SBarry Smith   }
475573b0fb4SBarry Smith }
476573b0fb4SBarry Smith 
477e5c89e4eSSatish Balay /*@C
478e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
479e5c89e4eSSatish Balay 
480e5c89e4eSSatish Balay    Not Collective
481e5c89e4eSSatish Balay 
482e5c89e4eSSatish Balay    Input Parameters:
483e5c89e4eSSatish Balay +  a - pointer to string first string
484e5c89e4eSSatish Balay -  b - pointer to second string
485e5c89e4eSSatish Balay 
486e5c89e4eSSatish Balay    Output Parameter:
4878c74ee41SBarry Smith .  flg - PETSC_TRUE if the two strings are equal
488e5c89e4eSSatish Balay 
489e5c89e4eSSatish Balay    Level: intermediate
490e5c89e4eSSatish Balay 
49195452b02SPatrick Sanan    Notes:
49295452b02SPatrick Sanan     Not for use in Fortran
4936f013253SBarry Smith 
494e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
495e5c89e4eSSatish Balay 
496e5c89e4eSSatish Balay @*/
4977087cfbeSBarry Smith PetscErrorCode  PetscStrcmp(const char a[],const char b[],PetscBool  *flg)
498e5c89e4eSSatish Balay {
499e5c89e4eSSatish Balay   int c;
500e5c89e4eSSatish Balay 
501e5c89e4eSSatish Balay   PetscFunctionBegin;
502a297a907SKarl Rupp   if (!a && !b)      *flg = PETSC_TRUE;
503a297a907SKarl Rupp   else if (!a || !b) *flg = PETSC_FALSE;
504a297a907SKarl Rupp   else {
505e5c89e4eSSatish Balay     c = strcmp(a,b);
506e5c89e4eSSatish Balay     if (c) *flg = PETSC_FALSE;
507e5c89e4eSSatish Balay     else   *flg = PETSC_TRUE;
508e5c89e4eSSatish Balay   }
509e5c89e4eSSatish Balay   PetscFunctionReturn(0);
510e5c89e4eSSatish Balay }
511e5c89e4eSSatish Balay 
512e5c89e4eSSatish Balay /*@C
513e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
514e5c89e4eSSatish Balay 
515e5c89e4eSSatish Balay    Not Collective
516e5c89e4eSSatish Balay 
517e5c89e4eSSatish Balay    Input Parameters:
518e5c89e4eSSatish Balay +  a - pointer to first string
519e5c89e4eSSatish Balay -  b - pointer to second string
520e5c89e4eSSatish Balay 
521e5c89e4eSSatish Balay    Output Parameter:
522e5c89e4eSSatish Balay .  flg - if the first string is greater
523e5c89e4eSSatish Balay 
524e5c89e4eSSatish Balay    Notes:
525e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
526e5c89e4eSSatish Balay     all others
527e5c89e4eSSatish Balay 
5286f013253SBarry Smith    Not for use in Fortran
5296f013253SBarry Smith 
530e5c89e4eSSatish Balay    Level: intermediate
531e5c89e4eSSatish Balay 
532e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
533e5c89e4eSSatish Balay 
534e5c89e4eSSatish Balay @*/
5357087cfbeSBarry Smith PetscErrorCode  PetscStrgrt(const char a[],const char b[],PetscBool  *t)
536e5c89e4eSSatish Balay {
537e5c89e4eSSatish Balay   int c;
538e5c89e4eSSatish Balay 
539e5c89e4eSSatish Balay   PetscFunctionBegin;
540a297a907SKarl Rupp   if (!a && !b) *t = PETSC_FALSE;
541a297a907SKarl Rupp   else if (a && !b) *t = PETSC_TRUE;
542a297a907SKarl Rupp   else if (!a && b) *t = PETSC_FALSE;
543a297a907SKarl Rupp   else {
544e5c89e4eSSatish Balay     c = strcmp(a,b);
545e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
546e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
547e5c89e4eSSatish Balay   }
548e5c89e4eSSatish Balay   PetscFunctionReturn(0);
549e5c89e4eSSatish Balay }
550e5c89e4eSSatish Balay 
551e5c89e4eSSatish Balay /*@C
552e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
553e5c89e4eSSatish Balay      except possibly for case.
554e5c89e4eSSatish Balay 
555e5c89e4eSSatish Balay    Not Collective
556e5c89e4eSSatish Balay 
557e5c89e4eSSatish Balay    Input Parameters:
558e5c89e4eSSatish Balay +  a - pointer to first string
559e5c89e4eSSatish Balay -  b - pointer to second string
560e5c89e4eSSatish Balay 
561e5c89e4eSSatish Balay    Output Parameter:
562e5c89e4eSSatish Balay .  flg - if the two strings are the same
563e5c89e4eSSatish Balay 
564e5c89e4eSSatish Balay    Notes:
565e5c89e4eSSatish Balay     Null arguments are ok
566e5c89e4eSSatish Balay 
5676f013253SBarry Smith    Not for use in Fortran
5686f013253SBarry Smith 
569e5c89e4eSSatish Balay    Level: intermediate
570e5c89e4eSSatish Balay 
571e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
572e5c89e4eSSatish Balay 
573e5c89e4eSSatish Balay @*/
5747087cfbeSBarry Smith PetscErrorCode  PetscStrcasecmp(const char a[],const char b[],PetscBool  *t)
575e5c89e4eSSatish Balay {
576e5c89e4eSSatish Balay   int c;
577e5c89e4eSSatish Balay 
578e5c89e4eSSatish Balay   PetscFunctionBegin;
579e5c89e4eSSatish Balay   if (!a && !b) c = 0;
580e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
58132b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
58232b366c8SSatish Balay   else c = strcasecmp(a,b);
58332b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
584e5c89e4eSSatish Balay   else c = stricmp(a,b);
585e5c89e4eSSatish Balay #else
58632b366c8SSatish Balay   else {
58732b366c8SSatish Balay     char           *aa,*bb;
58832b366c8SSatish Balay     PetscErrorCode ierr;
58932b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
59032b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
59132b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
59232b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
59332b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
594503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
595503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
59632b366c8SSatish Balay     PetscFunctionReturn(0);
59732b366c8SSatish Balay   }
598e5c89e4eSSatish Balay #endif
599e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
600e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
601e5c89e4eSSatish Balay   PetscFunctionReturn(0);
602e5c89e4eSSatish Balay }
603e5c89e4eSSatish Balay 
604e5c89e4eSSatish Balay /*@C
605e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
606e5c89e4eSSatish Balay 
607e5c89e4eSSatish Balay    Not Collective
608e5c89e4eSSatish Balay 
609e5c89e4eSSatish Balay    Input Parameters:
610e5c89e4eSSatish Balay +  a - pointer to first string
611e5c89e4eSSatish Balay .  b - pointer to second string
612e5c89e4eSSatish Balay -  n - length to compare up to
613e5c89e4eSSatish Balay 
614e5c89e4eSSatish Balay    Output Parameter:
615e5c89e4eSSatish Balay .  t - if the two strings are equal
616e5c89e4eSSatish Balay 
617e5c89e4eSSatish Balay    Level: intermediate
618e5c89e4eSSatish Balay 
61995452b02SPatrick Sanan    Notes:
62095452b02SPatrick Sanan     Not for use in Fortran
6216f013253SBarry Smith 
622e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
623e5c89e4eSSatish Balay 
624e5c89e4eSSatish Balay @*/
6257087cfbeSBarry Smith PetscErrorCode  PetscStrncmp(const char a[],const char b[],size_t n,PetscBool  *t)
626e5c89e4eSSatish Balay {
627e5c89e4eSSatish Balay   int c;
628e5c89e4eSSatish Balay 
629e5c89e4eSSatish Balay   PetscFunctionBegin;
630e5c89e4eSSatish Balay   c = strncmp(a,b,n);
631e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
632e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
633e5c89e4eSSatish Balay   PetscFunctionReturn(0);
634e5c89e4eSSatish Balay }
635e5c89e4eSSatish Balay 
636e5c89e4eSSatish Balay /*@C
637a5b23f4aSJose E. Roman    PetscStrchr - Locates first occurrence of a character in a string
638e5c89e4eSSatish Balay 
639e5c89e4eSSatish Balay    Not Collective
640e5c89e4eSSatish Balay 
641e5c89e4eSSatish Balay    Input Parameters:
642e5c89e4eSSatish Balay +  a - pointer to string
643e5c89e4eSSatish Balay -  b - character
644e5c89e4eSSatish Balay 
645e5c89e4eSSatish Balay    Output Parameter:
646a5b23f4aSJose E. Roman .  c - location of occurrence, NULL if not found
647e5c89e4eSSatish Balay 
648e5c89e4eSSatish Balay    Level: intermediate
649e5c89e4eSSatish Balay 
65095452b02SPatrick Sanan    Notes:
65195452b02SPatrick Sanan     Not for use in Fortran
6526f013253SBarry Smith 
653e5c89e4eSSatish Balay @*/
6547087cfbeSBarry Smith PetscErrorCode  PetscStrchr(const char a[],char b,char *c[])
655e5c89e4eSSatish Balay {
656e5c89e4eSSatish Balay   PetscFunctionBegin;
657e5c89e4eSSatish Balay   *c = (char*)strchr(a,b);
658e5c89e4eSSatish Balay   PetscFunctionReturn(0);
659e5c89e4eSSatish Balay }
660e5c89e4eSSatish Balay 
661e5c89e4eSSatish Balay /*@C
662a5b23f4aSJose E. Roman    PetscStrrchr - Locates one location past the last occurrence of a character in a string,
663e5c89e4eSSatish Balay       if the character is not found then returns entire string
664e5c89e4eSSatish Balay 
665e5c89e4eSSatish Balay    Not Collective
666e5c89e4eSSatish Balay 
667e5c89e4eSSatish Balay    Input Parameters:
668e5c89e4eSSatish Balay +  a - pointer to string
669e5c89e4eSSatish Balay -  b - character
670e5c89e4eSSatish Balay 
671e5c89e4eSSatish Balay    Output Parameter:
672a5b23f4aSJose E. Roman .  tmp - location of occurrence, a if not found
673e5c89e4eSSatish Balay 
674e5c89e4eSSatish Balay    Level: intermediate
675e5c89e4eSSatish Balay 
67695452b02SPatrick Sanan    Notes:
67795452b02SPatrick Sanan     Not for use in Fortran
6786f013253SBarry Smith 
679e5c89e4eSSatish Balay @*/
6807087cfbeSBarry Smith PetscErrorCode  PetscStrrchr(const char a[],char b,char *tmp[])
681e5c89e4eSSatish Balay {
682e5c89e4eSSatish Balay   PetscFunctionBegin;
683e5c89e4eSSatish Balay   *tmp = (char*)strrchr(a,b);
684a297a907SKarl Rupp   if (!*tmp) *tmp = (char*)a;
685a297a907SKarl Rupp   else *tmp = *tmp + 1;
686e5c89e4eSSatish Balay   PetscFunctionReturn(0);
687e5c89e4eSSatish Balay }
688e5c89e4eSSatish Balay 
689e5c89e4eSSatish Balay /*@C
690e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
691e5c89e4eSSatish Balay 
692e5c89e4eSSatish Balay    Not Collective
693e5c89e4eSSatish Balay 
694e5c89e4eSSatish Balay    Input Parameters:
695e5c89e4eSSatish Balay .  a - pointer to string
696e5c89e4eSSatish Balay 
697e5c89e4eSSatish Balay    Level: intermediate
698e5c89e4eSSatish Balay 
69995452b02SPatrick Sanan    Notes:
70095452b02SPatrick Sanan     Not for use in Fortran
7016f013253SBarry Smith 
702e5c89e4eSSatish Balay @*/
7037087cfbeSBarry Smith PetscErrorCode  PetscStrtolower(char a[])
704e5c89e4eSSatish Balay {
705e5c89e4eSSatish Balay   PetscFunctionBegin;
706e5c89e4eSSatish Balay   while (*a) {
707e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
708e5c89e4eSSatish Balay     a++;
709e5c89e4eSSatish Balay   }
710e5c89e4eSSatish Balay   PetscFunctionReturn(0);
711e5c89e4eSSatish Balay }
712e5c89e4eSSatish Balay 
7132f234a98SBarry Smith /*@C
7146e3a5469SBarry Smith    PetscStrtoupper - Converts string to upper case
7152f234a98SBarry Smith 
7162f234a98SBarry Smith    Not Collective
7172f234a98SBarry Smith 
7182f234a98SBarry Smith    Input Parameters:
7192f234a98SBarry Smith .  a - pointer to string
7202f234a98SBarry Smith 
7212f234a98SBarry Smith    Level: intermediate
7222f234a98SBarry Smith 
72395452b02SPatrick Sanan    Notes:
72495452b02SPatrick Sanan     Not for use in Fortran
7252f234a98SBarry Smith 
7262f234a98SBarry Smith @*/
7272f234a98SBarry Smith PetscErrorCode  PetscStrtoupper(char a[])
7282f234a98SBarry Smith {
7292f234a98SBarry Smith   PetscFunctionBegin;
7302f234a98SBarry Smith   while (*a) {
7312f234a98SBarry Smith     if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a';
7322f234a98SBarry Smith     a++;
7332f234a98SBarry Smith   }
7342f234a98SBarry Smith   PetscFunctionReturn(0);
7352f234a98SBarry Smith }
7362f234a98SBarry Smith 
7377ba3a57cSBarry Smith /*@C
7387ba3a57cSBarry Smith    PetscStrendswith - Determines if a string ends with a certain string
7391d1a0024SBarry Smith 
7407ba3a57cSBarry Smith    Not Collective
7417ba3a57cSBarry Smith 
7427ba3a57cSBarry Smith    Input Parameters:
7437ba3a57cSBarry Smith +  a - pointer to string
7447ba3a57cSBarry Smith -  b - string to endwith
7457ba3a57cSBarry Smith 
7467ba3a57cSBarry Smith    Output Parameter:
7477ba3a57cSBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
7487ba3a57cSBarry Smith 
74995452b02SPatrick Sanan    Notes:
75095452b02SPatrick Sanan     Not for use in Fortran
7517ba3a57cSBarry Smith 
7527ba3a57cSBarry Smith    Level: intermediate
7537ba3a57cSBarry Smith 
7547ba3a57cSBarry Smith @*/
7557ba3a57cSBarry Smith PetscErrorCode  PetscStrendswith(const char a[],const char b[],PetscBool *flg)
7567ba3a57cSBarry Smith {
7577ba3a57cSBarry Smith   char           *test;
7587ba3a57cSBarry Smith   PetscErrorCode ierr;
7597ba3a57cSBarry Smith   size_t         na,nb;
7607ba3a57cSBarry Smith 
7617ba3a57cSBarry Smith   PetscFunctionBegin;
7627ba3a57cSBarry Smith   *flg = PETSC_FALSE;
7637ba3a57cSBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
7647ba3a57cSBarry Smith   if (test) {
7657ba3a57cSBarry Smith     ierr = PetscStrlen(a,&na);CHKERRQ(ierr);
7667ba3a57cSBarry Smith     ierr = PetscStrlen(b,&nb);CHKERRQ(ierr);
7677ba3a57cSBarry Smith     if (a+na-nb == test) *flg = PETSC_TRUE;
7687ba3a57cSBarry Smith   }
7697ba3a57cSBarry Smith   PetscFunctionReturn(0);
7707ba3a57cSBarry Smith }
7717ba3a57cSBarry Smith 
7722c9581d2SBarry Smith /*@C
7732c9581d2SBarry Smith    PetscStrbeginswith - Determines if a string begins with a certain string
7742c9581d2SBarry Smith 
7752c9581d2SBarry Smith    Not Collective
7762c9581d2SBarry Smith 
7772c9581d2SBarry Smith    Input Parameters:
7782c9581d2SBarry Smith +  a - pointer to string
7792c9581d2SBarry Smith -  b - string to begin with
7802c9581d2SBarry Smith 
7812c9581d2SBarry Smith    Output Parameter:
7822c9581d2SBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
7832c9581d2SBarry Smith 
78495452b02SPatrick Sanan    Notes:
78595452b02SPatrick Sanan     Not for use in Fortran
7862c9581d2SBarry Smith 
7872c9581d2SBarry Smith    Level: intermediate
7882c9581d2SBarry Smith 
7896e3a5469SBarry Smith .seealso: PetscStrendswithwhich(), PetscStrendswith(), PetscStrtoupper, PetscStrtolower(), PetscStrrchr(), PetscStrchr(),
7906e3a5469SBarry Smith           PetscStrncmp(), PetscStrlen(), PetscStrncmp(), PetscStrcmp()
7916e3a5469SBarry Smith 
7922c9581d2SBarry Smith @*/
7932c9581d2SBarry Smith PetscErrorCode  PetscStrbeginswith(const char a[],const char b[],PetscBool *flg)
7942c9581d2SBarry Smith {
7952c9581d2SBarry Smith   char           *test;
7962c9581d2SBarry Smith   PetscErrorCode ierr;
7972c9581d2SBarry Smith 
7982c9581d2SBarry Smith   PetscFunctionBegin;
7992c9581d2SBarry Smith   *flg = PETSC_FALSE;
8002c9581d2SBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
801a297a907SKarl Rupp   if (test && (test == a)) *flg = PETSC_TRUE;
8022c9581d2SBarry Smith   PetscFunctionReturn(0);
8032c9581d2SBarry Smith }
8042c9581d2SBarry Smith 
8057ba3a57cSBarry Smith /*@C
8067ba3a57cSBarry Smith    PetscStrendswithwhich - Determines if a string ends with one of several possible strings
8077ba3a57cSBarry Smith 
8087ba3a57cSBarry Smith    Not Collective
8097ba3a57cSBarry Smith 
8107ba3a57cSBarry Smith    Input Parameters:
8117ba3a57cSBarry Smith +  a - pointer to string
812fa4b66f2SVaclav Hapla -  bs - strings to end with (last entry must be NULL)
8137ba3a57cSBarry Smith 
8147ba3a57cSBarry Smith    Output Parameter:
815fa4b66f2SVaclav Hapla .  cnt - the index of the string it ends with or the index of NULL
8167ba3a57cSBarry Smith 
81795452b02SPatrick Sanan    Notes:
81895452b02SPatrick Sanan     Not for use in Fortran
8197ba3a57cSBarry Smith 
8207ba3a57cSBarry Smith    Level: intermediate
8217ba3a57cSBarry Smith 
8227ba3a57cSBarry Smith @*/
8237ba3a57cSBarry Smith PetscErrorCode  PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt)
8247ba3a57cSBarry Smith {
8257ba3a57cSBarry Smith   PetscBool      flg;
8267ba3a57cSBarry Smith   PetscErrorCode ierr;
8277ba3a57cSBarry Smith 
8287ba3a57cSBarry Smith   PetscFunctionBegin;
8297ba3a57cSBarry Smith   *cnt = 0;
8307ba3a57cSBarry Smith   while (bs[*cnt]) {
8317ba3a57cSBarry Smith     ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr);
8327ba3a57cSBarry Smith     if (flg) PetscFunctionReturn(0);
8337ba3a57cSBarry Smith     *cnt += 1;
8347ba3a57cSBarry Smith   }
8357ba3a57cSBarry Smith   PetscFunctionReturn(0);
8367ba3a57cSBarry Smith }
8377ba3a57cSBarry Smith 
8387ba3a57cSBarry Smith /*@C
839a5b23f4aSJose E. Roman    PetscStrrstr - Locates last occurrence of string in another string
8407ba3a57cSBarry Smith 
8417ba3a57cSBarry Smith    Not Collective
8427ba3a57cSBarry Smith 
8437ba3a57cSBarry Smith    Input Parameters:
8447ba3a57cSBarry Smith +  a - pointer to string
8457ba3a57cSBarry Smith -  b - string to find
8467ba3a57cSBarry Smith 
8477ba3a57cSBarry Smith    Output Parameter:
848a5b23f4aSJose E. Roman .  tmp - location of occurrence
8497ba3a57cSBarry Smith 
85095452b02SPatrick Sanan    Notes:
85195452b02SPatrick Sanan     Not for use in Fortran
8527ba3a57cSBarry Smith 
8537ba3a57cSBarry Smith    Level: intermediate
8547ba3a57cSBarry Smith 
8557ba3a57cSBarry Smith @*/
8567ba3a57cSBarry Smith PetscErrorCode  PetscStrrstr(const char a[],const char b[],char *tmp[])
8577ba3a57cSBarry Smith {
85802c9f0b5SLisandro Dalcin   const char *stmp = a, *ltmp = NULL;
8597ba3a57cSBarry Smith 
8607ba3a57cSBarry Smith   PetscFunctionBegin;
8617ba3a57cSBarry Smith   while (stmp) {
8627ba3a57cSBarry Smith     stmp = (char*)strstr(stmp,b);
8637ba3a57cSBarry Smith     if (stmp) {ltmp = stmp;stmp++;}
8647ba3a57cSBarry Smith   }
8657ba3a57cSBarry Smith   *tmp = (char*)ltmp;
8667ba3a57cSBarry Smith   PetscFunctionReturn(0);
8677ba3a57cSBarry Smith }
8687ba3a57cSBarry Smith 
8697ba3a57cSBarry Smith /*@C
870a5b23f4aSJose E. Roman    PetscStrstr - Locates first occurrence of string in another string
8717ba3a57cSBarry Smith 
8727ba3a57cSBarry Smith    Not Collective
8737ba3a57cSBarry Smith 
8747ba3a57cSBarry Smith    Input Parameters:
875160f4796SJed Brown +  haystack - string to search
876160f4796SJed Brown -  needle - string to find
8777ba3a57cSBarry Smith 
8787ba3a57cSBarry Smith    Output Parameter:
879a5b23f4aSJose E. Roman .  tmp - location of occurrence, is a NULL if the string is not found
8807ba3a57cSBarry Smith 
88195452b02SPatrick Sanan    Notes:
88295452b02SPatrick Sanan     Not for use in Fortran
8837ba3a57cSBarry Smith 
8847ba3a57cSBarry Smith    Level: intermediate
8857ba3a57cSBarry Smith 
8867ba3a57cSBarry Smith @*/
887160f4796SJed Brown PetscErrorCode  PetscStrstr(const char haystack[],const char needle[],char *tmp[])
8887ba3a57cSBarry Smith {
8897ba3a57cSBarry Smith   PetscFunctionBegin;
890160f4796SJed Brown   *tmp = (char*)strstr(haystack,needle);
8917ba3a57cSBarry Smith   PetscFunctionReturn(0);
8927ba3a57cSBarry Smith }
8937ba3a57cSBarry Smith 
8947ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
8951d1a0024SBarry Smith 
896e5c89e4eSSatish Balay /*@C
897e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
898e5c89e4eSSatish Balay 
899e5c89e4eSSatish Balay    Not Collective
900e5c89e4eSSatish Balay 
901e5c89e4eSSatish Balay    Input Parameters:
902e5c89e4eSSatish Balay .  a - pointer to token
903e5c89e4eSSatish Balay 
904e5c89e4eSSatish Balay    Output Parameter:
905a5b23f4aSJose E. Roman .  result - location of occurrence, NULL if not found
906e5c89e4eSSatish Balay 
907e5c89e4eSSatish Balay    Notes:
908e5c89e4eSSatish Balay 
909e5c89e4eSSatish Balay      This version is different from the system version in that
910e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
911e5c89e4eSSatish Balay 
9124704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
9134704e885SBarry Smith    as a single token.
9144704e885SBarry Smith 
9153a9c465aSBarry 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
9163a9c465aSBarry Smith    second will return a null terminated y
9173a9c465aSBarry Smith 
9183a9c465aSBarry 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
9193a9c465aSBarry Smith 
9206f013253SBarry Smith     Not for use in Fortran
9216f013253SBarry Smith 
922e5c89e4eSSatish Balay    Level: intermediate
923e5c89e4eSSatish Balay 
924e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
925e5c89e4eSSatish Balay @*/
9267087cfbeSBarry Smith PetscErrorCode  PetscTokenFind(PetscToken a,char *result[])
927e5c89e4eSSatish Balay {
9284704e885SBarry Smith   char *ptr = a->current,token;
929e5c89e4eSSatish Balay 
930e5c89e4eSSatish Balay   PetscFunctionBegin;
931e5c89e4eSSatish Balay   *result = a->current;
93202c9f0b5SLisandro Dalcin   if (ptr && !*ptr) {*result = NULL; PetscFunctionReturn(0);}
9334704e885SBarry Smith   token = a->token;
93490fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
935e5c89e4eSSatish Balay   while (ptr) {
9364704e885SBarry Smith     if (*ptr == token) {
937e5c89e4eSSatish Balay       *ptr++ = 0;
938e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
939e5c89e4eSSatish Balay       a->current = ptr;
940e5c89e4eSSatish Balay       break;
941e5c89e4eSSatish Balay     }
942e5c89e4eSSatish Balay     if (!*ptr) {
94302c9f0b5SLisandro Dalcin       a->current = NULL;
944e5c89e4eSSatish Balay       break;
945e5c89e4eSSatish Balay     }
946e5c89e4eSSatish Balay     ptr++;
947e5c89e4eSSatish Balay   }
948e5c89e4eSSatish Balay   PetscFunctionReturn(0);
949e5c89e4eSSatish Balay }
950e5c89e4eSSatish Balay 
951e5c89e4eSSatish Balay /*@C
952e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
953e5c89e4eSSatish Balay 
954e5c89e4eSSatish Balay    Not Collective
955e5c89e4eSSatish Balay 
956e5c89e4eSSatish Balay    Input Parameters:
957e5c89e4eSSatish Balay +  string - the string to look in
9583a9c465aSBarry Smith -  b - the separator character
959e5c89e4eSSatish Balay 
960e5c89e4eSSatish Balay    Output Parameter:
9613a9c465aSBarry Smith .  t- the token object
962e5c89e4eSSatish Balay 
963e5c89e4eSSatish Balay    Notes:
964e5c89e4eSSatish Balay 
965e5c89e4eSSatish Balay      This version is different from the system version in that
966e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
967e5c89e4eSSatish Balay 
9686f013253SBarry Smith     Not for use in Fortran
9696f013253SBarry Smith 
970e5c89e4eSSatish Balay    Level: intermediate
971e5c89e4eSSatish Balay 
972e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
973e5c89e4eSSatish Balay @*/
9747087cfbeSBarry Smith PetscErrorCode  PetscTokenCreate(const char a[],const char b,PetscToken *t)
975e5c89e4eSSatish Balay {
976e5c89e4eSSatish Balay   PetscErrorCode ierr;
977e5c89e4eSSatish Balay 
978e5c89e4eSSatish Balay   PetscFunctionBegin;
979b00a9115SJed Brown   ierr = PetscNew(t);CHKERRQ(ierr);
980e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
981a297a907SKarl Rupp 
982e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
983e5c89e4eSSatish Balay   (*t)->token   = b;
984e5c89e4eSSatish Balay   PetscFunctionReturn(0);
985e5c89e4eSSatish Balay }
986e5c89e4eSSatish Balay 
987e5c89e4eSSatish Balay /*@C
988e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
989e5c89e4eSSatish Balay 
990e5c89e4eSSatish Balay    Not Collective
991e5c89e4eSSatish Balay 
992e5c89e4eSSatish Balay    Input Parameters:
993e5c89e4eSSatish Balay .  a - pointer to token
994e5c89e4eSSatish Balay 
995e5c89e4eSSatish Balay    Level: intermediate
996e5c89e4eSSatish Balay 
99795452b02SPatrick Sanan    Notes:
99895452b02SPatrick Sanan     Not for use in Fortran
9996f013253SBarry Smith 
1000e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
1001e5c89e4eSSatish Balay @*/
10028c74ee41SBarry Smith PetscErrorCode  PetscTokenDestroy(PetscToken *a)
1003e5c89e4eSSatish Balay {
1004e5c89e4eSSatish Balay   PetscErrorCode ierr;
1005e5c89e4eSSatish Balay 
1006e5c89e4eSSatish Balay   PetscFunctionBegin;
10078c74ee41SBarry Smith   if (!*a) PetscFunctionReturn(0);
10088c74ee41SBarry Smith   ierr = PetscFree((*a)->array);CHKERRQ(ierr);
10098c74ee41SBarry Smith   ierr = PetscFree(*a);CHKERRQ(ierr);
1010e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1011e5c89e4eSSatish Balay }
1012e5c89e4eSSatish Balay 
10138e81d068SLisandro Dalcin /*@C
10148e81d068SLisandro Dalcin    PetscStrInList - search string in character-delimited list
10158e81d068SLisandro Dalcin 
10168e81d068SLisandro Dalcin    Not Collective
10178e81d068SLisandro Dalcin 
10188e81d068SLisandro Dalcin    Input Parameters:
10198e81d068SLisandro Dalcin +  str - the string to look for
10208e81d068SLisandro Dalcin .  list - the list to search in
10218e81d068SLisandro Dalcin -  sep - the separator character
10228e81d068SLisandro Dalcin 
10238e81d068SLisandro Dalcin    Output Parameter:
10248e81d068SLisandro Dalcin .  found - whether str is in list
10258e81d068SLisandro Dalcin 
10268e81d068SLisandro Dalcin    Level: intermediate
10278e81d068SLisandro Dalcin 
102895452b02SPatrick Sanan    Notes:
102995452b02SPatrick Sanan     Not for use in Fortran
10308e81d068SLisandro Dalcin 
10318e81d068SLisandro Dalcin .seealso: PetscTokenCreate(), PetscTokenFind(), PetscStrcmp()
10328e81d068SLisandro Dalcin @*/
10338e81d068SLisandro Dalcin PetscErrorCode PetscStrInList(const char str[],const char list[],char sep,PetscBool *found)
10348e81d068SLisandro Dalcin {
10358e81d068SLisandro Dalcin   PetscToken     token;
10368e81d068SLisandro Dalcin   char           *item;
10378e81d068SLisandro Dalcin   PetscErrorCode ierr;
10388e81d068SLisandro Dalcin 
10398e81d068SLisandro Dalcin   PetscFunctionBegin;
10408e81d068SLisandro Dalcin   *found = PETSC_FALSE;
10418e81d068SLisandro Dalcin   ierr = PetscTokenCreate(list,sep,&token);CHKERRQ(ierr);
10428e81d068SLisandro Dalcin   ierr = PetscTokenFind(token,&item);CHKERRQ(ierr);
10438e81d068SLisandro Dalcin   while (item) {
10448e81d068SLisandro Dalcin     ierr = PetscStrcmp(str,item,found);CHKERRQ(ierr);
10458e81d068SLisandro Dalcin     if (*found) break;
10468e81d068SLisandro Dalcin     ierr = PetscTokenFind(token,&item);CHKERRQ(ierr);
10478e81d068SLisandro Dalcin   }
10488e81d068SLisandro Dalcin   ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
10498e81d068SLisandro Dalcin   PetscFunctionReturn(0);
10508e81d068SLisandro Dalcin }
1051e5c89e4eSSatish Balay 
1052e5c89e4eSSatish Balay /*@C
1053e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
1054e5c89e4eSSatish Balay 
1055e5c89e4eSSatish Balay    Not Collective
1056e5c89e4eSSatish Balay 
1057e5c89e4eSSatish Balay    Output Parameter:
1058e5c89e4eSSatish Balay .  dir - the directory
1059e5c89e4eSSatish Balay 
1060e5c89e4eSSatish Balay    Level: developer
1061e5c89e4eSSatish Balay 
106295452b02SPatrick Sanan    Notes:
106395452b02SPatrick Sanan     Not for use in Fortran
10646f013253SBarry Smith 
1065e5c89e4eSSatish Balay @*/
10667087cfbeSBarry Smith PetscErrorCode  PetscGetPetscDir(const char *dir[])
1067e5c89e4eSSatish Balay {
1068e5c89e4eSSatish Balay   PetscFunctionBegin;
1069e5c89e4eSSatish Balay   *dir = PETSC_DIR;
1070e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1071e5c89e4eSSatish Balay }
1072e5c89e4eSSatish Balay 
1073e5c89e4eSSatish Balay /*@C
1074e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
1075e5c89e4eSSatish Balay 
1076e5c89e4eSSatish Balay    Not Collective
1077e5c89e4eSSatish Balay 
1078e5c89e4eSSatish Balay    Input Parameters:
1079e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
108071573d7dSBarry Smith .   aa - the string to look in
1081d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
1082e5c89e4eSSatish Balay -   len - the length of b
1083e5c89e4eSSatish Balay 
1084e5c89e4eSSatish Balay    Notes:
1085e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
1086d5649816SBarry Smith       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
1087e5c89e4eSSatish Balay       as well as any environmental variables.
1088e5c89e4eSSatish Balay 
10896f013253SBarry Smith       PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
1090acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
1091acc6cc86SBarry Smith 
10926f013253SBarry Smith       Not for use in Fortran
10936f013253SBarry Smith 
1094e5c89e4eSSatish Balay    Level: intermediate
1095e5c89e4eSSatish Balay 
1096e5c89e4eSSatish Balay @*/
10977087cfbeSBarry Smith PetscErrorCode  PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
1098e5c89e4eSSatish Balay {
1099e5c89e4eSSatish Balay   PetscErrorCode ierr;
1100e5c89e4eSSatish Balay   int            i = 0;
1101e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
110271573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
110302c9f0b5SLisandro Dalcin   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",NULL};
110402c9f0b5SLisandro Dalcin   char           *r[] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
1105ace3abfcSBarry Smith   PetscBool      flag;
1106589a23caSBarry Smith   static size_t  DISPLAY_LENGTH = 265,USER_LENGTH = 256, HOST_LENGTH = 256;
1107e5c89e4eSSatish Balay 
1108e5c89e4eSSatish Balay   PetscFunctionBegin;
1109e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
111071573d7dSBarry Smith   if (aa == b) {
111122982a5fSBarry Smith     ierr = PetscStrallocpy(aa,(char**)&a);CHKERRQ(ierr);
111271573d7dSBarry Smith   }
1113785e854fSJed Brown   ierr = PetscMalloc1(len,&work);CHKERRQ(ierr);
1114e5c89e4eSSatish Balay 
1115e5c89e4eSSatish Balay   /* get values for replaced variables */
1116f1d4cc8fSBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,&r[0]);CHKERRQ(ierr);
1117f1d4cc8fSBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,&r[1]);CHKERRQ(ierr);
1118f1d4cc8fSBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,&r[2]);CHKERRQ(ierr);
1119589a23caSBarry Smith   ierr = PetscMalloc1(DISPLAY_LENGTH,&r[3]);CHKERRQ(ierr);
1120785e854fSJed Brown   ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[4]);CHKERRQ(ierr);
1121785e854fSJed Brown   ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[5]);CHKERRQ(ierr);
1122589a23caSBarry Smith   ierr = PetscMalloc1(USER_LENGTH,&r[6]);CHKERRQ(ierr);
1123589a23caSBarry Smith   ierr = PetscMalloc1(HOST_LENGTH,&r[7]);CHKERRQ(ierr);
1124589a23caSBarry Smith   ierr = PetscGetDisplay(r[3],DISPLAY_LENGTH);CHKERRQ(ierr);
1125f1d4cc8fSBarry Smith   ierr = PetscGetHomeDirectory(r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1126f1d4cc8fSBarry Smith   ierr = PetscGetWorkingDirectory(r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1127589a23caSBarry Smith   ierr = PetscGetUserName(r[6],USER_LENGTH);CHKERRQ(ierr);
1128589a23caSBarry Smith   ierr = PetscGetHostName(r[7],HOST_LENGTH);CHKERRQ(ierr);
1129487e5849SBarry Smith 
1130487e5849SBarry Smith   /* replace that are in environment */
1131589a23caSBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,sizeof(env),&flag);CHKERRQ(ierr);
1132487e5849SBarry Smith   if (flag) {
113331936d58SMatthew G. Knepley     ierr = PetscFree(r[2]);CHKERRQ(ierr);
1134f1d4cc8fSBarry Smith     ierr = PetscStrallocpy(env,&r[2]);CHKERRQ(ierr);
1135487e5849SBarry Smith   }
1136e5c89e4eSSatish Balay 
1137e5c89e4eSSatish Balay   /* replace the requested strings */
1138e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
1139e5c89e4eSSatish Balay   while (s[i]) {
1140e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
1141e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1142e5c89e4eSSatish Balay     while (par) {
1143e5c89e4eSSatish Balay       *par =  0;
1144e5c89e4eSSatish Balay       par += l;
1145e5c89e4eSSatish Balay 
1146e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
1147e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
1148e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
114917186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
1150589a23caSBarry Smith       ierr = PetscStrncpy(work,b,len);CHKERRQ(ierr);
1151589a23caSBarry Smith       ierr = PetscStrlcat(work,r[i],len);CHKERRQ(ierr);
1152589a23caSBarry Smith       ierr = PetscStrlcat(work,par,len);CHKERRQ(ierr);
1153e5c89e4eSSatish Balay       ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr);
1154e5c89e4eSSatish Balay       ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1155e5c89e4eSSatish Balay     }
1156e5c89e4eSSatish Balay     i++;
1157e5c89e4eSSatish Balay   }
1158487e5849SBarry Smith   i = 0;
1159487e5849SBarry Smith   while (r[i]) {
1160e5c89e4eSSatish Balay     tfree = (char*)r[i];
1161e5c89e4eSSatish Balay     ierr  = PetscFree(tfree);CHKERRQ(ierr);
1162487e5849SBarry Smith     i++;
1163e5c89e4eSSatish Balay   }
1164e5c89e4eSSatish Balay 
1165e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
1166e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1167e5c89e4eSSatish Balay   while (par) {
1168e5c89e4eSSatish Balay     *par  = 0;
1169e5c89e4eSSatish Balay     par  += 2;
1170589a23caSBarry Smith     ierr  = PetscStrncpy(work,b,len);CHKERRQ(ierr);
1171e5c89e4eSSatish Balay     ierr  = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
1172e5c89e4eSSatish Balay     *epar = 0;
1173e5c89e4eSSatish Balay     epar += 1;
1174589a23caSBarry Smith     ierr  = PetscOptionsGetenv(comm,par,env,sizeof(env),&flag);CHKERRQ(ierr);
11757ba3a57cSBarry Smith     if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
1176589a23caSBarry Smith     ierr = PetscStrlcat(work,env,len);CHKERRQ(ierr);
1177589a23caSBarry Smith     ierr = PetscStrlcat(work,epar,len);CHKERRQ(ierr);
1178589a23caSBarry Smith     ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr);
1179e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1180e5c89e4eSSatish Balay   }
1181e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
118271573d7dSBarry Smith   if (aa == b) {
118371573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
118471573d7dSBarry Smith   }
1185e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1186e5c89e4eSSatish Balay }
1187e5c89e4eSSatish Balay 
1188a53986e1SJed Brown /*@C
1189a53986e1SJed Brown    PetscEListFind - searches list of strings for given string, using case insensitive matching
1190e5c89e4eSSatish Balay 
1191a53986e1SJed Brown    Not Collective
1192a53986e1SJed Brown 
1193a53986e1SJed Brown    Input Parameters:
1194a53986e1SJed Brown +  n - number of strings in
1195a53986e1SJed Brown .  list - list of strings to search
1196a53986e1SJed Brown -  str - string to look for, empty string "" accepts default (first entry in list)
1197a53986e1SJed Brown 
1198a53986e1SJed Brown    Output Parameters:
1199a53986e1SJed Brown +  value - index of matching string (if found)
1200a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1201a53986e1SJed Brown 
1202a53986e1SJed Brown    Notes:
1203a53986e1SJed Brown    Not for use in Fortran
1204a53986e1SJed Brown 
1205a53986e1SJed Brown    Level: advanced
1206a53986e1SJed Brown @*/
1207a53986e1SJed Brown PetscErrorCode PetscEListFind(PetscInt n,const char *const *list,const char *str,PetscInt *value,PetscBool *found)
1208a53986e1SJed Brown {
1209a53986e1SJed Brown   PetscErrorCode ierr;
1210a53986e1SJed Brown   PetscBool matched;
1211a53986e1SJed Brown   PetscInt i;
1212a53986e1SJed Brown 
1213a53986e1SJed Brown   PetscFunctionBegin;
1214a53986e1SJed Brown   if (found) *found = PETSC_FALSE;
1215a53986e1SJed Brown   for (i=0; i<n; i++) {
1216a53986e1SJed Brown     ierr = PetscStrcasecmp(str,list[i],&matched);CHKERRQ(ierr);
1217a53986e1SJed Brown     if (matched || !str[0]) {
1218a53986e1SJed Brown       if (found) *found = PETSC_TRUE;
1219a53986e1SJed Brown       *value = i;
1220a53986e1SJed Brown       break;
1221a53986e1SJed Brown     }
1222a53986e1SJed Brown   }
1223a53986e1SJed Brown   PetscFunctionReturn(0);
1224a53986e1SJed Brown }
1225a53986e1SJed Brown 
1226a53986e1SJed Brown /*@C
12278e81d068SLisandro Dalcin    PetscEnumFind - searches enum list of strings for given string, using case insensitive matching
1228a53986e1SJed Brown 
1229a53986e1SJed Brown    Not Collective
1230a53986e1SJed Brown 
1231a53986e1SJed Brown    Input Parameters:
1232a53986e1SJed Brown +  enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL
1233a53986e1SJed Brown -  str - string to look for
1234a53986e1SJed Brown 
1235a53986e1SJed Brown    Output Parameters:
1236a53986e1SJed Brown +  value - index of matching string (if found)
1237a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1238a53986e1SJed Brown 
1239a53986e1SJed Brown    Notes:
1240a53986e1SJed Brown    Not for use in Fortran
1241a53986e1SJed Brown 
1242a53986e1SJed Brown    Level: advanced
1243a53986e1SJed Brown @*/
1244a53986e1SJed Brown PetscErrorCode PetscEnumFind(const char *const *enumlist,const char *str,PetscEnum *value,PetscBool *found)
1245a53986e1SJed Brown {
1246a53986e1SJed Brown   PetscErrorCode ierr;
1247d05ba7d2SLisandro Dalcin   PetscInt n = 0,evalue;
1248a53986e1SJed Brown   PetscBool efound;
1249a53986e1SJed Brown 
1250a53986e1SJed Brown   PetscFunctionBegin;
1251d05ba7d2SLisandro Dalcin   while (enumlist[n++]) if (n > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
1252a53986e1SJed Brown   if (n < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
1253a53986e1SJed Brown   n -= 3; /* drop enum name, prefix, and null termination */
1254a53986e1SJed Brown   ierr = PetscEListFind(n,enumlist,str,&evalue,&efound);CHKERRQ(ierr);
1255cfb463b1SJed Brown   if (efound) *value = (PetscEnum)evalue;
1256a53986e1SJed Brown   if (found) *found = efound;
1257a53986e1SJed Brown   PetscFunctionReturn(0);
1258a53986e1SJed Brown }
1259