xref: /petsc/src/sys/utils/str.c (revision 51a1f156e04910655d4f827b832d63ea3b5c2e4b)
1e5c89e4eSSatish Balay /*
2e5c89e4eSSatish Balay     We define the string operations here. The reason we just do not use
3e5c89e4eSSatish Balay   the standard string routines in the PETSc code is that on some machines
4e5c89e4eSSatish Balay   they are broken or have the wrong prototypes.
5e5c89e4eSSatish Balay 
6e5c89e4eSSatish Balay */
7c6db04a5SJed Brown #include <petscsys.h>                   /*I  "petscsys.h"   I*/
83964eb88SJed Brown #if defined(PETSC_HAVE_STRINGS_H)
93964eb88SJed Brown #  include <strings.h>          /* strcasecmp */
103964eb88SJed Brown #endif
113964eb88SJed Brown 
123c311c98SBarry Smith /*@C
13*51a1f156SVaclav Hapla    PetscStrToArray - Separates a string by a character (for example ' ' or '\n') and creates an array of strings
143c311c98SBarry Smith 
153c311c98SBarry Smith    Not Collective
163c311c98SBarry Smith 
173c311c98SBarry Smith    Input Parameters:
18d67fe73bSBarry Smith +  s - pointer to string
19*51a1f156SVaclav Hapla -  sp - separator character
203c311c98SBarry Smith 
213c311c98SBarry Smith    Output Parameter:
223c311c98SBarry Smith +   argc - the number of entries in the array
233c311c98SBarry Smith -   args - an array of the entries with a null at the end
243c311c98SBarry Smith 
253c311c98SBarry Smith    Level: intermediate
263c311c98SBarry Smith 
2795452b02SPatrick Sanan    Notes:
2895452b02SPatrick Sanan     this may be called before PetscInitialize() or after PetscFinalize()
293c311c98SBarry Smith 
306f013253SBarry Smith    Not for use in Fortran
316f013253SBarry Smith 
3295452b02SPatrick Sanan    Developer Notes:
3395452b02SPatrick Sanan     Using raw malloc() and does not call error handlers since this may be used before PETSc is initialized. Used
34b4cd4cebSBarry Smith      to generate argc, args arguments passed to MPI_Init()
35301d30feSBarry Smith 
36b4cd4cebSBarry Smith .seealso: PetscStrToArrayDestroy(), PetscToken, PetscTokenCreate()
373c311c98SBarry Smith 
383c311c98SBarry Smith @*/
39d67fe73bSBarry Smith PetscErrorCode  PetscStrToArray(const char s[],char sp,int *argc,char ***args)
403c311c98SBarry Smith {
41c3bcdc7eSBarry Smith   int       i,j,n,*lens,cnt = 0;
42ace3abfcSBarry Smith   PetscBool flg = PETSC_FALSE;
433c311c98SBarry Smith 
4440a7e1efSBarry Smith   if (!s) n = 0;
4540a7e1efSBarry Smith   else    n = strlen(s);
463c311c98SBarry Smith   *argc = 0;
4761528463SBarry Smith   *args = NULL;
48acf7dc08SSatish Balay   for (; n>0; n--) {   /* remove separator chars at the end - and will empty the string if all chars are separator chars */
49acf7dc08SSatish Balay     if (s[n-1] != sp) break;
50acf7dc08SSatish Balay   }
514996c5bdSBarry Smith   if (!n) {
524996c5bdSBarry Smith     return(0);
534996c5bdSBarry Smith   }
543c311c98SBarry Smith   for (i=0; i<n; i++) {
55d67fe73bSBarry Smith     if (s[i] != sp) break;
563c311c98SBarry Smith   }
573c311c98SBarry Smith   for (;i<n+1; i++) {
58d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
59d67fe73bSBarry Smith     else if (s[i] != sp) {flg = PETSC_FALSE;}
603c311c98SBarry Smith   }
61a2ea699eSBarry Smith   (*args) = (char**) malloc(((*argc)+1)*sizeof(char*)); if (!*args) return PETSC_ERR_MEM;
6253e6e2c4SHong Zhang   lens    = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM;
633c311c98SBarry Smith   for (i=0; i<*argc; i++) lens[i] = 0;
643c311c98SBarry Smith 
653c311c98SBarry Smith   *argc = 0;
663c311c98SBarry Smith   for (i=0; i<n; i++) {
67d67fe73bSBarry Smith     if (s[i] != sp) break;
683c311c98SBarry Smith   }
697dd9f305SSatish Balay   for (;i<n+1; i++) {
70d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
71d67fe73bSBarry Smith     else if (s[i] != sp) {lens[*argc]++;flg = PETSC_FALSE;}
723c311c98SBarry Smith   }
733c311c98SBarry Smith 
743c311c98SBarry Smith   for (i=0; i<*argc; i++) {
75c3bcdc7eSBarry Smith     (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char));
76c3bcdc7eSBarry Smith     if (!(*args)[i]) {
77c3bcdc7eSBarry Smith       free(lens);
78c3bcdc7eSBarry Smith       for (j=0; j<i; j++) free((*args)[j]);
79c3bcdc7eSBarry Smith       free(*args);
80c3bcdc7eSBarry Smith       return PETSC_ERR_MEM;
81c3bcdc7eSBarry Smith     }
823c311c98SBarry Smith   }
83a2ea699eSBarry Smith   free(lens);
84301d30feSBarry Smith   (*args)[*argc] = 0;
853c311c98SBarry Smith 
863c311c98SBarry Smith   *argc = 0;
873c311c98SBarry Smith   for (i=0; i<n; i++) {
88d67fe73bSBarry Smith     if (s[i] != sp) break;
893c311c98SBarry Smith   }
903c311c98SBarry Smith   for (;i<n+1; i++) {
91d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
92d67fe73bSBarry Smith     else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;}
933c311c98SBarry Smith   }
943c311c98SBarry Smith   return 0;
953c311c98SBarry Smith }
963c311c98SBarry Smith 
97301d30feSBarry Smith /*@C
98301d30feSBarry Smith    PetscStrToArrayDestroy - Frees array created with PetscStrToArray().
99301d30feSBarry Smith 
100301d30feSBarry Smith    Not Collective
101301d30feSBarry Smith 
102301d30feSBarry Smith    Output Parameters:
103301d30feSBarry Smith +  argc - the number of arguments
104301d30feSBarry Smith -  args - the array of arguments
105301d30feSBarry Smith 
106301d30feSBarry Smith    Level: intermediate
107301d30feSBarry Smith 
10895452b02SPatrick Sanan    Notes:
10995452b02SPatrick Sanan     This may be called before PetscInitialize() or after PetscFinalize()
110301d30feSBarry Smith 
1116f013253SBarry Smith    Not for use in Fortran
1126f013253SBarry Smith 
113301d30feSBarry Smith .seealso: PetscStrToArray()
114301d30feSBarry Smith 
115301d30feSBarry Smith @*/
1167087cfbeSBarry Smith PetscErrorCode  PetscStrToArrayDestroy(int argc,char **args)
117301d30feSBarry Smith {
118301d30feSBarry Smith   PetscInt i;
119301d30feSBarry Smith 
120a297a907SKarl Rupp   for (i=0; i<argc; i++) free(args[i]);
121a297a907SKarl Rupp   if (args) free(args);
122301d30feSBarry Smith   return 0;
123301d30feSBarry Smith }
124301d30feSBarry Smith 
125e5c89e4eSSatish Balay /*@C
126e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
127e5c89e4eSSatish Balay 
128e5c89e4eSSatish Balay    Not Collective
129e5c89e4eSSatish Balay 
130e5c89e4eSSatish Balay    Input Parameters:
131e5c89e4eSSatish Balay .  s - pointer to string
132e5c89e4eSSatish Balay 
133e5c89e4eSSatish Balay    Output Parameter:
134e5c89e4eSSatish Balay .  len - length in bytes
135e5c89e4eSSatish Balay 
136e5c89e4eSSatish Balay    Level: intermediate
137e5c89e4eSSatish Balay 
138e5c89e4eSSatish Balay    Note:
139e5c89e4eSSatish Balay    This routine is analogous to strlen().
140e5c89e4eSSatish Balay 
141e5c89e4eSSatish Balay    Null string returns a length of zero
142e5c89e4eSSatish Balay 
1436f013253SBarry Smith    Not for use in Fortran
1446f013253SBarry Smith 
145e5c89e4eSSatish Balay @*/
1467087cfbeSBarry Smith PetscErrorCode  PetscStrlen(const char s[],size_t *len)
147e5c89e4eSSatish Balay {
148e5c89e4eSSatish Balay   PetscFunctionBegin;
149a297a907SKarl Rupp   if (!s) *len = 0;
150a297a907SKarl Rupp   else    *len = strlen(s);
151e5c89e4eSSatish Balay   PetscFunctionReturn(0);
152e5c89e4eSSatish Balay }
153e5c89e4eSSatish Balay 
154e5c89e4eSSatish Balay /*@C
155e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
156e5c89e4eSSatish Balay 
157e5c89e4eSSatish Balay    Not Collective
158e5c89e4eSSatish Balay 
159e5c89e4eSSatish Balay    Input Parameters:
160e5c89e4eSSatish Balay .  s - pointer to string
161e5c89e4eSSatish Balay 
162e5c89e4eSSatish Balay    Output Parameter:
163e5c89e4eSSatish Balay .  t - the copied string
164e5c89e4eSSatish Balay 
165e5c89e4eSSatish Balay    Level: intermediate
166e5c89e4eSSatish Balay 
167e5c89e4eSSatish Balay    Note:
168e5c89e4eSSatish Balay       Null string returns a new null string
169e5c89e4eSSatish Balay 
1706f013253SBarry Smith       Not for use in Fortran
1716f013253SBarry Smith 
172e5c89e4eSSatish Balay @*/
1737087cfbeSBarry Smith PetscErrorCode  PetscStrallocpy(const char s[],char *t[])
174e5c89e4eSSatish Balay {
175e5c89e4eSSatish Balay   PetscErrorCode ierr;
176e5c89e4eSSatish Balay   size_t         len;
17771573d7dSBarry Smith   char           *tmp = 0;
178e5c89e4eSSatish Balay 
179e5c89e4eSSatish Balay   PetscFunctionBegin;
180e5c89e4eSSatish Balay   if (s) {
181e5c89e4eSSatish Balay     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
182854ce69bSBarry Smith     ierr = PetscMalloc1(1+len,&tmp);CHKERRQ(ierr);
18371573d7dSBarry Smith     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
184e5c89e4eSSatish Balay   }
18571573d7dSBarry Smith   *t = tmp;
186e5c89e4eSSatish Balay   PetscFunctionReturn(0);
187e5c89e4eSSatish Balay }
188e5c89e4eSSatish Balay 
18947340559SBarry Smith /*@C
19047340559SBarry Smith    PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
19147340559SBarry Smith 
19247340559SBarry Smith    Not Collective
19347340559SBarry Smith 
19447340559SBarry Smith    Input Parameters:
19547340559SBarry Smith .  s - pointer to array of strings (final string is a null)
19647340559SBarry Smith 
19747340559SBarry Smith    Output Parameter:
19847340559SBarry Smith .  t - the copied array string
19947340559SBarry Smith 
20047340559SBarry Smith    Level: intermediate
20147340559SBarry Smith 
20247340559SBarry Smith    Note:
20347340559SBarry Smith       Not for use in Fortran
20447340559SBarry Smith 
20547340559SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
20647340559SBarry Smith 
20747340559SBarry Smith @*/
20847340559SBarry Smith PetscErrorCode  PetscStrArrayallocpy(const char *const *list,char ***t)
20947340559SBarry Smith {
21047340559SBarry Smith   PetscErrorCode ierr;
21147340559SBarry Smith   PetscInt       i,n = 0;
21247340559SBarry Smith 
21347340559SBarry Smith   PetscFunctionBegin;
21447340559SBarry Smith   while (list[n++]) ;
215854ce69bSBarry Smith   ierr = PetscMalloc1(n+1,t);CHKERRQ(ierr);
21647340559SBarry Smith   for (i=0; i<n; i++) {
21747340559SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
21847340559SBarry Smith   }
2190298fd71SBarry Smith   (*t)[n] = NULL;
22047340559SBarry Smith   PetscFunctionReturn(0);
22147340559SBarry Smith }
22247340559SBarry Smith 
22347340559SBarry Smith /*@C
22447340559SBarry Smith    PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
22547340559SBarry Smith 
22647340559SBarry Smith    Not Collective
22747340559SBarry Smith 
22847340559SBarry Smith    Output Parameters:
22947340559SBarry Smith .   list - array of strings
23047340559SBarry Smith 
23147340559SBarry Smith    Level: intermediate
23247340559SBarry Smith 
23395452b02SPatrick Sanan    Notes:
23495452b02SPatrick Sanan     Not for use in Fortran
23547340559SBarry Smith 
23647340559SBarry Smith .seealso: PetscStrArrayallocpy()
23747340559SBarry Smith 
23847340559SBarry Smith @*/
2396fed8037SJed Brown PetscErrorCode PetscStrArrayDestroy(char ***list)
24047340559SBarry Smith {
24147340559SBarry Smith   PetscInt       n = 0;
24247340559SBarry Smith   PetscErrorCode ierr;
24347340559SBarry Smith 
2446fed8037SJed Brown   PetscFunctionBegin;
2456fed8037SJed Brown   if (!*list) PetscFunctionReturn(0);
2466fed8037SJed Brown   while ((*list)[n]) {
2476fed8037SJed Brown     ierr = PetscFree((*list)[n]);CHKERRQ(ierr);
24847340559SBarry Smith     n++;
24947340559SBarry Smith   }
2506fed8037SJed Brown   ierr = PetscFree(*list);CHKERRQ(ierr);
2516fed8037SJed Brown   PetscFunctionReturn(0);
25247340559SBarry Smith }
25347340559SBarry Smith 
2546991f827SBarry Smith /*@C
2556991f827SBarry Smith    PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
2566991f827SBarry Smith 
2576991f827SBarry Smith    Not Collective
2586991f827SBarry Smith 
2596991f827SBarry Smith    Input Parameters:
2606991f827SBarry Smith +  n - the number of string entries
2616991f827SBarry Smith -  s - pointer to array of strings
2626991f827SBarry Smith 
2636991f827SBarry Smith    Output Parameter:
2646991f827SBarry Smith .  t - the copied array string
2656991f827SBarry Smith 
2666991f827SBarry Smith    Level: intermediate
2676991f827SBarry Smith 
2686991f827SBarry Smith    Note:
2696991f827SBarry Smith       Not for use in Fortran
2706991f827SBarry Smith 
2716991f827SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
2726991f827SBarry Smith 
2736991f827SBarry Smith @*/
2746991f827SBarry Smith PetscErrorCode  PetscStrNArrayallocpy(PetscInt n,const char *const *list,char ***t)
2756991f827SBarry Smith {
2766991f827SBarry Smith   PetscErrorCode ierr;
2776991f827SBarry Smith   PetscInt       i;
2786991f827SBarry Smith 
2796991f827SBarry Smith   PetscFunctionBegin;
2806991f827SBarry Smith   ierr = PetscMalloc1(n,t);CHKERRQ(ierr);
2816991f827SBarry Smith   for (i=0; i<n; i++) {
2826991f827SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
2836991f827SBarry Smith   }
2846991f827SBarry Smith   PetscFunctionReturn(0);
2856991f827SBarry Smith }
2866991f827SBarry Smith 
2876991f827SBarry Smith /*@C
2886991f827SBarry Smith    PetscStrNArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
2896991f827SBarry Smith 
2906991f827SBarry Smith    Not Collective
2916991f827SBarry Smith 
2926991f827SBarry Smith    Output Parameters:
2936991f827SBarry Smith +   n - number of string entries
2946991f827SBarry Smith -   list - array of strings
2956991f827SBarry Smith 
2966991f827SBarry Smith    Level: intermediate
2976991f827SBarry Smith 
29895452b02SPatrick Sanan    Notes:
29995452b02SPatrick Sanan     Not for use in Fortran
3006991f827SBarry Smith 
3016991f827SBarry Smith .seealso: PetscStrArrayallocpy()
3026991f827SBarry Smith 
3036991f827SBarry Smith @*/
3046991f827SBarry Smith PetscErrorCode PetscStrNArrayDestroy(PetscInt n,char ***list)
3056991f827SBarry Smith {
3066991f827SBarry Smith   PetscErrorCode ierr;
3076991f827SBarry Smith   PetscInt       i;
3086991f827SBarry Smith 
3096991f827SBarry Smith   PetscFunctionBegin;
3106991f827SBarry Smith   if (!*list) PetscFunctionReturn(0);
3116991f827SBarry Smith   for (i=0; i<n; i++){
3126991f827SBarry Smith     ierr = PetscFree((*list)[i]);CHKERRQ(ierr);
3136991f827SBarry Smith   }
3146991f827SBarry Smith   ierr = PetscFree(*list);CHKERRQ(ierr);
3156991f827SBarry Smith   PetscFunctionReturn(0);
3166991f827SBarry Smith }
3176991f827SBarry Smith 
318e5c89e4eSSatish Balay /*@C
319e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
320e5c89e4eSSatish Balay 
321e5c89e4eSSatish Balay    Not Collective
322e5c89e4eSSatish Balay 
323e5c89e4eSSatish Balay    Input Parameters:
324e5c89e4eSSatish Balay .  t - pointer to string
325e5c89e4eSSatish Balay 
326e5c89e4eSSatish Balay    Output Parameter:
327e5c89e4eSSatish Balay .  s - the copied string
328e5c89e4eSSatish Balay 
329e5c89e4eSSatish Balay    Level: intermediate
330e5c89e4eSSatish Balay 
3316f013253SBarry Smith    Notes:
332e5c89e4eSSatish Balay      Null string returns a string starting with zero
333e5c89e4eSSatish Balay 
3346f013253SBarry Smith      Not for use in Fortran
3356f013253SBarry Smith 
336a126751eSBarry Smith .seealso: PetscStrncpy(), PetscStrcat(), PetscStrlcat()
337e5c89e4eSSatish Balay 
338e5c89e4eSSatish Balay @*/
339acc6cc86SBarry Smith 
3407087cfbeSBarry Smith PetscErrorCode  PetscStrcpy(char s[],const char t[])
341e5c89e4eSSatish Balay {
342e5c89e4eSSatish Balay   PetscFunctionBegin;
34317186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
344a297a907SKarl Rupp   if (t) strcpy(s,t);
345a297a907SKarl Rupp   else if (s) s[0] = 0;
346e5c89e4eSSatish Balay   PetscFunctionReturn(0);
347e5c89e4eSSatish Balay }
348e5c89e4eSSatish Balay 
349e5c89e4eSSatish Balay /*@C
350e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
351e5c89e4eSSatish Balay 
352e5c89e4eSSatish Balay    Not Collective
353e5c89e4eSSatish Balay 
354e5c89e4eSSatish Balay    Input Parameters:
355e5c89e4eSSatish Balay +  t - pointer to string
356e5c89e4eSSatish Balay -  n - the length to copy
357e5c89e4eSSatish Balay 
358e5c89e4eSSatish Balay    Output Parameter:
359e5c89e4eSSatish Balay .  s - the copied string
360e5c89e4eSSatish Balay 
361e5c89e4eSSatish Balay    Level: intermediate
362e5c89e4eSSatish Balay 
363e5c89e4eSSatish Balay    Note:
364e5c89e4eSSatish Balay      Null string returns a string starting with zero
365e5c89e4eSSatish Balay 
366ff32304bSBarry Smith      If the string that is being copied is of length n or larger then the entire string is not
3671b6ef838SBarry Smith      copied and the final location of s is set to NULL. This is different then the behavior of
3681b6ef838SBarry Smith      strncpy() which leaves s non-terminated if there is not room for the entire string.
369ff32304bSBarry Smith 
37062a5de14SBarry Smith   Developers Note: Should this be PetscStrlcpy() to reflect its behavior which is like strlcpy() not strncpy()
37162a5de14SBarry Smith 
372a126751eSBarry Smith .seealso: PetscStrcpy(), PetscStrcat(), PetscStrlcat()
373e5c89e4eSSatish Balay 
374e5c89e4eSSatish Balay @*/
3757087cfbeSBarry Smith PetscErrorCode  PetscStrncpy(char s[],const char t[],size_t n)
376e5c89e4eSSatish Balay {
377e5c89e4eSSatish Balay   PetscFunctionBegin;
37817186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
37962a5de14SBarry Smith   if (s && !n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Requires an output string of length at least 1 to hold the termination character");
380ff32304bSBarry Smith   if (t) {
3818dc57659SBarry Smith     if (n > 1) {
3822c26941aSBarry Smith       strncpy(s,t,n-1);
383ff32304bSBarry Smith       s[n-1] = '\0';
3848dc57659SBarry Smith     } else {
3858dc57659SBarry Smith       s[0] = '\0';
3868dc57659SBarry Smith     }
387ff32304bSBarry Smith   } else if (s) s[0] = 0;
388e5c89e4eSSatish Balay   PetscFunctionReturn(0);
389e5c89e4eSSatish Balay }
390e5c89e4eSSatish Balay 
391e5c89e4eSSatish Balay /*@C
392e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
393e5c89e4eSSatish Balay 
394e5c89e4eSSatish Balay    Not Collective
395e5c89e4eSSatish Balay 
396e5c89e4eSSatish Balay    Input Parameters:
397e5e2177aSMatthew Knepley +  s - string to be added to
398e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
399e5c89e4eSSatish Balay 
400e5c89e4eSSatish Balay    Level: intermediate
401e5c89e4eSSatish Balay 
40295452b02SPatrick Sanan    Notes:
40395452b02SPatrick Sanan     Not for use in Fortran
4046f013253SBarry Smith 
405a126751eSBarry Smith .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrlcat()
406e5c89e4eSSatish Balay 
407e5c89e4eSSatish Balay @*/
4087087cfbeSBarry Smith PetscErrorCode  PetscStrcat(char s[],const char t[])
409e5c89e4eSSatish Balay {
410e5c89e4eSSatish Balay   PetscFunctionBegin;
4119b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
412e5c89e4eSSatish Balay   strcat(s,t);
413e5c89e4eSSatish Balay   PetscFunctionReturn(0);
414e5c89e4eSSatish Balay }
415e5c89e4eSSatish Balay 
416e5c89e4eSSatish Balay /*@C
417a126751eSBarry Smith    PetscStrlcat - Concatenates a string onto a given string, up to a given length
418e5c89e4eSSatish Balay 
419e5c89e4eSSatish Balay    Not Collective
420e5c89e4eSSatish Balay 
421e5c89e4eSSatish Balay    Input Parameters:
422e0ffd71fSBarry Smith +  s - pointer to string to be added to at end
423e5c89e4eSSatish Balay .  t - string to be added to
42424a58d73SPatrick Sanan -  n - length of the original allocated string
425e5c89e4eSSatish Balay 
426e5c89e4eSSatish Balay    Level: intermediate
427e5c89e4eSSatish Balay 
42824a58d73SPatrick Sanan   Notes:
42924a58d73SPatrick Sanan   Not for use in Fortran
4306f013253SBarry Smith 
43124a58d73SPatrick Sanan   Unlike the system call strncat(), the length passed in is the length of the
43224a58d73SPatrick Sanan   original allocated space, not the length of the left-over space. This is
43324a58d73SPatrick Sanan   similar to the BSD system call strlcat().
434153a8027SBarry Smith 
435e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
436e5c89e4eSSatish Balay 
437e5c89e4eSSatish Balay @*/
438a126751eSBarry Smith PetscErrorCode  PetscStrlcat(char s[],const char t[],size_t n)
439e5c89e4eSSatish Balay {
440153a8027SBarry Smith   size_t         len;
441153a8027SBarry Smith   PetscErrorCode ierr;
442153a8027SBarry Smith 
443e5c89e4eSSatish Balay   PetscFunctionBegin;
444681eeb0aSBarry Smith   if (t && !n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"String buffer length must be positive");
445e0ffd71fSBarry Smith   if (!t) PetscFunctionReturn(0);
446153a8027SBarry Smith   ierr = PetscStrlen(t,&len);CHKERRQ(ierr);
447153a8027SBarry Smith   strncat(s,t,n - len);
448681eeb0aSBarry Smith   s[n-1] = 0;
449e5c89e4eSSatish Balay   PetscFunctionReturn(0);
450e5c89e4eSSatish Balay }
451e5c89e4eSSatish Balay 
452573b0fb4SBarry Smith void  PetscStrcmpNoError(const char a[],const char b[],PetscBool  *flg)
453573b0fb4SBarry Smith {
454573b0fb4SBarry Smith   int c;
455573b0fb4SBarry Smith 
456573b0fb4SBarry Smith   if (!a && !b)      *flg = PETSC_TRUE;
457573b0fb4SBarry Smith   else if (!a || !b) *flg = PETSC_FALSE;
458573b0fb4SBarry Smith   else {
459573b0fb4SBarry Smith     c = strcmp(a,b);
460573b0fb4SBarry Smith     if (c) *flg = PETSC_FALSE;
461573b0fb4SBarry Smith     else   *flg = PETSC_TRUE;
462573b0fb4SBarry Smith   }
463573b0fb4SBarry Smith }
464573b0fb4SBarry Smith 
465e5c89e4eSSatish Balay /*@C
466e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
467e5c89e4eSSatish Balay 
468e5c89e4eSSatish Balay    Not Collective
469e5c89e4eSSatish Balay 
470e5c89e4eSSatish Balay    Input Parameters:
471e5c89e4eSSatish Balay +  a - pointer to string first string
472e5c89e4eSSatish Balay -  b - pointer to second string
473e5c89e4eSSatish Balay 
474e5c89e4eSSatish Balay    Output Parameter:
4758c74ee41SBarry Smith .  flg - PETSC_TRUE if the two strings are equal
476e5c89e4eSSatish Balay 
477e5c89e4eSSatish Balay    Level: intermediate
478e5c89e4eSSatish Balay 
47995452b02SPatrick Sanan    Notes:
48095452b02SPatrick Sanan     Not for use in Fortran
4816f013253SBarry Smith 
482e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
483e5c89e4eSSatish Balay 
484e5c89e4eSSatish Balay @*/
4857087cfbeSBarry Smith PetscErrorCode  PetscStrcmp(const char a[],const char b[],PetscBool  *flg)
486e5c89e4eSSatish Balay {
487e5c89e4eSSatish Balay   int c;
488e5c89e4eSSatish Balay 
489e5c89e4eSSatish Balay   PetscFunctionBegin;
490a297a907SKarl Rupp   if (!a && !b)      *flg = PETSC_TRUE;
491a297a907SKarl Rupp   else if (!a || !b) *flg = PETSC_FALSE;
492a297a907SKarl Rupp   else {
493e5c89e4eSSatish Balay     c = strcmp(a,b);
494e5c89e4eSSatish Balay     if (c) *flg = PETSC_FALSE;
495e5c89e4eSSatish Balay     else   *flg = PETSC_TRUE;
496e5c89e4eSSatish Balay   }
497e5c89e4eSSatish Balay   PetscFunctionReturn(0);
498e5c89e4eSSatish Balay }
499e5c89e4eSSatish Balay 
500e5c89e4eSSatish Balay /*@C
501e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
502e5c89e4eSSatish Balay 
503e5c89e4eSSatish Balay    Not Collective
504e5c89e4eSSatish Balay 
505e5c89e4eSSatish Balay    Input Parameters:
506e5c89e4eSSatish Balay +  a - pointer to first string
507e5c89e4eSSatish Balay -  b - pointer to second string
508e5c89e4eSSatish Balay 
509e5c89e4eSSatish Balay    Output Parameter:
510e5c89e4eSSatish Balay .  flg - if the first string is greater
511e5c89e4eSSatish Balay 
512e5c89e4eSSatish Balay    Notes:
513e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
514e5c89e4eSSatish Balay     all others
515e5c89e4eSSatish Balay 
5166f013253SBarry Smith    Not for use in Fortran
5176f013253SBarry Smith 
518e5c89e4eSSatish Balay    Level: intermediate
519e5c89e4eSSatish Balay 
520e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
521e5c89e4eSSatish Balay 
522e5c89e4eSSatish Balay @*/
5237087cfbeSBarry Smith PetscErrorCode  PetscStrgrt(const char a[],const char b[],PetscBool  *t)
524e5c89e4eSSatish Balay {
525e5c89e4eSSatish Balay   int c;
526e5c89e4eSSatish Balay 
527e5c89e4eSSatish Balay   PetscFunctionBegin;
528a297a907SKarl Rupp   if (!a && !b) *t = PETSC_FALSE;
529a297a907SKarl Rupp   else if (a && !b) *t = PETSC_TRUE;
530a297a907SKarl Rupp   else if (!a && b) *t = PETSC_FALSE;
531a297a907SKarl Rupp   else {
532e5c89e4eSSatish Balay     c = strcmp(a,b);
533e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
534e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
535e5c89e4eSSatish Balay   }
536e5c89e4eSSatish Balay   PetscFunctionReturn(0);
537e5c89e4eSSatish Balay }
538e5c89e4eSSatish Balay 
539e5c89e4eSSatish Balay /*@C
540e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
541e5c89e4eSSatish Balay      except possibly for case.
542e5c89e4eSSatish Balay 
543e5c89e4eSSatish Balay    Not Collective
544e5c89e4eSSatish Balay 
545e5c89e4eSSatish Balay    Input Parameters:
546e5c89e4eSSatish Balay +  a - pointer to first string
547e5c89e4eSSatish Balay -  b - pointer to second string
548e5c89e4eSSatish Balay 
549e5c89e4eSSatish Balay    Output Parameter:
550e5c89e4eSSatish Balay .  flg - if the two strings are the same
551e5c89e4eSSatish Balay 
552e5c89e4eSSatish Balay    Notes:
553e5c89e4eSSatish Balay     Null arguments are ok
554e5c89e4eSSatish Balay 
5556f013253SBarry Smith    Not for use in Fortran
5566f013253SBarry Smith 
557e5c89e4eSSatish Balay    Level: intermediate
558e5c89e4eSSatish Balay 
559e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
560e5c89e4eSSatish Balay 
561e5c89e4eSSatish Balay @*/
5627087cfbeSBarry Smith PetscErrorCode  PetscStrcasecmp(const char a[],const char b[],PetscBool  *t)
563e5c89e4eSSatish Balay {
564e5c89e4eSSatish Balay   int c;
565e5c89e4eSSatish Balay 
566e5c89e4eSSatish Balay   PetscFunctionBegin;
567e5c89e4eSSatish Balay   if (!a && !b) c = 0;
568e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
56932b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
57032b366c8SSatish Balay   else c = strcasecmp(a,b);
57132b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
572e5c89e4eSSatish Balay   else c = stricmp(a,b);
573e5c89e4eSSatish Balay #else
57432b366c8SSatish Balay   else {
57532b366c8SSatish Balay     char           *aa,*bb;
57632b366c8SSatish Balay     PetscErrorCode ierr;
57732b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
57832b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
57932b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
58032b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
58132b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
582503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
583503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
58432b366c8SSatish Balay     PetscFunctionReturn(0);
58532b366c8SSatish Balay   }
586e5c89e4eSSatish Balay #endif
587e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
588e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
589e5c89e4eSSatish Balay   PetscFunctionReturn(0);
590e5c89e4eSSatish Balay }
591e5c89e4eSSatish Balay 
59232b366c8SSatish Balay 
59332b366c8SSatish Balay 
594e5c89e4eSSatish Balay /*@C
595e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
596e5c89e4eSSatish Balay 
597e5c89e4eSSatish Balay    Not Collective
598e5c89e4eSSatish Balay 
599e5c89e4eSSatish Balay    Input Parameters:
600e5c89e4eSSatish Balay +  a - pointer to first string
601e5c89e4eSSatish Balay .  b - pointer to second string
602e5c89e4eSSatish Balay -  n - length to compare up to
603e5c89e4eSSatish Balay 
604e5c89e4eSSatish Balay    Output Parameter:
605e5c89e4eSSatish Balay .  t - if the two strings are equal
606e5c89e4eSSatish Balay 
607e5c89e4eSSatish Balay    Level: intermediate
608e5c89e4eSSatish Balay 
60995452b02SPatrick Sanan    Notes:
61095452b02SPatrick Sanan     Not for use in Fortran
6116f013253SBarry Smith 
612e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
613e5c89e4eSSatish Balay 
614e5c89e4eSSatish Balay @*/
6157087cfbeSBarry Smith PetscErrorCode  PetscStrncmp(const char a[],const char b[],size_t n,PetscBool  *t)
616e5c89e4eSSatish Balay {
617e5c89e4eSSatish Balay   int c;
618e5c89e4eSSatish Balay 
619e5c89e4eSSatish Balay   PetscFunctionBegin;
620e5c89e4eSSatish Balay   c = strncmp(a,b,n);
621e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
622e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
623e5c89e4eSSatish Balay   PetscFunctionReturn(0);
624e5c89e4eSSatish Balay }
625e5c89e4eSSatish Balay 
626e5c89e4eSSatish Balay /*@C
627e5c89e4eSSatish Balay    PetscStrchr - Locates first occurance of a character in a string
628e5c89e4eSSatish Balay 
629e5c89e4eSSatish Balay    Not Collective
630e5c89e4eSSatish Balay 
631e5c89e4eSSatish Balay    Input Parameters:
632e5c89e4eSSatish Balay +  a - pointer to string
633e5c89e4eSSatish Balay -  b - character
634e5c89e4eSSatish Balay 
635e5c89e4eSSatish Balay    Output Parameter:
6360298fd71SBarry Smith .  c - location of occurance, NULL if not found
637e5c89e4eSSatish Balay 
638e5c89e4eSSatish Balay    Level: intermediate
639e5c89e4eSSatish Balay 
64095452b02SPatrick Sanan    Notes:
64195452b02SPatrick Sanan     Not for use in Fortran
6426f013253SBarry Smith 
643e5c89e4eSSatish Balay @*/
6447087cfbeSBarry Smith PetscErrorCode  PetscStrchr(const char a[],char b,char *c[])
645e5c89e4eSSatish Balay {
646e5c89e4eSSatish Balay   PetscFunctionBegin;
647e5c89e4eSSatish Balay   *c = (char*)strchr(a,b);
648e5c89e4eSSatish Balay   PetscFunctionReturn(0);
649e5c89e4eSSatish Balay }
650e5c89e4eSSatish Balay 
651e5c89e4eSSatish Balay /*@C
652e5c89e4eSSatish Balay    PetscStrrchr - Locates one location past the last occurance of a character in a string,
653e5c89e4eSSatish Balay       if the character is not found then returns entire string
654e5c89e4eSSatish Balay 
655e5c89e4eSSatish Balay    Not Collective
656e5c89e4eSSatish Balay 
657e5c89e4eSSatish Balay    Input Parameters:
658e5c89e4eSSatish Balay +  a - pointer to string
659e5c89e4eSSatish Balay -  b - character
660e5c89e4eSSatish Balay 
661e5c89e4eSSatish Balay    Output Parameter:
662e5c89e4eSSatish Balay .  tmp - location of occurance, a if not found
663e5c89e4eSSatish Balay 
664e5c89e4eSSatish Balay    Level: intermediate
665e5c89e4eSSatish Balay 
66695452b02SPatrick Sanan    Notes:
66795452b02SPatrick Sanan     Not for use in Fortran
6686f013253SBarry Smith 
669e5c89e4eSSatish Balay @*/
6707087cfbeSBarry Smith PetscErrorCode  PetscStrrchr(const char a[],char b,char *tmp[])
671e5c89e4eSSatish Balay {
672e5c89e4eSSatish Balay   PetscFunctionBegin;
673e5c89e4eSSatish Balay   *tmp = (char*)strrchr(a,b);
674a297a907SKarl Rupp   if (!*tmp) *tmp = (char*)a;
675a297a907SKarl Rupp   else *tmp = *tmp + 1;
676e5c89e4eSSatish Balay   PetscFunctionReturn(0);
677e5c89e4eSSatish Balay }
678e5c89e4eSSatish Balay 
679e5c89e4eSSatish Balay /*@C
680e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
681e5c89e4eSSatish Balay 
682e5c89e4eSSatish Balay    Not Collective
683e5c89e4eSSatish Balay 
684e5c89e4eSSatish Balay    Input Parameters:
685e5c89e4eSSatish Balay .  a - pointer to string
686e5c89e4eSSatish Balay 
687e5c89e4eSSatish Balay    Level: intermediate
688e5c89e4eSSatish Balay 
68995452b02SPatrick Sanan    Notes:
69095452b02SPatrick Sanan     Not for use in Fortran
6916f013253SBarry Smith 
692e5c89e4eSSatish Balay @*/
6937087cfbeSBarry Smith PetscErrorCode  PetscStrtolower(char a[])
694e5c89e4eSSatish Balay {
695e5c89e4eSSatish Balay   PetscFunctionBegin;
696e5c89e4eSSatish Balay   while (*a) {
697e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
698e5c89e4eSSatish Balay     a++;
699e5c89e4eSSatish Balay   }
700e5c89e4eSSatish Balay   PetscFunctionReturn(0);
701e5c89e4eSSatish Balay }
702e5c89e4eSSatish Balay 
7032f234a98SBarry Smith /*@C
7046e3a5469SBarry Smith    PetscStrtoupper - Converts string to upper case
7052f234a98SBarry Smith 
7062f234a98SBarry Smith    Not Collective
7072f234a98SBarry Smith 
7082f234a98SBarry Smith    Input Parameters:
7092f234a98SBarry Smith .  a - pointer to string
7102f234a98SBarry Smith 
7112f234a98SBarry Smith    Level: intermediate
7122f234a98SBarry Smith 
71395452b02SPatrick Sanan    Notes:
71495452b02SPatrick Sanan     Not for use in Fortran
7152f234a98SBarry Smith 
7162f234a98SBarry Smith @*/
7172f234a98SBarry Smith PetscErrorCode  PetscStrtoupper(char a[])
7182f234a98SBarry Smith {
7192f234a98SBarry Smith   PetscFunctionBegin;
7202f234a98SBarry Smith   while (*a) {
7212f234a98SBarry Smith     if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a';
7222f234a98SBarry Smith     a++;
7232f234a98SBarry Smith   }
7242f234a98SBarry Smith   PetscFunctionReturn(0);
7252f234a98SBarry Smith }
7262f234a98SBarry Smith 
7277ba3a57cSBarry Smith /*@C
7287ba3a57cSBarry Smith    PetscStrendswith - Determines if a string ends with a certain string
7291d1a0024SBarry Smith 
7307ba3a57cSBarry Smith    Not Collective
7317ba3a57cSBarry Smith 
7327ba3a57cSBarry Smith    Input Parameters:
7337ba3a57cSBarry Smith +  a - pointer to string
7347ba3a57cSBarry Smith -  b - string to endwith
7357ba3a57cSBarry Smith 
7367ba3a57cSBarry Smith    Output Parameter:
7377ba3a57cSBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
7387ba3a57cSBarry Smith 
73995452b02SPatrick Sanan    Notes:
74095452b02SPatrick Sanan     Not for use in Fortran
7417ba3a57cSBarry Smith 
7427ba3a57cSBarry Smith    Level: intermediate
7437ba3a57cSBarry Smith 
7447ba3a57cSBarry Smith @*/
7457ba3a57cSBarry Smith PetscErrorCode  PetscStrendswith(const char a[],const char b[],PetscBool *flg)
7467ba3a57cSBarry Smith {
7477ba3a57cSBarry Smith   char           *test;
7487ba3a57cSBarry Smith   PetscErrorCode ierr;
7497ba3a57cSBarry Smith   size_t         na,nb;
7507ba3a57cSBarry Smith 
7517ba3a57cSBarry Smith   PetscFunctionBegin;
7527ba3a57cSBarry Smith   *flg = PETSC_FALSE;
7537ba3a57cSBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
7547ba3a57cSBarry Smith   if (test) {
7557ba3a57cSBarry Smith     ierr = PetscStrlen(a,&na);CHKERRQ(ierr);
7567ba3a57cSBarry Smith     ierr = PetscStrlen(b,&nb);CHKERRQ(ierr);
7577ba3a57cSBarry Smith     if (a+na-nb == test) *flg = PETSC_TRUE;
7587ba3a57cSBarry Smith   }
7597ba3a57cSBarry Smith   PetscFunctionReturn(0);
7607ba3a57cSBarry Smith }
7617ba3a57cSBarry Smith 
7622c9581d2SBarry Smith /*@C
7632c9581d2SBarry Smith    PetscStrbeginswith - Determines if a string begins with a certain string
7642c9581d2SBarry Smith 
7652c9581d2SBarry Smith    Not Collective
7662c9581d2SBarry Smith 
7672c9581d2SBarry Smith    Input Parameters:
7682c9581d2SBarry Smith +  a - pointer to string
7692c9581d2SBarry Smith -  b - string to begin with
7702c9581d2SBarry Smith 
7712c9581d2SBarry Smith    Output Parameter:
7722c9581d2SBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
7732c9581d2SBarry Smith 
77495452b02SPatrick Sanan    Notes:
77595452b02SPatrick Sanan     Not for use in Fortran
7762c9581d2SBarry Smith 
7772c9581d2SBarry Smith    Level: intermediate
7782c9581d2SBarry Smith 
7796e3a5469SBarry Smith .seealso: PetscStrendswithwhich(), PetscStrendswith(), PetscStrtoupper, PetscStrtolower(), PetscStrrchr(), PetscStrchr(),
7806e3a5469SBarry Smith           PetscStrncmp(), PetscStrlen(), PetscStrncmp(), PetscStrcmp()
7816e3a5469SBarry Smith 
7822c9581d2SBarry Smith @*/
7832c9581d2SBarry Smith PetscErrorCode  PetscStrbeginswith(const char a[],const char b[],PetscBool *flg)
7842c9581d2SBarry Smith {
7852c9581d2SBarry Smith   char           *test;
7862c9581d2SBarry Smith   PetscErrorCode ierr;
7872c9581d2SBarry Smith 
7882c9581d2SBarry Smith   PetscFunctionBegin;
7892c9581d2SBarry Smith   *flg = PETSC_FALSE;
7902c9581d2SBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
791a297a907SKarl Rupp   if (test && (test == a)) *flg = PETSC_TRUE;
7922c9581d2SBarry Smith   PetscFunctionReturn(0);
7932c9581d2SBarry Smith }
7942c9581d2SBarry Smith 
7952c9581d2SBarry Smith 
7967ba3a57cSBarry Smith /*@C
7977ba3a57cSBarry Smith    PetscStrendswithwhich - Determines if a string ends with one of several possible strings
7987ba3a57cSBarry Smith 
7997ba3a57cSBarry Smith    Not Collective
8007ba3a57cSBarry Smith 
8017ba3a57cSBarry Smith    Input Parameters:
8027ba3a57cSBarry Smith +  a - pointer to string
8037ba3a57cSBarry Smith -  bs - strings to endwith (last entry must be null)
8047ba3a57cSBarry Smith 
8057ba3a57cSBarry Smith    Output Parameter:
8067ba3a57cSBarry Smith .  cnt - the index of the string it ends with or 1+the last possible index
8077ba3a57cSBarry Smith 
80895452b02SPatrick Sanan    Notes:
80995452b02SPatrick Sanan     Not for use in Fortran
8107ba3a57cSBarry Smith 
8117ba3a57cSBarry Smith    Level: intermediate
8127ba3a57cSBarry Smith 
8137ba3a57cSBarry Smith @*/
8147ba3a57cSBarry Smith PetscErrorCode  PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt)
8157ba3a57cSBarry Smith {
8167ba3a57cSBarry Smith   PetscBool      flg;
8177ba3a57cSBarry Smith   PetscErrorCode ierr;
8187ba3a57cSBarry Smith 
8197ba3a57cSBarry Smith   PetscFunctionBegin;
8207ba3a57cSBarry Smith   *cnt = 0;
8217ba3a57cSBarry Smith   while (bs[*cnt]) {
8227ba3a57cSBarry Smith     ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr);
8237ba3a57cSBarry Smith     if (flg) PetscFunctionReturn(0);
8247ba3a57cSBarry Smith     *cnt += 1;
8257ba3a57cSBarry Smith   }
8267ba3a57cSBarry Smith   PetscFunctionReturn(0);
8277ba3a57cSBarry Smith }
8287ba3a57cSBarry Smith 
8297ba3a57cSBarry Smith /*@C
8307ba3a57cSBarry Smith    PetscStrrstr - Locates last occurance of string in another string
8317ba3a57cSBarry Smith 
8327ba3a57cSBarry Smith    Not Collective
8337ba3a57cSBarry Smith 
8347ba3a57cSBarry Smith    Input Parameters:
8357ba3a57cSBarry Smith +  a - pointer to string
8367ba3a57cSBarry Smith -  b - string to find
8377ba3a57cSBarry Smith 
8387ba3a57cSBarry Smith    Output Parameter:
8397ba3a57cSBarry Smith .  tmp - location of occurance
8407ba3a57cSBarry Smith 
84195452b02SPatrick Sanan    Notes:
84295452b02SPatrick Sanan     Not for use in Fortran
8437ba3a57cSBarry Smith 
8447ba3a57cSBarry Smith    Level: intermediate
8457ba3a57cSBarry Smith 
8467ba3a57cSBarry Smith @*/
8477ba3a57cSBarry Smith PetscErrorCode  PetscStrrstr(const char a[],const char b[],char *tmp[])
8487ba3a57cSBarry Smith {
8497ba3a57cSBarry Smith   const char *stmp = a, *ltmp = 0;
8507ba3a57cSBarry Smith 
8517ba3a57cSBarry Smith   PetscFunctionBegin;
8527ba3a57cSBarry Smith   while (stmp) {
8537ba3a57cSBarry Smith     stmp = (char*)strstr(stmp,b);
8547ba3a57cSBarry Smith     if (stmp) {ltmp = stmp;stmp++;}
8557ba3a57cSBarry Smith   }
8567ba3a57cSBarry Smith   *tmp = (char*)ltmp;
8577ba3a57cSBarry Smith   PetscFunctionReturn(0);
8587ba3a57cSBarry Smith }
8597ba3a57cSBarry Smith 
8607ba3a57cSBarry Smith /*@C
8617ba3a57cSBarry Smith    PetscStrstr - Locates first occurance of string in another string
8627ba3a57cSBarry Smith 
8637ba3a57cSBarry Smith    Not Collective
8647ba3a57cSBarry Smith 
8657ba3a57cSBarry Smith    Input Parameters:
866160f4796SJed Brown +  haystack - string to search
867160f4796SJed Brown -  needle - string to find
8687ba3a57cSBarry Smith 
8697ba3a57cSBarry Smith    Output Parameter:
8700298fd71SBarry Smith .  tmp - location of occurance, is a NULL if the string is not found
8717ba3a57cSBarry Smith 
87295452b02SPatrick Sanan    Notes:
87395452b02SPatrick Sanan     Not for use in Fortran
8747ba3a57cSBarry Smith 
8757ba3a57cSBarry Smith    Level: intermediate
8767ba3a57cSBarry Smith 
8777ba3a57cSBarry Smith @*/
878160f4796SJed Brown PetscErrorCode  PetscStrstr(const char haystack[],const char needle[],char *tmp[])
8797ba3a57cSBarry Smith {
8807ba3a57cSBarry Smith   PetscFunctionBegin;
881160f4796SJed Brown   *tmp = (char*)strstr(haystack,needle);
8827ba3a57cSBarry Smith   PetscFunctionReturn(0);
8837ba3a57cSBarry Smith }
8847ba3a57cSBarry Smith 
8857ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
8861d1a0024SBarry Smith 
887e5c89e4eSSatish Balay /*@C
888e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
889e5c89e4eSSatish Balay 
890e5c89e4eSSatish Balay    Not Collective
891e5c89e4eSSatish Balay 
892e5c89e4eSSatish Balay    Input Parameters:
893e5c89e4eSSatish Balay .  a - pointer to token
894e5c89e4eSSatish Balay 
895e5c89e4eSSatish Balay    Output Parameter:
8960298fd71SBarry Smith .  result - location of occurance, NULL if not found
897e5c89e4eSSatish Balay 
898e5c89e4eSSatish Balay    Notes:
899e5c89e4eSSatish Balay 
900e5c89e4eSSatish Balay      This version is different from the system version in that
901e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
902e5c89e4eSSatish Balay 
9034704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
9044704e885SBarry Smith    as a single token.
9054704e885SBarry Smith 
9063a9c465aSBarry 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
9073a9c465aSBarry Smith    second will return a null terminated y
9083a9c465aSBarry Smith 
9093a9c465aSBarry 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
9103a9c465aSBarry Smith 
9116f013253SBarry Smith     Not for use in Fortran
9126f013253SBarry Smith 
913e5c89e4eSSatish Balay    Level: intermediate
914e5c89e4eSSatish Balay 
9156f013253SBarry Smith 
916e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
917e5c89e4eSSatish Balay @*/
9187087cfbeSBarry Smith PetscErrorCode  PetscTokenFind(PetscToken a,char *result[])
919e5c89e4eSSatish Balay {
9204704e885SBarry Smith   char *ptr = a->current,token;
921e5c89e4eSSatish Balay 
922e5c89e4eSSatish Balay   PetscFunctionBegin;
923e5c89e4eSSatish Balay   *result = a->current;
9244704e885SBarry Smith   if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);}
9254704e885SBarry Smith   token = a->token;
92690fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
927e5c89e4eSSatish Balay   while (ptr) {
9284704e885SBarry Smith     if (*ptr == token) {
929e5c89e4eSSatish Balay       *ptr++ = 0;
930e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
931e5c89e4eSSatish Balay       a->current = ptr;
932e5c89e4eSSatish Balay       break;
933e5c89e4eSSatish Balay     }
934e5c89e4eSSatish Balay     if (!*ptr) {
935e5c89e4eSSatish Balay       a->current = 0;
936e5c89e4eSSatish Balay       break;
937e5c89e4eSSatish Balay     }
938e5c89e4eSSatish Balay     ptr++;
939e5c89e4eSSatish Balay   }
940e5c89e4eSSatish Balay   PetscFunctionReturn(0);
941e5c89e4eSSatish Balay }
942e5c89e4eSSatish Balay 
943e5c89e4eSSatish Balay /*@C
944e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
945e5c89e4eSSatish Balay 
946e5c89e4eSSatish Balay    Not Collective
947e5c89e4eSSatish Balay 
948e5c89e4eSSatish Balay    Input Parameters:
949e5c89e4eSSatish Balay +  string - the string to look in
9503a9c465aSBarry Smith -  b - the separator character
951e5c89e4eSSatish Balay 
952e5c89e4eSSatish Balay    Output Parameter:
9533a9c465aSBarry Smith .  t- the token object
954e5c89e4eSSatish Balay 
955e5c89e4eSSatish Balay    Notes:
956e5c89e4eSSatish Balay 
957e5c89e4eSSatish Balay      This version is different from the system version in that
958e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
959e5c89e4eSSatish Balay 
9606f013253SBarry Smith     Not for use in Fortran
9616f013253SBarry Smith 
962e5c89e4eSSatish Balay    Level: intermediate
963e5c89e4eSSatish Balay 
964e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
965e5c89e4eSSatish Balay @*/
9667087cfbeSBarry Smith PetscErrorCode  PetscTokenCreate(const char a[],const char b,PetscToken *t)
967e5c89e4eSSatish Balay {
968e5c89e4eSSatish Balay   PetscErrorCode ierr;
969e5c89e4eSSatish Balay 
970e5c89e4eSSatish Balay   PetscFunctionBegin;
971b00a9115SJed Brown   ierr = PetscNew(t);CHKERRQ(ierr);
972e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
973a297a907SKarl Rupp 
974e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
975e5c89e4eSSatish Balay   (*t)->token   = b;
976e5c89e4eSSatish Balay   PetscFunctionReturn(0);
977e5c89e4eSSatish Balay }
978e5c89e4eSSatish Balay 
979e5c89e4eSSatish Balay /*@C
980e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
981e5c89e4eSSatish Balay 
982e5c89e4eSSatish Balay    Not Collective
983e5c89e4eSSatish Balay 
984e5c89e4eSSatish Balay    Input Parameters:
985e5c89e4eSSatish Balay .  a - pointer to token
986e5c89e4eSSatish Balay 
987e5c89e4eSSatish Balay    Level: intermediate
988e5c89e4eSSatish Balay 
98995452b02SPatrick Sanan    Notes:
99095452b02SPatrick Sanan     Not for use in Fortran
9916f013253SBarry Smith 
992e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
993e5c89e4eSSatish Balay @*/
9948c74ee41SBarry Smith PetscErrorCode  PetscTokenDestroy(PetscToken *a)
995e5c89e4eSSatish Balay {
996e5c89e4eSSatish Balay   PetscErrorCode ierr;
997e5c89e4eSSatish Balay 
998e5c89e4eSSatish Balay   PetscFunctionBegin;
9998c74ee41SBarry Smith   if (!*a) PetscFunctionReturn(0);
10008c74ee41SBarry Smith   ierr = PetscFree((*a)->array);CHKERRQ(ierr);
10018c74ee41SBarry Smith   ierr = PetscFree(*a);CHKERRQ(ierr);
1002e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1003e5c89e4eSSatish Balay }
1004e5c89e4eSSatish Balay 
10058e81d068SLisandro Dalcin /*@C
10068e81d068SLisandro Dalcin    PetscStrInList - search string in character-delimited list
10078e81d068SLisandro Dalcin 
10088e81d068SLisandro Dalcin    Not Collective
10098e81d068SLisandro Dalcin 
10108e81d068SLisandro Dalcin    Input Parameters:
10118e81d068SLisandro Dalcin +  str - the string to look for
10128e81d068SLisandro Dalcin .  list - the list to search in
10138e81d068SLisandro Dalcin -  sep - the separator character
10148e81d068SLisandro Dalcin 
10158e81d068SLisandro Dalcin    Output Parameter:
10168e81d068SLisandro Dalcin .  found - whether str is in list
10178e81d068SLisandro Dalcin 
10188e81d068SLisandro Dalcin    Level: intermediate
10198e81d068SLisandro Dalcin 
102095452b02SPatrick Sanan    Notes:
102195452b02SPatrick Sanan     Not for use in Fortran
10228e81d068SLisandro Dalcin 
10238e81d068SLisandro Dalcin .seealso: PetscTokenCreate(), PetscTokenFind(), PetscStrcmp()
10248e81d068SLisandro Dalcin @*/
10258e81d068SLisandro Dalcin PetscErrorCode PetscStrInList(const char str[],const char list[],char sep,PetscBool *found)
10268e81d068SLisandro Dalcin {
10278e81d068SLisandro Dalcin   PetscToken     token;
10288e81d068SLisandro Dalcin   char           *item;
10298e81d068SLisandro Dalcin   PetscErrorCode ierr;
10308e81d068SLisandro Dalcin 
10318e81d068SLisandro Dalcin   PetscFunctionBegin;
10328e81d068SLisandro Dalcin   *found = PETSC_FALSE;
10338e81d068SLisandro Dalcin   ierr = PetscTokenCreate(list,sep,&token);CHKERRQ(ierr);
10348e81d068SLisandro Dalcin   ierr = PetscTokenFind(token,&item);CHKERRQ(ierr);
10358e81d068SLisandro Dalcin   while (item) {
10368e81d068SLisandro Dalcin     ierr = PetscStrcmp(str,item,found);CHKERRQ(ierr);
10378e81d068SLisandro Dalcin     if (*found) break;
10388e81d068SLisandro Dalcin     ierr = PetscTokenFind(token,&item);CHKERRQ(ierr);
10398e81d068SLisandro Dalcin   }
10408e81d068SLisandro Dalcin   ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
10418e81d068SLisandro Dalcin   PetscFunctionReturn(0);
10428e81d068SLisandro Dalcin }
1043e5c89e4eSSatish Balay 
1044e5c89e4eSSatish Balay /*@C
1045e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
1046e5c89e4eSSatish Balay 
1047e5c89e4eSSatish Balay    Not Collective
1048e5c89e4eSSatish Balay 
1049e5c89e4eSSatish Balay    Output Parameter:
1050e5c89e4eSSatish Balay .  dir - the directory
1051e5c89e4eSSatish Balay 
1052e5c89e4eSSatish Balay    Level: developer
1053e5c89e4eSSatish Balay 
105495452b02SPatrick Sanan    Notes:
105595452b02SPatrick Sanan     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 /*@C
1066e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
1067e5c89e4eSSatish Balay 
1068e5c89e4eSSatish Balay    Not Collective
1069e5c89e4eSSatish Balay 
1070e5c89e4eSSatish Balay    Input Parameters:
1071e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
107271573d7dSBarry Smith .   aa - the string to look in
1073d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
1074e5c89e4eSSatish Balay -   len - the length of b
1075e5c89e4eSSatish Balay 
1076e5c89e4eSSatish Balay    Notes:
1077e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
1078d5649816SBarry Smith       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
1079e5c89e4eSSatish Balay       as well as any environmental variables.
1080e5c89e4eSSatish Balay 
10816f013253SBarry Smith       PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
1082acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
1083acc6cc86SBarry Smith 
10846f013253SBarry Smith       Not for use in Fortran
10856f013253SBarry Smith 
1086e5c89e4eSSatish Balay    Level: intermediate
1087e5c89e4eSSatish Balay 
1088e5c89e4eSSatish Balay @*/
10897087cfbeSBarry Smith PetscErrorCode  PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
1090e5c89e4eSSatish Balay {
1091e5c89e4eSSatish Balay   PetscErrorCode ierr;
1092e5c89e4eSSatish Balay   int            i = 0;
1093e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
109471573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
1095d5649816SBarry Smith   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0};
1096f489ac74SBarry Smith   char           *r[] = {0,0,0,0,0,0,0,0,0};
1097ace3abfcSBarry Smith   PetscBool      flag;
1098e5c89e4eSSatish Balay 
1099e5c89e4eSSatish Balay   PetscFunctionBegin;
1100e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
110171573d7dSBarry Smith   if (aa == b) {
110222982a5fSBarry Smith     ierr = PetscStrallocpy(aa,(char**)&a);CHKERRQ(ierr);
110371573d7dSBarry Smith   }
1104785e854fSJed Brown   ierr = PetscMalloc1(len,&work);CHKERRQ(ierr);
1105e5c89e4eSSatish Balay 
1106e5c89e4eSSatish Balay   /* get values for replaced variables */
1107f1d4cc8fSBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,&r[0]);CHKERRQ(ierr);
1108f1d4cc8fSBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,&r[1]);CHKERRQ(ierr);
1109f1d4cc8fSBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,&r[2]);CHKERRQ(ierr);
1110785e854fSJed Brown   ierr = PetscMalloc1(256,&r[3]);CHKERRQ(ierr);
1111785e854fSJed Brown   ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[4]);CHKERRQ(ierr);
1112785e854fSJed Brown   ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[5]);CHKERRQ(ierr);
1113785e854fSJed Brown   ierr = PetscMalloc1(256,&r[6]);CHKERRQ(ierr);
1114785e854fSJed Brown   ierr = PetscMalloc1(256,&r[7]);CHKERRQ(ierr);
1115f1d4cc8fSBarry Smith   ierr = PetscGetDisplay(r[3],256);CHKERRQ(ierr);
1116f1d4cc8fSBarry Smith   ierr = PetscGetHomeDirectory(r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1117f1d4cc8fSBarry Smith   ierr = PetscGetWorkingDirectory(r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1118f1d4cc8fSBarry Smith   ierr = PetscGetUserName(r[6],256);CHKERRQ(ierr);
1119f1d4cc8fSBarry Smith   ierr = PetscGetHostName(r[7],256);CHKERRQ(ierr);
1120487e5849SBarry Smith 
1121487e5849SBarry Smith   /* replace that are in environment */
1122487e5849SBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr);
1123487e5849SBarry Smith   if (flag) {
112431936d58SMatthew G. Knepley     ierr = PetscFree(r[2]);CHKERRQ(ierr);
1125f1d4cc8fSBarry Smith     ierr = PetscStrallocpy(env,&r[2]);CHKERRQ(ierr);
1126487e5849SBarry Smith   }
1127e5c89e4eSSatish Balay 
1128e5c89e4eSSatish Balay   /* replace the requested strings */
1129e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
1130e5c89e4eSSatish Balay   while (s[i]) {
1131e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
1132e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1133e5c89e4eSSatish Balay     while (par) {
1134e5c89e4eSSatish Balay       *par =  0;
1135e5c89e4eSSatish Balay       par += l;
1136e5c89e4eSSatish Balay 
1137e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
1138e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
1139e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
114017186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
1141e5c89e4eSSatish Balay       ierr = PetscStrcpy(work,b);CHKERRQ(ierr);
1142e5c89e4eSSatish Balay       ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr);
1143e5c89e4eSSatish Balay       ierr = PetscStrcat(work,par);CHKERRQ(ierr);
1144e5c89e4eSSatish Balay       ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr);
1145e5c89e4eSSatish Balay       ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1146e5c89e4eSSatish Balay     }
1147e5c89e4eSSatish Balay     i++;
1148e5c89e4eSSatish Balay   }
1149487e5849SBarry Smith   i = 0;
1150487e5849SBarry Smith   while (r[i]) {
1151e5c89e4eSSatish Balay     tfree = (char*)r[i];
1152e5c89e4eSSatish Balay     ierr  = PetscFree(tfree);CHKERRQ(ierr);
1153487e5849SBarry Smith     i++;
1154e5c89e4eSSatish Balay   }
1155e5c89e4eSSatish Balay 
1156e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
1157e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1158e5c89e4eSSatish Balay   while (par) {
1159e5c89e4eSSatish Balay     *par  = 0;
1160e5c89e4eSSatish Balay     par  += 2;
1161e5c89e4eSSatish Balay     ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
1162e5c89e4eSSatish Balay     ierr  = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
1163e5c89e4eSSatish Balay     *epar = 0;
1164e5c89e4eSSatish Balay     epar += 1;
1165e5c89e4eSSatish Balay     ierr  = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr);
11667ba3a57cSBarry Smith     if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
1167e5c89e4eSSatish Balay     ierr = PetscStrcat(work,env);CHKERRQ(ierr);
1168e5c89e4eSSatish Balay     ierr = PetscStrcat(work,epar);CHKERRQ(ierr);
1169e5c89e4eSSatish Balay     ierr = PetscStrcpy(b,work);CHKERRQ(ierr);
1170e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1171e5c89e4eSSatish Balay   }
1172e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
117371573d7dSBarry Smith   if (aa == b) {
117471573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
117571573d7dSBarry Smith   }
1176e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1177e5c89e4eSSatish Balay }
1178e5c89e4eSSatish Balay 
1179a53986e1SJed Brown /*@C
1180a53986e1SJed Brown    PetscEListFind - searches list of strings for given string, using case insensitive matching
1181e5c89e4eSSatish Balay 
1182a53986e1SJed Brown    Not Collective
1183a53986e1SJed Brown 
1184a53986e1SJed Brown    Input Parameters:
1185a53986e1SJed Brown +  n - number of strings in
1186a53986e1SJed Brown .  list - list of strings to search
1187a53986e1SJed Brown -  str - string to look for, empty string "" accepts default (first entry in list)
1188a53986e1SJed Brown 
1189a53986e1SJed Brown    Output Parameters:
1190a53986e1SJed Brown +  value - index of matching string (if found)
1191a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1192a53986e1SJed Brown 
1193a53986e1SJed Brown    Notes:
1194a53986e1SJed Brown    Not for use in Fortran
1195a53986e1SJed Brown 
1196a53986e1SJed Brown    Level: advanced
1197a53986e1SJed Brown @*/
1198a53986e1SJed Brown PetscErrorCode PetscEListFind(PetscInt n,const char *const *list,const char *str,PetscInt *value,PetscBool *found)
1199a53986e1SJed Brown {
1200a53986e1SJed Brown   PetscErrorCode ierr;
1201a53986e1SJed Brown   PetscBool matched;
1202a53986e1SJed Brown   PetscInt i;
1203a53986e1SJed Brown 
1204a53986e1SJed Brown   PetscFunctionBegin;
1205a53986e1SJed Brown   if (found) *found = PETSC_FALSE;
1206a53986e1SJed Brown   for (i=0; i<n; i++) {
1207a53986e1SJed Brown     ierr = PetscStrcasecmp(str,list[i],&matched);CHKERRQ(ierr);
1208a53986e1SJed Brown     if (matched || !str[0]) {
1209a53986e1SJed Brown       if (found) *found = PETSC_TRUE;
1210a53986e1SJed Brown       *value = i;
1211a53986e1SJed Brown       break;
1212a53986e1SJed Brown     }
1213a53986e1SJed Brown   }
1214a53986e1SJed Brown   PetscFunctionReturn(0);
1215a53986e1SJed Brown }
1216a53986e1SJed Brown 
1217a53986e1SJed Brown /*@C
12188e81d068SLisandro Dalcin    PetscEnumFind - searches enum list of strings for given string, using case insensitive matching
1219a53986e1SJed Brown 
1220a53986e1SJed Brown    Not Collective
1221a53986e1SJed Brown 
1222a53986e1SJed Brown    Input Parameters:
1223a53986e1SJed Brown +  enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL
1224a53986e1SJed Brown -  str - string to look for
1225a53986e1SJed Brown 
1226a53986e1SJed Brown    Output Parameters:
1227a53986e1SJed Brown +  value - index of matching string (if found)
1228a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1229a53986e1SJed Brown 
1230a53986e1SJed Brown    Notes:
1231a53986e1SJed Brown    Not for use in Fortran
1232a53986e1SJed Brown 
1233a53986e1SJed Brown    Level: advanced
1234a53986e1SJed Brown @*/
1235a53986e1SJed Brown PetscErrorCode PetscEnumFind(const char *const *enumlist,const char *str,PetscEnum *value,PetscBool *found)
1236a53986e1SJed Brown {
1237a53986e1SJed Brown   PetscErrorCode ierr;
1238d05ba7d2SLisandro Dalcin   PetscInt n = 0,evalue;
1239a53986e1SJed Brown   PetscBool efound;
1240a53986e1SJed Brown 
1241a53986e1SJed Brown   PetscFunctionBegin;
1242d05ba7d2SLisandro 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");
1243a53986e1SJed Brown   if (n < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
1244a53986e1SJed Brown   n -= 3; /* drop enum name, prefix, and null termination */
1245a53986e1SJed Brown   ierr = PetscEListFind(n,enumlist,str,&evalue,&efound);CHKERRQ(ierr);
1246cfb463b1SJed Brown   if (efound) *value = (PetscEnum)evalue;
1247a53986e1SJed Brown   if (found) *found = efound;
1248a53986e1SJed Brown   PetscFunctionReturn(0);
1249a53986e1SJed Brown }
1250