xref: /petsc/src/sys/utils/str.c (revision 61528463d6d595c31510031c724dfae4b69de24b)
17d0a6c19SBarry Smith 
2e5c89e4eSSatish Balay /*
3e5c89e4eSSatish Balay     We define the string operations here. The reason we just do not use
4e5c89e4eSSatish Balay   the standard string routines in the PETSc code is that on some machines
5e5c89e4eSSatish Balay   they are broken or have the wrong prototypes.
6e5c89e4eSSatish Balay 
7e5c89e4eSSatish Balay */
8c6db04a5SJed Brown #include <petscsys.h>                   /*I  "petscsys.h"   I*/
96ce87071SSatish Balay #if defined(PETSC_HAVE_STRING_H)
106ce87071SSatish Balay #include <string.h>             /* strstr */
116ce87071SSatish Balay #endif
123964eb88SJed Brown #if defined(PETSC_HAVE_STRINGS_H)
133964eb88SJed Brown #  include <strings.h>          /* strcasecmp */
143964eb88SJed Brown #endif
153964eb88SJed Brown 
16e5c89e4eSSatish Balay #undef __FUNCT__
173c311c98SBarry Smith #define __FUNCT__ "PetscStrToArray"
183c311c98SBarry Smith /*@C
19bebe2cf6SSatish Balay    PetscStrToArray - Separates a string by a charactor (for example ' ' or '\n') and creates an array of strings
203c311c98SBarry Smith 
213c311c98SBarry Smith    Not Collective
223c311c98SBarry Smith 
233c311c98SBarry Smith    Input Parameters:
24d67fe73bSBarry Smith +  s - pointer to string
25a2ea699eSBarry Smith -  sp - separator charactor
263c311c98SBarry Smith 
273c311c98SBarry Smith    Output Parameter:
283c311c98SBarry Smith +   argc - the number of entries in the array
293c311c98SBarry Smith -   args - an array of the entries with a null at the end
303c311c98SBarry Smith 
313c311c98SBarry Smith    Level: intermediate
323c311c98SBarry Smith 
33301d30feSBarry Smith    Notes: this may be called before PetscInitialize() or after PetscFinalize()
343c311c98SBarry Smith 
356f013253SBarry Smith    Not for use in Fortran
366f013253SBarry Smith 
37b4cd4cebSBarry Smith    Developer Notes: Using raw malloc() and does not call error handlers since this may be used before PETSc is initialized. Used
38b4cd4cebSBarry Smith      to generate argc, args arguments passed to MPI_Init()
39301d30feSBarry Smith 
40b4cd4cebSBarry Smith .seealso: PetscStrToArrayDestroy(), PetscToken, PetscTokenCreate()
413c311c98SBarry Smith 
423c311c98SBarry Smith @*/
43d67fe73bSBarry Smith PetscErrorCode  PetscStrToArray(const char s[],char sp,int *argc,char ***args)
443c311c98SBarry Smith {
453c311c98SBarry Smith   int       i,n,*lens,cnt = 0;
46ace3abfcSBarry Smith   PetscBool flg = PETSC_FALSE;
473c311c98SBarry Smith 
4840a7e1efSBarry Smith   if (!s) n = 0;
4940a7e1efSBarry Smith   else    n = strlen(s);
503c311c98SBarry Smith   *argc = 0;
51*61528463SBarry Smith   *args = NULL;
524996c5bdSBarry Smith   if (!n) {
534996c5bdSBarry Smith     return(0);
544996c5bdSBarry Smith   }
553c311c98SBarry Smith   for (i=0; i<n; i++) {
56d67fe73bSBarry Smith     if (s[i] != sp) break;
573c311c98SBarry Smith   }
583c311c98SBarry Smith   for (;i<n+1; i++) {
59d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
60d67fe73bSBarry Smith     else if (s[i] != sp) {flg = PETSC_FALSE;}
613c311c98SBarry Smith   }
62*61528463SBarry Smith   if (!*argc) { /* string only has separator characters */
63*61528463SBarry Smith     return(0);
64*61528463SBarry Smith   }
65a2ea699eSBarry Smith   (*args) = (char**) malloc(((*argc)+1)*sizeof(char*)); if (!*args) return PETSC_ERR_MEM;
6653e6e2c4SHong Zhang   lens    = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM;
673c311c98SBarry Smith   for (i=0; i<*argc; i++) lens[i] = 0;
683c311c98SBarry Smith 
693c311c98SBarry Smith   *argc = 0;
703c311c98SBarry Smith   for (i=0; i<n; i++) {
71d67fe73bSBarry Smith     if (s[i] != sp) break;
723c311c98SBarry Smith   }
733c311c98SBarry Smith   for (;i<n+1; i++) {
74d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
75d67fe73bSBarry Smith     else if (s[i] != sp) {lens[*argc]++;flg = PETSC_FALSE;}
763c311c98SBarry Smith   }
773c311c98SBarry Smith 
783c311c98SBarry Smith   for (i=0; i<*argc; i++) {
79675282fdSHong Zhang     (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char)); if (!(*args)[i]) return PETSC_ERR_MEM;
803c311c98SBarry Smith   }
81a2ea699eSBarry Smith   free(lens);
82301d30feSBarry Smith   (*args)[*argc] = 0;
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 
953c311c98SBarry Smith #undef __FUNCT__
96301d30feSBarry Smith #define __FUNCT__ "PetscStrToArrayDestroy"
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 
108301d30feSBarry Smith    Concepts: command line arguments
109301d30feSBarry Smith 
110301d30feSBarry Smith    Notes: This may be called before PetscInitialize() or after PetscFinalize()
111301d30feSBarry Smith 
1126f013253SBarry Smith    Not for use in Fortran
1136f013253SBarry Smith 
114301d30feSBarry Smith .seealso: PetscStrToArray()
115301d30feSBarry Smith 
116301d30feSBarry Smith @*/
1177087cfbeSBarry Smith PetscErrorCode  PetscStrToArrayDestroy(int argc,char **args)
118301d30feSBarry Smith {
119301d30feSBarry Smith   PetscInt i;
120301d30feSBarry Smith 
121a297a907SKarl Rupp   for (i=0; i<argc; i++) free(args[i]);
122a297a907SKarl Rupp   if (args) free(args);
123301d30feSBarry Smith   return 0;
124301d30feSBarry Smith }
125301d30feSBarry Smith 
126301d30feSBarry Smith #undef __FUNCT__
127e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrlen"
128e5c89e4eSSatish Balay /*@C
129e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
130e5c89e4eSSatish Balay 
131e5c89e4eSSatish Balay    Not Collective
132e5c89e4eSSatish Balay 
133e5c89e4eSSatish Balay    Input Parameters:
134e5c89e4eSSatish Balay .  s - pointer to string
135e5c89e4eSSatish Balay 
136e5c89e4eSSatish Balay    Output Parameter:
137e5c89e4eSSatish Balay .  len - length in bytes
138e5c89e4eSSatish Balay 
139e5c89e4eSSatish Balay    Level: intermediate
140e5c89e4eSSatish Balay 
141e5c89e4eSSatish Balay    Note:
142e5c89e4eSSatish Balay    This routine is analogous to strlen().
143e5c89e4eSSatish Balay 
144e5c89e4eSSatish Balay    Null string returns a length of zero
145e5c89e4eSSatish Balay 
1466f013253SBarry Smith    Not for use in Fortran
1476f013253SBarry Smith 
148e5c89e4eSSatish Balay   Concepts: string length
149e5c89e4eSSatish Balay 
150e5c89e4eSSatish Balay @*/
1517087cfbeSBarry Smith PetscErrorCode  PetscStrlen(const char s[],size_t *len)
152e5c89e4eSSatish Balay {
153e5c89e4eSSatish Balay   PetscFunctionBegin;
154a297a907SKarl Rupp   if (!s) *len = 0;
155a297a907SKarl Rupp   else    *len = strlen(s);
156e5c89e4eSSatish Balay   PetscFunctionReturn(0);
157e5c89e4eSSatish Balay }
158e5c89e4eSSatish Balay 
159e5c89e4eSSatish Balay #undef __FUNCT__
160e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrallocpy"
161e5c89e4eSSatish Balay /*@C
162e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
163e5c89e4eSSatish Balay 
164e5c89e4eSSatish Balay    Not Collective
165e5c89e4eSSatish Balay 
166e5c89e4eSSatish Balay    Input Parameters:
167e5c89e4eSSatish Balay .  s - pointer to string
168e5c89e4eSSatish Balay 
169e5c89e4eSSatish Balay    Output Parameter:
170e5c89e4eSSatish Balay .  t - the copied string
171e5c89e4eSSatish Balay 
172e5c89e4eSSatish Balay    Level: intermediate
173e5c89e4eSSatish Balay 
174e5c89e4eSSatish Balay    Note:
175e5c89e4eSSatish Balay       Null string returns a new null string
176e5c89e4eSSatish Balay 
1776f013253SBarry Smith       Not for use in Fortran
1786f013253SBarry Smith 
179e5c89e4eSSatish Balay   Concepts: string copy
180e5c89e4eSSatish Balay 
181e5c89e4eSSatish Balay @*/
1827087cfbeSBarry Smith PetscErrorCode  PetscStrallocpy(const char s[],char *t[])
183e5c89e4eSSatish Balay {
184e5c89e4eSSatish Balay   PetscErrorCode ierr;
185e5c89e4eSSatish Balay   size_t         len;
18671573d7dSBarry Smith   char           *tmp = 0;
187e5c89e4eSSatish Balay 
188e5c89e4eSSatish Balay   PetscFunctionBegin;
189e5c89e4eSSatish Balay   if (s) {
190e5c89e4eSSatish Balay     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
191854ce69bSBarry Smith     ierr = PetscMalloc1(1+len,&tmp);CHKERRQ(ierr);
19271573d7dSBarry Smith     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
193e5c89e4eSSatish Balay   }
19471573d7dSBarry Smith   *t = tmp;
195e5c89e4eSSatish Balay   PetscFunctionReturn(0);
196e5c89e4eSSatish Balay }
197e5c89e4eSSatish Balay 
198e5c89e4eSSatish Balay #undef __FUNCT__
19947340559SBarry Smith #define __FUNCT__ "PetscStrArrayallocpy"
20047340559SBarry Smith /*@C
20147340559SBarry Smith    PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
20247340559SBarry Smith 
20347340559SBarry Smith    Not Collective
20447340559SBarry Smith 
20547340559SBarry Smith    Input Parameters:
20647340559SBarry Smith .  s - pointer to array of strings (final string is a null)
20747340559SBarry Smith 
20847340559SBarry Smith    Output Parameter:
20947340559SBarry Smith .  t - the copied array string
21047340559SBarry Smith 
21147340559SBarry Smith    Level: intermediate
21247340559SBarry Smith 
21347340559SBarry Smith    Note:
21447340559SBarry Smith       Not for use in Fortran
21547340559SBarry Smith 
21647340559SBarry Smith   Concepts: string copy
21747340559SBarry Smith 
21847340559SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
21947340559SBarry Smith 
22047340559SBarry Smith @*/
22147340559SBarry Smith PetscErrorCode  PetscStrArrayallocpy(const char *const *list,char ***t)
22247340559SBarry Smith {
22347340559SBarry Smith   PetscErrorCode ierr;
22447340559SBarry Smith   PetscInt       i,n = 0;
22547340559SBarry Smith 
22647340559SBarry Smith   PetscFunctionBegin;
22747340559SBarry Smith   while (list[n++]) ;
228854ce69bSBarry Smith   ierr = PetscMalloc1(n+1,t);CHKERRQ(ierr);
22947340559SBarry Smith   for (i=0; i<n; i++) {
23047340559SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
23147340559SBarry Smith   }
2320298fd71SBarry Smith   (*t)[n] = NULL;
23347340559SBarry Smith   PetscFunctionReturn(0);
23447340559SBarry Smith }
23547340559SBarry Smith 
23647340559SBarry Smith #undef __FUNCT__
23747340559SBarry Smith #define __FUNCT__ "PetscStrArrayDestroy"
23847340559SBarry Smith /*@C
23947340559SBarry Smith    PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
24047340559SBarry Smith 
24147340559SBarry Smith    Not Collective
24247340559SBarry Smith 
24347340559SBarry Smith    Output Parameters:
24447340559SBarry Smith .   list - array of strings
24547340559SBarry Smith 
24647340559SBarry Smith    Level: intermediate
24747340559SBarry Smith 
24847340559SBarry Smith    Concepts: command line arguments
24947340559SBarry Smith 
25047340559SBarry Smith    Notes: Not for use in Fortran
25147340559SBarry Smith 
25247340559SBarry Smith .seealso: PetscStrArrayallocpy()
25347340559SBarry Smith 
25447340559SBarry Smith @*/
2556fed8037SJed Brown PetscErrorCode PetscStrArrayDestroy(char ***list)
25647340559SBarry Smith {
25747340559SBarry Smith   PetscInt       n = 0;
25847340559SBarry Smith   PetscErrorCode ierr;
25947340559SBarry Smith 
2606fed8037SJed Brown   PetscFunctionBegin;
2616fed8037SJed Brown   if (!*list) PetscFunctionReturn(0);
2626fed8037SJed Brown   while ((*list)[n]) {
2636fed8037SJed Brown     ierr = PetscFree((*list)[n]);CHKERRQ(ierr);
26447340559SBarry Smith     n++;
26547340559SBarry Smith   }
2666fed8037SJed Brown   ierr = PetscFree(*list);CHKERRQ(ierr);
2676fed8037SJed Brown   PetscFunctionReturn(0);
26847340559SBarry Smith }
26947340559SBarry Smith 
27047340559SBarry Smith #undef __FUNCT__
2716991f827SBarry Smith #define __FUNCT__ "PetscStrNArrayallocpy"
2726991f827SBarry Smith /*@C
2736991f827SBarry Smith    PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
2746991f827SBarry Smith 
2756991f827SBarry Smith    Not Collective
2766991f827SBarry Smith 
2776991f827SBarry Smith    Input Parameters:
2786991f827SBarry Smith +  n - the number of string entries
2796991f827SBarry Smith -  s - pointer to array of strings
2806991f827SBarry Smith 
2816991f827SBarry Smith    Output Parameter:
2826991f827SBarry Smith .  t - the copied array string
2836991f827SBarry Smith 
2846991f827SBarry Smith    Level: intermediate
2856991f827SBarry Smith 
2866991f827SBarry Smith    Note:
2876991f827SBarry Smith       Not for use in Fortran
2886991f827SBarry Smith 
2896991f827SBarry Smith   Concepts: string copy
2906991f827SBarry Smith 
2916991f827SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
2926991f827SBarry Smith 
2936991f827SBarry Smith @*/
2946991f827SBarry Smith PetscErrorCode  PetscStrNArrayallocpy(PetscInt n,const char *const *list,char ***t)
2956991f827SBarry Smith {
2966991f827SBarry Smith   PetscErrorCode ierr;
2976991f827SBarry Smith   PetscInt       i;
2986991f827SBarry Smith 
2996991f827SBarry Smith   PetscFunctionBegin;
3006991f827SBarry Smith   ierr = PetscMalloc1(n,t);CHKERRQ(ierr);
3016991f827SBarry Smith   for (i=0; i<n; i++) {
3026991f827SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
3036991f827SBarry Smith   }
3046991f827SBarry Smith   PetscFunctionReturn(0);
3056991f827SBarry Smith }
3066991f827SBarry Smith 
3076991f827SBarry Smith #undef __FUNCT__
3086991f827SBarry Smith #define __FUNCT__ "PetscStrNArrayDestroy"
3096991f827SBarry Smith /*@C
3106991f827SBarry Smith    PetscStrNArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
3116991f827SBarry Smith 
3126991f827SBarry Smith    Not Collective
3136991f827SBarry Smith 
3146991f827SBarry Smith    Output Parameters:
3156991f827SBarry Smith +   n - number of string entries
3166991f827SBarry Smith -   list - array of strings
3176991f827SBarry Smith 
3186991f827SBarry Smith    Level: intermediate
3196991f827SBarry Smith 
3206991f827SBarry Smith    Notes: Not for use in Fortran
3216991f827SBarry Smith 
3226991f827SBarry Smith .seealso: PetscStrArrayallocpy()
3236991f827SBarry Smith 
3246991f827SBarry Smith @*/
3256991f827SBarry Smith PetscErrorCode PetscStrNArrayDestroy(PetscInt n,char ***list)
3266991f827SBarry Smith {
3276991f827SBarry Smith   PetscErrorCode ierr;
3286991f827SBarry Smith   PetscInt       i;
3296991f827SBarry Smith 
3306991f827SBarry Smith   PetscFunctionBegin;
3316991f827SBarry Smith   if (!*list) PetscFunctionReturn(0);
3326991f827SBarry Smith   for (i=0; i<n; i++){
3336991f827SBarry Smith     ierr = PetscFree((*list)[i]);CHKERRQ(ierr);
3346991f827SBarry Smith   }
3356991f827SBarry Smith   ierr = PetscFree(*list);CHKERRQ(ierr);
3366991f827SBarry Smith   PetscFunctionReturn(0);
3376991f827SBarry Smith }
3386991f827SBarry Smith 
3396991f827SBarry Smith #undef __FUNCT__
340e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcpy"
341e5c89e4eSSatish Balay /*@C
342e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
343e5c89e4eSSatish Balay 
344e5c89e4eSSatish Balay    Not Collective
345e5c89e4eSSatish Balay 
346e5c89e4eSSatish Balay    Input Parameters:
347e5c89e4eSSatish Balay .  t - pointer to string
348e5c89e4eSSatish Balay 
349e5c89e4eSSatish Balay    Output Parameter:
350e5c89e4eSSatish Balay .  s - the copied string
351e5c89e4eSSatish Balay 
352e5c89e4eSSatish Balay    Level: intermediate
353e5c89e4eSSatish Balay 
3546f013253SBarry Smith    Notes:
355e5c89e4eSSatish Balay      Null string returns a string starting with zero
356e5c89e4eSSatish Balay 
3576f013253SBarry Smith      Not for use in Fortran
3586f013253SBarry Smith 
359e5c89e4eSSatish Balay   Concepts: string copy
360e5c89e4eSSatish Balay 
361e5c89e4eSSatish Balay .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat()
362e5c89e4eSSatish Balay 
363e5c89e4eSSatish Balay @*/
364acc6cc86SBarry Smith 
3657087cfbeSBarry Smith PetscErrorCode  PetscStrcpy(char s[],const char t[])
366e5c89e4eSSatish Balay {
367e5c89e4eSSatish Balay   PetscFunctionBegin;
36817186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
369a297a907SKarl Rupp   if (t) strcpy(s,t);
370a297a907SKarl Rupp   else if (s) s[0] = 0;
371e5c89e4eSSatish Balay   PetscFunctionReturn(0);
372e5c89e4eSSatish Balay }
373e5c89e4eSSatish Balay 
374e5c89e4eSSatish Balay #undef __FUNCT__
375e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncpy"
376e5c89e4eSSatish Balay /*@C
377e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
378e5c89e4eSSatish Balay 
379e5c89e4eSSatish Balay    Not Collective
380e5c89e4eSSatish Balay 
381e5c89e4eSSatish Balay    Input Parameters:
382e5c89e4eSSatish Balay +  t - pointer to string
383e5c89e4eSSatish Balay -  n - the length to copy
384e5c89e4eSSatish Balay 
385e5c89e4eSSatish Balay    Output Parameter:
386e5c89e4eSSatish Balay .  s - the copied string
387e5c89e4eSSatish Balay 
388e5c89e4eSSatish Balay    Level: intermediate
389e5c89e4eSSatish Balay 
390e5c89e4eSSatish Balay    Note:
391e5c89e4eSSatish Balay      Null string returns a string starting with zero
392e5c89e4eSSatish Balay 
393ff32304bSBarry Smith      If the string that is being copied is of length n or larger then the entire string is not
394ff32304bSBarry Smith      copied and the file location of s is set to NULL. This is different then the behavior of
395ff32304bSBarry Smith      strncpy() which leaves s non-terminated.
396ff32304bSBarry Smith 
397e5c89e4eSSatish Balay   Concepts: string copy
398e5c89e4eSSatish Balay 
399e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat()
400e5c89e4eSSatish Balay 
401e5c89e4eSSatish Balay @*/
4027087cfbeSBarry Smith PetscErrorCode  PetscStrncpy(char s[],const char t[],size_t n)
403e5c89e4eSSatish Balay {
404e5c89e4eSSatish Balay   PetscFunctionBegin;
40517186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
406ff32304bSBarry Smith   if (t) {
4078dc57659SBarry Smith     if (n > 1) {
4082c26941aSBarry Smith       strncpy(s,t,n-1);
409ff32304bSBarry Smith       s[n-1] = '\0';
4108dc57659SBarry Smith     } else {
4118dc57659SBarry Smith       s[0] = '\0';
4128dc57659SBarry Smith     }
413ff32304bSBarry Smith   } else if (s) s[0] = 0;
414e5c89e4eSSatish Balay   PetscFunctionReturn(0);
415e5c89e4eSSatish Balay }
416e5c89e4eSSatish Balay 
417e5c89e4eSSatish Balay #undef __FUNCT__
418e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcat"
419e5c89e4eSSatish Balay /*@C
420e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
421e5c89e4eSSatish Balay 
422e5c89e4eSSatish Balay    Not Collective
423e5c89e4eSSatish Balay 
424e5c89e4eSSatish Balay    Input Parameters:
425e5e2177aSMatthew Knepley +  s - string to be added to
426e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
427e5c89e4eSSatish Balay 
428e5c89e4eSSatish Balay    Level: intermediate
429e5c89e4eSSatish Balay 
4306f013253SBarry Smith    Notes: Not for use in Fortran
4316f013253SBarry Smith 
432e5c89e4eSSatish Balay   Concepts: string copy
433e5c89e4eSSatish Balay 
434e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat()
435e5c89e4eSSatish Balay 
436e5c89e4eSSatish Balay @*/
4377087cfbeSBarry Smith PetscErrorCode  PetscStrcat(char s[],const char t[])
438e5c89e4eSSatish Balay {
439e5c89e4eSSatish Balay   PetscFunctionBegin;
4409b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
441e5c89e4eSSatish Balay   strcat(s,t);
442e5c89e4eSSatish Balay   PetscFunctionReturn(0);
443e5c89e4eSSatish Balay }
444e5c89e4eSSatish Balay 
445e5c89e4eSSatish Balay #undef __FUNCT__
446e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncat"
447e5c89e4eSSatish Balay /*@C
448e5c89e4eSSatish Balay    PetscStrncat - Concatenates a string onto a given string, up to a given length
449e5c89e4eSSatish Balay 
450e5c89e4eSSatish Balay    Not Collective
451e5c89e4eSSatish Balay 
452e5c89e4eSSatish Balay    Input Parameters:
453e5c89e4eSSatish Balay +  s - pointer to string to be added to end
454e5c89e4eSSatish Balay .  t - string to be added to
455e5c89e4eSSatish Balay .  n - maximum length to copy
456e5c89e4eSSatish Balay 
457e5c89e4eSSatish Balay    Level: intermediate
458e5c89e4eSSatish Balay 
4596f013253SBarry Smith   Notes:    Not for use in Fortran
4606f013253SBarry Smith 
461e5c89e4eSSatish Balay   Concepts: string copy
462e5c89e4eSSatish Balay 
463e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
464e5c89e4eSSatish Balay 
465e5c89e4eSSatish Balay @*/
4667087cfbeSBarry Smith PetscErrorCode  PetscStrncat(char s[],const char t[],size_t n)
467e5c89e4eSSatish Balay {
468e5c89e4eSSatish Balay   PetscFunctionBegin;
469e5c89e4eSSatish Balay   strncat(s,t,n);
470e5c89e4eSSatish Balay   PetscFunctionReturn(0);
471e5c89e4eSSatish Balay }
472e5c89e4eSSatish Balay 
473e5c89e4eSSatish Balay #undef __FUNCT__
474573b0fb4SBarry Smith #define __FUNCT__ "PetscStrcmpNoError"
475573b0fb4SBarry Smith /*
476573b0fb4SBarry Smith    Only to be used with PetscCheck__FUNCT__()!
477573b0fb4SBarry Smith 
478573b0fb4SBarry Smith    Will be removed once we eliminate the __FUNCT__ paradigm
479573b0fb4SBarry Smith */
480573b0fb4SBarry Smith void  PetscStrcmpNoError(const char a[],const char b[],PetscBool  *flg)
481573b0fb4SBarry Smith {
482573b0fb4SBarry Smith   int c;
483573b0fb4SBarry Smith 
484573b0fb4SBarry Smith   if (!a && !b)      *flg = PETSC_TRUE;
485573b0fb4SBarry Smith   else if (!a || !b) *flg = PETSC_FALSE;
486573b0fb4SBarry Smith   else {
487573b0fb4SBarry Smith     c = strcmp(a,b);
488573b0fb4SBarry Smith     if (c) *flg = PETSC_FALSE;
489573b0fb4SBarry Smith     else   *flg = PETSC_TRUE;
490573b0fb4SBarry Smith   }
491573b0fb4SBarry Smith }
492573b0fb4SBarry Smith 
493573b0fb4SBarry Smith #undef __FUNCT__
494e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcmp"
495e5c89e4eSSatish Balay /*@C
496e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
497e5c89e4eSSatish Balay 
498e5c89e4eSSatish Balay    Not Collective
499e5c89e4eSSatish Balay 
500e5c89e4eSSatish Balay    Input Parameters:
501e5c89e4eSSatish Balay +  a - pointer to string first string
502e5c89e4eSSatish Balay -  b - pointer to second string
503e5c89e4eSSatish Balay 
504e5c89e4eSSatish Balay    Output Parameter:
5058c74ee41SBarry Smith .  flg - PETSC_TRUE if the two strings are equal
506e5c89e4eSSatish Balay 
507e5c89e4eSSatish Balay    Level: intermediate
508e5c89e4eSSatish Balay 
5096f013253SBarry Smith    Notes:    Not for use in Fortran
5106f013253SBarry Smith 
511e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
512e5c89e4eSSatish Balay 
513e5c89e4eSSatish Balay @*/
5147087cfbeSBarry Smith PetscErrorCode  PetscStrcmp(const char a[],const char b[],PetscBool  *flg)
515e5c89e4eSSatish Balay {
516e5c89e4eSSatish Balay   int c;
517e5c89e4eSSatish Balay 
518e5c89e4eSSatish Balay   PetscFunctionBegin;
519a297a907SKarl Rupp   if (!a && !b)      *flg = PETSC_TRUE;
520a297a907SKarl Rupp   else if (!a || !b) *flg = PETSC_FALSE;
521a297a907SKarl Rupp   else {
522e5c89e4eSSatish Balay     c = strcmp(a,b);
523e5c89e4eSSatish Balay     if (c) *flg = PETSC_FALSE;
524e5c89e4eSSatish Balay     else   *flg = PETSC_TRUE;
525e5c89e4eSSatish Balay   }
526e5c89e4eSSatish Balay   PetscFunctionReturn(0);
527e5c89e4eSSatish Balay }
528e5c89e4eSSatish Balay 
529e5c89e4eSSatish Balay #undef __FUNCT__
530e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrgrt"
531e5c89e4eSSatish Balay /*@C
532e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
533e5c89e4eSSatish Balay 
534e5c89e4eSSatish Balay    Not Collective
535e5c89e4eSSatish Balay 
536e5c89e4eSSatish Balay    Input Parameters:
537e5c89e4eSSatish Balay +  a - pointer to first string
538e5c89e4eSSatish Balay -  b - pointer to second string
539e5c89e4eSSatish Balay 
540e5c89e4eSSatish Balay    Output Parameter:
541e5c89e4eSSatish Balay .  flg - if the first string is greater
542e5c89e4eSSatish Balay 
543e5c89e4eSSatish Balay    Notes:
544e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
545e5c89e4eSSatish Balay     all others
546e5c89e4eSSatish Balay 
5476f013253SBarry Smith    Not for use in Fortran
5486f013253SBarry Smith 
549e5c89e4eSSatish Balay    Level: intermediate
550e5c89e4eSSatish Balay 
551e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
552e5c89e4eSSatish Balay 
553e5c89e4eSSatish Balay @*/
5547087cfbeSBarry Smith PetscErrorCode  PetscStrgrt(const char a[],const char b[],PetscBool  *t)
555e5c89e4eSSatish Balay {
556e5c89e4eSSatish Balay   int c;
557e5c89e4eSSatish Balay 
558e5c89e4eSSatish Balay   PetscFunctionBegin;
559a297a907SKarl Rupp   if (!a && !b) *t = PETSC_FALSE;
560a297a907SKarl Rupp   else if (a && !b) *t = PETSC_TRUE;
561a297a907SKarl Rupp   else if (!a && b) *t = PETSC_FALSE;
562a297a907SKarl Rupp   else {
563e5c89e4eSSatish Balay     c = strcmp(a,b);
564e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
565e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
566e5c89e4eSSatish Balay   }
567e5c89e4eSSatish Balay   PetscFunctionReturn(0);
568e5c89e4eSSatish Balay }
569e5c89e4eSSatish Balay 
570e5c89e4eSSatish Balay #undef __FUNCT__
571e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcasecmp"
572e5c89e4eSSatish Balay /*@C
573e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
574e5c89e4eSSatish Balay      except possibly for case.
575e5c89e4eSSatish Balay 
576e5c89e4eSSatish Balay    Not Collective
577e5c89e4eSSatish Balay 
578e5c89e4eSSatish Balay    Input Parameters:
579e5c89e4eSSatish Balay +  a - pointer to first string
580e5c89e4eSSatish Balay -  b - pointer to second string
581e5c89e4eSSatish Balay 
582e5c89e4eSSatish Balay    Output Parameter:
583e5c89e4eSSatish Balay .  flg - if the two strings are the same
584e5c89e4eSSatish Balay 
585e5c89e4eSSatish Balay    Notes:
586e5c89e4eSSatish Balay     Null arguments are ok
587e5c89e4eSSatish Balay 
5886f013253SBarry Smith    Not for use in Fortran
5896f013253SBarry Smith 
590e5c89e4eSSatish Balay    Level: intermediate
591e5c89e4eSSatish Balay 
592e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
593e5c89e4eSSatish Balay 
594e5c89e4eSSatish Balay @*/
5957087cfbeSBarry Smith PetscErrorCode  PetscStrcasecmp(const char a[],const char b[],PetscBool  *t)
596e5c89e4eSSatish Balay {
597e5c89e4eSSatish Balay   int c;
598e5c89e4eSSatish Balay 
599e5c89e4eSSatish Balay   PetscFunctionBegin;
600e5c89e4eSSatish Balay   if (!a && !b) c = 0;
601e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
60232b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
60332b366c8SSatish Balay   else c = strcasecmp(a,b);
60432b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
605e5c89e4eSSatish Balay   else c = stricmp(a,b);
606e5c89e4eSSatish Balay #else
60732b366c8SSatish Balay   else {
60832b366c8SSatish Balay     char           *aa,*bb;
60932b366c8SSatish Balay     PetscErrorCode ierr;
61032b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
61132b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
61232b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
61332b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
61432b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
615503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
616503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
61732b366c8SSatish Balay     PetscFunctionReturn(0);
61832b366c8SSatish Balay   }
619e5c89e4eSSatish Balay #endif
620e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
621e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
622e5c89e4eSSatish Balay   PetscFunctionReturn(0);
623e5c89e4eSSatish Balay }
624e5c89e4eSSatish Balay 
62532b366c8SSatish Balay 
62632b366c8SSatish Balay 
627e5c89e4eSSatish Balay #undef __FUNCT__
628e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncmp"
629e5c89e4eSSatish Balay /*@C
630e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
631e5c89e4eSSatish Balay 
632e5c89e4eSSatish Balay    Not Collective
633e5c89e4eSSatish Balay 
634e5c89e4eSSatish Balay    Input Parameters:
635e5c89e4eSSatish Balay +  a - pointer to first string
636e5c89e4eSSatish Balay .  b - pointer to second string
637e5c89e4eSSatish Balay -  n - length to compare up to
638e5c89e4eSSatish Balay 
639e5c89e4eSSatish Balay    Output Parameter:
640e5c89e4eSSatish Balay .  t - if the two strings are equal
641e5c89e4eSSatish Balay 
642e5c89e4eSSatish Balay    Level: intermediate
643e5c89e4eSSatish Balay 
6446f013253SBarry Smith    Notes:    Not for use in Fortran
6456f013253SBarry Smith 
646e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
647e5c89e4eSSatish Balay 
648e5c89e4eSSatish Balay @*/
6497087cfbeSBarry Smith PetscErrorCode  PetscStrncmp(const char a[],const char b[],size_t n,PetscBool  *t)
650e5c89e4eSSatish Balay {
651e5c89e4eSSatish Balay   int c;
652e5c89e4eSSatish Balay 
653e5c89e4eSSatish Balay   PetscFunctionBegin;
654e5c89e4eSSatish Balay   c = strncmp(a,b,n);
655e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
656e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
657e5c89e4eSSatish Balay   PetscFunctionReturn(0);
658e5c89e4eSSatish Balay }
659e5c89e4eSSatish Balay 
660e5c89e4eSSatish Balay #undef __FUNCT__
661e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrchr"
662e5c89e4eSSatish Balay /*@C
663e5c89e4eSSatish Balay    PetscStrchr - Locates first occurance of a character in a 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:
6720298fd71SBarry Smith .  c - location of occurance, NULL if not found
673e5c89e4eSSatish Balay 
674e5c89e4eSSatish Balay    Level: intermediate
675e5c89e4eSSatish Balay 
6766f013253SBarry Smith    Notes:    Not for use in Fortran
6776f013253SBarry Smith 
678e5c89e4eSSatish Balay @*/
6797087cfbeSBarry Smith PetscErrorCode  PetscStrchr(const char a[],char b,char *c[])
680e5c89e4eSSatish Balay {
681e5c89e4eSSatish Balay   PetscFunctionBegin;
682e5c89e4eSSatish Balay   *c = (char*)strchr(a,b);
683e5c89e4eSSatish Balay   PetscFunctionReturn(0);
684e5c89e4eSSatish Balay }
685e5c89e4eSSatish Balay 
686e5c89e4eSSatish Balay #undef __FUNCT__
687e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrrchr"
688e5c89e4eSSatish Balay /*@C
689e5c89e4eSSatish Balay    PetscStrrchr - Locates one location past the last occurance of a character in a string,
690e5c89e4eSSatish Balay       if the character is not found then returns entire string
691e5c89e4eSSatish Balay 
692e5c89e4eSSatish Balay    Not Collective
693e5c89e4eSSatish Balay 
694e5c89e4eSSatish Balay    Input Parameters:
695e5c89e4eSSatish Balay +  a - pointer to string
696e5c89e4eSSatish Balay -  b - character
697e5c89e4eSSatish Balay 
698e5c89e4eSSatish Balay    Output Parameter:
699e5c89e4eSSatish Balay .  tmp - location of occurance, a if not found
700e5c89e4eSSatish Balay 
701e5c89e4eSSatish Balay    Level: intermediate
702e5c89e4eSSatish Balay 
7036f013253SBarry Smith    Notes:    Not for use in Fortran
7046f013253SBarry Smith 
705e5c89e4eSSatish Balay @*/
7067087cfbeSBarry Smith PetscErrorCode  PetscStrrchr(const char a[],char b,char *tmp[])
707e5c89e4eSSatish Balay {
708e5c89e4eSSatish Balay   PetscFunctionBegin;
709e5c89e4eSSatish Balay   *tmp = (char*)strrchr(a,b);
710a297a907SKarl Rupp   if (!*tmp) *tmp = (char*)a;
711a297a907SKarl Rupp   else *tmp = *tmp + 1;
712e5c89e4eSSatish Balay   PetscFunctionReturn(0);
713e5c89e4eSSatish Balay }
714e5c89e4eSSatish Balay 
715e5c89e4eSSatish Balay #undef __FUNCT__
716e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrtolower"
717e5c89e4eSSatish Balay /*@C
718e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
719e5c89e4eSSatish Balay 
720e5c89e4eSSatish Balay    Not Collective
721e5c89e4eSSatish Balay 
722e5c89e4eSSatish Balay    Input Parameters:
723e5c89e4eSSatish Balay .  a - pointer to string
724e5c89e4eSSatish Balay 
725e5c89e4eSSatish Balay    Level: intermediate
726e5c89e4eSSatish Balay 
7276f013253SBarry Smith    Notes:    Not for use in Fortran
7286f013253SBarry Smith 
729e5c89e4eSSatish Balay @*/
7307087cfbeSBarry Smith PetscErrorCode  PetscStrtolower(char a[])
731e5c89e4eSSatish Balay {
732e5c89e4eSSatish Balay   PetscFunctionBegin;
733e5c89e4eSSatish Balay   while (*a) {
734e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
735e5c89e4eSSatish Balay     a++;
736e5c89e4eSSatish Balay   }
737e5c89e4eSSatish Balay   PetscFunctionReturn(0);
738e5c89e4eSSatish Balay }
739e5c89e4eSSatish Balay 
7407ba3a57cSBarry Smith #undef __FUNCT__
7412f234a98SBarry Smith #define __FUNCT__ "PetscStrtoupper"
7422f234a98SBarry Smith /*@C
7432f234a98SBarry Smith    PetscStrtolower - Converts string to upper case
7442f234a98SBarry Smith 
7452f234a98SBarry Smith    Not Collective
7462f234a98SBarry Smith 
7472f234a98SBarry Smith    Input Parameters:
7482f234a98SBarry Smith .  a - pointer to string
7492f234a98SBarry Smith 
7502f234a98SBarry Smith    Level: intermediate
7512f234a98SBarry Smith 
7522f234a98SBarry Smith    Notes:    Not for use in Fortran
7532f234a98SBarry Smith 
7542f234a98SBarry Smith @*/
7552f234a98SBarry Smith PetscErrorCode  PetscStrtoupper(char a[])
7562f234a98SBarry Smith {
7572f234a98SBarry Smith   PetscFunctionBegin;
7582f234a98SBarry Smith   while (*a) {
7592f234a98SBarry Smith     if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a';
7602f234a98SBarry Smith     a++;
7612f234a98SBarry Smith   }
7622f234a98SBarry Smith   PetscFunctionReturn(0);
7632f234a98SBarry Smith }
7642f234a98SBarry Smith 
7652f234a98SBarry Smith #undef __FUNCT__
7667ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswith"
7677ba3a57cSBarry Smith /*@C
7687ba3a57cSBarry Smith    PetscStrendswith - Determines if a string ends with a certain string
7691d1a0024SBarry Smith 
7707ba3a57cSBarry Smith    Not Collective
7717ba3a57cSBarry Smith 
7727ba3a57cSBarry Smith    Input Parameters:
7737ba3a57cSBarry Smith +  a - pointer to string
7747ba3a57cSBarry Smith -  b - string to endwith
7757ba3a57cSBarry Smith 
7767ba3a57cSBarry Smith    Output Parameter:
7777ba3a57cSBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
7787ba3a57cSBarry Smith 
7797ba3a57cSBarry Smith    Notes:     Not for use in Fortran
7807ba3a57cSBarry Smith 
7817ba3a57cSBarry Smith    Level: intermediate
7827ba3a57cSBarry Smith 
7837ba3a57cSBarry Smith @*/
7847ba3a57cSBarry Smith PetscErrorCode  PetscStrendswith(const char a[],const char b[],PetscBool *flg)
7857ba3a57cSBarry Smith {
7867ba3a57cSBarry Smith   char           *test;
7877ba3a57cSBarry Smith   PetscErrorCode ierr;
7887ba3a57cSBarry Smith   size_t         na,nb;
7897ba3a57cSBarry Smith 
7907ba3a57cSBarry Smith   PetscFunctionBegin;
7917ba3a57cSBarry Smith   *flg = PETSC_FALSE;
7927ba3a57cSBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
7937ba3a57cSBarry Smith   if (test) {
7947ba3a57cSBarry Smith     ierr = PetscStrlen(a,&na);CHKERRQ(ierr);
7957ba3a57cSBarry Smith     ierr = PetscStrlen(b,&nb);CHKERRQ(ierr);
7967ba3a57cSBarry Smith     if (a+na-nb == test) *flg = PETSC_TRUE;
7977ba3a57cSBarry Smith   }
7987ba3a57cSBarry Smith   PetscFunctionReturn(0);
7997ba3a57cSBarry Smith }
8007ba3a57cSBarry Smith 
8017ba3a57cSBarry Smith #undef __FUNCT__
8022c9581d2SBarry Smith #define __FUNCT__ "PetscStrbeginswith"
8032c9581d2SBarry Smith /*@C
8042c9581d2SBarry Smith    PetscStrbeginswith - Determines if a string begins with a certain string
8052c9581d2SBarry Smith 
8062c9581d2SBarry Smith    Not Collective
8072c9581d2SBarry Smith 
8082c9581d2SBarry Smith    Input Parameters:
8092c9581d2SBarry Smith +  a - pointer to string
8102c9581d2SBarry Smith -  b - string to beginwith
8112c9581d2SBarry Smith 
8122c9581d2SBarry Smith    Output Parameter:
8132c9581d2SBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
8142c9581d2SBarry Smith 
8152c9581d2SBarry Smith    Notes:     Not for use in Fortran
8162c9581d2SBarry Smith 
8172c9581d2SBarry Smith    Level: intermediate
8182c9581d2SBarry Smith 
8192c9581d2SBarry Smith @*/
8202c9581d2SBarry Smith PetscErrorCode  PetscStrbeginswith(const char a[],const char b[],PetscBool *flg)
8212c9581d2SBarry Smith {
8222c9581d2SBarry Smith   char           *test;
8232c9581d2SBarry Smith   PetscErrorCode ierr;
8242c9581d2SBarry Smith 
8252c9581d2SBarry Smith   PetscFunctionBegin;
8262c9581d2SBarry Smith   *flg = PETSC_FALSE;
8272c9581d2SBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
828a297a907SKarl Rupp   if (test && (test == a)) *flg = PETSC_TRUE;
8292c9581d2SBarry Smith   PetscFunctionReturn(0);
8302c9581d2SBarry Smith }
8312c9581d2SBarry Smith 
8322c9581d2SBarry Smith 
8332c9581d2SBarry Smith #undef __FUNCT__
8347ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswithwhich"
8357ba3a57cSBarry Smith /*@C
8367ba3a57cSBarry Smith    PetscStrendswithwhich - Determines if a string ends with one of several possible strings
8377ba3a57cSBarry Smith 
8387ba3a57cSBarry Smith    Not Collective
8397ba3a57cSBarry Smith 
8407ba3a57cSBarry Smith    Input Parameters:
8417ba3a57cSBarry Smith +  a - pointer to string
8427ba3a57cSBarry Smith -  bs - strings to endwith (last entry must be null)
8437ba3a57cSBarry Smith 
8447ba3a57cSBarry Smith    Output Parameter:
8457ba3a57cSBarry Smith .  cnt - the index of the string it ends with or 1+the last possible index
8467ba3a57cSBarry Smith 
8477ba3a57cSBarry Smith    Notes:     Not for use in Fortran
8487ba3a57cSBarry Smith 
8497ba3a57cSBarry Smith    Level: intermediate
8507ba3a57cSBarry Smith 
8517ba3a57cSBarry Smith @*/
8527ba3a57cSBarry Smith PetscErrorCode  PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt)
8537ba3a57cSBarry Smith {
8547ba3a57cSBarry Smith   PetscBool      flg;
8557ba3a57cSBarry Smith   PetscErrorCode ierr;
8567ba3a57cSBarry Smith 
8577ba3a57cSBarry Smith   PetscFunctionBegin;
8587ba3a57cSBarry Smith   *cnt = 0;
8597ba3a57cSBarry Smith   while (bs[*cnt]) {
8607ba3a57cSBarry Smith     ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr);
8617ba3a57cSBarry Smith     if (flg) PetscFunctionReturn(0);
8627ba3a57cSBarry Smith     *cnt += 1;
8637ba3a57cSBarry Smith   }
8647ba3a57cSBarry Smith   PetscFunctionReturn(0);
8657ba3a57cSBarry Smith }
8667ba3a57cSBarry Smith 
8677ba3a57cSBarry Smith #undef __FUNCT__
8687ba3a57cSBarry Smith #define __FUNCT__ "PetscStrrstr"
8697ba3a57cSBarry Smith /*@C
8707ba3a57cSBarry Smith    PetscStrrstr - Locates last occurance of string in another string
8717ba3a57cSBarry Smith 
8727ba3a57cSBarry Smith    Not Collective
8737ba3a57cSBarry Smith 
8747ba3a57cSBarry Smith    Input Parameters:
8757ba3a57cSBarry Smith +  a - pointer to string
8767ba3a57cSBarry Smith -  b - string to find
8777ba3a57cSBarry Smith 
8787ba3a57cSBarry Smith    Output Parameter:
8797ba3a57cSBarry Smith .  tmp - location of occurance
8807ba3a57cSBarry Smith 
8817ba3a57cSBarry Smith    Notes:     Not for use in Fortran
8827ba3a57cSBarry Smith 
8837ba3a57cSBarry Smith    Level: intermediate
8847ba3a57cSBarry Smith 
8857ba3a57cSBarry Smith @*/
8867ba3a57cSBarry Smith PetscErrorCode  PetscStrrstr(const char a[],const char b[],char *tmp[])
8877ba3a57cSBarry Smith {
8887ba3a57cSBarry Smith   const char *stmp = a, *ltmp = 0;
8897ba3a57cSBarry Smith 
8907ba3a57cSBarry Smith   PetscFunctionBegin;
8917ba3a57cSBarry Smith   while (stmp) {
8927ba3a57cSBarry Smith     stmp = (char*)strstr(stmp,b);
8937ba3a57cSBarry Smith     if (stmp) {ltmp = stmp;stmp++;}
8947ba3a57cSBarry Smith   }
8957ba3a57cSBarry Smith   *tmp = (char*)ltmp;
8967ba3a57cSBarry Smith   PetscFunctionReturn(0);
8977ba3a57cSBarry Smith }
8987ba3a57cSBarry Smith 
8997ba3a57cSBarry Smith #undef __FUNCT__
9007ba3a57cSBarry Smith #define __FUNCT__ "PetscStrstr"
9017ba3a57cSBarry Smith /*@C
9027ba3a57cSBarry Smith    PetscStrstr - Locates first occurance of string in another string
9037ba3a57cSBarry Smith 
9047ba3a57cSBarry Smith    Not Collective
9057ba3a57cSBarry Smith 
9067ba3a57cSBarry Smith    Input Parameters:
907160f4796SJed Brown +  haystack - string to search
908160f4796SJed Brown -  needle - string to find
9097ba3a57cSBarry Smith 
9107ba3a57cSBarry Smith    Output Parameter:
9110298fd71SBarry Smith .  tmp - location of occurance, is a NULL if the string is not found
9127ba3a57cSBarry Smith 
9137ba3a57cSBarry Smith    Notes: Not for use in Fortran
9147ba3a57cSBarry Smith 
9157ba3a57cSBarry Smith    Level: intermediate
9167ba3a57cSBarry Smith 
9177ba3a57cSBarry Smith @*/
918160f4796SJed Brown PetscErrorCode  PetscStrstr(const char haystack[],const char needle[],char *tmp[])
9197ba3a57cSBarry Smith {
9207ba3a57cSBarry Smith   PetscFunctionBegin;
921160f4796SJed Brown   *tmp = (char*)strstr(haystack,needle);
9227ba3a57cSBarry Smith   PetscFunctionReturn(0);
9237ba3a57cSBarry Smith }
9247ba3a57cSBarry Smith 
9257ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
9261d1a0024SBarry Smith 
927e5c89e4eSSatish Balay #undef __FUNCT__
928e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenFind"
929e5c89e4eSSatish Balay /*@C
930e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
931e5c89e4eSSatish Balay 
932e5c89e4eSSatish Balay    Not Collective
933e5c89e4eSSatish Balay 
934e5c89e4eSSatish Balay    Input Parameters:
935e5c89e4eSSatish Balay .  a - pointer to token
936e5c89e4eSSatish Balay 
937e5c89e4eSSatish Balay    Output Parameter:
9380298fd71SBarry Smith .  result - location of occurance, NULL if not found
939e5c89e4eSSatish Balay 
940e5c89e4eSSatish Balay    Notes:
941e5c89e4eSSatish Balay 
942e5c89e4eSSatish Balay      This version is different from the system version in that
943e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
944e5c89e4eSSatish Balay 
9454704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
9464704e885SBarry Smith    as a single token.
9474704e885SBarry Smith 
9483a9c465aSBarry 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
9493a9c465aSBarry Smith    second will return a null terminated y
9503a9c465aSBarry Smith 
9513a9c465aSBarry 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
9523a9c465aSBarry Smith 
9536f013253SBarry Smith     Not for use in Fortran
9546f013253SBarry Smith 
955e5c89e4eSSatish Balay    Level: intermediate
956e5c89e4eSSatish Balay 
9576f013253SBarry Smith 
958e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
959e5c89e4eSSatish Balay @*/
9607087cfbeSBarry Smith PetscErrorCode  PetscTokenFind(PetscToken a,char *result[])
961e5c89e4eSSatish Balay {
9624704e885SBarry Smith   char *ptr = a->current,token;
963e5c89e4eSSatish Balay 
964e5c89e4eSSatish Balay   PetscFunctionBegin;
965e5c89e4eSSatish Balay   *result = a->current;
9664704e885SBarry Smith   if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);}
9674704e885SBarry Smith   token = a->token;
96890fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
969e5c89e4eSSatish Balay   while (ptr) {
9704704e885SBarry Smith     if (*ptr == token) {
971e5c89e4eSSatish Balay       *ptr++ = 0;
972e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
973e5c89e4eSSatish Balay       a->current = ptr;
974e5c89e4eSSatish Balay       break;
975e5c89e4eSSatish Balay     }
976e5c89e4eSSatish Balay     if (!*ptr) {
977e5c89e4eSSatish Balay       a->current = 0;
978e5c89e4eSSatish Balay       break;
979e5c89e4eSSatish Balay     }
980e5c89e4eSSatish Balay     ptr++;
981e5c89e4eSSatish Balay   }
982e5c89e4eSSatish Balay   PetscFunctionReturn(0);
983e5c89e4eSSatish Balay }
984e5c89e4eSSatish Balay 
985e5c89e4eSSatish Balay #undef __FUNCT__
986e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenCreate"
987e5c89e4eSSatish Balay /*@C
988e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
989e5c89e4eSSatish Balay 
990e5c89e4eSSatish Balay    Not Collective
991e5c89e4eSSatish Balay 
992e5c89e4eSSatish Balay    Input Parameters:
993e5c89e4eSSatish Balay +  string - the string to look in
9943a9c465aSBarry Smith -  b - the separator character
995e5c89e4eSSatish Balay 
996e5c89e4eSSatish Balay    Output Parameter:
9973a9c465aSBarry Smith .  t- the token object
998e5c89e4eSSatish Balay 
999e5c89e4eSSatish Balay    Notes:
1000e5c89e4eSSatish Balay 
1001e5c89e4eSSatish Balay      This version is different from the system version in that
1002e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
1003e5c89e4eSSatish Balay 
10046f013253SBarry Smith     Not for use in Fortran
10056f013253SBarry Smith 
1006e5c89e4eSSatish Balay    Level: intermediate
1007e5c89e4eSSatish Balay 
1008e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
1009e5c89e4eSSatish Balay @*/
10107087cfbeSBarry Smith PetscErrorCode  PetscTokenCreate(const char a[],const char b,PetscToken *t)
1011e5c89e4eSSatish Balay {
1012e5c89e4eSSatish Balay   PetscErrorCode ierr;
1013e5c89e4eSSatish Balay 
1014e5c89e4eSSatish Balay   PetscFunctionBegin;
1015b00a9115SJed Brown   ierr = PetscNew(t);CHKERRQ(ierr);
1016e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
1017a297a907SKarl Rupp 
1018e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
1019e5c89e4eSSatish Balay   (*t)->token   = b;
1020e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1021e5c89e4eSSatish Balay }
1022e5c89e4eSSatish Balay 
1023e5c89e4eSSatish Balay #undef __FUNCT__
1024e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenDestroy"
1025e5c89e4eSSatish Balay /*@C
1026e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
1027e5c89e4eSSatish Balay 
1028e5c89e4eSSatish Balay    Not Collective
1029e5c89e4eSSatish Balay 
1030e5c89e4eSSatish Balay    Input Parameters:
1031e5c89e4eSSatish Balay .  a - pointer to token
1032e5c89e4eSSatish Balay 
1033e5c89e4eSSatish Balay    Level: intermediate
1034e5c89e4eSSatish Balay 
10356f013253SBarry Smith    Notes:     Not for use in Fortran
10366f013253SBarry Smith 
1037e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
1038e5c89e4eSSatish Balay @*/
10398c74ee41SBarry Smith PetscErrorCode  PetscTokenDestroy(PetscToken *a)
1040e5c89e4eSSatish Balay {
1041e5c89e4eSSatish Balay   PetscErrorCode ierr;
1042e5c89e4eSSatish Balay 
1043e5c89e4eSSatish Balay   PetscFunctionBegin;
10448c74ee41SBarry Smith   if (!*a) PetscFunctionReturn(0);
10458c74ee41SBarry Smith   ierr = PetscFree((*a)->array);CHKERRQ(ierr);
10468c74ee41SBarry Smith   ierr = PetscFree(*a);CHKERRQ(ierr);
1047e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1048e5c89e4eSSatish Balay }
1049e5c89e4eSSatish Balay 
1050e5c89e4eSSatish Balay 
1051e5c89e4eSSatish Balay #undef __FUNCT__
1052e5c89e4eSSatish Balay #define __FUNCT__ "PetscGetPetscDir"
1053e5c89e4eSSatish Balay /*@C
1054e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
1055e5c89e4eSSatish Balay 
1056e5c89e4eSSatish Balay    Not Collective
1057e5c89e4eSSatish Balay 
1058e5c89e4eSSatish Balay    Output Parameter:
1059e5c89e4eSSatish Balay .  dir - the directory
1060e5c89e4eSSatish Balay 
1061e5c89e4eSSatish Balay    Level: developer
1062e5c89e4eSSatish Balay 
10636f013253SBarry Smith    Notes: 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 #undef __FUNCT__
1074e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrreplace"
1075e5c89e4eSSatish Balay /*@C
1076e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
1077e5c89e4eSSatish Balay 
1078e5c89e4eSSatish Balay    Not Collective
1079e5c89e4eSSatish Balay 
1080e5c89e4eSSatish Balay    Input Parameters:
1081e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
108271573d7dSBarry Smith .   aa - the string to look in
1083d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
1084e5c89e4eSSatish Balay -   len - the length of b
1085e5c89e4eSSatish Balay 
1086e5c89e4eSSatish Balay    Notes:
1087e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
1088d5649816SBarry Smith       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
1089e5c89e4eSSatish Balay       as well as any environmental variables.
1090e5c89e4eSSatish Balay 
10916f013253SBarry Smith       PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
1092acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
1093acc6cc86SBarry Smith 
10946f013253SBarry Smith       Not for use in Fortran
10956f013253SBarry Smith 
1096e5c89e4eSSatish Balay    Level: intermediate
1097e5c89e4eSSatish Balay 
1098e5c89e4eSSatish Balay @*/
10997087cfbeSBarry Smith PetscErrorCode  PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
1100e5c89e4eSSatish Balay {
1101e5c89e4eSSatish Balay   PetscErrorCode ierr;
1102e5c89e4eSSatish Balay   int            i = 0;
1103e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
110471573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
1105d5649816SBarry Smith   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0};
1106d5649816SBarry Smith   const char     *r[] = {0,0,0,0,0,0,0,0,0};
1107ace3abfcSBarry Smith   PetscBool      flag;
1108e5c89e4eSSatish Balay 
1109e5c89e4eSSatish Balay   PetscFunctionBegin;
1110e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
111171573d7dSBarry Smith   if (aa == b) {
111222982a5fSBarry Smith     ierr = PetscStrallocpy(aa,(char**)&a);CHKERRQ(ierr);
111371573d7dSBarry Smith   }
1114785e854fSJed Brown   ierr = PetscMalloc1(len,&work);CHKERRQ(ierr);
1115e5c89e4eSSatish Balay 
1116e5c89e4eSSatish Balay   /* get values for replaced variables */
1117487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr);
1118487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr);
1119487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr);
1120785e854fSJed Brown   ierr = PetscMalloc1(256,&r[3]);CHKERRQ(ierr);
1121785e854fSJed Brown   ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[4]);CHKERRQ(ierr);
1122785e854fSJed Brown   ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[5]);CHKERRQ(ierr);
1123785e854fSJed Brown   ierr = PetscMalloc1(256,&r[6]);CHKERRQ(ierr);
1124785e854fSJed Brown   ierr = PetscMalloc1(256,&r[7]);CHKERRQ(ierr);
1125487e5849SBarry Smith   ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr);
1126487e5849SBarry Smith   ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1127487e5849SBarry Smith   ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1128487e5849SBarry Smith   ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr);
1129d5649816SBarry Smith   ierr = PetscGetHostName((char*)r[7],256);CHKERRQ(ierr);
1130487e5849SBarry Smith 
1131487e5849SBarry Smith   /* replace that are in environment */
1132487e5849SBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr);
1133487e5849SBarry Smith   if (flag) {
113431936d58SMatthew G. Knepley     ierr = PetscFree(r[2]);CHKERRQ(ierr);
1135487e5849SBarry Smith     ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr);
1136487e5849SBarry Smith   }
1137e5c89e4eSSatish Balay 
1138e5c89e4eSSatish Balay   /* replace the requested strings */
1139e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
1140e5c89e4eSSatish Balay   while (s[i]) {
1141e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
1142e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1143e5c89e4eSSatish Balay     while (par) {
1144e5c89e4eSSatish Balay       *par =  0;
1145e5c89e4eSSatish Balay       par += l;
1146e5c89e4eSSatish Balay 
1147e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
1148e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
1149e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
115017186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
1151e5c89e4eSSatish Balay       ierr = PetscStrcpy(work,b);CHKERRQ(ierr);
1152e5c89e4eSSatish Balay       ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr);
1153e5c89e4eSSatish Balay       ierr = PetscStrcat(work,par);CHKERRQ(ierr);
1154e5c89e4eSSatish Balay       ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr);
1155e5c89e4eSSatish Balay       ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1156e5c89e4eSSatish Balay     }
1157e5c89e4eSSatish Balay     i++;
1158e5c89e4eSSatish Balay   }
1159487e5849SBarry Smith   i = 0;
1160487e5849SBarry Smith   while (r[i]) {
1161e5c89e4eSSatish Balay     tfree = (char*)r[i];
1162e5c89e4eSSatish Balay     ierr  = PetscFree(tfree);CHKERRQ(ierr);
1163487e5849SBarry Smith     i++;
1164e5c89e4eSSatish Balay   }
1165e5c89e4eSSatish Balay 
1166e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
1167e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1168e5c89e4eSSatish Balay   while (par) {
1169e5c89e4eSSatish Balay     *par  = 0;
1170e5c89e4eSSatish Balay     par  += 2;
1171e5c89e4eSSatish Balay     ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
1172e5c89e4eSSatish Balay     ierr  = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
1173e5c89e4eSSatish Balay     *epar = 0;
1174e5c89e4eSSatish Balay     epar += 1;
1175e5c89e4eSSatish Balay     ierr  = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr);
11767ba3a57cSBarry Smith     if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
1177e5c89e4eSSatish Balay     ierr = PetscStrcat(work,env);CHKERRQ(ierr);
1178e5c89e4eSSatish Balay     ierr = PetscStrcat(work,epar);CHKERRQ(ierr);
1179e5c89e4eSSatish Balay     ierr = PetscStrcpy(b,work);CHKERRQ(ierr);
1180e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1181e5c89e4eSSatish Balay   }
1182e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
118371573d7dSBarry Smith   if (aa == b) {
118471573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
118571573d7dSBarry Smith   }
1186e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1187e5c89e4eSSatish Balay }
1188e5c89e4eSSatish Balay 
1189a53986e1SJed Brown #undef __FUNCT__
1190a53986e1SJed Brown #define __FUNCT__ "PetscEListFind"
1191a53986e1SJed Brown /*@C
1192a53986e1SJed Brown    PetscEListFind - searches list of strings for given string, using case insensitive matching
1193e5c89e4eSSatish Balay 
1194a53986e1SJed Brown    Not Collective
1195a53986e1SJed Brown 
1196a53986e1SJed Brown    Input Parameters:
1197a53986e1SJed Brown +  n - number of strings in
1198a53986e1SJed Brown .  list - list of strings to search
1199a53986e1SJed Brown -  str - string to look for, empty string "" accepts default (first entry in list)
1200a53986e1SJed Brown 
1201a53986e1SJed Brown    Output Parameters:
1202a53986e1SJed Brown +  value - index of matching string (if found)
1203a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1204a53986e1SJed Brown 
1205a53986e1SJed Brown    Notes:
1206a53986e1SJed Brown    Not for use in Fortran
1207a53986e1SJed Brown 
1208a53986e1SJed Brown    Level: advanced
1209a53986e1SJed Brown @*/
1210a53986e1SJed Brown PetscErrorCode PetscEListFind(PetscInt n,const char *const *list,const char *str,PetscInt *value,PetscBool *found)
1211a53986e1SJed Brown {
1212a53986e1SJed Brown   PetscErrorCode ierr;
1213a53986e1SJed Brown   PetscBool matched;
1214a53986e1SJed Brown   PetscInt i;
1215a53986e1SJed Brown 
1216a53986e1SJed Brown   PetscFunctionBegin;
1217a53986e1SJed Brown   if (found) *found = PETSC_FALSE;
1218a53986e1SJed Brown   for (i=0; i<n; i++) {
1219a53986e1SJed Brown     ierr = PetscStrcasecmp(str,list[i],&matched);CHKERRQ(ierr);
1220a53986e1SJed Brown     if (matched || !str[0]) {
1221a53986e1SJed Brown       if (found) *found = PETSC_TRUE;
1222a53986e1SJed Brown       *value = i;
1223a53986e1SJed Brown       break;
1224a53986e1SJed Brown     }
1225a53986e1SJed Brown   }
1226a53986e1SJed Brown   PetscFunctionReturn(0);
1227a53986e1SJed Brown }
1228a53986e1SJed Brown 
1229a53986e1SJed Brown #undef __FUNCT__
1230a53986e1SJed Brown #define __FUNCT__ "PetscEnumFind"
1231a53986e1SJed Brown /*@C
1232a53986e1SJed Brown    PetscEListFind - searches enum list of strings for given string, using case insensitive matching
1233a53986e1SJed Brown 
1234a53986e1SJed Brown    Not Collective
1235a53986e1SJed Brown 
1236a53986e1SJed Brown    Input Parameters:
1237a53986e1SJed Brown +  enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL
1238a53986e1SJed Brown -  str - string to look for
1239a53986e1SJed Brown 
1240a53986e1SJed Brown    Output Parameters:
1241a53986e1SJed Brown +  value - index of matching string (if found)
1242a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1243a53986e1SJed Brown 
1244a53986e1SJed Brown    Notes:
1245a53986e1SJed Brown    Not for use in Fortran
1246a53986e1SJed Brown 
1247a53986e1SJed Brown    Level: advanced
1248a53986e1SJed Brown @*/
1249a53986e1SJed Brown PetscErrorCode PetscEnumFind(const char *const *enumlist,const char *str,PetscEnum *value,PetscBool *found)
1250a53986e1SJed Brown {
1251a53986e1SJed Brown   PetscErrorCode ierr;
1252d05ba7d2SLisandro Dalcin   PetscInt n = 0,evalue;
1253a53986e1SJed Brown   PetscBool efound;
1254a53986e1SJed Brown 
1255a53986e1SJed Brown   PetscFunctionBegin;
1256d05ba7d2SLisandro 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");
1257a53986e1SJed Brown   if (n < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
1258a53986e1SJed Brown   n -= 3; /* drop enum name, prefix, and null termination */
1259a53986e1SJed Brown   ierr = PetscEListFind(n,enumlist,str,&evalue,&efound);CHKERRQ(ierr);
1260cfb463b1SJed Brown   if (efound) *value = (PetscEnum)evalue;
1261a53986e1SJed Brown   if (found) *found = efound;
1262a53986e1SJed Brown   PetscFunctionReturn(0);
1263a53986e1SJed Brown }
1264