xref: /petsc/src/sys/utils/str.c (revision acf7dc08c8506770a828aadefe51e7a00645f35a)
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 {
45c3bcdc7eSBarry Smith   int       i,j,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;
5161528463SBarry Smith   *args = NULL;
52*acf7dc08SSatish Balay   for (; n>0; n--) {   /* remove separator chars at the end - and will empty the string if all chars are separator chars */
53*acf7dc08SSatish Balay     if (s[n-1] != sp) break;
54*acf7dc08SSatish Balay   }
554996c5bdSBarry Smith   if (!n) {
564996c5bdSBarry Smith     return(0);
574996c5bdSBarry Smith   }
583c311c98SBarry Smith   for (i=0; i<n; i++) {
59d67fe73bSBarry Smith     if (s[i] != sp) break;
603c311c98SBarry Smith   }
613c311c98SBarry Smith   for (;i<n+1; i++) {
62d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
63d67fe73bSBarry Smith     else if (s[i] != sp) {flg = PETSC_FALSE;}
643c311c98SBarry 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   }
737dd9f305SSatish Balay   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++) {
79c3bcdc7eSBarry Smith     (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char));
80c3bcdc7eSBarry Smith     if (!(*args)[i]) {
81c3bcdc7eSBarry Smith       free(lens);
82c3bcdc7eSBarry Smith       for (j=0; j<i; j++) free((*args)[j]);
83c3bcdc7eSBarry Smith       free(*args);
84c3bcdc7eSBarry Smith       return PETSC_ERR_MEM;
85c3bcdc7eSBarry Smith     }
863c311c98SBarry Smith   }
87a2ea699eSBarry Smith   free(lens);
88301d30feSBarry Smith   (*args)[*argc] = 0;
893c311c98SBarry Smith 
903c311c98SBarry Smith   *argc = 0;
913c311c98SBarry Smith   for (i=0; i<n; i++) {
92d67fe73bSBarry Smith     if (s[i] != sp) break;
933c311c98SBarry Smith   }
943c311c98SBarry Smith   for (;i<n+1; i++) {
95d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
96d67fe73bSBarry Smith     else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;}
973c311c98SBarry Smith   }
983c311c98SBarry Smith   return 0;
993c311c98SBarry Smith }
1003c311c98SBarry Smith 
1013c311c98SBarry Smith #undef __FUNCT__
102301d30feSBarry Smith #define __FUNCT__ "PetscStrToArrayDestroy"
103301d30feSBarry Smith /*@C
104301d30feSBarry Smith    PetscStrToArrayDestroy - Frees array created with PetscStrToArray().
105301d30feSBarry Smith 
106301d30feSBarry Smith    Not Collective
107301d30feSBarry Smith 
108301d30feSBarry Smith    Output Parameters:
109301d30feSBarry Smith +  argc - the number of arguments
110301d30feSBarry Smith -  args - the array of arguments
111301d30feSBarry Smith 
112301d30feSBarry Smith    Level: intermediate
113301d30feSBarry Smith 
114301d30feSBarry Smith    Concepts: command line arguments
115301d30feSBarry Smith 
116301d30feSBarry Smith    Notes: This may be called before PetscInitialize() or after PetscFinalize()
117301d30feSBarry Smith 
1186f013253SBarry Smith    Not for use in Fortran
1196f013253SBarry Smith 
120301d30feSBarry Smith .seealso: PetscStrToArray()
121301d30feSBarry Smith 
122301d30feSBarry Smith @*/
1237087cfbeSBarry Smith PetscErrorCode  PetscStrToArrayDestroy(int argc,char **args)
124301d30feSBarry Smith {
125301d30feSBarry Smith   PetscInt i;
126301d30feSBarry Smith 
127a297a907SKarl Rupp   for (i=0; i<argc; i++) free(args[i]);
128a297a907SKarl Rupp   if (args) free(args);
129301d30feSBarry Smith   return 0;
130301d30feSBarry Smith }
131301d30feSBarry Smith 
132301d30feSBarry Smith #undef __FUNCT__
133e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrlen"
134e5c89e4eSSatish Balay /*@C
135e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
136e5c89e4eSSatish Balay 
137e5c89e4eSSatish Balay    Not Collective
138e5c89e4eSSatish Balay 
139e5c89e4eSSatish Balay    Input Parameters:
140e5c89e4eSSatish Balay .  s - pointer to string
141e5c89e4eSSatish Balay 
142e5c89e4eSSatish Balay    Output Parameter:
143e5c89e4eSSatish Balay .  len - length in bytes
144e5c89e4eSSatish Balay 
145e5c89e4eSSatish Balay    Level: intermediate
146e5c89e4eSSatish Balay 
147e5c89e4eSSatish Balay    Note:
148e5c89e4eSSatish Balay    This routine is analogous to strlen().
149e5c89e4eSSatish Balay 
150e5c89e4eSSatish Balay    Null string returns a length of zero
151e5c89e4eSSatish Balay 
1526f013253SBarry Smith    Not for use in Fortran
1536f013253SBarry Smith 
154e5c89e4eSSatish Balay   Concepts: string length
155e5c89e4eSSatish Balay 
156e5c89e4eSSatish Balay @*/
1577087cfbeSBarry Smith PetscErrorCode  PetscStrlen(const char s[],size_t *len)
158e5c89e4eSSatish Balay {
159e5c89e4eSSatish Balay   PetscFunctionBegin;
160a297a907SKarl Rupp   if (!s) *len = 0;
161a297a907SKarl Rupp   else    *len = strlen(s);
162e5c89e4eSSatish Balay   PetscFunctionReturn(0);
163e5c89e4eSSatish Balay }
164e5c89e4eSSatish Balay 
165e5c89e4eSSatish Balay #undef __FUNCT__
166e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrallocpy"
167e5c89e4eSSatish Balay /*@C
168e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
169e5c89e4eSSatish Balay 
170e5c89e4eSSatish Balay    Not Collective
171e5c89e4eSSatish Balay 
172e5c89e4eSSatish Balay    Input Parameters:
173e5c89e4eSSatish Balay .  s - pointer to string
174e5c89e4eSSatish Balay 
175e5c89e4eSSatish Balay    Output Parameter:
176e5c89e4eSSatish Balay .  t - the copied string
177e5c89e4eSSatish Balay 
178e5c89e4eSSatish Balay    Level: intermediate
179e5c89e4eSSatish Balay 
180e5c89e4eSSatish Balay    Note:
181e5c89e4eSSatish Balay       Null string returns a new null string
182e5c89e4eSSatish Balay 
1836f013253SBarry Smith       Not for use in Fortran
1846f013253SBarry Smith 
185e5c89e4eSSatish Balay   Concepts: string copy
186e5c89e4eSSatish Balay 
187e5c89e4eSSatish Balay @*/
1887087cfbeSBarry Smith PetscErrorCode  PetscStrallocpy(const char s[],char *t[])
189e5c89e4eSSatish Balay {
190e5c89e4eSSatish Balay   PetscErrorCode ierr;
191e5c89e4eSSatish Balay   size_t         len;
19271573d7dSBarry Smith   char           *tmp = 0;
193e5c89e4eSSatish Balay 
194e5c89e4eSSatish Balay   PetscFunctionBegin;
195e5c89e4eSSatish Balay   if (s) {
196e5c89e4eSSatish Balay     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
197854ce69bSBarry Smith     ierr = PetscMalloc1(1+len,&tmp);CHKERRQ(ierr);
19871573d7dSBarry Smith     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
199e5c89e4eSSatish Balay   }
20071573d7dSBarry Smith   *t = tmp;
201e5c89e4eSSatish Balay   PetscFunctionReturn(0);
202e5c89e4eSSatish Balay }
203e5c89e4eSSatish Balay 
204e5c89e4eSSatish Balay #undef __FUNCT__
20547340559SBarry Smith #define __FUNCT__ "PetscStrArrayallocpy"
20647340559SBarry Smith /*@C
20747340559SBarry Smith    PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
20847340559SBarry Smith 
20947340559SBarry Smith    Not Collective
21047340559SBarry Smith 
21147340559SBarry Smith    Input Parameters:
21247340559SBarry Smith .  s - pointer to array of strings (final string is a null)
21347340559SBarry Smith 
21447340559SBarry Smith    Output Parameter:
21547340559SBarry Smith .  t - the copied array string
21647340559SBarry Smith 
21747340559SBarry Smith    Level: intermediate
21847340559SBarry Smith 
21947340559SBarry Smith    Note:
22047340559SBarry Smith       Not for use in Fortran
22147340559SBarry Smith 
22247340559SBarry Smith   Concepts: string copy
22347340559SBarry Smith 
22447340559SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
22547340559SBarry Smith 
22647340559SBarry Smith @*/
22747340559SBarry Smith PetscErrorCode  PetscStrArrayallocpy(const char *const *list,char ***t)
22847340559SBarry Smith {
22947340559SBarry Smith   PetscErrorCode ierr;
23047340559SBarry Smith   PetscInt       i,n = 0;
23147340559SBarry Smith 
23247340559SBarry Smith   PetscFunctionBegin;
23347340559SBarry Smith   while (list[n++]) ;
234854ce69bSBarry Smith   ierr = PetscMalloc1(n+1,t);CHKERRQ(ierr);
23547340559SBarry Smith   for (i=0; i<n; i++) {
23647340559SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
23747340559SBarry Smith   }
2380298fd71SBarry Smith   (*t)[n] = NULL;
23947340559SBarry Smith   PetscFunctionReturn(0);
24047340559SBarry Smith }
24147340559SBarry Smith 
24247340559SBarry Smith #undef __FUNCT__
24347340559SBarry Smith #define __FUNCT__ "PetscStrArrayDestroy"
24447340559SBarry Smith /*@C
24547340559SBarry Smith    PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
24647340559SBarry Smith 
24747340559SBarry Smith    Not Collective
24847340559SBarry Smith 
24947340559SBarry Smith    Output Parameters:
25047340559SBarry Smith .   list - array of strings
25147340559SBarry Smith 
25247340559SBarry Smith    Level: intermediate
25347340559SBarry Smith 
25447340559SBarry Smith    Concepts: command line arguments
25547340559SBarry Smith 
25647340559SBarry Smith    Notes: Not for use in Fortran
25747340559SBarry Smith 
25847340559SBarry Smith .seealso: PetscStrArrayallocpy()
25947340559SBarry Smith 
26047340559SBarry Smith @*/
2616fed8037SJed Brown PetscErrorCode PetscStrArrayDestroy(char ***list)
26247340559SBarry Smith {
26347340559SBarry Smith   PetscInt       n = 0;
26447340559SBarry Smith   PetscErrorCode ierr;
26547340559SBarry Smith 
2666fed8037SJed Brown   PetscFunctionBegin;
2676fed8037SJed Brown   if (!*list) PetscFunctionReturn(0);
2686fed8037SJed Brown   while ((*list)[n]) {
2696fed8037SJed Brown     ierr = PetscFree((*list)[n]);CHKERRQ(ierr);
27047340559SBarry Smith     n++;
27147340559SBarry Smith   }
2726fed8037SJed Brown   ierr = PetscFree(*list);CHKERRQ(ierr);
2736fed8037SJed Brown   PetscFunctionReturn(0);
27447340559SBarry Smith }
27547340559SBarry Smith 
27647340559SBarry Smith #undef __FUNCT__
2776991f827SBarry Smith #define __FUNCT__ "PetscStrNArrayallocpy"
2786991f827SBarry Smith /*@C
2796991f827SBarry Smith    PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
2806991f827SBarry Smith 
2816991f827SBarry Smith    Not Collective
2826991f827SBarry Smith 
2836991f827SBarry Smith    Input Parameters:
2846991f827SBarry Smith +  n - the number of string entries
2856991f827SBarry Smith -  s - pointer to array of strings
2866991f827SBarry Smith 
2876991f827SBarry Smith    Output Parameter:
2886991f827SBarry Smith .  t - the copied array string
2896991f827SBarry Smith 
2906991f827SBarry Smith    Level: intermediate
2916991f827SBarry Smith 
2926991f827SBarry Smith    Note:
2936991f827SBarry Smith       Not for use in Fortran
2946991f827SBarry Smith 
2956991f827SBarry Smith   Concepts: string copy
2966991f827SBarry Smith 
2976991f827SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
2986991f827SBarry Smith 
2996991f827SBarry Smith @*/
3006991f827SBarry Smith PetscErrorCode  PetscStrNArrayallocpy(PetscInt n,const char *const *list,char ***t)
3016991f827SBarry Smith {
3026991f827SBarry Smith   PetscErrorCode ierr;
3036991f827SBarry Smith   PetscInt       i;
3046991f827SBarry Smith 
3056991f827SBarry Smith   PetscFunctionBegin;
3066991f827SBarry Smith   ierr = PetscMalloc1(n,t);CHKERRQ(ierr);
3076991f827SBarry Smith   for (i=0; i<n; i++) {
3086991f827SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
3096991f827SBarry Smith   }
3106991f827SBarry Smith   PetscFunctionReturn(0);
3116991f827SBarry Smith }
3126991f827SBarry Smith 
3136991f827SBarry Smith #undef __FUNCT__
3146991f827SBarry Smith #define __FUNCT__ "PetscStrNArrayDestroy"
3156991f827SBarry Smith /*@C
3166991f827SBarry Smith    PetscStrNArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
3176991f827SBarry Smith 
3186991f827SBarry Smith    Not Collective
3196991f827SBarry Smith 
3206991f827SBarry Smith    Output Parameters:
3216991f827SBarry Smith +   n - number of string entries
3226991f827SBarry Smith -   list - array of strings
3236991f827SBarry Smith 
3246991f827SBarry Smith    Level: intermediate
3256991f827SBarry Smith 
3266991f827SBarry Smith    Notes: Not for use in Fortran
3276991f827SBarry Smith 
3286991f827SBarry Smith .seealso: PetscStrArrayallocpy()
3296991f827SBarry Smith 
3306991f827SBarry Smith @*/
3316991f827SBarry Smith PetscErrorCode PetscStrNArrayDestroy(PetscInt n,char ***list)
3326991f827SBarry Smith {
3336991f827SBarry Smith   PetscErrorCode ierr;
3346991f827SBarry Smith   PetscInt       i;
3356991f827SBarry Smith 
3366991f827SBarry Smith   PetscFunctionBegin;
3376991f827SBarry Smith   if (!*list) PetscFunctionReturn(0);
3386991f827SBarry Smith   for (i=0; i<n; i++){
3396991f827SBarry Smith     ierr = PetscFree((*list)[i]);CHKERRQ(ierr);
3406991f827SBarry Smith   }
3416991f827SBarry Smith   ierr = PetscFree(*list);CHKERRQ(ierr);
3426991f827SBarry Smith   PetscFunctionReturn(0);
3436991f827SBarry Smith }
3446991f827SBarry Smith 
3456991f827SBarry Smith #undef __FUNCT__
346e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcpy"
347e5c89e4eSSatish Balay /*@C
348e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
349e5c89e4eSSatish Balay 
350e5c89e4eSSatish Balay    Not Collective
351e5c89e4eSSatish Balay 
352e5c89e4eSSatish Balay    Input Parameters:
353e5c89e4eSSatish Balay .  t - pointer to string
354e5c89e4eSSatish Balay 
355e5c89e4eSSatish Balay    Output Parameter:
356e5c89e4eSSatish Balay .  s - the copied string
357e5c89e4eSSatish Balay 
358e5c89e4eSSatish Balay    Level: intermediate
359e5c89e4eSSatish Balay 
3606f013253SBarry Smith    Notes:
361e5c89e4eSSatish Balay      Null string returns a string starting with zero
362e5c89e4eSSatish Balay 
3636f013253SBarry Smith      Not for use in Fortran
3646f013253SBarry Smith 
365e5c89e4eSSatish Balay   Concepts: string copy
366e5c89e4eSSatish Balay 
367e5c89e4eSSatish Balay .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat()
368e5c89e4eSSatish Balay 
369e5c89e4eSSatish Balay @*/
370acc6cc86SBarry Smith 
3717087cfbeSBarry Smith PetscErrorCode  PetscStrcpy(char s[],const char t[])
372e5c89e4eSSatish Balay {
373e5c89e4eSSatish Balay   PetscFunctionBegin;
37417186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
375a297a907SKarl Rupp   if (t) strcpy(s,t);
376a297a907SKarl Rupp   else if (s) s[0] = 0;
377e5c89e4eSSatish Balay   PetscFunctionReturn(0);
378e5c89e4eSSatish Balay }
379e5c89e4eSSatish Balay 
380e5c89e4eSSatish Balay #undef __FUNCT__
381e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncpy"
382e5c89e4eSSatish Balay /*@C
383e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
384e5c89e4eSSatish Balay 
385e5c89e4eSSatish Balay    Not Collective
386e5c89e4eSSatish Balay 
387e5c89e4eSSatish Balay    Input Parameters:
388e5c89e4eSSatish Balay +  t - pointer to string
389e5c89e4eSSatish Balay -  n - the length to copy
390e5c89e4eSSatish Balay 
391e5c89e4eSSatish Balay    Output Parameter:
392e5c89e4eSSatish Balay .  s - the copied string
393e5c89e4eSSatish Balay 
394e5c89e4eSSatish Balay    Level: intermediate
395e5c89e4eSSatish Balay 
396e5c89e4eSSatish Balay    Note:
397e5c89e4eSSatish Balay      Null string returns a string starting with zero
398e5c89e4eSSatish Balay 
399ff32304bSBarry Smith      If the string that is being copied is of length n or larger then the entire string is not
400ff32304bSBarry Smith      copied and the file location of s is set to NULL. This is different then the behavior of
401ff32304bSBarry Smith      strncpy() which leaves s non-terminated.
402ff32304bSBarry Smith 
403e5c89e4eSSatish Balay   Concepts: string copy
404e5c89e4eSSatish Balay 
405e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat()
406e5c89e4eSSatish Balay 
407e5c89e4eSSatish Balay @*/
4087087cfbeSBarry Smith PetscErrorCode  PetscStrncpy(char s[],const char t[],size_t n)
409e5c89e4eSSatish Balay {
410e5c89e4eSSatish Balay   PetscFunctionBegin;
41117186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
412ff32304bSBarry Smith   if (t) {
4138dc57659SBarry Smith     if (n > 1) {
4142c26941aSBarry Smith       strncpy(s,t,n-1);
415ff32304bSBarry Smith       s[n-1] = '\0';
4168dc57659SBarry Smith     } else {
4178dc57659SBarry Smith       s[0] = '\0';
4188dc57659SBarry Smith     }
419ff32304bSBarry Smith   } else if (s) s[0] = 0;
420e5c89e4eSSatish Balay   PetscFunctionReturn(0);
421e5c89e4eSSatish Balay }
422e5c89e4eSSatish Balay 
423e5c89e4eSSatish Balay #undef __FUNCT__
424e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcat"
425e5c89e4eSSatish Balay /*@C
426e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
427e5c89e4eSSatish Balay 
428e5c89e4eSSatish Balay    Not Collective
429e5c89e4eSSatish Balay 
430e5c89e4eSSatish Balay    Input Parameters:
431e5e2177aSMatthew Knepley +  s - string to be added to
432e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
433e5c89e4eSSatish Balay 
434e5c89e4eSSatish Balay    Level: intermediate
435e5c89e4eSSatish Balay 
4366f013253SBarry Smith    Notes: Not for use in Fortran
4376f013253SBarry Smith 
438e5c89e4eSSatish Balay   Concepts: string copy
439e5c89e4eSSatish Balay 
440e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat()
441e5c89e4eSSatish Balay 
442e5c89e4eSSatish Balay @*/
4437087cfbeSBarry Smith PetscErrorCode  PetscStrcat(char s[],const char t[])
444e5c89e4eSSatish Balay {
445e5c89e4eSSatish Balay   PetscFunctionBegin;
4469b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
447e5c89e4eSSatish Balay   strcat(s,t);
448e5c89e4eSSatish Balay   PetscFunctionReturn(0);
449e5c89e4eSSatish Balay }
450e5c89e4eSSatish Balay 
451e5c89e4eSSatish Balay #undef __FUNCT__
452e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncat"
453e5c89e4eSSatish Balay /*@C
454e5c89e4eSSatish Balay    PetscStrncat - Concatenates a string onto a given string, up to a given length
455e5c89e4eSSatish Balay 
456e5c89e4eSSatish Balay    Not Collective
457e5c89e4eSSatish Balay 
458e5c89e4eSSatish Balay    Input Parameters:
459e5c89e4eSSatish Balay +  s - pointer to string to be added to end
460e5c89e4eSSatish Balay .  t - string to be added to
461e5c89e4eSSatish Balay .  n - maximum length to copy
462e5c89e4eSSatish Balay 
463e5c89e4eSSatish Balay    Level: intermediate
464e5c89e4eSSatish Balay 
4656f013253SBarry Smith   Notes:    Not for use in Fortran
4666f013253SBarry Smith 
467e5c89e4eSSatish Balay   Concepts: string copy
468e5c89e4eSSatish Balay 
469e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
470e5c89e4eSSatish Balay 
471e5c89e4eSSatish Balay @*/
4727087cfbeSBarry Smith PetscErrorCode  PetscStrncat(char s[],const char t[],size_t n)
473e5c89e4eSSatish Balay {
474e5c89e4eSSatish Balay   PetscFunctionBegin;
475e5c89e4eSSatish Balay   strncat(s,t,n);
476e5c89e4eSSatish Balay   PetscFunctionReturn(0);
477e5c89e4eSSatish Balay }
478e5c89e4eSSatish Balay 
479e5c89e4eSSatish Balay #undef __FUNCT__
480573b0fb4SBarry Smith #define __FUNCT__ "PetscStrcmpNoError"
481573b0fb4SBarry Smith /*
482573b0fb4SBarry Smith    Only to be used with PetscCheck__FUNCT__()!
483573b0fb4SBarry Smith 
484573b0fb4SBarry Smith    Will be removed once we eliminate the __FUNCT__ paradigm
485573b0fb4SBarry Smith */
486573b0fb4SBarry Smith void  PetscStrcmpNoError(const char a[],const char b[],PetscBool  *flg)
487573b0fb4SBarry Smith {
488573b0fb4SBarry Smith   int c;
489573b0fb4SBarry Smith 
490573b0fb4SBarry Smith   if (!a && !b)      *flg = PETSC_TRUE;
491573b0fb4SBarry Smith   else if (!a || !b) *flg = PETSC_FALSE;
492573b0fb4SBarry Smith   else {
493573b0fb4SBarry Smith     c = strcmp(a,b);
494573b0fb4SBarry Smith     if (c) *flg = PETSC_FALSE;
495573b0fb4SBarry Smith     else   *flg = PETSC_TRUE;
496573b0fb4SBarry Smith   }
497573b0fb4SBarry Smith }
498573b0fb4SBarry Smith 
499573b0fb4SBarry Smith #undef __FUNCT__
500e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcmp"
501e5c89e4eSSatish Balay /*@C
502e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
503e5c89e4eSSatish Balay 
504e5c89e4eSSatish Balay    Not Collective
505e5c89e4eSSatish Balay 
506e5c89e4eSSatish Balay    Input Parameters:
507e5c89e4eSSatish Balay +  a - pointer to string first string
508e5c89e4eSSatish Balay -  b - pointer to second string
509e5c89e4eSSatish Balay 
510e5c89e4eSSatish Balay    Output Parameter:
5118c74ee41SBarry Smith .  flg - PETSC_TRUE if the two strings are equal
512e5c89e4eSSatish Balay 
513e5c89e4eSSatish Balay    Level: intermediate
514e5c89e4eSSatish Balay 
5156f013253SBarry Smith    Notes:    Not for use in Fortran
5166f013253SBarry Smith 
517e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
518e5c89e4eSSatish Balay 
519e5c89e4eSSatish Balay @*/
5207087cfbeSBarry Smith PetscErrorCode  PetscStrcmp(const char a[],const char b[],PetscBool  *flg)
521e5c89e4eSSatish Balay {
522e5c89e4eSSatish Balay   int c;
523e5c89e4eSSatish Balay 
524e5c89e4eSSatish Balay   PetscFunctionBegin;
525a297a907SKarl Rupp   if (!a && !b)      *flg = PETSC_TRUE;
526a297a907SKarl Rupp   else if (!a || !b) *flg = PETSC_FALSE;
527a297a907SKarl Rupp   else {
528e5c89e4eSSatish Balay     c = strcmp(a,b);
529e5c89e4eSSatish Balay     if (c) *flg = PETSC_FALSE;
530e5c89e4eSSatish Balay     else   *flg = PETSC_TRUE;
531e5c89e4eSSatish Balay   }
532e5c89e4eSSatish Balay   PetscFunctionReturn(0);
533e5c89e4eSSatish Balay }
534e5c89e4eSSatish Balay 
535e5c89e4eSSatish Balay #undef __FUNCT__
536e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrgrt"
537e5c89e4eSSatish Balay /*@C
538e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
539e5c89e4eSSatish Balay 
540e5c89e4eSSatish Balay    Not Collective
541e5c89e4eSSatish Balay 
542e5c89e4eSSatish Balay    Input Parameters:
543e5c89e4eSSatish Balay +  a - pointer to first string
544e5c89e4eSSatish Balay -  b - pointer to second string
545e5c89e4eSSatish Balay 
546e5c89e4eSSatish Balay    Output Parameter:
547e5c89e4eSSatish Balay .  flg - if the first string is greater
548e5c89e4eSSatish Balay 
549e5c89e4eSSatish Balay    Notes:
550e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
551e5c89e4eSSatish Balay     all others
552e5c89e4eSSatish Balay 
5536f013253SBarry Smith    Not for use in Fortran
5546f013253SBarry Smith 
555e5c89e4eSSatish Balay    Level: intermediate
556e5c89e4eSSatish Balay 
557e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
558e5c89e4eSSatish Balay 
559e5c89e4eSSatish Balay @*/
5607087cfbeSBarry Smith PetscErrorCode  PetscStrgrt(const char a[],const char b[],PetscBool  *t)
561e5c89e4eSSatish Balay {
562e5c89e4eSSatish Balay   int c;
563e5c89e4eSSatish Balay 
564e5c89e4eSSatish Balay   PetscFunctionBegin;
565a297a907SKarl Rupp   if (!a && !b) *t = PETSC_FALSE;
566a297a907SKarl Rupp   else if (a && !b) *t = PETSC_TRUE;
567a297a907SKarl Rupp   else if (!a && b) *t = PETSC_FALSE;
568a297a907SKarl Rupp   else {
569e5c89e4eSSatish Balay     c = strcmp(a,b);
570e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
571e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
572e5c89e4eSSatish Balay   }
573e5c89e4eSSatish Balay   PetscFunctionReturn(0);
574e5c89e4eSSatish Balay }
575e5c89e4eSSatish Balay 
576e5c89e4eSSatish Balay #undef __FUNCT__
577e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcasecmp"
578e5c89e4eSSatish Balay /*@C
579e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
580e5c89e4eSSatish Balay      except possibly for case.
581e5c89e4eSSatish Balay 
582e5c89e4eSSatish Balay    Not Collective
583e5c89e4eSSatish Balay 
584e5c89e4eSSatish Balay    Input Parameters:
585e5c89e4eSSatish Balay +  a - pointer to first string
586e5c89e4eSSatish Balay -  b - pointer to second string
587e5c89e4eSSatish Balay 
588e5c89e4eSSatish Balay    Output Parameter:
589e5c89e4eSSatish Balay .  flg - if the two strings are the same
590e5c89e4eSSatish Balay 
591e5c89e4eSSatish Balay    Notes:
592e5c89e4eSSatish Balay     Null arguments are ok
593e5c89e4eSSatish Balay 
5946f013253SBarry Smith    Not for use in Fortran
5956f013253SBarry Smith 
596e5c89e4eSSatish Balay    Level: intermediate
597e5c89e4eSSatish Balay 
598e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
599e5c89e4eSSatish Balay 
600e5c89e4eSSatish Balay @*/
6017087cfbeSBarry Smith PetscErrorCode  PetscStrcasecmp(const char a[],const char b[],PetscBool  *t)
602e5c89e4eSSatish Balay {
603e5c89e4eSSatish Balay   int c;
604e5c89e4eSSatish Balay 
605e5c89e4eSSatish Balay   PetscFunctionBegin;
606e5c89e4eSSatish Balay   if (!a && !b) c = 0;
607e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
60832b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
60932b366c8SSatish Balay   else c = strcasecmp(a,b);
61032b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
611e5c89e4eSSatish Balay   else c = stricmp(a,b);
612e5c89e4eSSatish Balay #else
61332b366c8SSatish Balay   else {
61432b366c8SSatish Balay     char           *aa,*bb;
61532b366c8SSatish Balay     PetscErrorCode ierr;
61632b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
61732b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
61832b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
61932b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
62032b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
621503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
622503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
62332b366c8SSatish Balay     PetscFunctionReturn(0);
62432b366c8SSatish Balay   }
625e5c89e4eSSatish Balay #endif
626e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
627e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
628e5c89e4eSSatish Balay   PetscFunctionReturn(0);
629e5c89e4eSSatish Balay }
630e5c89e4eSSatish Balay 
63132b366c8SSatish Balay 
63232b366c8SSatish Balay 
633e5c89e4eSSatish Balay #undef __FUNCT__
634e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncmp"
635e5c89e4eSSatish Balay /*@C
636e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
637e5c89e4eSSatish Balay 
638e5c89e4eSSatish Balay    Not Collective
639e5c89e4eSSatish Balay 
640e5c89e4eSSatish Balay    Input Parameters:
641e5c89e4eSSatish Balay +  a - pointer to first string
642e5c89e4eSSatish Balay .  b - pointer to second string
643e5c89e4eSSatish Balay -  n - length to compare up to
644e5c89e4eSSatish Balay 
645e5c89e4eSSatish Balay    Output Parameter:
646e5c89e4eSSatish Balay .  t - if the two strings are equal
647e5c89e4eSSatish Balay 
648e5c89e4eSSatish Balay    Level: intermediate
649e5c89e4eSSatish Balay 
6506f013253SBarry Smith    Notes:    Not for use in Fortran
6516f013253SBarry Smith 
652e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
653e5c89e4eSSatish Balay 
654e5c89e4eSSatish Balay @*/
6557087cfbeSBarry Smith PetscErrorCode  PetscStrncmp(const char a[],const char b[],size_t n,PetscBool  *t)
656e5c89e4eSSatish Balay {
657e5c89e4eSSatish Balay   int c;
658e5c89e4eSSatish Balay 
659e5c89e4eSSatish Balay   PetscFunctionBegin;
660e5c89e4eSSatish Balay   c = strncmp(a,b,n);
661e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
662e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
663e5c89e4eSSatish Balay   PetscFunctionReturn(0);
664e5c89e4eSSatish Balay }
665e5c89e4eSSatish Balay 
666e5c89e4eSSatish Balay #undef __FUNCT__
667e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrchr"
668e5c89e4eSSatish Balay /*@C
669e5c89e4eSSatish Balay    PetscStrchr - Locates first occurance of a character in a string
670e5c89e4eSSatish Balay 
671e5c89e4eSSatish Balay    Not Collective
672e5c89e4eSSatish Balay 
673e5c89e4eSSatish Balay    Input Parameters:
674e5c89e4eSSatish Balay +  a - pointer to string
675e5c89e4eSSatish Balay -  b - character
676e5c89e4eSSatish Balay 
677e5c89e4eSSatish Balay    Output Parameter:
6780298fd71SBarry Smith .  c - location of occurance, NULL if not found
679e5c89e4eSSatish Balay 
680e5c89e4eSSatish Balay    Level: intermediate
681e5c89e4eSSatish Balay 
6826f013253SBarry Smith    Notes:    Not for use in Fortran
6836f013253SBarry Smith 
684e5c89e4eSSatish Balay @*/
6857087cfbeSBarry Smith PetscErrorCode  PetscStrchr(const char a[],char b,char *c[])
686e5c89e4eSSatish Balay {
687e5c89e4eSSatish Balay   PetscFunctionBegin;
688e5c89e4eSSatish Balay   *c = (char*)strchr(a,b);
689e5c89e4eSSatish Balay   PetscFunctionReturn(0);
690e5c89e4eSSatish Balay }
691e5c89e4eSSatish Balay 
692e5c89e4eSSatish Balay #undef __FUNCT__
693e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrrchr"
694e5c89e4eSSatish Balay /*@C
695e5c89e4eSSatish Balay    PetscStrrchr - Locates one location past the last occurance of a character in a string,
696e5c89e4eSSatish Balay       if the character is not found then returns entire string
697e5c89e4eSSatish Balay 
698e5c89e4eSSatish Balay    Not Collective
699e5c89e4eSSatish Balay 
700e5c89e4eSSatish Balay    Input Parameters:
701e5c89e4eSSatish Balay +  a - pointer to string
702e5c89e4eSSatish Balay -  b - character
703e5c89e4eSSatish Balay 
704e5c89e4eSSatish Balay    Output Parameter:
705e5c89e4eSSatish Balay .  tmp - location of occurance, a if not found
706e5c89e4eSSatish Balay 
707e5c89e4eSSatish Balay    Level: intermediate
708e5c89e4eSSatish Balay 
7096f013253SBarry Smith    Notes:    Not for use in Fortran
7106f013253SBarry Smith 
711e5c89e4eSSatish Balay @*/
7127087cfbeSBarry Smith PetscErrorCode  PetscStrrchr(const char a[],char b,char *tmp[])
713e5c89e4eSSatish Balay {
714e5c89e4eSSatish Balay   PetscFunctionBegin;
715e5c89e4eSSatish Balay   *tmp = (char*)strrchr(a,b);
716a297a907SKarl Rupp   if (!*tmp) *tmp = (char*)a;
717a297a907SKarl Rupp   else *tmp = *tmp + 1;
718e5c89e4eSSatish Balay   PetscFunctionReturn(0);
719e5c89e4eSSatish Balay }
720e5c89e4eSSatish Balay 
721e5c89e4eSSatish Balay #undef __FUNCT__
722e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrtolower"
723e5c89e4eSSatish Balay /*@C
724e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
725e5c89e4eSSatish Balay 
726e5c89e4eSSatish Balay    Not Collective
727e5c89e4eSSatish Balay 
728e5c89e4eSSatish Balay    Input Parameters:
729e5c89e4eSSatish Balay .  a - pointer to string
730e5c89e4eSSatish Balay 
731e5c89e4eSSatish Balay    Level: intermediate
732e5c89e4eSSatish Balay 
7336f013253SBarry Smith    Notes:    Not for use in Fortran
7346f013253SBarry Smith 
735e5c89e4eSSatish Balay @*/
7367087cfbeSBarry Smith PetscErrorCode  PetscStrtolower(char a[])
737e5c89e4eSSatish Balay {
738e5c89e4eSSatish Balay   PetscFunctionBegin;
739e5c89e4eSSatish Balay   while (*a) {
740e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
741e5c89e4eSSatish Balay     a++;
742e5c89e4eSSatish Balay   }
743e5c89e4eSSatish Balay   PetscFunctionReturn(0);
744e5c89e4eSSatish Balay }
745e5c89e4eSSatish Balay 
7467ba3a57cSBarry Smith #undef __FUNCT__
7472f234a98SBarry Smith #define __FUNCT__ "PetscStrtoupper"
7482f234a98SBarry Smith /*@C
7492f234a98SBarry Smith    PetscStrtolower - Converts string to upper case
7502f234a98SBarry Smith 
7512f234a98SBarry Smith    Not Collective
7522f234a98SBarry Smith 
7532f234a98SBarry Smith    Input Parameters:
7542f234a98SBarry Smith .  a - pointer to string
7552f234a98SBarry Smith 
7562f234a98SBarry Smith    Level: intermediate
7572f234a98SBarry Smith 
7582f234a98SBarry Smith    Notes:    Not for use in Fortran
7592f234a98SBarry Smith 
7602f234a98SBarry Smith @*/
7612f234a98SBarry Smith PetscErrorCode  PetscStrtoupper(char a[])
7622f234a98SBarry Smith {
7632f234a98SBarry Smith   PetscFunctionBegin;
7642f234a98SBarry Smith   while (*a) {
7652f234a98SBarry Smith     if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a';
7662f234a98SBarry Smith     a++;
7672f234a98SBarry Smith   }
7682f234a98SBarry Smith   PetscFunctionReturn(0);
7692f234a98SBarry Smith }
7702f234a98SBarry Smith 
7712f234a98SBarry Smith #undef __FUNCT__
7727ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswith"
7737ba3a57cSBarry Smith /*@C
7747ba3a57cSBarry Smith    PetscStrendswith - Determines if a string ends with a certain string
7751d1a0024SBarry Smith 
7767ba3a57cSBarry Smith    Not Collective
7777ba3a57cSBarry Smith 
7787ba3a57cSBarry Smith    Input Parameters:
7797ba3a57cSBarry Smith +  a - pointer to string
7807ba3a57cSBarry Smith -  b - string to endwith
7817ba3a57cSBarry Smith 
7827ba3a57cSBarry Smith    Output Parameter:
7837ba3a57cSBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
7847ba3a57cSBarry Smith 
7857ba3a57cSBarry Smith    Notes:     Not for use in Fortran
7867ba3a57cSBarry Smith 
7877ba3a57cSBarry Smith    Level: intermediate
7887ba3a57cSBarry Smith 
7897ba3a57cSBarry Smith @*/
7907ba3a57cSBarry Smith PetscErrorCode  PetscStrendswith(const char a[],const char b[],PetscBool *flg)
7917ba3a57cSBarry Smith {
7927ba3a57cSBarry Smith   char           *test;
7937ba3a57cSBarry Smith   PetscErrorCode ierr;
7947ba3a57cSBarry Smith   size_t         na,nb;
7957ba3a57cSBarry Smith 
7967ba3a57cSBarry Smith   PetscFunctionBegin;
7977ba3a57cSBarry Smith   *flg = PETSC_FALSE;
7987ba3a57cSBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
7997ba3a57cSBarry Smith   if (test) {
8007ba3a57cSBarry Smith     ierr = PetscStrlen(a,&na);CHKERRQ(ierr);
8017ba3a57cSBarry Smith     ierr = PetscStrlen(b,&nb);CHKERRQ(ierr);
8027ba3a57cSBarry Smith     if (a+na-nb == test) *flg = PETSC_TRUE;
8037ba3a57cSBarry Smith   }
8047ba3a57cSBarry Smith   PetscFunctionReturn(0);
8057ba3a57cSBarry Smith }
8067ba3a57cSBarry Smith 
8077ba3a57cSBarry Smith #undef __FUNCT__
8082c9581d2SBarry Smith #define __FUNCT__ "PetscStrbeginswith"
8092c9581d2SBarry Smith /*@C
8102c9581d2SBarry Smith    PetscStrbeginswith - Determines if a string begins with a certain string
8112c9581d2SBarry Smith 
8122c9581d2SBarry Smith    Not Collective
8132c9581d2SBarry Smith 
8142c9581d2SBarry Smith    Input Parameters:
8152c9581d2SBarry Smith +  a - pointer to string
8162c9581d2SBarry Smith -  b - string to beginwith
8172c9581d2SBarry Smith 
8182c9581d2SBarry Smith    Output Parameter:
8192c9581d2SBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
8202c9581d2SBarry Smith 
8212c9581d2SBarry Smith    Notes:     Not for use in Fortran
8222c9581d2SBarry Smith 
8232c9581d2SBarry Smith    Level: intermediate
8242c9581d2SBarry Smith 
8252c9581d2SBarry Smith @*/
8262c9581d2SBarry Smith PetscErrorCode  PetscStrbeginswith(const char a[],const char b[],PetscBool *flg)
8272c9581d2SBarry Smith {
8282c9581d2SBarry Smith   char           *test;
8292c9581d2SBarry Smith   PetscErrorCode ierr;
8302c9581d2SBarry Smith 
8312c9581d2SBarry Smith   PetscFunctionBegin;
8322c9581d2SBarry Smith   *flg = PETSC_FALSE;
8332c9581d2SBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
834a297a907SKarl Rupp   if (test && (test == a)) *flg = PETSC_TRUE;
8352c9581d2SBarry Smith   PetscFunctionReturn(0);
8362c9581d2SBarry Smith }
8372c9581d2SBarry Smith 
8382c9581d2SBarry Smith 
8392c9581d2SBarry Smith #undef __FUNCT__
8407ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswithwhich"
8417ba3a57cSBarry Smith /*@C
8427ba3a57cSBarry Smith    PetscStrendswithwhich - Determines if a string ends with one of several possible strings
8437ba3a57cSBarry Smith 
8447ba3a57cSBarry Smith    Not Collective
8457ba3a57cSBarry Smith 
8467ba3a57cSBarry Smith    Input Parameters:
8477ba3a57cSBarry Smith +  a - pointer to string
8487ba3a57cSBarry Smith -  bs - strings to endwith (last entry must be null)
8497ba3a57cSBarry Smith 
8507ba3a57cSBarry Smith    Output Parameter:
8517ba3a57cSBarry Smith .  cnt - the index of the string it ends with or 1+the last possible index
8527ba3a57cSBarry Smith 
8537ba3a57cSBarry Smith    Notes:     Not for use in Fortran
8547ba3a57cSBarry Smith 
8557ba3a57cSBarry Smith    Level: intermediate
8567ba3a57cSBarry Smith 
8577ba3a57cSBarry Smith @*/
8587ba3a57cSBarry Smith PetscErrorCode  PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt)
8597ba3a57cSBarry Smith {
8607ba3a57cSBarry Smith   PetscBool      flg;
8617ba3a57cSBarry Smith   PetscErrorCode ierr;
8627ba3a57cSBarry Smith 
8637ba3a57cSBarry Smith   PetscFunctionBegin;
8647ba3a57cSBarry Smith   *cnt = 0;
8657ba3a57cSBarry Smith   while (bs[*cnt]) {
8667ba3a57cSBarry Smith     ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr);
8677ba3a57cSBarry Smith     if (flg) PetscFunctionReturn(0);
8687ba3a57cSBarry Smith     *cnt += 1;
8697ba3a57cSBarry Smith   }
8707ba3a57cSBarry Smith   PetscFunctionReturn(0);
8717ba3a57cSBarry Smith }
8727ba3a57cSBarry Smith 
8737ba3a57cSBarry Smith #undef __FUNCT__
8747ba3a57cSBarry Smith #define __FUNCT__ "PetscStrrstr"
8757ba3a57cSBarry Smith /*@C
8767ba3a57cSBarry Smith    PetscStrrstr - Locates last occurance of string in another string
8777ba3a57cSBarry Smith 
8787ba3a57cSBarry Smith    Not Collective
8797ba3a57cSBarry Smith 
8807ba3a57cSBarry Smith    Input Parameters:
8817ba3a57cSBarry Smith +  a - pointer to string
8827ba3a57cSBarry Smith -  b - string to find
8837ba3a57cSBarry Smith 
8847ba3a57cSBarry Smith    Output Parameter:
8857ba3a57cSBarry Smith .  tmp - location of occurance
8867ba3a57cSBarry Smith 
8877ba3a57cSBarry Smith    Notes:     Not for use in Fortran
8887ba3a57cSBarry Smith 
8897ba3a57cSBarry Smith    Level: intermediate
8907ba3a57cSBarry Smith 
8917ba3a57cSBarry Smith @*/
8927ba3a57cSBarry Smith PetscErrorCode  PetscStrrstr(const char a[],const char b[],char *tmp[])
8937ba3a57cSBarry Smith {
8947ba3a57cSBarry Smith   const char *stmp = a, *ltmp = 0;
8957ba3a57cSBarry Smith 
8967ba3a57cSBarry Smith   PetscFunctionBegin;
8977ba3a57cSBarry Smith   while (stmp) {
8987ba3a57cSBarry Smith     stmp = (char*)strstr(stmp,b);
8997ba3a57cSBarry Smith     if (stmp) {ltmp = stmp;stmp++;}
9007ba3a57cSBarry Smith   }
9017ba3a57cSBarry Smith   *tmp = (char*)ltmp;
9027ba3a57cSBarry Smith   PetscFunctionReturn(0);
9037ba3a57cSBarry Smith }
9047ba3a57cSBarry Smith 
9057ba3a57cSBarry Smith #undef __FUNCT__
9067ba3a57cSBarry Smith #define __FUNCT__ "PetscStrstr"
9077ba3a57cSBarry Smith /*@C
9087ba3a57cSBarry Smith    PetscStrstr - Locates first occurance of string in another string
9097ba3a57cSBarry Smith 
9107ba3a57cSBarry Smith    Not Collective
9117ba3a57cSBarry Smith 
9127ba3a57cSBarry Smith    Input Parameters:
913160f4796SJed Brown +  haystack - string to search
914160f4796SJed Brown -  needle - string to find
9157ba3a57cSBarry Smith 
9167ba3a57cSBarry Smith    Output Parameter:
9170298fd71SBarry Smith .  tmp - location of occurance, is a NULL if the string is not found
9187ba3a57cSBarry Smith 
9197ba3a57cSBarry Smith    Notes: Not for use in Fortran
9207ba3a57cSBarry Smith 
9217ba3a57cSBarry Smith    Level: intermediate
9227ba3a57cSBarry Smith 
9237ba3a57cSBarry Smith @*/
924160f4796SJed Brown PetscErrorCode  PetscStrstr(const char haystack[],const char needle[],char *tmp[])
9257ba3a57cSBarry Smith {
9267ba3a57cSBarry Smith   PetscFunctionBegin;
927160f4796SJed Brown   *tmp = (char*)strstr(haystack,needle);
9287ba3a57cSBarry Smith   PetscFunctionReturn(0);
9297ba3a57cSBarry Smith }
9307ba3a57cSBarry Smith 
9317ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
9321d1a0024SBarry Smith 
933e5c89e4eSSatish Balay #undef __FUNCT__
934e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenFind"
935e5c89e4eSSatish Balay /*@C
936e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
937e5c89e4eSSatish Balay 
938e5c89e4eSSatish Balay    Not Collective
939e5c89e4eSSatish Balay 
940e5c89e4eSSatish Balay    Input Parameters:
941e5c89e4eSSatish Balay .  a - pointer to token
942e5c89e4eSSatish Balay 
943e5c89e4eSSatish Balay    Output Parameter:
9440298fd71SBarry Smith .  result - location of occurance, NULL if not found
945e5c89e4eSSatish Balay 
946e5c89e4eSSatish Balay    Notes:
947e5c89e4eSSatish Balay 
948e5c89e4eSSatish Balay      This version is different from the system version in that
949e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
950e5c89e4eSSatish Balay 
9514704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
9524704e885SBarry Smith    as a single token.
9534704e885SBarry Smith 
9543a9c465aSBarry 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
9553a9c465aSBarry Smith    second will return a null terminated y
9563a9c465aSBarry Smith 
9573a9c465aSBarry 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
9583a9c465aSBarry Smith 
9596f013253SBarry Smith     Not for use in Fortran
9606f013253SBarry Smith 
961e5c89e4eSSatish Balay    Level: intermediate
962e5c89e4eSSatish Balay 
9636f013253SBarry Smith 
964e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
965e5c89e4eSSatish Balay @*/
9667087cfbeSBarry Smith PetscErrorCode  PetscTokenFind(PetscToken a,char *result[])
967e5c89e4eSSatish Balay {
9684704e885SBarry Smith   char *ptr = a->current,token;
969e5c89e4eSSatish Balay 
970e5c89e4eSSatish Balay   PetscFunctionBegin;
971e5c89e4eSSatish Balay   *result = a->current;
9724704e885SBarry Smith   if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);}
9734704e885SBarry Smith   token = a->token;
97490fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
975e5c89e4eSSatish Balay   while (ptr) {
9764704e885SBarry Smith     if (*ptr == token) {
977e5c89e4eSSatish Balay       *ptr++ = 0;
978e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
979e5c89e4eSSatish Balay       a->current = ptr;
980e5c89e4eSSatish Balay       break;
981e5c89e4eSSatish Balay     }
982e5c89e4eSSatish Balay     if (!*ptr) {
983e5c89e4eSSatish Balay       a->current = 0;
984e5c89e4eSSatish Balay       break;
985e5c89e4eSSatish Balay     }
986e5c89e4eSSatish Balay     ptr++;
987e5c89e4eSSatish Balay   }
988e5c89e4eSSatish Balay   PetscFunctionReturn(0);
989e5c89e4eSSatish Balay }
990e5c89e4eSSatish Balay 
991e5c89e4eSSatish Balay #undef __FUNCT__
992e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenCreate"
993e5c89e4eSSatish Balay /*@C
994e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
995e5c89e4eSSatish Balay 
996e5c89e4eSSatish Balay    Not Collective
997e5c89e4eSSatish Balay 
998e5c89e4eSSatish Balay    Input Parameters:
999e5c89e4eSSatish Balay +  string - the string to look in
10003a9c465aSBarry Smith -  b - the separator character
1001e5c89e4eSSatish Balay 
1002e5c89e4eSSatish Balay    Output Parameter:
10033a9c465aSBarry Smith .  t- the token object
1004e5c89e4eSSatish Balay 
1005e5c89e4eSSatish Balay    Notes:
1006e5c89e4eSSatish Balay 
1007e5c89e4eSSatish Balay      This version is different from the system version in that
1008e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
1009e5c89e4eSSatish Balay 
10106f013253SBarry Smith     Not for use in Fortran
10116f013253SBarry Smith 
1012e5c89e4eSSatish Balay    Level: intermediate
1013e5c89e4eSSatish Balay 
1014e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
1015e5c89e4eSSatish Balay @*/
10167087cfbeSBarry Smith PetscErrorCode  PetscTokenCreate(const char a[],const char b,PetscToken *t)
1017e5c89e4eSSatish Balay {
1018e5c89e4eSSatish Balay   PetscErrorCode ierr;
1019e5c89e4eSSatish Balay 
1020e5c89e4eSSatish Balay   PetscFunctionBegin;
1021b00a9115SJed Brown   ierr = PetscNew(t);CHKERRQ(ierr);
1022e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
1023a297a907SKarl Rupp 
1024e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
1025e5c89e4eSSatish Balay   (*t)->token   = b;
1026e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1027e5c89e4eSSatish Balay }
1028e5c89e4eSSatish Balay 
1029e5c89e4eSSatish Balay #undef __FUNCT__
1030e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenDestroy"
1031e5c89e4eSSatish Balay /*@C
1032e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
1033e5c89e4eSSatish Balay 
1034e5c89e4eSSatish Balay    Not Collective
1035e5c89e4eSSatish Balay 
1036e5c89e4eSSatish Balay    Input Parameters:
1037e5c89e4eSSatish Balay .  a - pointer to token
1038e5c89e4eSSatish Balay 
1039e5c89e4eSSatish Balay    Level: intermediate
1040e5c89e4eSSatish Balay 
10416f013253SBarry Smith    Notes:     Not for use in Fortran
10426f013253SBarry Smith 
1043e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
1044e5c89e4eSSatish Balay @*/
10458c74ee41SBarry Smith PetscErrorCode  PetscTokenDestroy(PetscToken *a)
1046e5c89e4eSSatish Balay {
1047e5c89e4eSSatish Balay   PetscErrorCode ierr;
1048e5c89e4eSSatish Balay 
1049e5c89e4eSSatish Balay   PetscFunctionBegin;
10508c74ee41SBarry Smith   if (!*a) PetscFunctionReturn(0);
10518c74ee41SBarry Smith   ierr = PetscFree((*a)->array);CHKERRQ(ierr);
10528c74ee41SBarry Smith   ierr = PetscFree(*a);CHKERRQ(ierr);
1053e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1054e5c89e4eSSatish Balay }
1055e5c89e4eSSatish Balay 
1056e5c89e4eSSatish Balay 
1057e5c89e4eSSatish Balay #undef __FUNCT__
1058e5c89e4eSSatish Balay #define __FUNCT__ "PetscGetPetscDir"
1059e5c89e4eSSatish Balay /*@C
1060e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
1061e5c89e4eSSatish Balay 
1062e5c89e4eSSatish Balay    Not Collective
1063e5c89e4eSSatish Balay 
1064e5c89e4eSSatish Balay    Output Parameter:
1065e5c89e4eSSatish Balay .  dir - the directory
1066e5c89e4eSSatish Balay 
1067e5c89e4eSSatish Balay    Level: developer
1068e5c89e4eSSatish Balay 
10696f013253SBarry Smith    Notes: Not for use in Fortran
10706f013253SBarry Smith 
1071e5c89e4eSSatish Balay @*/
10727087cfbeSBarry Smith PetscErrorCode  PetscGetPetscDir(const char *dir[])
1073e5c89e4eSSatish Balay {
1074e5c89e4eSSatish Balay   PetscFunctionBegin;
1075e5c89e4eSSatish Balay   *dir = PETSC_DIR;
1076e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1077e5c89e4eSSatish Balay }
1078e5c89e4eSSatish Balay 
1079e5c89e4eSSatish Balay #undef __FUNCT__
1080e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrreplace"
1081e5c89e4eSSatish Balay /*@C
1082e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
1083e5c89e4eSSatish Balay 
1084e5c89e4eSSatish Balay    Not Collective
1085e5c89e4eSSatish Balay 
1086e5c89e4eSSatish Balay    Input Parameters:
1087e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
108871573d7dSBarry Smith .   aa - the string to look in
1089d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
1090e5c89e4eSSatish Balay -   len - the length of b
1091e5c89e4eSSatish Balay 
1092e5c89e4eSSatish Balay    Notes:
1093e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
1094d5649816SBarry Smith       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
1095e5c89e4eSSatish Balay       as well as any environmental variables.
1096e5c89e4eSSatish Balay 
10976f013253SBarry Smith       PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
1098acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
1099acc6cc86SBarry Smith 
11006f013253SBarry Smith       Not for use in Fortran
11016f013253SBarry Smith 
1102e5c89e4eSSatish Balay    Level: intermediate
1103e5c89e4eSSatish Balay 
1104e5c89e4eSSatish Balay @*/
11057087cfbeSBarry Smith PetscErrorCode  PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
1106e5c89e4eSSatish Balay {
1107e5c89e4eSSatish Balay   PetscErrorCode ierr;
1108e5c89e4eSSatish Balay   int            i = 0;
1109e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
111071573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
1111d5649816SBarry Smith   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0};
1112d5649816SBarry Smith   const char     *r[] = {0,0,0,0,0,0,0,0,0};
1113ace3abfcSBarry Smith   PetscBool      flag;
1114e5c89e4eSSatish Balay 
1115e5c89e4eSSatish Balay   PetscFunctionBegin;
1116e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
111771573d7dSBarry Smith   if (aa == b) {
111822982a5fSBarry Smith     ierr = PetscStrallocpy(aa,(char**)&a);CHKERRQ(ierr);
111971573d7dSBarry Smith   }
1120785e854fSJed Brown   ierr = PetscMalloc1(len,&work);CHKERRQ(ierr);
1121e5c89e4eSSatish Balay 
1122e5c89e4eSSatish Balay   /* get values for replaced variables */
1123487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr);
1124487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr);
1125487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr);
1126785e854fSJed Brown   ierr = PetscMalloc1(256,&r[3]);CHKERRQ(ierr);
1127785e854fSJed Brown   ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[4]);CHKERRQ(ierr);
1128785e854fSJed Brown   ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[5]);CHKERRQ(ierr);
1129785e854fSJed Brown   ierr = PetscMalloc1(256,&r[6]);CHKERRQ(ierr);
1130785e854fSJed Brown   ierr = PetscMalloc1(256,&r[7]);CHKERRQ(ierr);
1131487e5849SBarry Smith   ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr);
1132487e5849SBarry Smith   ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1133487e5849SBarry Smith   ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1134487e5849SBarry Smith   ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr);
1135d5649816SBarry Smith   ierr = PetscGetHostName((char*)r[7],256);CHKERRQ(ierr);
1136487e5849SBarry Smith 
1137487e5849SBarry Smith   /* replace that are in environment */
1138487e5849SBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr);
1139487e5849SBarry Smith   if (flag) {
114031936d58SMatthew G. Knepley     ierr = PetscFree(r[2]);CHKERRQ(ierr);
1141487e5849SBarry Smith     ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr);
1142487e5849SBarry Smith   }
1143e5c89e4eSSatish Balay 
1144e5c89e4eSSatish Balay   /* replace the requested strings */
1145e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
1146e5c89e4eSSatish Balay   while (s[i]) {
1147e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
1148e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1149e5c89e4eSSatish Balay     while (par) {
1150e5c89e4eSSatish Balay       *par =  0;
1151e5c89e4eSSatish Balay       par += l;
1152e5c89e4eSSatish Balay 
1153e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
1154e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
1155e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
115617186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
1157e5c89e4eSSatish Balay       ierr = PetscStrcpy(work,b);CHKERRQ(ierr);
1158e5c89e4eSSatish Balay       ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr);
1159e5c89e4eSSatish Balay       ierr = PetscStrcat(work,par);CHKERRQ(ierr);
1160e5c89e4eSSatish Balay       ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr);
1161e5c89e4eSSatish Balay       ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1162e5c89e4eSSatish Balay     }
1163e5c89e4eSSatish Balay     i++;
1164e5c89e4eSSatish Balay   }
1165487e5849SBarry Smith   i = 0;
1166487e5849SBarry Smith   while (r[i]) {
1167e5c89e4eSSatish Balay     tfree = (char*)r[i];
1168e5c89e4eSSatish Balay     ierr  = PetscFree(tfree);CHKERRQ(ierr);
1169487e5849SBarry Smith     i++;
1170e5c89e4eSSatish Balay   }
1171e5c89e4eSSatish Balay 
1172e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
1173e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1174e5c89e4eSSatish Balay   while (par) {
1175e5c89e4eSSatish Balay     *par  = 0;
1176e5c89e4eSSatish Balay     par  += 2;
1177e5c89e4eSSatish Balay     ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
1178e5c89e4eSSatish Balay     ierr  = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
1179e5c89e4eSSatish Balay     *epar = 0;
1180e5c89e4eSSatish Balay     epar += 1;
1181e5c89e4eSSatish Balay     ierr  = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr);
11827ba3a57cSBarry Smith     if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
1183e5c89e4eSSatish Balay     ierr = PetscStrcat(work,env);CHKERRQ(ierr);
1184e5c89e4eSSatish Balay     ierr = PetscStrcat(work,epar);CHKERRQ(ierr);
1185e5c89e4eSSatish Balay     ierr = PetscStrcpy(b,work);CHKERRQ(ierr);
1186e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1187e5c89e4eSSatish Balay   }
1188e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
118971573d7dSBarry Smith   if (aa == b) {
119071573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
119171573d7dSBarry Smith   }
1192e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1193e5c89e4eSSatish Balay }
1194e5c89e4eSSatish Balay 
1195a53986e1SJed Brown #undef __FUNCT__
1196a53986e1SJed Brown #define __FUNCT__ "PetscEListFind"
1197a53986e1SJed Brown /*@C
1198a53986e1SJed Brown    PetscEListFind - searches list of strings for given string, using case insensitive matching
1199e5c89e4eSSatish Balay 
1200a53986e1SJed Brown    Not Collective
1201a53986e1SJed Brown 
1202a53986e1SJed Brown    Input Parameters:
1203a53986e1SJed Brown +  n - number of strings in
1204a53986e1SJed Brown .  list - list of strings to search
1205a53986e1SJed Brown -  str - string to look for, empty string "" accepts default (first entry in list)
1206a53986e1SJed Brown 
1207a53986e1SJed Brown    Output Parameters:
1208a53986e1SJed Brown +  value - index of matching string (if found)
1209a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1210a53986e1SJed Brown 
1211a53986e1SJed Brown    Notes:
1212a53986e1SJed Brown    Not for use in Fortran
1213a53986e1SJed Brown 
1214a53986e1SJed Brown    Level: advanced
1215a53986e1SJed Brown @*/
1216a53986e1SJed Brown PetscErrorCode PetscEListFind(PetscInt n,const char *const *list,const char *str,PetscInt *value,PetscBool *found)
1217a53986e1SJed Brown {
1218a53986e1SJed Brown   PetscErrorCode ierr;
1219a53986e1SJed Brown   PetscBool matched;
1220a53986e1SJed Brown   PetscInt i;
1221a53986e1SJed Brown 
1222a53986e1SJed Brown   PetscFunctionBegin;
1223a53986e1SJed Brown   if (found) *found = PETSC_FALSE;
1224a53986e1SJed Brown   for (i=0; i<n; i++) {
1225a53986e1SJed Brown     ierr = PetscStrcasecmp(str,list[i],&matched);CHKERRQ(ierr);
1226a53986e1SJed Brown     if (matched || !str[0]) {
1227a53986e1SJed Brown       if (found) *found = PETSC_TRUE;
1228a53986e1SJed Brown       *value = i;
1229a53986e1SJed Brown       break;
1230a53986e1SJed Brown     }
1231a53986e1SJed Brown   }
1232a53986e1SJed Brown   PetscFunctionReturn(0);
1233a53986e1SJed Brown }
1234a53986e1SJed Brown 
1235a53986e1SJed Brown #undef __FUNCT__
1236a53986e1SJed Brown #define __FUNCT__ "PetscEnumFind"
1237a53986e1SJed Brown /*@C
1238a53986e1SJed Brown    PetscEListFind - searches enum list of strings for given string, using case insensitive matching
1239a53986e1SJed Brown 
1240a53986e1SJed Brown    Not Collective
1241a53986e1SJed Brown 
1242a53986e1SJed Brown    Input Parameters:
1243a53986e1SJed Brown +  enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL
1244a53986e1SJed Brown -  str - string to look for
1245a53986e1SJed Brown 
1246a53986e1SJed Brown    Output Parameters:
1247a53986e1SJed Brown +  value - index of matching string (if found)
1248a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1249a53986e1SJed Brown 
1250a53986e1SJed Brown    Notes:
1251a53986e1SJed Brown    Not for use in Fortran
1252a53986e1SJed Brown 
1253a53986e1SJed Brown    Level: advanced
1254a53986e1SJed Brown @*/
1255a53986e1SJed Brown PetscErrorCode PetscEnumFind(const char *const *enumlist,const char *str,PetscEnum *value,PetscBool *found)
1256a53986e1SJed Brown {
1257a53986e1SJed Brown   PetscErrorCode ierr;
1258d05ba7d2SLisandro Dalcin   PetscInt n = 0,evalue;
1259a53986e1SJed Brown   PetscBool efound;
1260a53986e1SJed Brown 
1261a53986e1SJed Brown   PetscFunctionBegin;
1262d05ba7d2SLisandro 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");
1263a53986e1SJed Brown   if (n < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
1264a53986e1SJed Brown   n -= 3; /* drop enum name, prefix, and null termination */
1265a53986e1SJed Brown   ierr = PetscEListFind(n,enumlist,str,&evalue,&efound);CHKERRQ(ierr);
1266cfb463b1SJed Brown   if (efound) *value = (PetscEnum)evalue;
1267a53986e1SJed Brown   if (found) *found = efound;
1268a53986e1SJed Brown   PetscFunctionReturn(0);
1269a53986e1SJed Brown }
1270