xref: /petsc/src/sys/utils/str.c (revision 6991f827c8a892fc5b642fee1563a9b520cca98c)
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
19d67fe73bSBarry Smith    PetscStrToArray - Seperates 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;
514996c5bdSBarry Smith   if (!n) {
524996c5bdSBarry Smith     *args = 0;
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   }
62a2ea699eSBarry Smith   (*args) = (char**) malloc(((*argc)+1)*sizeof(char*)); if (!*args) return PETSC_ERR_MEM;
6353e6e2c4SHong Zhang   lens    = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM;
643c311c98SBarry Smith   for (i=0; i<*argc; i++) lens[i] = 0;
653c311c98SBarry Smith 
663c311c98SBarry Smith   *argc = 0;
673c311c98SBarry Smith   for (i=0; i<n; i++) {
68d67fe73bSBarry Smith     if (s[i] != sp) break;
693c311c98SBarry Smith   }
703c311c98SBarry Smith   for (;i<n+1; i++) {
71d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
72d67fe73bSBarry Smith     else if (s[i] != sp) {lens[*argc]++;flg = PETSC_FALSE;}
733c311c98SBarry Smith   }
743c311c98SBarry Smith 
753c311c98SBarry Smith   for (i=0; i<*argc; i++) {
76675282fdSHong Zhang     (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char)); if (!(*args)[i]) return PETSC_ERR_MEM;
773c311c98SBarry Smith   }
78a2ea699eSBarry Smith   free(lens);
79301d30feSBarry Smith   (*args)[*argc] = 0;
803c311c98SBarry Smith 
813c311c98SBarry Smith   *argc = 0;
823c311c98SBarry Smith   for (i=0; i<n; i++) {
83d67fe73bSBarry Smith     if (s[i] != sp) break;
843c311c98SBarry Smith   }
853c311c98SBarry Smith   for (;i<n+1; i++) {
86d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
87d67fe73bSBarry Smith     else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;}
883c311c98SBarry Smith   }
893c311c98SBarry Smith   return 0;
903c311c98SBarry Smith }
913c311c98SBarry Smith 
923c311c98SBarry Smith #undef __FUNCT__
93301d30feSBarry Smith #define __FUNCT__ "PetscStrToArrayDestroy"
94301d30feSBarry Smith /*@C
95301d30feSBarry Smith    PetscStrToArrayDestroy - Frees array created with PetscStrToArray().
96301d30feSBarry Smith 
97301d30feSBarry Smith    Not Collective
98301d30feSBarry Smith 
99301d30feSBarry Smith    Output Parameters:
100301d30feSBarry Smith +  argc - the number of arguments
101301d30feSBarry Smith -  args - the array of arguments
102301d30feSBarry Smith 
103301d30feSBarry Smith    Level: intermediate
104301d30feSBarry Smith 
105301d30feSBarry Smith    Concepts: command line arguments
106301d30feSBarry Smith 
107301d30feSBarry Smith    Notes: This may be called before PetscInitialize() or after PetscFinalize()
108301d30feSBarry Smith 
1096f013253SBarry Smith    Not for use in Fortran
1106f013253SBarry Smith 
111301d30feSBarry Smith .seealso: PetscStrToArray()
112301d30feSBarry Smith 
113301d30feSBarry Smith @*/
1147087cfbeSBarry Smith PetscErrorCode  PetscStrToArrayDestroy(int argc,char **args)
115301d30feSBarry Smith {
116301d30feSBarry Smith   PetscInt i;
117301d30feSBarry Smith 
118a297a907SKarl Rupp   for (i=0; i<argc; i++) free(args[i]);
119a297a907SKarl Rupp   if (args) free(args);
120301d30feSBarry Smith   return 0;
121301d30feSBarry Smith }
122301d30feSBarry Smith 
123301d30feSBarry Smith #undef __FUNCT__
124e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrlen"
125e5c89e4eSSatish Balay /*@C
126e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
127e5c89e4eSSatish Balay 
128e5c89e4eSSatish Balay    Not Collective
129e5c89e4eSSatish Balay 
130e5c89e4eSSatish Balay    Input Parameters:
131e5c89e4eSSatish Balay .  s - pointer to string
132e5c89e4eSSatish Balay 
133e5c89e4eSSatish Balay    Output Parameter:
134e5c89e4eSSatish Balay .  len - length in bytes
135e5c89e4eSSatish Balay 
136e5c89e4eSSatish Balay    Level: intermediate
137e5c89e4eSSatish Balay 
138e5c89e4eSSatish Balay    Note:
139e5c89e4eSSatish Balay    This routine is analogous to strlen().
140e5c89e4eSSatish Balay 
141e5c89e4eSSatish Balay    Null string returns a length of zero
142e5c89e4eSSatish Balay 
1436f013253SBarry Smith    Not for use in Fortran
1446f013253SBarry Smith 
145e5c89e4eSSatish Balay   Concepts: string length
146e5c89e4eSSatish Balay 
147e5c89e4eSSatish Balay @*/
1487087cfbeSBarry Smith PetscErrorCode  PetscStrlen(const char s[],size_t *len)
149e5c89e4eSSatish Balay {
150e5c89e4eSSatish Balay   PetscFunctionBegin;
151a297a907SKarl Rupp   if (!s) *len = 0;
152a297a907SKarl Rupp   else    *len = strlen(s);
153e5c89e4eSSatish Balay   PetscFunctionReturn(0);
154e5c89e4eSSatish Balay }
155e5c89e4eSSatish Balay 
156e5c89e4eSSatish Balay #undef __FUNCT__
157e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrallocpy"
158e5c89e4eSSatish Balay /*@C
159e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
160e5c89e4eSSatish Balay 
161e5c89e4eSSatish Balay    Not Collective
162e5c89e4eSSatish Balay 
163e5c89e4eSSatish Balay    Input Parameters:
164e5c89e4eSSatish Balay .  s - pointer to string
165e5c89e4eSSatish Balay 
166e5c89e4eSSatish Balay    Output Parameter:
167e5c89e4eSSatish Balay .  t - the copied string
168e5c89e4eSSatish Balay 
169e5c89e4eSSatish Balay    Level: intermediate
170e5c89e4eSSatish Balay 
171e5c89e4eSSatish Balay    Note:
172e5c89e4eSSatish Balay       Null string returns a new null string
173e5c89e4eSSatish Balay 
1746f013253SBarry Smith       Not for use in Fortran
1756f013253SBarry Smith 
176e5c89e4eSSatish Balay   Concepts: string copy
177e5c89e4eSSatish Balay 
178e5c89e4eSSatish Balay @*/
1797087cfbeSBarry Smith PetscErrorCode  PetscStrallocpy(const char s[],char *t[])
180e5c89e4eSSatish Balay {
181e5c89e4eSSatish Balay   PetscErrorCode ierr;
182e5c89e4eSSatish Balay   size_t         len;
18371573d7dSBarry Smith   char           *tmp = 0;
184e5c89e4eSSatish Balay 
185e5c89e4eSSatish Balay   PetscFunctionBegin;
186e5c89e4eSSatish Balay   if (s) {
187e5c89e4eSSatish Balay     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
188854ce69bSBarry Smith     ierr = PetscMalloc1(1+len,&tmp);CHKERRQ(ierr);
18971573d7dSBarry Smith     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
190e5c89e4eSSatish Balay   }
19171573d7dSBarry Smith   *t = tmp;
192e5c89e4eSSatish Balay   PetscFunctionReturn(0);
193e5c89e4eSSatish Balay }
194e5c89e4eSSatish Balay 
195e5c89e4eSSatish Balay #undef __FUNCT__
19647340559SBarry Smith #define __FUNCT__ "PetscStrArrayallocpy"
19747340559SBarry Smith /*@C
19847340559SBarry Smith    PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
19947340559SBarry Smith 
20047340559SBarry Smith    Not Collective
20147340559SBarry Smith 
20247340559SBarry Smith    Input Parameters:
20347340559SBarry Smith .  s - pointer to array of strings (final string is a null)
20447340559SBarry Smith 
20547340559SBarry Smith    Output Parameter:
20647340559SBarry Smith .  t - the copied array string
20747340559SBarry Smith 
20847340559SBarry Smith    Level: intermediate
20947340559SBarry Smith 
21047340559SBarry Smith    Note:
21147340559SBarry Smith       Not for use in Fortran
21247340559SBarry Smith 
21347340559SBarry Smith   Concepts: string copy
21447340559SBarry Smith 
21547340559SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
21647340559SBarry Smith 
21747340559SBarry Smith @*/
21847340559SBarry Smith PetscErrorCode  PetscStrArrayallocpy(const char *const *list,char ***t)
21947340559SBarry Smith {
22047340559SBarry Smith   PetscErrorCode ierr;
22147340559SBarry Smith   PetscInt       i,n = 0;
22247340559SBarry Smith 
22347340559SBarry Smith   PetscFunctionBegin;
22447340559SBarry Smith   while (list[n++]) ;
225854ce69bSBarry Smith   ierr = PetscMalloc1(n+1,t);CHKERRQ(ierr);
22647340559SBarry Smith   for (i=0; i<n; i++) {
22747340559SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
22847340559SBarry Smith   }
2290298fd71SBarry Smith   (*t)[n] = NULL;
23047340559SBarry Smith   PetscFunctionReturn(0);
23147340559SBarry Smith }
23247340559SBarry Smith 
23347340559SBarry Smith #undef __FUNCT__
23447340559SBarry Smith #define __FUNCT__ "PetscStrArrayDestroy"
23547340559SBarry Smith /*@C
23647340559SBarry Smith    PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
23747340559SBarry Smith 
23847340559SBarry Smith    Not Collective
23947340559SBarry Smith 
24047340559SBarry Smith    Output Parameters:
24147340559SBarry Smith .   list - array of strings
24247340559SBarry Smith 
24347340559SBarry Smith    Level: intermediate
24447340559SBarry Smith 
24547340559SBarry Smith    Concepts: command line arguments
24647340559SBarry Smith 
24747340559SBarry Smith    Notes: Not for use in Fortran
24847340559SBarry Smith 
24947340559SBarry Smith .seealso: PetscStrArrayallocpy()
25047340559SBarry Smith 
25147340559SBarry Smith @*/
2526fed8037SJed Brown PetscErrorCode PetscStrArrayDestroy(char ***list)
25347340559SBarry Smith {
25447340559SBarry Smith   PetscInt       n = 0;
25547340559SBarry Smith   PetscErrorCode ierr;
25647340559SBarry Smith 
2576fed8037SJed Brown   PetscFunctionBegin;
2586fed8037SJed Brown   if (!*list) PetscFunctionReturn(0);
2596fed8037SJed Brown   while ((*list)[n]) {
2606fed8037SJed Brown     ierr = PetscFree((*list)[n]);CHKERRQ(ierr);
26147340559SBarry Smith     n++;
26247340559SBarry Smith   }
2636fed8037SJed Brown   ierr = PetscFree(*list);CHKERRQ(ierr);
2646fed8037SJed Brown   PetscFunctionReturn(0);
26547340559SBarry Smith }
26647340559SBarry Smith 
26747340559SBarry Smith #undef __FUNCT__
268*6991f827SBarry Smith #define __FUNCT__ "PetscStrNArrayallocpy"
269*6991f827SBarry Smith /*@C
270*6991f827SBarry Smith    PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
271*6991f827SBarry Smith 
272*6991f827SBarry Smith    Not Collective
273*6991f827SBarry Smith 
274*6991f827SBarry Smith    Input Parameters:
275*6991f827SBarry Smith +  n - the number of string entries
276*6991f827SBarry Smith -  s - pointer to array of strings
277*6991f827SBarry Smith 
278*6991f827SBarry Smith    Output Parameter:
279*6991f827SBarry Smith .  t - the copied array string
280*6991f827SBarry Smith 
281*6991f827SBarry Smith    Level: intermediate
282*6991f827SBarry Smith 
283*6991f827SBarry Smith    Note:
284*6991f827SBarry Smith       Not for use in Fortran
285*6991f827SBarry Smith 
286*6991f827SBarry Smith   Concepts: string copy
287*6991f827SBarry Smith 
288*6991f827SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
289*6991f827SBarry Smith 
290*6991f827SBarry Smith @*/
291*6991f827SBarry Smith PetscErrorCode  PetscStrNArrayallocpy(PetscInt n,const char *const *list,char ***t)
292*6991f827SBarry Smith {
293*6991f827SBarry Smith   PetscErrorCode ierr;
294*6991f827SBarry Smith   PetscInt       i;
295*6991f827SBarry Smith 
296*6991f827SBarry Smith   PetscFunctionBegin;
297*6991f827SBarry Smith   ierr = PetscMalloc1(n,t);CHKERRQ(ierr);
298*6991f827SBarry Smith   for (i=0; i<n; i++) {
299*6991f827SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
300*6991f827SBarry Smith   }
301*6991f827SBarry Smith   PetscFunctionReturn(0);
302*6991f827SBarry Smith }
303*6991f827SBarry Smith 
304*6991f827SBarry Smith #undef __FUNCT__
305*6991f827SBarry Smith #define __FUNCT__ "PetscStrNArrayDestroy"
306*6991f827SBarry Smith /*@C
307*6991f827SBarry Smith    PetscStrNArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
308*6991f827SBarry Smith 
309*6991f827SBarry Smith    Not Collective
310*6991f827SBarry Smith 
311*6991f827SBarry Smith    Output Parameters:
312*6991f827SBarry Smith +   n - number of string entries
313*6991f827SBarry Smith -   list - array of strings
314*6991f827SBarry Smith 
315*6991f827SBarry Smith    Level: intermediate
316*6991f827SBarry Smith 
317*6991f827SBarry Smith    Notes: Not for use in Fortran
318*6991f827SBarry Smith 
319*6991f827SBarry Smith .seealso: PetscStrArrayallocpy()
320*6991f827SBarry Smith 
321*6991f827SBarry Smith @*/
322*6991f827SBarry Smith PetscErrorCode PetscStrNArrayDestroy(PetscInt n,char ***list)
323*6991f827SBarry Smith {
324*6991f827SBarry Smith   PetscErrorCode ierr;
325*6991f827SBarry Smith   PetscInt       i;
326*6991f827SBarry Smith 
327*6991f827SBarry Smith   PetscFunctionBegin;
328*6991f827SBarry Smith   if (!*list) PetscFunctionReturn(0);
329*6991f827SBarry Smith   for (i=0; i<n; i++){
330*6991f827SBarry Smith     ierr = PetscFree((*list)[i]);CHKERRQ(ierr);
331*6991f827SBarry Smith   }
332*6991f827SBarry Smith   ierr = PetscFree(*list);CHKERRQ(ierr);
333*6991f827SBarry Smith   PetscFunctionReturn(0);
334*6991f827SBarry Smith }
335*6991f827SBarry Smith 
336*6991f827SBarry Smith #undef __FUNCT__
337e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcpy"
338e5c89e4eSSatish Balay /*@C
339e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
340e5c89e4eSSatish Balay 
341e5c89e4eSSatish Balay    Not Collective
342e5c89e4eSSatish Balay 
343e5c89e4eSSatish Balay    Input Parameters:
344e5c89e4eSSatish Balay .  t - pointer to string
345e5c89e4eSSatish Balay 
346e5c89e4eSSatish Balay    Output Parameter:
347e5c89e4eSSatish Balay .  s - the copied string
348e5c89e4eSSatish Balay 
349e5c89e4eSSatish Balay    Level: intermediate
350e5c89e4eSSatish Balay 
3516f013253SBarry Smith    Notes:
352e5c89e4eSSatish Balay      Null string returns a string starting with zero
353e5c89e4eSSatish Balay 
3546f013253SBarry Smith      Not for use in Fortran
3556f013253SBarry Smith 
356e5c89e4eSSatish Balay   Concepts: string copy
357e5c89e4eSSatish Balay 
358e5c89e4eSSatish Balay .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat()
359e5c89e4eSSatish Balay 
360e5c89e4eSSatish Balay @*/
361acc6cc86SBarry Smith 
3627087cfbeSBarry Smith PetscErrorCode  PetscStrcpy(char s[],const char t[])
363e5c89e4eSSatish Balay {
364e5c89e4eSSatish Balay   PetscFunctionBegin;
36517186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
366a297a907SKarl Rupp   if (t) strcpy(s,t);
367a297a907SKarl Rupp   else if (s) s[0] = 0;
368e5c89e4eSSatish Balay   PetscFunctionReturn(0);
369e5c89e4eSSatish Balay }
370e5c89e4eSSatish Balay 
371e5c89e4eSSatish Balay #undef __FUNCT__
372e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncpy"
373e5c89e4eSSatish Balay /*@C
374e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
375e5c89e4eSSatish Balay 
376e5c89e4eSSatish Balay    Not Collective
377e5c89e4eSSatish Balay 
378e5c89e4eSSatish Balay    Input Parameters:
379e5c89e4eSSatish Balay +  t - pointer to string
380e5c89e4eSSatish Balay -  n - the length to copy
381e5c89e4eSSatish Balay 
382e5c89e4eSSatish Balay    Output Parameter:
383e5c89e4eSSatish Balay .  s - the copied string
384e5c89e4eSSatish Balay 
385e5c89e4eSSatish Balay    Level: intermediate
386e5c89e4eSSatish Balay 
387e5c89e4eSSatish Balay    Note:
388e5c89e4eSSatish Balay      Null string returns a string starting with zero
389e5c89e4eSSatish Balay 
390ff32304bSBarry Smith      If the string that is being copied is of length n or larger then the entire string is not
391ff32304bSBarry Smith      copied and the file location of s is set to NULL. This is different then the behavior of
392ff32304bSBarry Smith      strncpy() which leaves s non-terminated.
393ff32304bSBarry Smith 
394e5c89e4eSSatish Balay   Concepts: string copy
395e5c89e4eSSatish Balay 
396e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat()
397e5c89e4eSSatish Balay 
398e5c89e4eSSatish Balay @*/
3997087cfbeSBarry Smith PetscErrorCode  PetscStrncpy(char s[],const char t[],size_t n)
400e5c89e4eSSatish Balay {
401e5c89e4eSSatish Balay   PetscFunctionBegin;
40217186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
403ff32304bSBarry Smith   if (t) {
4048dc57659SBarry Smith     if (n > 1) {
4052c26941aSBarry Smith       strncpy(s,t,n-1);
406ff32304bSBarry Smith       s[n-1] = '\0';
4078dc57659SBarry Smith     } else {
4088dc57659SBarry Smith       s[0] = '\0';
4098dc57659SBarry Smith     }
410ff32304bSBarry Smith   } else if (s) s[0] = 0;
411e5c89e4eSSatish Balay   PetscFunctionReturn(0);
412e5c89e4eSSatish Balay }
413e5c89e4eSSatish Balay 
414e5c89e4eSSatish Balay #undef __FUNCT__
415e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcat"
416e5c89e4eSSatish Balay /*@C
417e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
418e5c89e4eSSatish Balay 
419e5c89e4eSSatish Balay    Not Collective
420e5c89e4eSSatish Balay 
421e5c89e4eSSatish Balay    Input Parameters:
422e5e2177aSMatthew Knepley +  s - string to be added to
423e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
424e5c89e4eSSatish Balay 
425e5c89e4eSSatish Balay    Level: intermediate
426e5c89e4eSSatish Balay 
4276f013253SBarry Smith    Notes: Not for use in Fortran
4286f013253SBarry Smith 
429e5c89e4eSSatish Balay   Concepts: string copy
430e5c89e4eSSatish Balay 
431e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat()
432e5c89e4eSSatish Balay 
433e5c89e4eSSatish Balay @*/
4347087cfbeSBarry Smith PetscErrorCode  PetscStrcat(char s[],const char t[])
435e5c89e4eSSatish Balay {
436e5c89e4eSSatish Balay   PetscFunctionBegin;
4379b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
438e5c89e4eSSatish Balay   strcat(s,t);
439e5c89e4eSSatish Balay   PetscFunctionReturn(0);
440e5c89e4eSSatish Balay }
441e5c89e4eSSatish Balay 
442e5c89e4eSSatish Balay #undef __FUNCT__
443e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncat"
444e5c89e4eSSatish Balay /*@C
445e5c89e4eSSatish Balay    PetscStrncat - Concatenates a string onto a given string, up to a given length
446e5c89e4eSSatish Balay 
447e5c89e4eSSatish Balay    Not Collective
448e5c89e4eSSatish Balay 
449e5c89e4eSSatish Balay    Input Parameters:
450e5c89e4eSSatish Balay +  s - pointer to string to be added to end
451e5c89e4eSSatish Balay .  t - string to be added to
452e5c89e4eSSatish Balay .  n - maximum length to copy
453e5c89e4eSSatish Balay 
454e5c89e4eSSatish Balay    Level: intermediate
455e5c89e4eSSatish Balay 
4566f013253SBarry Smith   Notes:    Not for use in Fortran
4576f013253SBarry Smith 
458e5c89e4eSSatish Balay   Concepts: string copy
459e5c89e4eSSatish Balay 
460e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
461e5c89e4eSSatish Balay 
462e5c89e4eSSatish Balay @*/
4637087cfbeSBarry Smith PetscErrorCode  PetscStrncat(char s[],const char t[],size_t n)
464e5c89e4eSSatish Balay {
465e5c89e4eSSatish Balay   PetscFunctionBegin;
466e5c89e4eSSatish Balay   strncat(s,t,n);
467e5c89e4eSSatish Balay   PetscFunctionReturn(0);
468e5c89e4eSSatish Balay }
469e5c89e4eSSatish Balay 
470e5c89e4eSSatish Balay #undef __FUNCT__
471573b0fb4SBarry Smith #define __FUNCT__ "PetscStrcmpNoError"
472573b0fb4SBarry Smith /*
473573b0fb4SBarry Smith    Only to be used with PetscCheck__FUNCT__()!
474573b0fb4SBarry Smith 
475573b0fb4SBarry Smith    Will be removed once we eliminate the __FUNCT__ paradigm
476573b0fb4SBarry Smith */
477573b0fb4SBarry Smith void  PetscStrcmpNoError(const char a[],const char b[],PetscBool  *flg)
478573b0fb4SBarry Smith {
479573b0fb4SBarry Smith   int c;
480573b0fb4SBarry Smith 
481573b0fb4SBarry Smith   if (!a && !b)      *flg = PETSC_TRUE;
482573b0fb4SBarry Smith   else if (!a || !b) *flg = PETSC_FALSE;
483573b0fb4SBarry Smith   else {
484573b0fb4SBarry Smith     c = strcmp(a,b);
485573b0fb4SBarry Smith     if (c) *flg = PETSC_FALSE;
486573b0fb4SBarry Smith     else   *flg = PETSC_TRUE;
487573b0fb4SBarry Smith   }
488573b0fb4SBarry Smith }
489573b0fb4SBarry Smith 
490573b0fb4SBarry Smith #undef __FUNCT__
491e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcmp"
492e5c89e4eSSatish Balay /*@C
493e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
494e5c89e4eSSatish Balay 
495e5c89e4eSSatish Balay    Not Collective
496e5c89e4eSSatish Balay 
497e5c89e4eSSatish Balay    Input Parameters:
498e5c89e4eSSatish Balay +  a - pointer to string first string
499e5c89e4eSSatish Balay -  b - pointer to second string
500e5c89e4eSSatish Balay 
501e5c89e4eSSatish Balay    Output Parameter:
5028c74ee41SBarry Smith .  flg - PETSC_TRUE if the two strings are equal
503e5c89e4eSSatish Balay 
504e5c89e4eSSatish Balay    Level: intermediate
505e5c89e4eSSatish Balay 
5066f013253SBarry Smith    Notes:    Not for use in Fortran
5076f013253SBarry Smith 
508e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
509e5c89e4eSSatish Balay 
510e5c89e4eSSatish Balay @*/
5117087cfbeSBarry Smith PetscErrorCode  PetscStrcmp(const char a[],const char b[],PetscBool  *flg)
512e5c89e4eSSatish Balay {
513e5c89e4eSSatish Balay   int c;
514e5c89e4eSSatish Balay 
515e5c89e4eSSatish Balay   PetscFunctionBegin;
516a297a907SKarl Rupp   if (!a && !b)      *flg = PETSC_TRUE;
517a297a907SKarl Rupp   else if (!a || !b) *flg = PETSC_FALSE;
518a297a907SKarl Rupp   else {
519e5c89e4eSSatish Balay     c = strcmp(a,b);
520e5c89e4eSSatish Balay     if (c) *flg = PETSC_FALSE;
521e5c89e4eSSatish Balay     else   *flg = PETSC_TRUE;
522e5c89e4eSSatish Balay   }
523e5c89e4eSSatish Balay   PetscFunctionReturn(0);
524e5c89e4eSSatish Balay }
525e5c89e4eSSatish Balay 
526e5c89e4eSSatish Balay #undef __FUNCT__
527e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrgrt"
528e5c89e4eSSatish Balay /*@C
529e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
530e5c89e4eSSatish Balay 
531e5c89e4eSSatish Balay    Not Collective
532e5c89e4eSSatish Balay 
533e5c89e4eSSatish Balay    Input Parameters:
534e5c89e4eSSatish Balay +  a - pointer to first string
535e5c89e4eSSatish Balay -  b - pointer to second string
536e5c89e4eSSatish Balay 
537e5c89e4eSSatish Balay    Output Parameter:
538e5c89e4eSSatish Balay .  flg - if the first string is greater
539e5c89e4eSSatish Balay 
540e5c89e4eSSatish Balay    Notes:
541e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
542e5c89e4eSSatish Balay     all others
543e5c89e4eSSatish Balay 
5446f013253SBarry Smith    Not for use in Fortran
5456f013253SBarry Smith 
546e5c89e4eSSatish Balay    Level: intermediate
547e5c89e4eSSatish Balay 
548e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
549e5c89e4eSSatish Balay 
550e5c89e4eSSatish Balay @*/
5517087cfbeSBarry Smith PetscErrorCode  PetscStrgrt(const char a[],const char b[],PetscBool  *t)
552e5c89e4eSSatish Balay {
553e5c89e4eSSatish Balay   int c;
554e5c89e4eSSatish Balay 
555e5c89e4eSSatish Balay   PetscFunctionBegin;
556a297a907SKarl Rupp   if (!a && !b) *t = PETSC_FALSE;
557a297a907SKarl Rupp   else if (a && !b) *t = PETSC_TRUE;
558a297a907SKarl Rupp   else if (!a && b) *t = PETSC_FALSE;
559a297a907SKarl Rupp   else {
560e5c89e4eSSatish Balay     c = strcmp(a,b);
561e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
562e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
563e5c89e4eSSatish Balay   }
564e5c89e4eSSatish Balay   PetscFunctionReturn(0);
565e5c89e4eSSatish Balay }
566e5c89e4eSSatish Balay 
567e5c89e4eSSatish Balay #undef __FUNCT__
568e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcasecmp"
569e5c89e4eSSatish Balay /*@C
570e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
571e5c89e4eSSatish Balay      except possibly for case.
572e5c89e4eSSatish Balay 
573e5c89e4eSSatish Balay    Not Collective
574e5c89e4eSSatish Balay 
575e5c89e4eSSatish Balay    Input Parameters:
576e5c89e4eSSatish Balay +  a - pointer to first string
577e5c89e4eSSatish Balay -  b - pointer to second string
578e5c89e4eSSatish Balay 
579e5c89e4eSSatish Balay    Output Parameter:
580e5c89e4eSSatish Balay .  flg - if the two strings are the same
581e5c89e4eSSatish Balay 
582e5c89e4eSSatish Balay    Notes:
583e5c89e4eSSatish Balay     Null arguments are ok
584e5c89e4eSSatish Balay 
5856f013253SBarry Smith    Not for use in Fortran
5866f013253SBarry Smith 
587e5c89e4eSSatish Balay    Level: intermediate
588e5c89e4eSSatish Balay 
589e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
590e5c89e4eSSatish Balay 
591e5c89e4eSSatish Balay @*/
5927087cfbeSBarry Smith PetscErrorCode  PetscStrcasecmp(const char a[],const char b[],PetscBool  *t)
593e5c89e4eSSatish Balay {
594e5c89e4eSSatish Balay   int c;
595e5c89e4eSSatish Balay 
596e5c89e4eSSatish Balay   PetscFunctionBegin;
597e5c89e4eSSatish Balay   if (!a && !b) c = 0;
598e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
59932b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
60032b366c8SSatish Balay   else c = strcasecmp(a,b);
60132b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
602e5c89e4eSSatish Balay   else c = stricmp(a,b);
603e5c89e4eSSatish Balay #else
60432b366c8SSatish Balay   else {
60532b366c8SSatish Balay     char           *aa,*bb;
60632b366c8SSatish Balay     PetscErrorCode ierr;
60732b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
60832b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
60932b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
61032b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
61132b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
612503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
613503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
61432b366c8SSatish Balay     PetscFunctionReturn(0);
61532b366c8SSatish Balay   }
616e5c89e4eSSatish Balay #endif
617e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
618e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
619e5c89e4eSSatish Balay   PetscFunctionReturn(0);
620e5c89e4eSSatish Balay }
621e5c89e4eSSatish Balay 
62232b366c8SSatish Balay 
62332b366c8SSatish Balay 
624e5c89e4eSSatish Balay #undef __FUNCT__
625e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncmp"
626e5c89e4eSSatish Balay /*@C
627e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
628e5c89e4eSSatish Balay 
629e5c89e4eSSatish Balay    Not Collective
630e5c89e4eSSatish Balay 
631e5c89e4eSSatish Balay    Input Parameters:
632e5c89e4eSSatish Balay +  a - pointer to first string
633e5c89e4eSSatish Balay .  b - pointer to second string
634e5c89e4eSSatish Balay -  n - length to compare up to
635e5c89e4eSSatish Balay 
636e5c89e4eSSatish Balay    Output Parameter:
637e5c89e4eSSatish Balay .  t - if the two strings are equal
638e5c89e4eSSatish Balay 
639e5c89e4eSSatish Balay    Level: intermediate
640e5c89e4eSSatish Balay 
6416f013253SBarry Smith    Notes:    Not for use in Fortran
6426f013253SBarry Smith 
643e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
644e5c89e4eSSatish Balay 
645e5c89e4eSSatish Balay @*/
6467087cfbeSBarry Smith PetscErrorCode  PetscStrncmp(const char a[],const char b[],size_t n,PetscBool  *t)
647e5c89e4eSSatish Balay {
648e5c89e4eSSatish Balay   int c;
649e5c89e4eSSatish Balay 
650e5c89e4eSSatish Balay   PetscFunctionBegin;
651e5c89e4eSSatish Balay   c = strncmp(a,b,n);
652e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
653e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
654e5c89e4eSSatish Balay   PetscFunctionReturn(0);
655e5c89e4eSSatish Balay }
656e5c89e4eSSatish Balay 
657e5c89e4eSSatish Balay #undef __FUNCT__
658e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrchr"
659e5c89e4eSSatish Balay /*@C
660e5c89e4eSSatish Balay    PetscStrchr - Locates first occurance of a character in a string
661e5c89e4eSSatish Balay 
662e5c89e4eSSatish Balay    Not Collective
663e5c89e4eSSatish Balay 
664e5c89e4eSSatish Balay    Input Parameters:
665e5c89e4eSSatish Balay +  a - pointer to string
666e5c89e4eSSatish Balay -  b - character
667e5c89e4eSSatish Balay 
668e5c89e4eSSatish Balay    Output Parameter:
6690298fd71SBarry Smith .  c - location of occurance, NULL if not found
670e5c89e4eSSatish Balay 
671e5c89e4eSSatish Balay    Level: intermediate
672e5c89e4eSSatish Balay 
6736f013253SBarry Smith    Notes:    Not for use in Fortran
6746f013253SBarry Smith 
675e5c89e4eSSatish Balay @*/
6767087cfbeSBarry Smith PetscErrorCode  PetscStrchr(const char a[],char b,char *c[])
677e5c89e4eSSatish Balay {
678e5c89e4eSSatish Balay   PetscFunctionBegin;
679e5c89e4eSSatish Balay   *c = (char*)strchr(a,b);
680e5c89e4eSSatish Balay   PetscFunctionReturn(0);
681e5c89e4eSSatish Balay }
682e5c89e4eSSatish Balay 
683e5c89e4eSSatish Balay #undef __FUNCT__
684e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrrchr"
685e5c89e4eSSatish Balay /*@C
686e5c89e4eSSatish Balay    PetscStrrchr - Locates one location past the last occurance of a character in a string,
687e5c89e4eSSatish Balay       if the character is not found then returns entire string
688e5c89e4eSSatish Balay 
689e5c89e4eSSatish Balay    Not Collective
690e5c89e4eSSatish Balay 
691e5c89e4eSSatish Balay    Input Parameters:
692e5c89e4eSSatish Balay +  a - pointer to string
693e5c89e4eSSatish Balay -  b - character
694e5c89e4eSSatish Balay 
695e5c89e4eSSatish Balay    Output Parameter:
696e5c89e4eSSatish Balay .  tmp - location of occurance, a if not found
697e5c89e4eSSatish Balay 
698e5c89e4eSSatish Balay    Level: intermediate
699e5c89e4eSSatish Balay 
7006f013253SBarry Smith    Notes:    Not for use in Fortran
7016f013253SBarry Smith 
702e5c89e4eSSatish Balay @*/
7037087cfbeSBarry Smith PetscErrorCode  PetscStrrchr(const char a[],char b,char *tmp[])
704e5c89e4eSSatish Balay {
705e5c89e4eSSatish Balay   PetscFunctionBegin;
706e5c89e4eSSatish Balay   *tmp = (char*)strrchr(a,b);
707a297a907SKarl Rupp   if (!*tmp) *tmp = (char*)a;
708a297a907SKarl Rupp   else *tmp = *tmp + 1;
709e5c89e4eSSatish Balay   PetscFunctionReturn(0);
710e5c89e4eSSatish Balay }
711e5c89e4eSSatish Balay 
712e5c89e4eSSatish Balay #undef __FUNCT__
713e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrtolower"
714e5c89e4eSSatish Balay /*@C
715e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
716e5c89e4eSSatish Balay 
717e5c89e4eSSatish Balay    Not Collective
718e5c89e4eSSatish Balay 
719e5c89e4eSSatish Balay    Input Parameters:
720e5c89e4eSSatish Balay .  a - pointer to string
721e5c89e4eSSatish Balay 
722e5c89e4eSSatish Balay    Level: intermediate
723e5c89e4eSSatish Balay 
7246f013253SBarry Smith    Notes:    Not for use in Fortran
7256f013253SBarry Smith 
726e5c89e4eSSatish Balay @*/
7277087cfbeSBarry Smith PetscErrorCode  PetscStrtolower(char a[])
728e5c89e4eSSatish Balay {
729e5c89e4eSSatish Balay   PetscFunctionBegin;
730e5c89e4eSSatish Balay   while (*a) {
731e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
732e5c89e4eSSatish Balay     a++;
733e5c89e4eSSatish Balay   }
734e5c89e4eSSatish Balay   PetscFunctionReturn(0);
735e5c89e4eSSatish Balay }
736e5c89e4eSSatish Balay 
7377ba3a57cSBarry Smith #undef __FUNCT__
7382f234a98SBarry Smith #define __FUNCT__ "PetscStrtoupper"
7392f234a98SBarry Smith /*@C
7402f234a98SBarry Smith    PetscStrtolower - Converts string to upper case
7412f234a98SBarry Smith 
7422f234a98SBarry Smith    Not Collective
7432f234a98SBarry Smith 
7442f234a98SBarry Smith    Input Parameters:
7452f234a98SBarry Smith .  a - pointer to string
7462f234a98SBarry Smith 
7472f234a98SBarry Smith    Level: intermediate
7482f234a98SBarry Smith 
7492f234a98SBarry Smith    Notes:    Not for use in Fortran
7502f234a98SBarry Smith 
7512f234a98SBarry Smith @*/
7522f234a98SBarry Smith PetscErrorCode  PetscStrtoupper(char a[])
7532f234a98SBarry Smith {
7542f234a98SBarry Smith   PetscFunctionBegin;
7552f234a98SBarry Smith   while (*a) {
7562f234a98SBarry Smith     if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a';
7572f234a98SBarry Smith     a++;
7582f234a98SBarry Smith   }
7592f234a98SBarry Smith   PetscFunctionReturn(0);
7602f234a98SBarry Smith }
7612f234a98SBarry Smith 
7622f234a98SBarry Smith #undef __FUNCT__
7637ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswith"
7647ba3a57cSBarry Smith /*@C
7657ba3a57cSBarry Smith    PetscStrendswith - Determines if a string ends with a certain string
7661d1a0024SBarry Smith 
7677ba3a57cSBarry Smith    Not Collective
7687ba3a57cSBarry Smith 
7697ba3a57cSBarry Smith    Input Parameters:
7707ba3a57cSBarry Smith +  a - pointer to string
7717ba3a57cSBarry Smith -  b - string to endwith
7727ba3a57cSBarry Smith 
7737ba3a57cSBarry Smith    Output Parameter:
7747ba3a57cSBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
7757ba3a57cSBarry Smith 
7767ba3a57cSBarry Smith    Notes:     Not for use in Fortran
7777ba3a57cSBarry Smith 
7787ba3a57cSBarry Smith    Level: intermediate
7797ba3a57cSBarry Smith 
7807ba3a57cSBarry Smith @*/
7817ba3a57cSBarry Smith PetscErrorCode  PetscStrendswith(const char a[],const char b[],PetscBool *flg)
7827ba3a57cSBarry Smith {
7837ba3a57cSBarry Smith   char           *test;
7847ba3a57cSBarry Smith   PetscErrorCode ierr;
7857ba3a57cSBarry Smith   size_t         na,nb;
7867ba3a57cSBarry Smith 
7877ba3a57cSBarry Smith   PetscFunctionBegin;
7887ba3a57cSBarry Smith   *flg = PETSC_FALSE;
7897ba3a57cSBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
7907ba3a57cSBarry Smith   if (test) {
7917ba3a57cSBarry Smith     ierr = PetscStrlen(a,&na);CHKERRQ(ierr);
7927ba3a57cSBarry Smith     ierr = PetscStrlen(b,&nb);CHKERRQ(ierr);
7937ba3a57cSBarry Smith     if (a+na-nb == test) *flg = PETSC_TRUE;
7947ba3a57cSBarry Smith   }
7957ba3a57cSBarry Smith   PetscFunctionReturn(0);
7967ba3a57cSBarry Smith }
7977ba3a57cSBarry Smith 
7987ba3a57cSBarry Smith #undef __FUNCT__
7992c9581d2SBarry Smith #define __FUNCT__ "PetscStrbeginswith"
8002c9581d2SBarry Smith /*@C
8012c9581d2SBarry Smith    PetscStrbeginswith - Determines if a string begins with a certain string
8022c9581d2SBarry Smith 
8032c9581d2SBarry Smith    Not Collective
8042c9581d2SBarry Smith 
8052c9581d2SBarry Smith    Input Parameters:
8062c9581d2SBarry Smith +  a - pointer to string
8072c9581d2SBarry Smith -  b - string to beginwith
8082c9581d2SBarry Smith 
8092c9581d2SBarry Smith    Output Parameter:
8102c9581d2SBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
8112c9581d2SBarry Smith 
8122c9581d2SBarry Smith    Notes:     Not for use in Fortran
8132c9581d2SBarry Smith 
8142c9581d2SBarry Smith    Level: intermediate
8152c9581d2SBarry Smith 
8162c9581d2SBarry Smith @*/
8172c9581d2SBarry Smith PetscErrorCode  PetscStrbeginswith(const char a[],const char b[],PetscBool *flg)
8182c9581d2SBarry Smith {
8192c9581d2SBarry Smith   char           *test;
8202c9581d2SBarry Smith   PetscErrorCode ierr;
8212c9581d2SBarry Smith 
8222c9581d2SBarry Smith   PetscFunctionBegin;
8232c9581d2SBarry Smith   *flg = PETSC_FALSE;
8242c9581d2SBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
825a297a907SKarl Rupp   if (test && (test == a)) *flg = PETSC_TRUE;
8262c9581d2SBarry Smith   PetscFunctionReturn(0);
8272c9581d2SBarry Smith }
8282c9581d2SBarry Smith 
8292c9581d2SBarry Smith 
8302c9581d2SBarry Smith #undef __FUNCT__
8317ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswithwhich"
8327ba3a57cSBarry Smith /*@C
8337ba3a57cSBarry Smith    PetscStrendswithwhich - Determines if a string ends with one of several possible strings
8347ba3a57cSBarry Smith 
8357ba3a57cSBarry Smith    Not Collective
8367ba3a57cSBarry Smith 
8377ba3a57cSBarry Smith    Input Parameters:
8387ba3a57cSBarry Smith +  a - pointer to string
8397ba3a57cSBarry Smith -  bs - strings to endwith (last entry must be null)
8407ba3a57cSBarry Smith 
8417ba3a57cSBarry Smith    Output Parameter:
8427ba3a57cSBarry Smith .  cnt - the index of the string it ends with or 1+the last possible index
8437ba3a57cSBarry Smith 
8447ba3a57cSBarry Smith    Notes:     Not for use in Fortran
8457ba3a57cSBarry Smith 
8467ba3a57cSBarry Smith    Level: intermediate
8477ba3a57cSBarry Smith 
8487ba3a57cSBarry Smith @*/
8497ba3a57cSBarry Smith PetscErrorCode  PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt)
8507ba3a57cSBarry Smith {
8517ba3a57cSBarry Smith   PetscBool      flg;
8527ba3a57cSBarry Smith   PetscErrorCode ierr;
8537ba3a57cSBarry Smith 
8547ba3a57cSBarry Smith   PetscFunctionBegin;
8557ba3a57cSBarry Smith   *cnt = 0;
8567ba3a57cSBarry Smith   while (bs[*cnt]) {
8577ba3a57cSBarry Smith     ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr);
8587ba3a57cSBarry Smith     if (flg) PetscFunctionReturn(0);
8597ba3a57cSBarry Smith     *cnt += 1;
8607ba3a57cSBarry Smith   }
8617ba3a57cSBarry Smith   PetscFunctionReturn(0);
8627ba3a57cSBarry Smith }
8637ba3a57cSBarry Smith 
8647ba3a57cSBarry Smith #undef __FUNCT__
8657ba3a57cSBarry Smith #define __FUNCT__ "PetscStrrstr"
8667ba3a57cSBarry Smith /*@C
8677ba3a57cSBarry Smith    PetscStrrstr - Locates last occurance of string in another string
8687ba3a57cSBarry Smith 
8697ba3a57cSBarry Smith    Not Collective
8707ba3a57cSBarry Smith 
8717ba3a57cSBarry Smith    Input Parameters:
8727ba3a57cSBarry Smith +  a - pointer to string
8737ba3a57cSBarry Smith -  b - string to find
8747ba3a57cSBarry Smith 
8757ba3a57cSBarry Smith    Output Parameter:
8767ba3a57cSBarry Smith .  tmp - location of occurance
8777ba3a57cSBarry Smith 
8787ba3a57cSBarry Smith    Notes:     Not for use in Fortran
8797ba3a57cSBarry Smith 
8807ba3a57cSBarry Smith    Level: intermediate
8817ba3a57cSBarry Smith 
8827ba3a57cSBarry Smith @*/
8837ba3a57cSBarry Smith PetscErrorCode  PetscStrrstr(const char a[],const char b[],char *tmp[])
8847ba3a57cSBarry Smith {
8857ba3a57cSBarry Smith   const char *stmp = a, *ltmp = 0;
8867ba3a57cSBarry Smith 
8877ba3a57cSBarry Smith   PetscFunctionBegin;
8887ba3a57cSBarry Smith   while (stmp) {
8897ba3a57cSBarry Smith     stmp = (char*)strstr(stmp,b);
8907ba3a57cSBarry Smith     if (stmp) {ltmp = stmp;stmp++;}
8917ba3a57cSBarry Smith   }
8927ba3a57cSBarry Smith   *tmp = (char*)ltmp;
8937ba3a57cSBarry Smith   PetscFunctionReturn(0);
8947ba3a57cSBarry Smith }
8957ba3a57cSBarry Smith 
8967ba3a57cSBarry Smith #undef __FUNCT__
8977ba3a57cSBarry Smith #define __FUNCT__ "PetscStrstr"
8987ba3a57cSBarry Smith /*@C
8997ba3a57cSBarry Smith    PetscStrstr - Locates first occurance of string in another string
9007ba3a57cSBarry Smith 
9017ba3a57cSBarry Smith    Not Collective
9027ba3a57cSBarry Smith 
9037ba3a57cSBarry Smith    Input Parameters:
904160f4796SJed Brown +  haystack - string to search
905160f4796SJed Brown -  needle - string to find
9067ba3a57cSBarry Smith 
9077ba3a57cSBarry Smith    Output Parameter:
9080298fd71SBarry Smith .  tmp - location of occurance, is a NULL if the string is not found
9097ba3a57cSBarry Smith 
9107ba3a57cSBarry Smith    Notes: Not for use in Fortran
9117ba3a57cSBarry Smith 
9127ba3a57cSBarry Smith    Level: intermediate
9137ba3a57cSBarry Smith 
9147ba3a57cSBarry Smith @*/
915160f4796SJed Brown PetscErrorCode  PetscStrstr(const char haystack[],const char needle[],char *tmp[])
9167ba3a57cSBarry Smith {
9177ba3a57cSBarry Smith   PetscFunctionBegin;
918160f4796SJed Brown   *tmp = (char*)strstr(haystack,needle);
9197ba3a57cSBarry Smith   PetscFunctionReturn(0);
9207ba3a57cSBarry Smith }
9217ba3a57cSBarry Smith 
9227ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
9231d1a0024SBarry Smith 
924e5c89e4eSSatish Balay #undef __FUNCT__
925e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenFind"
926e5c89e4eSSatish Balay /*@C
927e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
928e5c89e4eSSatish Balay 
929e5c89e4eSSatish Balay    Not Collective
930e5c89e4eSSatish Balay 
931e5c89e4eSSatish Balay    Input Parameters:
932e5c89e4eSSatish Balay .  a - pointer to token
933e5c89e4eSSatish Balay 
934e5c89e4eSSatish Balay    Output Parameter:
9350298fd71SBarry Smith .  result - location of occurance, NULL if not found
936e5c89e4eSSatish Balay 
937e5c89e4eSSatish Balay    Notes:
938e5c89e4eSSatish Balay 
939e5c89e4eSSatish Balay      This version is different from the system version in that
940e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
941e5c89e4eSSatish Balay 
9424704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
9434704e885SBarry Smith    as a single token.
9444704e885SBarry Smith 
9456f013253SBarry Smith     Not for use in Fortran
9466f013253SBarry Smith 
947e5c89e4eSSatish Balay    Level: intermediate
948e5c89e4eSSatish Balay 
9496f013253SBarry Smith 
950e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
951e5c89e4eSSatish Balay @*/
9527087cfbeSBarry Smith PetscErrorCode  PetscTokenFind(PetscToken a,char *result[])
953e5c89e4eSSatish Balay {
9544704e885SBarry Smith   char *ptr = a->current,token;
955e5c89e4eSSatish Balay 
956e5c89e4eSSatish Balay   PetscFunctionBegin;
957e5c89e4eSSatish Balay   *result = a->current;
9584704e885SBarry Smith   if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);}
9594704e885SBarry Smith   token = a->token;
96090fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
961e5c89e4eSSatish Balay   while (ptr) {
9624704e885SBarry Smith     if (*ptr == token) {
963e5c89e4eSSatish Balay       *ptr++ = 0;
964e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
965e5c89e4eSSatish Balay       a->current = ptr;
966e5c89e4eSSatish Balay       break;
967e5c89e4eSSatish Balay     }
968e5c89e4eSSatish Balay     if (!*ptr) {
969e5c89e4eSSatish Balay       a->current = 0;
970e5c89e4eSSatish Balay       break;
971e5c89e4eSSatish Balay     }
972e5c89e4eSSatish Balay     ptr++;
973e5c89e4eSSatish Balay   }
974e5c89e4eSSatish Balay   PetscFunctionReturn(0);
975e5c89e4eSSatish Balay }
976e5c89e4eSSatish Balay 
977e5c89e4eSSatish Balay #undef __FUNCT__
978e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenCreate"
979e5c89e4eSSatish Balay /*@C
980e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
981e5c89e4eSSatish Balay 
982e5c89e4eSSatish Balay    Not Collective
983e5c89e4eSSatish Balay 
984e5c89e4eSSatish Balay    Input Parameters:
985e5c89e4eSSatish Balay +  string - the string to look in
986e5c89e4eSSatish Balay -  token - the character to look for
987e5c89e4eSSatish Balay 
988e5c89e4eSSatish Balay    Output Parameter:
989e5c89e4eSSatish Balay .  a - pointer to token
990e5c89e4eSSatish Balay 
991e5c89e4eSSatish Balay    Notes:
992e5c89e4eSSatish Balay 
993e5c89e4eSSatish Balay      This version is different from the system version in that
994e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
995e5c89e4eSSatish Balay 
9966f013253SBarry Smith     Not for use in Fortran
9976f013253SBarry Smith 
998e5c89e4eSSatish Balay    Level: intermediate
999e5c89e4eSSatish Balay 
1000e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
1001e5c89e4eSSatish Balay @*/
10027087cfbeSBarry Smith PetscErrorCode  PetscTokenCreate(const char a[],const char b,PetscToken *t)
1003e5c89e4eSSatish Balay {
1004e5c89e4eSSatish Balay   PetscErrorCode ierr;
1005e5c89e4eSSatish Balay 
1006e5c89e4eSSatish Balay   PetscFunctionBegin;
1007b00a9115SJed Brown   ierr = PetscNew(t);CHKERRQ(ierr);
1008e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
1009a297a907SKarl Rupp 
1010e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
1011e5c89e4eSSatish Balay   (*t)->token   = b;
1012e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1013e5c89e4eSSatish Balay }
1014e5c89e4eSSatish Balay 
1015e5c89e4eSSatish Balay #undef __FUNCT__
1016e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenDestroy"
1017e5c89e4eSSatish Balay /*@C
1018e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
1019e5c89e4eSSatish Balay 
1020e5c89e4eSSatish Balay    Not Collective
1021e5c89e4eSSatish Balay 
1022e5c89e4eSSatish Balay    Input Parameters:
1023e5c89e4eSSatish Balay .  a - pointer to token
1024e5c89e4eSSatish Balay 
1025e5c89e4eSSatish Balay    Level: intermediate
1026e5c89e4eSSatish Balay 
10276f013253SBarry Smith    Notes:     Not for use in Fortran
10286f013253SBarry Smith 
1029e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
1030e5c89e4eSSatish Balay @*/
10318c74ee41SBarry Smith PetscErrorCode  PetscTokenDestroy(PetscToken *a)
1032e5c89e4eSSatish Balay {
1033e5c89e4eSSatish Balay   PetscErrorCode ierr;
1034e5c89e4eSSatish Balay 
1035e5c89e4eSSatish Balay   PetscFunctionBegin;
10368c74ee41SBarry Smith   if (!*a) PetscFunctionReturn(0);
10378c74ee41SBarry Smith   ierr = PetscFree((*a)->array);CHKERRQ(ierr);
10388c74ee41SBarry Smith   ierr = PetscFree(*a);CHKERRQ(ierr);
1039e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1040e5c89e4eSSatish Balay }
1041e5c89e4eSSatish Balay 
1042e5c89e4eSSatish Balay 
1043e5c89e4eSSatish Balay #undef __FUNCT__
1044e5c89e4eSSatish Balay #define __FUNCT__ "PetscGetPetscDir"
1045e5c89e4eSSatish Balay /*@C
1046e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
1047e5c89e4eSSatish Balay 
1048e5c89e4eSSatish Balay    Not Collective
1049e5c89e4eSSatish Balay 
1050e5c89e4eSSatish Balay    Output Parameter:
1051e5c89e4eSSatish Balay .  dir - the directory
1052e5c89e4eSSatish Balay 
1053e5c89e4eSSatish Balay    Level: developer
1054e5c89e4eSSatish Balay 
10556f013253SBarry Smith    Notes: Not for use in Fortran
10566f013253SBarry Smith 
1057e5c89e4eSSatish Balay @*/
10587087cfbeSBarry Smith PetscErrorCode  PetscGetPetscDir(const char *dir[])
1059e5c89e4eSSatish Balay {
1060e5c89e4eSSatish Balay   PetscFunctionBegin;
1061e5c89e4eSSatish Balay   *dir = PETSC_DIR;
1062e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1063e5c89e4eSSatish Balay }
1064e5c89e4eSSatish Balay 
1065e5c89e4eSSatish Balay #undef __FUNCT__
1066e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrreplace"
1067e5c89e4eSSatish Balay /*@C
1068e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
1069e5c89e4eSSatish Balay 
1070e5c89e4eSSatish Balay    Not Collective
1071e5c89e4eSSatish Balay 
1072e5c89e4eSSatish Balay    Input Parameters:
1073e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
107471573d7dSBarry Smith .   aa - the string to look in
1075d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
1076e5c89e4eSSatish Balay -   len - the length of b
1077e5c89e4eSSatish Balay 
1078e5c89e4eSSatish Balay    Notes:
1079e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
1080d5649816SBarry Smith       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
1081e5c89e4eSSatish Balay       as well as any environmental variables.
1082e5c89e4eSSatish Balay 
10836f013253SBarry Smith       PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
1084acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
1085acc6cc86SBarry Smith 
10866f013253SBarry Smith       Not for use in Fortran
10876f013253SBarry Smith 
1088e5c89e4eSSatish Balay    Level: intermediate
1089e5c89e4eSSatish Balay 
1090e5c89e4eSSatish Balay @*/
10917087cfbeSBarry Smith PetscErrorCode  PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
1092e5c89e4eSSatish Balay {
1093e5c89e4eSSatish Balay   PetscErrorCode ierr;
1094e5c89e4eSSatish Balay   int            i = 0;
1095e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
109671573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
1097d5649816SBarry Smith   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0};
1098d5649816SBarry Smith   const char     *r[] = {0,0,0,0,0,0,0,0,0};
1099ace3abfcSBarry Smith   PetscBool      flag;
1100e5c89e4eSSatish Balay 
1101e5c89e4eSSatish Balay   PetscFunctionBegin;
1102e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
110371573d7dSBarry Smith   if (aa == b) {
110422982a5fSBarry Smith     ierr = PetscStrallocpy(aa,(char**)&a);CHKERRQ(ierr);
110571573d7dSBarry Smith   }
1106785e854fSJed Brown   ierr = PetscMalloc1(len,&work);CHKERRQ(ierr);
1107e5c89e4eSSatish Balay 
1108e5c89e4eSSatish Balay   /* get values for replaced variables */
1109487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr);
1110487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr);
1111487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr);
1112785e854fSJed Brown   ierr = PetscMalloc1(256,&r[3]);CHKERRQ(ierr);
1113785e854fSJed Brown   ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[4]);CHKERRQ(ierr);
1114785e854fSJed Brown   ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[5]);CHKERRQ(ierr);
1115785e854fSJed Brown   ierr = PetscMalloc1(256,&r[6]);CHKERRQ(ierr);
1116785e854fSJed Brown   ierr = PetscMalloc1(256,&r[7]);CHKERRQ(ierr);
1117487e5849SBarry Smith   ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr);
1118487e5849SBarry Smith   ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1119487e5849SBarry Smith   ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1120487e5849SBarry Smith   ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr);
1121d5649816SBarry Smith   ierr = PetscGetHostName((char*)r[7],256);CHKERRQ(ierr);
1122487e5849SBarry Smith 
1123487e5849SBarry Smith   /* replace that are in environment */
1124487e5849SBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr);
1125487e5849SBarry Smith   if (flag) {
112631936d58SMatthew G. Knepley     ierr = PetscFree(r[2]);CHKERRQ(ierr);
1127487e5849SBarry Smith     ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr);
1128487e5849SBarry Smith   }
1129e5c89e4eSSatish Balay 
1130e5c89e4eSSatish Balay   /* replace the requested strings */
1131e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
1132e5c89e4eSSatish Balay   while (s[i]) {
1133e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
1134e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1135e5c89e4eSSatish Balay     while (par) {
1136e5c89e4eSSatish Balay       *par =  0;
1137e5c89e4eSSatish Balay       par += l;
1138e5c89e4eSSatish Balay 
1139e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
1140e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
1141e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
114217186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
1143e5c89e4eSSatish Balay       ierr = PetscStrcpy(work,b);CHKERRQ(ierr);
1144e5c89e4eSSatish Balay       ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr);
1145e5c89e4eSSatish Balay       ierr = PetscStrcat(work,par);CHKERRQ(ierr);
1146e5c89e4eSSatish Balay       ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr);
1147e5c89e4eSSatish Balay       ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1148e5c89e4eSSatish Balay     }
1149e5c89e4eSSatish Balay     i++;
1150e5c89e4eSSatish Balay   }
1151487e5849SBarry Smith   i = 0;
1152487e5849SBarry Smith   while (r[i]) {
1153e5c89e4eSSatish Balay     tfree = (char*)r[i];
1154e5c89e4eSSatish Balay     ierr  = PetscFree(tfree);CHKERRQ(ierr);
1155487e5849SBarry Smith     i++;
1156e5c89e4eSSatish Balay   }
1157e5c89e4eSSatish Balay 
1158e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
1159e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1160e5c89e4eSSatish Balay   while (par) {
1161e5c89e4eSSatish Balay     *par  = 0;
1162e5c89e4eSSatish Balay     par  += 2;
1163e5c89e4eSSatish Balay     ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
1164e5c89e4eSSatish Balay     ierr  = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
1165e5c89e4eSSatish Balay     *epar = 0;
1166e5c89e4eSSatish Balay     epar += 1;
1167e5c89e4eSSatish Balay     ierr  = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr);
11687ba3a57cSBarry Smith     if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
1169e5c89e4eSSatish Balay     ierr = PetscStrcat(work,env);CHKERRQ(ierr);
1170e5c89e4eSSatish Balay     ierr = PetscStrcat(work,epar);CHKERRQ(ierr);
1171e5c89e4eSSatish Balay     ierr = PetscStrcpy(b,work);CHKERRQ(ierr);
1172e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1173e5c89e4eSSatish Balay   }
1174e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
117571573d7dSBarry Smith   if (aa == b) {
117671573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
117771573d7dSBarry Smith   }
1178e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1179e5c89e4eSSatish Balay }
1180e5c89e4eSSatish Balay 
1181a53986e1SJed Brown #undef __FUNCT__
1182a53986e1SJed Brown #define __FUNCT__ "PetscEListFind"
1183a53986e1SJed Brown /*@C
1184a53986e1SJed Brown    PetscEListFind - searches list of strings for given string, using case insensitive matching
1185e5c89e4eSSatish Balay 
1186a53986e1SJed Brown    Not Collective
1187a53986e1SJed Brown 
1188a53986e1SJed Brown    Input Parameters:
1189a53986e1SJed Brown +  n - number of strings in
1190a53986e1SJed Brown .  list - list of strings to search
1191a53986e1SJed Brown -  str - string to look for, empty string "" accepts default (first entry in list)
1192a53986e1SJed Brown 
1193a53986e1SJed Brown    Output Parameters:
1194a53986e1SJed Brown +  value - index of matching string (if found)
1195a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1196a53986e1SJed Brown 
1197a53986e1SJed Brown    Notes:
1198a53986e1SJed Brown    Not for use in Fortran
1199a53986e1SJed Brown 
1200a53986e1SJed Brown    Level: advanced
1201a53986e1SJed Brown @*/
1202a53986e1SJed Brown PetscErrorCode PetscEListFind(PetscInt n,const char *const *list,const char *str,PetscInt *value,PetscBool *found)
1203a53986e1SJed Brown {
1204a53986e1SJed Brown   PetscErrorCode ierr;
1205a53986e1SJed Brown   PetscBool matched;
1206a53986e1SJed Brown   PetscInt i;
1207a53986e1SJed Brown 
1208a53986e1SJed Brown   PetscFunctionBegin;
1209a53986e1SJed Brown   if (found) *found = PETSC_FALSE;
1210a53986e1SJed Brown   for (i=0; i<n; i++) {
1211a53986e1SJed Brown     ierr = PetscStrcasecmp(str,list[i],&matched);CHKERRQ(ierr);
1212a53986e1SJed Brown     if (matched || !str[0]) {
1213a53986e1SJed Brown       if (found) *found = PETSC_TRUE;
1214a53986e1SJed Brown       *value = i;
1215a53986e1SJed Brown       break;
1216a53986e1SJed Brown     }
1217a53986e1SJed Brown   }
1218a53986e1SJed Brown   PetscFunctionReturn(0);
1219a53986e1SJed Brown }
1220a53986e1SJed Brown 
1221a53986e1SJed Brown #undef __FUNCT__
1222a53986e1SJed Brown #define __FUNCT__ "PetscEnumFind"
1223a53986e1SJed Brown /*@C
1224a53986e1SJed Brown    PetscEListFind - searches enum list of strings for given string, using case insensitive matching
1225a53986e1SJed Brown 
1226a53986e1SJed Brown    Not Collective
1227a53986e1SJed Brown 
1228a53986e1SJed Brown    Input Parameters:
1229a53986e1SJed Brown +  enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL
1230a53986e1SJed Brown -  str - string to look for
1231a53986e1SJed Brown 
1232a53986e1SJed Brown    Output Parameters:
1233a53986e1SJed Brown +  value - index of matching string (if found)
1234a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1235a53986e1SJed Brown 
1236a53986e1SJed Brown    Notes:
1237a53986e1SJed Brown    Not for use in Fortran
1238a53986e1SJed Brown 
1239a53986e1SJed Brown    Level: advanced
1240a53986e1SJed Brown @*/
1241a53986e1SJed Brown PetscErrorCode PetscEnumFind(const char *const *enumlist,const char *str,PetscEnum *value,PetscBool *found)
1242a53986e1SJed Brown {
1243a53986e1SJed Brown   PetscErrorCode ierr;
1244a53986e1SJed Brown   PetscInt n,evalue;
1245a53986e1SJed Brown   PetscBool efound;
1246a53986e1SJed Brown 
1247a53986e1SJed Brown   PetscFunctionBegin;
1248a53986e1SJed Brown   for (n = 0; enumlist[n]; n++) {
1249a53986e1SJed Brown     if (n > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries");
1250a53986e1SJed Brown   }
1251a53986e1SJed Brown   if (n < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
1252a53986e1SJed Brown   n -= 3;                       /* drop enum name, prefix, and null termination */
1253a53986e1SJed Brown   ierr = PetscEListFind(n,enumlist,str,&evalue,&efound);CHKERRQ(ierr);
1254cfb463b1SJed Brown   if (efound) *value = (PetscEnum)evalue;
1255a53986e1SJed Brown   if (found) *found = efound;
1256a53986e1SJed Brown   PetscFunctionReturn(0);
1257a53986e1SJed Brown }
1258