xref: /petsc/src/sys/utils/str.c (revision 681eeb0af371be82e1327e9f80a3d0f662b1c199)
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 
163c311c98SBarry Smith /*@C
17bebe2cf6SSatish Balay    PetscStrToArray - Separates a string by a charactor (for example ' ' or '\n') and creates an array of strings
183c311c98SBarry Smith 
193c311c98SBarry Smith    Not Collective
203c311c98SBarry Smith 
213c311c98SBarry Smith    Input Parameters:
22d67fe73bSBarry Smith +  s - pointer to string
23a2ea699eSBarry Smith -  sp - separator charactor
243c311c98SBarry Smith 
253c311c98SBarry Smith    Output Parameter:
263c311c98SBarry Smith +   argc - the number of entries in the array
273c311c98SBarry Smith -   args - an array of the entries with a null at the end
283c311c98SBarry Smith 
293c311c98SBarry Smith    Level: intermediate
303c311c98SBarry Smith 
31301d30feSBarry Smith    Notes: this may be called before PetscInitialize() or after PetscFinalize()
323c311c98SBarry Smith 
336f013253SBarry Smith    Not for use in Fortran
346f013253SBarry Smith 
35b4cd4cebSBarry Smith    Developer Notes: Using raw malloc() and does not call error handlers since this may be used before PETSc is initialized. Used
36b4cd4cebSBarry Smith      to generate argc, args arguments passed to MPI_Init()
37301d30feSBarry Smith 
38b4cd4cebSBarry Smith .seealso: PetscStrToArrayDestroy(), PetscToken, PetscTokenCreate()
393c311c98SBarry Smith 
403c311c98SBarry Smith @*/
41d67fe73bSBarry Smith PetscErrorCode  PetscStrToArray(const char s[],char sp,int *argc,char ***args)
423c311c98SBarry Smith {
43c3bcdc7eSBarry Smith   int       i,j,n,*lens,cnt = 0;
44ace3abfcSBarry Smith   PetscBool flg = PETSC_FALSE;
453c311c98SBarry Smith 
4640a7e1efSBarry Smith   if (!s) n = 0;
4740a7e1efSBarry Smith   else    n = strlen(s);
483c311c98SBarry Smith   *argc = 0;
4961528463SBarry Smith   *args = NULL;
50acf7dc08SSatish Balay   for (; n>0; n--) {   /* remove separator chars at the end - and will empty the string if all chars are separator chars */
51acf7dc08SSatish Balay     if (s[n-1] != sp) break;
52acf7dc08SSatish Balay   }
534996c5bdSBarry Smith   if (!n) {
544996c5bdSBarry Smith     return(0);
554996c5bdSBarry Smith   }
563c311c98SBarry Smith   for (i=0; i<n; i++) {
57d67fe73bSBarry Smith     if (s[i] != sp) break;
583c311c98SBarry Smith   }
593c311c98SBarry Smith   for (;i<n+1; i++) {
60d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
61d67fe73bSBarry Smith     else if (s[i] != sp) {flg = PETSC_FALSE;}
623c311c98SBarry Smith   }
63a2ea699eSBarry Smith   (*args) = (char**) malloc(((*argc)+1)*sizeof(char*)); if (!*args) return PETSC_ERR_MEM;
6453e6e2c4SHong Zhang   lens    = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM;
653c311c98SBarry Smith   for (i=0; i<*argc; i++) lens[i] = 0;
663c311c98SBarry Smith 
673c311c98SBarry Smith   *argc = 0;
683c311c98SBarry Smith   for (i=0; i<n; i++) {
69d67fe73bSBarry Smith     if (s[i] != sp) break;
703c311c98SBarry Smith   }
717dd9f305SSatish Balay   for (;i<n+1; i++) {
72d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
73d67fe73bSBarry Smith     else if (s[i] != sp) {lens[*argc]++;flg = PETSC_FALSE;}
743c311c98SBarry Smith   }
753c311c98SBarry Smith 
763c311c98SBarry Smith   for (i=0; i<*argc; i++) {
77c3bcdc7eSBarry Smith     (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char));
78c3bcdc7eSBarry Smith     if (!(*args)[i]) {
79c3bcdc7eSBarry Smith       free(lens);
80c3bcdc7eSBarry Smith       for (j=0; j<i; j++) free((*args)[j]);
81c3bcdc7eSBarry Smith       free(*args);
82c3bcdc7eSBarry Smith       return PETSC_ERR_MEM;
83c3bcdc7eSBarry Smith     }
843c311c98SBarry Smith   }
85a2ea699eSBarry Smith   free(lens);
86301d30feSBarry Smith   (*args)[*argc] = 0;
873c311c98SBarry Smith 
883c311c98SBarry Smith   *argc = 0;
893c311c98SBarry Smith   for (i=0; i<n; i++) {
90d67fe73bSBarry Smith     if (s[i] != sp) break;
913c311c98SBarry Smith   }
923c311c98SBarry Smith   for (;i<n+1; i++) {
93d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
94d67fe73bSBarry Smith     else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;}
953c311c98SBarry Smith   }
963c311c98SBarry Smith   return 0;
973c311c98SBarry Smith }
983c311c98SBarry Smith 
99301d30feSBarry Smith /*@C
100301d30feSBarry Smith    PetscStrToArrayDestroy - Frees array created with PetscStrToArray().
101301d30feSBarry Smith 
102301d30feSBarry Smith    Not Collective
103301d30feSBarry Smith 
104301d30feSBarry Smith    Output Parameters:
105301d30feSBarry Smith +  argc - the number of arguments
106301d30feSBarry Smith -  args - the array of arguments
107301d30feSBarry Smith 
108301d30feSBarry Smith    Level: intermediate
109301d30feSBarry Smith 
110301d30feSBarry Smith    Concepts: command line arguments
111301d30feSBarry Smith 
112301d30feSBarry Smith    Notes: This may be called before PetscInitialize() or after PetscFinalize()
113301d30feSBarry Smith 
1146f013253SBarry Smith    Not for use in Fortran
1156f013253SBarry Smith 
116301d30feSBarry Smith .seealso: PetscStrToArray()
117301d30feSBarry Smith 
118301d30feSBarry Smith @*/
1197087cfbeSBarry Smith PetscErrorCode  PetscStrToArrayDestroy(int argc,char **args)
120301d30feSBarry Smith {
121301d30feSBarry Smith   PetscInt i;
122301d30feSBarry Smith 
123a297a907SKarl Rupp   for (i=0; i<argc; i++) free(args[i]);
124a297a907SKarl Rupp   if (args) free(args);
125301d30feSBarry Smith   return 0;
126301d30feSBarry Smith }
127301d30feSBarry Smith 
128e5c89e4eSSatish Balay /*@C
129e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
130e5c89e4eSSatish Balay 
131e5c89e4eSSatish Balay    Not Collective
132e5c89e4eSSatish Balay 
133e5c89e4eSSatish Balay    Input Parameters:
134e5c89e4eSSatish Balay .  s - pointer to string
135e5c89e4eSSatish Balay 
136e5c89e4eSSatish Balay    Output Parameter:
137e5c89e4eSSatish Balay .  len - length in bytes
138e5c89e4eSSatish Balay 
139e5c89e4eSSatish Balay    Level: intermediate
140e5c89e4eSSatish Balay 
141e5c89e4eSSatish Balay    Note:
142e5c89e4eSSatish Balay    This routine is analogous to strlen().
143e5c89e4eSSatish Balay 
144e5c89e4eSSatish Balay    Null string returns a length of zero
145e5c89e4eSSatish Balay 
1466f013253SBarry Smith    Not for use in Fortran
1476f013253SBarry Smith 
148e5c89e4eSSatish Balay   Concepts: string length
149e5c89e4eSSatish Balay 
150e5c89e4eSSatish Balay @*/
1517087cfbeSBarry Smith PetscErrorCode  PetscStrlen(const char s[],size_t *len)
152e5c89e4eSSatish Balay {
153e5c89e4eSSatish Balay   PetscFunctionBegin;
154a297a907SKarl Rupp   if (!s) *len = 0;
155a297a907SKarl Rupp   else    *len = strlen(s);
156e5c89e4eSSatish Balay   PetscFunctionReturn(0);
157e5c89e4eSSatish Balay }
158e5c89e4eSSatish Balay 
159e5c89e4eSSatish Balay /*@C
160e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
161e5c89e4eSSatish Balay 
162e5c89e4eSSatish Balay    Not Collective
163e5c89e4eSSatish Balay 
164e5c89e4eSSatish Balay    Input Parameters:
165e5c89e4eSSatish Balay .  s - pointer to string
166e5c89e4eSSatish Balay 
167e5c89e4eSSatish Balay    Output Parameter:
168e5c89e4eSSatish Balay .  t - the copied string
169e5c89e4eSSatish Balay 
170e5c89e4eSSatish Balay    Level: intermediate
171e5c89e4eSSatish Balay 
172e5c89e4eSSatish Balay    Note:
173e5c89e4eSSatish Balay       Null string returns a new null string
174e5c89e4eSSatish Balay 
1756f013253SBarry Smith       Not for use in Fortran
1766f013253SBarry Smith 
177e5c89e4eSSatish Balay   Concepts: string copy
178e5c89e4eSSatish Balay 
179e5c89e4eSSatish Balay @*/
1807087cfbeSBarry Smith PetscErrorCode  PetscStrallocpy(const char s[],char *t[])
181e5c89e4eSSatish Balay {
182e5c89e4eSSatish Balay   PetscErrorCode ierr;
183e5c89e4eSSatish Balay   size_t         len;
18471573d7dSBarry Smith   char           *tmp = 0;
185e5c89e4eSSatish Balay 
186e5c89e4eSSatish Balay   PetscFunctionBegin;
187e5c89e4eSSatish Balay   if (s) {
188e5c89e4eSSatish Balay     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
189854ce69bSBarry Smith     ierr = PetscMalloc1(1+len,&tmp);CHKERRQ(ierr);
19071573d7dSBarry Smith     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
191e5c89e4eSSatish Balay   }
19271573d7dSBarry Smith   *t = tmp;
193e5c89e4eSSatish Balay   PetscFunctionReturn(0);
194e5c89e4eSSatish Balay }
195e5c89e4eSSatish Balay 
19647340559SBarry Smith /*@C
19747340559SBarry Smith    PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
19847340559SBarry Smith 
19947340559SBarry Smith    Not Collective
20047340559SBarry Smith 
20147340559SBarry Smith    Input Parameters:
20247340559SBarry Smith .  s - pointer to array of strings (final string is a null)
20347340559SBarry Smith 
20447340559SBarry Smith    Output Parameter:
20547340559SBarry Smith .  t - the copied array string
20647340559SBarry Smith 
20747340559SBarry Smith    Level: intermediate
20847340559SBarry Smith 
20947340559SBarry Smith    Note:
21047340559SBarry Smith       Not for use in Fortran
21147340559SBarry Smith 
21247340559SBarry Smith   Concepts: string copy
21347340559SBarry Smith 
21447340559SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
21547340559SBarry Smith 
21647340559SBarry Smith @*/
21747340559SBarry Smith PetscErrorCode  PetscStrArrayallocpy(const char *const *list,char ***t)
21847340559SBarry Smith {
21947340559SBarry Smith   PetscErrorCode ierr;
22047340559SBarry Smith   PetscInt       i,n = 0;
22147340559SBarry Smith 
22247340559SBarry Smith   PetscFunctionBegin;
22347340559SBarry Smith   while (list[n++]) ;
224854ce69bSBarry Smith   ierr = PetscMalloc1(n+1,t);CHKERRQ(ierr);
22547340559SBarry Smith   for (i=0; i<n; i++) {
22647340559SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
22747340559SBarry Smith   }
2280298fd71SBarry Smith   (*t)[n] = NULL;
22947340559SBarry Smith   PetscFunctionReturn(0);
23047340559SBarry Smith }
23147340559SBarry Smith 
23247340559SBarry Smith /*@C
23347340559SBarry Smith    PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
23447340559SBarry Smith 
23547340559SBarry Smith    Not Collective
23647340559SBarry Smith 
23747340559SBarry Smith    Output Parameters:
23847340559SBarry Smith .   list - array of strings
23947340559SBarry Smith 
24047340559SBarry Smith    Level: intermediate
24147340559SBarry Smith 
24247340559SBarry Smith    Concepts: command line arguments
24347340559SBarry Smith 
24447340559SBarry Smith    Notes: Not for use in Fortran
24547340559SBarry Smith 
24647340559SBarry Smith .seealso: PetscStrArrayallocpy()
24747340559SBarry Smith 
24847340559SBarry Smith @*/
2496fed8037SJed Brown PetscErrorCode PetscStrArrayDestroy(char ***list)
25047340559SBarry Smith {
25147340559SBarry Smith   PetscInt       n = 0;
25247340559SBarry Smith   PetscErrorCode ierr;
25347340559SBarry Smith 
2546fed8037SJed Brown   PetscFunctionBegin;
2556fed8037SJed Brown   if (!*list) PetscFunctionReturn(0);
2566fed8037SJed Brown   while ((*list)[n]) {
2576fed8037SJed Brown     ierr = PetscFree((*list)[n]);CHKERRQ(ierr);
25847340559SBarry Smith     n++;
25947340559SBarry Smith   }
2606fed8037SJed Brown   ierr = PetscFree(*list);CHKERRQ(ierr);
2616fed8037SJed Brown   PetscFunctionReturn(0);
26247340559SBarry Smith }
26347340559SBarry Smith 
2646991f827SBarry Smith /*@C
2656991f827SBarry Smith    PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
2666991f827SBarry Smith 
2676991f827SBarry Smith    Not Collective
2686991f827SBarry Smith 
2696991f827SBarry Smith    Input Parameters:
2706991f827SBarry Smith +  n - the number of string entries
2716991f827SBarry Smith -  s - pointer to array of strings
2726991f827SBarry Smith 
2736991f827SBarry Smith    Output Parameter:
2746991f827SBarry Smith .  t - the copied array string
2756991f827SBarry Smith 
2766991f827SBarry Smith    Level: intermediate
2776991f827SBarry Smith 
2786991f827SBarry Smith    Note:
2796991f827SBarry Smith       Not for use in Fortran
2806991f827SBarry Smith 
2816991f827SBarry Smith   Concepts: string copy
2826991f827SBarry Smith 
2836991f827SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
2846991f827SBarry Smith 
2856991f827SBarry Smith @*/
2866991f827SBarry Smith PetscErrorCode  PetscStrNArrayallocpy(PetscInt n,const char *const *list,char ***t)
2876991f827SBarry Smith {
2886991f827SBarry Smith   PetscErrorCode ierr;
2896991f827SBarry Smith   PetscInt       i;
2906991f827SBarry Smith 
2916991f827SBarry Smith   PetscFunctionBegin;
2926991f827SBarry Smith   ierr = PetscMalloc1(n,t);CHKERRQ(ierr);
2936991f827SBarry Smith   for (i=0; i<n; i++) {
2946991f827SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
2956991f827SBarry Smith   }
2966991f827SBarry Smith   PetscFunctionReturn(0);
2976991f827SBarry Smith }
2986991f827SBarry Smith 
2996991f827SBarry Smith /*@C
3006991f827SBarry Smith    PetscStrNArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
3016991f827SBarry Smith 
3026991f827SBarry Smith    Not Collective
3036991f827SBarry Smith 
3046991f827SBarry Smith    Output Parameters:
3056991f827SBarry Smith +   n - number of string entries
3066991f827SBarry Smith -   list - array of strings
3076991f827SBarry Smith 
3086991f827SBarry Smith    Level: intermediate
3096991f827SBarry Smith 
3106991f827SBarry Smith    Notes: Not for use in Fortran
3116991f827SBarry Smith 
3126991f827SBarry Smith .seealso: PetscStrArrayallocpy()
3136991f827SBarry Smith 
3146991f827SBarry Smith @*/
3156991f827SBarry Smith PetscErrorCode PetscStrNArrayDestroy(PetscInt n,char ***list)
3166991f827SBarry Smith {
3176991f827SBarry Smith   PetscErrorCode ierr;
3186991f827SBarry Smith   PetscInt       i;
3196991f827SBarry Smith 
3206991f827SBarry Smith   PetscFunctionBegin;
3216991f827SBarry Smith   if (!*list) PetscFunctionReturn(0);
3226991f827SBarry Smith   for (i=0; i<n; i++){
3236991f827SBarry Smith     ierr = PetscFree((*list)[i]);CHKERRQ(ierr);
3246991f827SBarry Smith   }
3256991f827SBarry Smith   ierr = PetscFree(*list);CHKERRQ(ierr);
3266991f827SBarry Smith   PetscFunctionReturn(0);
3276991f827SBarry Smith }
3286991f827SBarry Smith 
329e5c89e4eSSatish Balay /*@C
330e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
331e5c89e4eSSatish Balay 
332e5c89e4eSSatish Balay    Not Collective
333e5c89e4eSSatish Balay 
334e5c89e4eSSatish Balay    Input Parameters:
335e5c89e4eSSatish Balay .  t - pointer to string
336e5c89e4eSSatish Balay 
337e5c89e4eSSatish Balay    Output Parameter:
338e5c89e4eSSatish Balay .  s - the copied string
339e5c89e4eSSatish Balay 
340e5c89e4eSSatish Balay    Level: intermediate
341e5c89e4eSSatish Balay 
3426f013253SBarry Smith    Notes:
343e5c89e4eSSatish Balay      Null string returns a string starting with zero
344e5c89e4eSSatish Balay 
3456f013253SBarry Smith      Not for use in Fortran
3466f013253SBarry Smith 
347e5c89e4eSSatish Balay   Concepts: string copy
348e5c89e4eSSatish Balay 
349a126751eSBarry Smith .seealso: PetscStrncpy(), PetscStrcat(), PetscStrlcat()
350e5c89e4eSSatish Balay 
351e5c89e4eSSatish Balay @*/
352acc6cc86SBarry Smith 
3537087cfbeSBarry Smith PetscErrorCode  PetscStrcpy(char s[],const char t[])
354e5c89e4eSSatish Balay {
355e5c89e4eSSatish Balay   PetscFunctionBegin;
35617186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
357a297a907SKarl Rupp   if (t) strcpy(s,t);
358a297a907SKarl Rupp   else if (s) s[0] = 0;
359e5c89e4eSSatish Balay   PetscFunctionReturn(0);
360e5c89e4eSSatish Balay }
361e5c89e4eSSatish Balay 
362e5c89e4eSSatish Balay /*@C
363e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
364e5c89e4eSSatish Balay 
365e5c89e4eSSatish Balay    Not Collective
366e5c89e4eSSatish Balay 
367e5c89e4eSSatish Balay    Input Parameters:
368e5c89e4eSSatish Balay +  t - pointer to string
369e5c89e4eSSatish Balay -  n - the length to copy
370e5c89e4eSSatish Balay 
371e5c89e4eSSatish Balay    Output Parameter:
372e5c89e4eSSatish Balay .  s - the copied string
373e5c89e4eSSatish Balay 
374e5c89e4eSSatish Balay    Level: intermediate
375e5c89e4eSSatish Balay 
376e5c89e4eSSatish Balay    Note:
377e5c89e4eSSatish Balay      Null string returns a string starting with zero
378e5c89e4eSSatish Balay 
379ff32304bSBarry Smith      If the string that is being copied is of length n or larger then the entire string is not
380ff32304bSBarry Smith      copied and the file location of s is set to NULL. This is different then the behavior of
381ff32304bSBarry Smith      strncpy() which leaves s non-terminated.
382ff32304bSBarry Smith 
383e5c89e4eSSatish Balay   Concepts: string copy
384e5c89e4eSSatish Balay 
385a126751eSBarry Smith .seealso: PetscStrcpy(), PetscStrcat(), PetscStrlcat()
386e5c89e4eSSatish Balay 
387e5c89e4eSSatish Balay @*/
3887087cfbeSBarry Smith PetscErrorCode  PetscStrncpy(char s[],const char t[],size_t n)
389e5c89e4eSSatish Balay {
390e5c89e4eSSatish Balay   PetscFunctionBegin;
39117186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
392ff32304bSBarry Smith   if (t) {
3938dc57659SBarry Smith     if (n > 1) {
3942c26941aSBarry Smith       strncpy(s,t,n-1);
395ff32304bSBarry Smith       s[n-1] = '\0';
3968dc57659SBarry Smith     } else {
3978dc57659SBarry Smith       s[0] = '\0';
3988dc57659SBarry Smith     }
399ff32304bSBarry Smith   } else if (s) s[0] = 0;
400e5c89e4eSSatish Balay   PetscFunctionReturn(0);
401e5c89e4eSSatish Balay }
402e5c89e4eSSatish Balay 
403e5c89e4eSSatish Balay /*@C
404e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
405e5c89e4eSSatish Balay 
406e5c89e4eSSatish Balay    Not Collective
407e5c89e4eSSatish Balay 
408e5c89e4eSSatish Balay    Input Parameters:
409e5e2177aSMatthew Knepley +  s - string to be added to
410e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
411e5c89e4eSSatish Balay 
412e5c89e4eSSatish Balay    Level: intermediate
413e5c89e4eSSatish Balay 
4146f013253SBarry Smith    Notes: Not for use in Fortran
4156f013253SBarry Smith 
416e5c89e4eSSatish Balay   Concepts: string copy
417e5c89e4eSSatish Balay 
418a126751eSBarry Smith .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrlcat()
419e5c89e4eSSatish Balay 
420e5c89e4eSSatish Balay @*/
4217087cfbeSBarry Smith PetscErrorCode  PetscStrcat(char s[],const char t[])
422e5c89e4eSSatish Balay {
423e5c89e4eSSatish Balay   PetscFunctionBegin;
4249b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
425e5c89e4eSSatish Balay   strcat(s,t);
426e5c89e4eSSatish Balay   PetscFunctionReturn(0);
427e5c89e4eSSatish Balay }
428e5c89e4eSSatish Balay 
429e5c89e4eSSatish Balay /*@C
430a126751eSBarry Smith    PetscStrlcat - Concatenates a string onto a given string, up to a given length
431e5c89e4eSSatish Balay 
432e5c89e4eSSatish Balay    Not Collective
433e5c89e4eSSatish Balay 
434e5c89e4eSSatish Balay    Input Parameters:
435e5c89e4eSSatish Balay +  s - pointer to string to be added to end
436e5c89e4eSSatish Balay .  t - string to be added to
43724a58d73SPatrick Sanan -  n - length of the original allocated string
438e5c89e4eSSatish Balay 
439e5c89e4eSSatish Balay    Level: intermediate
440e5c89e4eSSatish Balay 
44124a58d73SPatrick Sanan   Notes:
44224a58d73SPatrick Sanan   Not for use in Fortran
4436f013253SBarry Smith 
44424a58d73SPatrick Sanan   Unlike the system call strncat(), the length passed in is the length of the
44524a58d73SPatrick Sanan   original allocated space, not the length of the left-over space. This is
44624a58d73SPatrick Sanan   similar to the BSD system call strlcat().
447153a8027SBarry Smith 
448e5c89e4eSSatish Balay   Concepts: string copy
449e5c89e4eSSatish Balay 
450e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
451e5c89e4eSSatish Balay 
452e5c89e4eSSatish Balay @*/
453a126751eSBarry Smith PetscErrorCode  PetscStrlcat(char s[],const char t[],size_t n)
454e5c89e4eSSatish Balay {
455153a8027SBarry Smith   size_t         len;
456153a8027SBarry Smith   PetscErrorCode ierr;
457153a8027SBarry Smith 
458e5c89e4eSSatish Balay   PetscFunctionBegin;
459*681eeb0aSBarry Smith   if (t && !n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"String buffer length must be positive");
460153a8027SBarry Smith   ierr = PetscStrlen(t,&len);CHKERRQ(ierr);
461153a8027SBarry Smith   strncat(s,t,n - len);
462*681eeb0aSBarry Smith   s[n-1] = 0;
463e5c89e4eSSatish Balay   PetscFunctionReturn(0);
464e5c89e4eSSatish Balay }
465e5c89e4eSSatish Balay 
466573b0fb4SBarry Smith /*
467573b0fb4SBarry Smith    Only to be used with PetscCheck__FUNCT__()!
468573b0fb4SBarry Smith 
469573b0fb4SBarry Smith */
470573b0fb4SBarry Smith void  PetscStrcmpNoError(const char a[],const char b[],PetscBool  *flg)
471573b0fb4SBarry Smith {
472573b0fb4SBarry Smith   int c;
473573b0fb4SBarry Smith 
474573b0fb4SBarry Smith   if (!a && !b)      *flg = PETSC_TRUE;
475573b0fb4SBarry Smith   else if (!a || !b) *flg = PETSC_FALSE;
476573b0fb4SBarry Smith   else {
477573b0fb4SBarry Smith     c = strcmp(a,b);
478573b0fb4SBarry Smith     if (c) *flg = PETSC_FALSE;
479573b0fb4SBarry Smith     else   *flg = PETSC_TRUE;
480573b0fb4SBarry Smith   }
481573b0fb4SBarry Smith }
482573b0fb4SBarry Smith 
483e5c89e4eSSatish Balay /*@C
484e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
485e5c89e4eSSatish Balay 
486e5c89e4eSSatish Balay    Not Collective
487e5c89e4eSSatish Balay 
488e5c89e4eSSatish Balay    Input Parameters:
489e5c89e4eSSatish Balay +  a - pointer to string first string
490e5c89e4eSSatish Balay -  b - pointer to second string
491e5c89e4eSSatish Balay 
492e5c89e4eSSatish Balay    Output Parameter:
4938c74ee41SBarry Smith .  flg - PETSC_TRUE if the two strings are equal
494e5c89e4eSSatish Balay 
495e5c89e4eSSatish Balay    Level: intermediate
496e5c89e4eSSatish Balay 
4976f013253SBarry Smith    Notes:    Not for use in Fortran
4986f013253SBarry Smith 
499e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
500e5c89e4eSSatish Balay 
501e5c89e4eSSatish Balay @*/
5027087cfbeSBarry Smith PetscErrorCode  PetscStrcmp(const char a[],const char b[],PetscBool  *flg)
503e5c89e4eSSatish Balay {
504e5c89e4eSSatish Balay   int c;
505e5c89e4eSSatish Balay 
506e5c89e4eSSatish Balay   PetscFunctionBegin;
507a297a907SKarl Rupp   if (!a && !b)      *flg = PETSC_TRUE;
508a297a907SKarl Rupp   else if (!a || !b) *flg = PETSC_FALSE;
509a297a907SKarl Rupp   else {
510e5c89e4eSSatish Balay     c = strcmp(a,b);
511e5c89e4eSSatish Balay     if (c) *flg = PETSC_FALSE;
512e5c89e4eSSatish Balay     else   *flg = PETSC_TRUE;
513e5c89e4eSSatish Balay   }
514e5c89e4eSSatish Balay   PetscFunctionReturn(0);
515e5c89e4eSSatish Balay }
516e5c89e4eSSatish Balay 
517e5c89e4eSSatish Balay /*@C
518e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
519e5c89e4eSSatish Balay 
520e5c89e4eSSatish Balay    Not Collective
521e5c89e4eSSatish Balay 
522e5c89e4eSSatish Balay    Input Parameters:
523e5c89e4eSSatish Balay +  a - pointer to first string
524e5c89e4eSSatish Balay -  b - pointer to second string
525e5c89e4eSSatish Balay 
526e5c89e4eSSatish Balay    Output Parameter:
527e5c89e4eSSatish Balay .  flg - if the first string is greater
528e5c89e4eSSatish Balay 
529e5c89e4eSSatish Balay    Notes:
530e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
531e5c89e4eSSatish Balay     all others
532e5c89e4eSSatish Balay 
5336f013253SBarry Smith    Not for use in Fortran
5346f013253SBarry Smith 
535e5c89e4eSSatish Balay    Level: intermediate
536e5c89e4eSSatish Balay 
537e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
538e5c89e4eSSatish Balay 
539e5c89e4eSSatish Balay @*/
5407087cfbeSBarry Smith PetscErrorCode  PetscStrgrt(const char a[],const char b[],PetscBool  *t)
541e5c89e4eSSatish Balay {
542e5c89e4eSSatish Balay   int c;
543e5c89e4eSSatish Balay 
544e5c89e4eSSatish Balay   PetscFunctionBegin;
545a297a907SKarl Rupp   if (!a && !b) *t = PETSC_FALSE;
546a297a907SKarl Rupp   else if (a && !b) *t = PETSC_TRUE;
547a297a907SKarl Rupp   else if (!a && b) *t = PETSC_FALSE;
548a297a907SKarl Rupp   else {
549e5c89e4eSSatish Balay     c = strcmp(a,b);
550e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
551e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
552e5c89e4eSSatish Balay   }
553e5c89e4eSSatish Balay   PetscFunctionReturn(0);
554e5c89e4eSSatish Balay }
555e5c89e4eSSatish Balay 
556e5c89e4eSSatish Balay /*@C
557e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
558e5c89e4eSSatish Balay      except possibly for case.
559e5c89e4eSSatish Balay 
560e5c89e4eSSatish Balay    Not Collective
561e5c89e4eSSatish Balay 
562e5c89e4eSSatish Balay    Input Parameters:
563e5c89e4eSSatish Balay +  a - pointer to first string
564e5c89e4eSSatish Balay -  b - pointer to second string
565e5c89e4eSSatish Balay 
566e5c89e4eSSatish Balay    Output Parameter:
567e5c89e4eSSatish Balay .  flg - if the two strings are the same
568e5c89e4eSSatish Balay 
569e5c89e4eSSatish Balay    Notes:
570e5c89e4eSSatish Balay     Null arguments are ok
571e5c89e4eSSatish Balay 
5726f013253SBarry Smith    Not for use in Fortran
5736f013253SBarry Smith 
574e5c89e4eSSatish Balay    Level: intermediate
575e5c89e4eSSatish Balay 
576e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
577e5c89e4eSSatish Balay 
578e5c89e4eSSatish Balay @*/
5797087cfbeSBarry Smith PetscErrorCode  PetscStrcasecmp(const char a[],const char b[],PetscBool  *t)
580e5c89e4eSSatish Balay {
581e5c89e4eSSatish Balay   int c;
582e5c89e4eSSatish Balay 
583e5c89e4eSSatish Balay   PetscFunctionBegin;
584e5c89e4eSSatish Balay   if (!a && !b) c = 0;
585e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
58632b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
58732b366c8SSatish Balay   else c = strcasecmp(a,b);
58832b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
589e5c89e4eSSatish Balay   else c = stricmp(a,b);
590e5c89e4eSSatish Balay #else
59132b366c8SSatish Balay   else {
59232b366c8SSatish Balay     char           *aa,*bb;
59332b366c8SSatish Balay     PetscErrorCode ierr;
59432b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
59532b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
59632b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
59732b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
59832b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
599503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
600503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
60132b366c8SSatish Balay     PetscFunctionReturn(0);
60232b366c8SSatish Balay   }
603e5c89e4eSSatish Balay #endif
604e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
605e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
606e5c89e4eSSatish Balay   PetscFunctionReturn(0);
607e5c89e4eSSatish Balay }
608e5c89e4eSSatish Balay 
60932b366c8SSatish Balay 
61032b366c8SSatish Balay 
611e5c89e4eSSatish Balay /*@C
612e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
613e5c89e4eSSatish Balay 
614e5c89e4eSSatish Balay    Not Collective
615e5c89e4eSSatish Balay 
616e5c89e4eSSatish Balay    Input Parameters:
617e5c89e4eSSatish Balay +  a - pointer to first string
618e5c89e4eSSatish Balay .  b - pointer to second string
619e5c89e4eSSatish Balay -  n - length to compare up to
620e5c89e4eSSatish Balay 
621e5c89e4eSSatish Balay    Output Parameter:
622e5c89e4eSSatish Balay .  t - if the two strings are equal
623e5c89e4eSSatish Balay 
624e5c89e4eSSatish Balay    Level: intermediate
625e5c89e4eSSatish Balay 
6266f013253SBarry Smith    Notes:    Not for use in Fortran
6276f013253SBarry Smith 
628e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
629e5c89e4eSSatish Balay 
630e5c89e4eSSatish Balay @*/
6317087cfbeSBarry Smith PetscErrorCode  PetscStrncmp(const char a[],const char b[],size_t n,PetscBool  *t)
632e5c89e4eSSatish Balay {
633e5c89e4eSSatish Balay   int c;
634e5c89e4eSSatish Balay 
635e5c89e4eSSatish Balay   PetscFunctionBegin;
636e5c89e4eSSatish Balay   c = strncmp(a,b,n);
637e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
638e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
639e5c89e4eSSatish Balay   PetscFunctionReturn(0);
640e5c89e4eSSatish Balay }
641e5c89e4eSSatish Balay 
642e5c89e4eSSatish Balay /*@C
643e5c89e4eSSatish Balay    PetscStrchr - Locates first occurance of a character in a string
644e5c89e4eSSatish Balay 
645e5c89e4eSSatish Balay    Not Collective
646e5c89e4eSSatish Balay 
647e5c89e4eSSatish Balay    Input Parameters:
648e5c89e4eSSatish Balay +  a - pointer to string
649e5c89e4eSSatish Balay -  b - character
650e5c89e4eSSatish Balay 
651e5c89e4eSSatish Balay    Output Parameter:
6520298fd71SBarry Smith .  c - location of occurance, NULL if not found
653e5c89e4eSSatish Balay 
654e5c89e4eSSatish Balay    Level: intermediate
655e5c89e4eSSatish Balay 
6566f013253SBarry Smith    Notes:    Not for use in Fortran
6576f013253SBarry Smith 
658e5c89e4eSSatish Balay @*/
6597087cfbeSBarry Smith PetscErrorCode  PetscStrchr(const char a[],char b,char *c[])
660e5c89e4eSSatish Balay {
661e5c89e4eSSatish Balay   PetscFunctionBegin;
662e5c89e4eSSatish Balay   *c = (char*)strchr(a,b);
663e5c89e4eSSatish Balay   PetscFunctionReturn(0);
664e5c89e4eSSatish Balay }
665e5c89e4eSSatish Balay 
666e5c89e4eSSatish Balay /*@C
667e5c89e4eSSatish Balay    PetscStrrchr - Locates one location past the last occurance of a character in a string,
668e5c89e4eSSatish Balay       if the character is not found then returns entire string
669e5c89e4eSSatish Balay 
670e5c89e4eSSatish Balay    Not Collective
671e5c89e4eSSatish Balay 
672e5c89e4eSSatish Balay    Input Parameters:
673e5c89e4eSSatish Balay +  a - pointer to string
674e5c89e4eSSatish Balay -  b - character
675e5c89e4eSSatish Balay 
676e5c89e4eSSatish Balay    Output Parameter:
677e5c89e4eSSatish Balay .  tmp - location of occurance, a if not found
678e5c89e4eSSatish Balay 
679e5c89e4eSSatish Balay    Level: intermediate
680e5c89e4eSSatish Balay 
6816f013253SBarry Smith    Notes:    Not for use in Fortran
6826f013253SBarry Smith 
683e5c89e4eSSatish Balay @*/
6847087cfbeSBarry Smith PetscErrorCode  PetscStrrchr(const char a[],char b,char *tmp[])
685e5c89e4eSSatish Balay {
686e5c89e4eSSatish Balay   PetscFunctionBegin;
687e5c89e4eSSatish Balay   *tmp = (char*)strrchr(a,b);
688a297a907SKarl Rupp   if (!*tmp) *tmp = (char*)a;
689a297a907SKarl Rupp   else *tmp = *tmp + 1;
690e5c89e4eSSatish Balay   PetscFunctionReturn(0);
691e5c89e4eSSatish Balay }
692e5c89e4eSSatish Balay 
693e5c89e4eSSatish Balay /*@C
694e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
695e5c89e4eSSatish Balay 
696e5c89e4eSSatish Balay    Not Collective
697e5c89e4eSSatish Balay 
698e5c89e4eSSatish Balay    Input Parameters:
699e5c89e4eSSatish Balay .  a - pointer to string
700e5c89e4eSSatish Balay 
701e5c89e4eSSatish Balay    Level: intermediate
702e5c89e4eSSatish Balay 
7036f013253SBarry Smith    Notes:    Not for use in Fortran
7046f013253SBarry Smith 
705e5c89e4eSSatish Balay @*/
7067087cfbeSBarry Smith PetscErrorCode  PetscStrtolower(char a[])
707e5c89e4eSSatish Balay {
708e5c89e4eSSatish Balay   PetscFunctionBegin;
709e5c89e4eSSatish Balay   while (*a) {
710e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
711e5c89e4eSSatish Balay     a++;
712e5c89e4eSSatish Balay   }
713e5c89e4eSSatish Balay   PetscFunctionReturn(0);
714e5c89e4eSSatish Balay }
715e5c89e4eSSatish Balay 
7162f234a98SBarry Smith /*@C
7176e3a5469SBarry Smith    PetscStrtoupper - Converts string to upper case
7182f234a98SBarry Smith 
7192f234a98SBarry Smith    Not Collective
7202f234a98SBarry Smith 
7212f234a98SBarry Smith    Input Parameters:
7222f234a98SBarry Smith .  a - pointer to string
7232f234a98SBarry Smith 
7242f234a98SBarry Smith    Level: intermediate
7252f234a98SBarry Smith 
7262f234a98SBarry Smith    Notes:    Not for use in Fortran
7272f234a98SBarry Smith 
7282f234a98SBarry Smith @*/
7292f234a98SBarry Smith PetscErrorCode  PetscStrtoupper(char a[])
7302f234a98SBarry Smith {
7312f234a98SBarry Smith   PetscFunctionBegin;
7322f234a98SBarry Smith   while (*a) {
7332f234a98SBarry Smith     if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a';
7342f234a98SBarry Smith     a++;
7352f234a98SBarry Smith   }
7362f234a98SBarry Smith   PetscFunctionReturn(0);
7372f234a98SBarry Smith }
7382f234a98SBarry Smith 
7397ba3a57cSBarry Smith /*@C
7407ba3a57cSBarry Smith    PetscStrendswith - Determines if a string ends with a certain string
7411d1a0024SBarry Smith 
7427ba3a57cSBarry Smith    Not Collective
7437ba3a57cSBarry Smith 
7447ba3a57cSBarry Smith    Input Parameters:
7457ba3a57cSBarry Smith +  a - pointer to string
7467ba3a57cSBarry Smith -  b - string to endwith
7477ba3a57cSBarry Smith 
7487ba3a57cSBarry Smith    Output Parameter:
7497ba3a57cSBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
7507ba3a57cSBarry Smith 
7517ba3a57cSBarry Smith    Notes:     Not for use in Fortran
7527ba3a57cSBarry Smith 
7537ba3a57cSBarry Smith    Level: intermediate
7547ba3a57cSBarry Smith 
7557ba3a57cSBarry Smith @*/
7567ba3a57cSBarry Smith PetscErrorCode  PetscStrendswith(const char a[],const char b[],PetscBool *flg)
7577ba3a57cSBarry Smith {
7587ba3a57cSBarry Smith   char           *test;
7597ba3a57cSBarry Smith   PetscErrorCode ierr;
7607ba3a57cSBarry Smith   size_t         na,nb;
7617ba3a57cSBarry Smith 
7627ba3a57cSBarry Smith   PetscFunctionBegin;
7637ba3a57cSBarry Smith   *flg = PETSC_FALSE;
7647ba3a57cSBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
7657ba3a57cSBarry Smith   if (test) {
7667ba3a57cSBarry Smith     ierr = PetscStrlen(a,&na);CHKERRQ(ierr);
7677ba3a57cSBarry Smith     ierr = PetscStrlen(b,&nb);CHKERRQ(ierr);
7687ba3a57cSBarry Smith     if (a+na-nb == test) *flg = PETSC_TRUE;
7697ba3a57cSBarry Smith   }
7707ba3a57cSBarry Smith   PetscFunctionReturn(0);
7717ba3a57cSBarry Smith }
7727ba3a57cSBarry Smith 
7732c9581d2SBarry Smith /*@C
7742c9581d2SBarry Smith    PetscStrbeginswith - Determines if a string begins with a certain string
7752c9581d2SBarry Smith 
7762c9581d2SBarry Smith    Not Collective
7772c9581d2SBarry Smith 
7782c9581d2SBarry Smith    Input Parameters:
7792c9581d2SBarry Smith +  a - pointer to string
7802c9581d2SBarry Smith -  b - string to begin with
7812c9581d2SBarry Smith 
7822c9581d2SBarry Smith    Output Parameter:
7832c9581d2SBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
7842c9581d2SBarry Smith 
7852c9581d2SBarry Smith    Notes:     Not for use in Fortran
7862c9581d2SBarry Smith 
7872c9581d2SBarry Smith    Level: intermediate
7882c9581d2SBarry Smith 
7896e3a5469SBarry Smith .seealso: PetscStrendswithwhich(), PetscStrendswith(), PetscStrtoupper, PetscStrtolower(), PetscStrrchr(), PetscStrchr(),
7906e3a5469SBarry Smith           PetscStrncmp(), PetscStrlen(), PetscStrncmp(), PetscStrcmp()
7916e3a5469SBarry Smith 
7922c9581d2SBarry Smith @*/
7932c9581d2SBarry Smith PetscErrorCode  PetscStrbeginswith(const char a[],const char b[],PetscBool *flg)
7942c9581d2SBarry Smith {
7952c9581d2SBarry Smith   char           *test;
7962c9581d2SBarry Smith   PetscErrorCode ierr;
7972c9581d2SBarry Smith 
7982c9581d2SBarry Smith   PetscFunctionBegin;
7992c9581d2SBarry Smith   *flg = PETSC_FALSE;
8002c9581d2SBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
801a297a907SKarl Rupp   if (test && (test == a)) *flg = PETSC_TRUE;
8022c9581d2SBarry Smith   PetscFunctionReturn(0);
8032c9581d2SBarry Smith }
8042c9581d2SBarry Smith 
8052c9581d2SBarry Smith 
8067ba3a57cSBarry Smith /*@C
8077ba3a57cSBarry Smith    PetscStrendswithwhich - Determines if a string ends with one of several possible strings
8087ba3a57cSBarry Smith 
8097ba3a57cSBarry Smith    Not Collective
8107ba3a57cSBarry Smith 
8117ba3a57cSBarry Smith    Input Parameters:
8127ba3a57cSBarry Smith +  a - pointer to string
8137ba3a57cSBarry Smith -  bs - strings to endwith (last entry must be null)
8147ba3a57cSBarry Smith 
8157ba3a57cSBarry Smith    Output Parameter:
8167ba3a57cSBarry Smith .  cnt - the index of the string it ends with or 1+the last possible index
8177ba3a57cSBarry Smith 
8187ba3a57cSBarry Smith    Notes:     Not for use in Fortran
8197ba3a57cSBarry Smith 
8207ba3a57cSBarry Smith    Level: intermediate
8217ba3a57cSBarry Smith 
8227ba3a57cSBarry Smith @*/
8237ba3a57cSBarry Smith PetscErrorCode  PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt)
8247ba3a57cSBarry Smith {
8257ba3a57cSBarry Smith   PetscBool      flg;
8267ba3a57cSBarry Smith   PetscErrorCode ierr;
8277ba3a57cSBarry Smith 
8287ba3a57cSBarry Smith   PetscFunctionBegin;
8297ba3a57cSBarry Smith   *cnt = 0;
8307ba3a57cSBarry Smith   while (bs[*cnt]) {
8317ba3a57cSBarry Smith     ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr);
8327ba3a57cSBarry Smith     if (flg) PetscFunctionReturn(0);
8337ba3a57cSBarry Smith     *cnt += 1;
8347ba3a57cSBarry Smith   }
8357ba3a57cSBarry Smith   PetscFunctionReturn(0);
8367ba3a57cSBarry Smith }
8377ba3a57cSBarry Smith 
8387ba3a57cSBarry Smith /*@C
8397ba3a57cSBarry Smith    PetscStrrstr - Locates last occurance of string in another string
8407ba3a57cSBarry Smith 
8417ba3a57cSBarry Smith    Not Collective
8427ba3a57cSBarry Smith 
8437ba3a57cSBarry Smith    Input Parameters:
8447ba3a57cSBarry Smith +  a - pointer to string
8457ba3a57cSBarry Smith -  b - string to find
8467ba3a57cSBarry Smith 
8477ba3a57cSBarry Smith    Output Parameter:
8487ba3a57cSBarry Smith .  tmp - location of occurance
8497ba3a57cSBarry Smith 
8507ba3a57cSBarry Smith    Notes:     Not for use in Fortran
8517ba3a57cSBarry Smith 
8527ba3a57cSBarry Smith    Level: intermediate
8537ba3a57cSBarry Smith 
8547ba3a57cSBarry Smith @*/
8557ba3a57cSBarry Smith PetscErrorCode  PetscStrrstr(const char a[],const char b[],char *tmp[])
8567ba3a57cSBarry Smith {
8577ba3a57cSBarry Smith   const char *stmp = a, *ltmp = 0;
8587ba3a57cSBarry Smith 
8597ba3a57cSBarry Smith   PetscFunctionBegin;
8607ba3a57cSBarry Smith   while (stmp) {
8617ba3a57cSBarry Smith     stmp = (char*)strstr(stmp,b);
8627ba3a57cSBarry Smith     if (stmp) {ltmp = stmp;stmp++;}
8637ba3a57cSBarry Smith   }
8647ba3a57cSBarry Smith   *tmp = (char*)ltmp;
8657ba3a57cSBarry Smith   PetscFunctionReturn(0);
8667ba3a57cSBarry Smith }
8677ba3a57cSBarry Smith 
8687ba3a57cSBarry Smith /*@C
8697ba3a57cSBarry Smith    PetscStrstr - Locates first occurance of string in another string
8707ba3a57cSBarry Smith 
8717ba3a57cSBarry Smith    Not Collective
8727ba3a57cSBarry Smith 
8737ba3a57cSBarry Smith    Input Parameters:
874160f4796SJed Brown +  haystack - string to search
875160f4796SJed Brown -  needle - string to find
8767ba3a57cSBarry Smith 
8777ba3a57cSBarry Smith    Output Parameter:
8780298fd71SBarry Smith .  tmp - location of occurance, is a NULL if the string is not found
8797ba3a57cSBarry Smith 
8807ba3a57cSBarry Smith    Notes: Not for use in Fortran
8817ba3a57cSBarry Smith 
8827ba3a57cSBarry Smith    Level: intermediate
8837ba3a57cSBarry Smith 
8847ba3a57cSBarry Smith @*/
885160f4796SJed Brown PetscErrorCode  PetscStrstr(const char haystack[],const char needle[],char *tmp[])
8867ba3a57cSBarry Smith {
8877ba3a57cSBarry Smith   PetscFunctionBegin;
888160f4796SJed Brown   *tmp = (char*)strstr(haystack,needle);
8897ba3a57cSBarry Smith   PetscFunctionReturn(0);
8907ba3a57cSBarry Smith }
8917ba3a57cSBarry Smith 
8927ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
8931d1a0024SBarry Smith 
894e5c89e4eSSatish Balay /*@C
895e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
896e5c89e4eSSatish Balay 
897e5c89e4eSSatish Balay    Not Collective
898e5c89e4eSSatish Balay 
899e5c89e4eSSatish Balay    Input Parameters:
900e5c89e4eSSatish Balay .  a - pointer to token
901e5c89e4eSSatish Balay 
902e5c89e4eSSatish Balay    Output Parameter:
9030298fd71SBarry Smith .  result - location of occurance, NULL if not found
904e5c89e4eSSatish Balay 
905e5c89e4eSSatish Balay    Notes:
906e5c89e4eSSatish Balay 
907e5c89e4eSSatish Balay      This version is different from the system version in that
908e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
909e5c89e4eSSatish Balay 
9104704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
9114704e885SBarry Smith    as a single token.
9124704e885SBarry Smith 
9133a9c465aSBarry 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
9143a9c465aSBarry Smith    second will return a null terminated y
9153a9c465aSBarry Smith 
9163a9c465aSBarry 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
9173a9c465aSBarry Smith 
9186f013253SBarry Smith     Not for use in Fortran
9196f013253SBarry Smith 
920e5c89e4eSSatish Balay    Level: intermediate
921e5c89e4eSSatish Balay 
9226f013253SBarry Smith 
923e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
924e5c89e4eSSatish Balay @*/
9257087cfbeSBarry Smith PetscErrorCode  PetscTokenFind(PetscToken a,char *result[])
926e5c89e4eSSatish Balay {
9274704e885SBarry Smith   char *ptr = a->current,token;
928e5c89e4eSSatish Balay 
929e5c89e4eSSatish Balay   PetscFunctionBegin;
930e5c89e4eSSatish Balay   *result = a->current;
9314704e885SBarry Smith   if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);}
9324704e885SBarry Smith   token = a->token;
93390fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
934e5c89e4eSSatish Balay   while (ptr) {
9354704e885SBarry Smith     if (*ptr == token) {
936e5c89e4eSSatish Balay       *ptr++ = 0;
937e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
938e5c89e4eSSatish Balay       a->current = ptr;
939e5c89e4eSSatish Balay       break;
940e5c89e4eSSatish Balay     }
941e5c89e4eSSatish Balay     if (!*ptr) {
942e5c89e4eSSatish Balay       a->current = 0;
943e5c89e4eSSatish Balay       break;
944e5c89e4eSSatish Balay     }
945e5c89e4eSSatish Balay     ptr++;
946e5c89e4eSSatish Balay   }
947e5c89e4eSSatish Balay   PetscFunctionReturn(0);
948e5c89e4eSSatish Balay }
949e5c89e4eSSatish Balay 
950e5c89e4eSSatish Balay /*@C
951e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
952e5c89e4eSSatish Balay 
953e5c89e4eSSatish Balay    Not Collective
954e5c89e4eSSatish Balay 
955e5c89e4eSSatish Balay    Input Parameters:
956e5c89e4eSSatish Balay +  string - the string to look in
9573a9c465aSBarry Smith -  b - the separator character
958e5c89e4eSSatish Balay 
959e5c89e4eSSatish Balay    Output Parameter:
9603a9c465aSBarry Smith .  t- the token object
961e5c89e4eSSatish Balay 
962e5c89e4eSSatish Balay    Notes:
963e5c89e4eSSatish Balay 
964e5c89e4eSSatish Balay      This version is different from the system version in that
965e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
966e5c89e4eSSatish Balay 
9676f013253SBarry Smith     Not for use in Fortran
9686f013253SBarry Smith 
969e5c89e4eSSatish Balay    Level: intermediate
970e5c89e4eSSatish Balay 
971e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
972e5c89e4eSSatish Balay @*/
9737087cfbeSBarry Smith PetscErrorCode  PetscTokenCreate(const char a[],const char b,PetscToken *t)
974e5c89e4eSSatish Balay {
975e5c89e4eSSatish Balay   PetscErrorCode ierr;
976e5c89e4eSSatish Balay 
977e5c89e4eSSatish Balay   PetscFunctionBegin;
978b00a9115SJed Brown   ierr = PetscNew(t);CHKERRQ(ierr);
979e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
980a297a907SKarl Rupp 
981e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
982e5c89e4eSSatish Balay   (*t)->token   = b;
983e5c89e4eSSatish Balay   PetscFunctionReturn(0);
984e5c89e4eSSatish Balay }
985e5c89e4eSSatish Balay 
986e5c89e4eSSatish Balay /*@C
987e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
988e5c89e4eSSatish Balay 
989e5c89e4eSSatish Balay    Not Collective
990e5c89e4eSSatish Balay 
991e5c89e4eSSatish Balay    Input Parameters:
992e5c89e4eSSatish Balay .  a - pointer to token
993e5c89e4eSSatish Balay 
994e5c89e4eSSatish Balay    Level: intermediate
995e5c89e4eSSatish Balay 
9966f013253SBarry Smith    Notes:     Not for use in Fortran
9976f013253SBarry Smith 
998e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
999e5c89e4eSSatish Balay @*/
10008c74ee41SBarry Smith PetscErrorCode  PetscTokenDestroy(PetscToken *a)
1001e5c89e4eSSatish Balay {
1002e5c89e4eSSatish Balay   PetscErrorCode ierr;
1003e5c89e4eSSatish Balay 
1004e5c89e4eSSatish Balay   PetscFunctionBegin;
10058c74ee41SBarry Smith   if (!*a) PetscFunctionReturn(0);
10068c74ee41SBarry Smith   ierr = PetscFree((*a)->array);CHKERRQ(ierr);
10078c74ee41SBarry Smith   ierr = PetscFree(*a);CHKERRQ(ierr);
1008e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1009e5c89e4eSSatish Balay }
1010e5c89e4eSSatish Balay 
10118e81d068SLisandro Dalcin /*@C
10128e81d068SLisandro Dalcin    PetscStrInList - search string in character-delimited list
10138e81d068SLisandro Dalcin 
10148e81d068SLisandro Dalcin    Not Collective
10158e81d068SLisandro Dalcin 
10168e81d068SLisandro Dalcin    Input Parameters:
10178e81d068SLisandro Dalcin +  str - the string to look for
10188e81d068SLisandro Dalcin .  list - the list to search in
10198e81d068SLisandro Dalcin -  sep - the separator character
10208e81d068SLisandro Dalcin 
10218e81d068SLisandro Dalcin    Output Parameter:
10228e81d068SLisandro Dalcin .  found - whether str is in list
10238e81d068SLisandro Dalcin 
10248e81d068SLisandro Dalcin    Level: intermediate
10258e81d068SLisandro Dalcin 
10268e81d068SLisandro Dalcin    Notes: Not for use in Fortran
10278e81d068SLisandro Dalcin 
10288e81d068SLisandro Dalcin .seealso: PetscTokenCreate(), PetscTokenFind(), PetscStrcmp()
10298e81d068SLisandro Dalcin @*/
10308e81d068SLisandro Dalcin PetscErrorCode PetscStrInList(const char str[],const char list[],char sep,PetscBool *found)
10318e81d068SLisandro Dalcin {
10328e81d068SLisandro Dalcin   PetscToken     token;
10338e81d068SLisandro Dalcin   char           *item;
10348e81d068SLisandro Dalcin   PetscErrorCode ierr;
10358e81d068SLisandro Dalcin 
10368e81d068SLisandro Dalcin   PetscFunctionBegin;
10378e81d068SLisandro Dalcin   *found = PETSC_FALSE;
10388e81d068SLisandro Dalcin   ierr = PetscTokenCreate(list,sep,&token);CHKERRQ(ierr);
10398e81d068SLisandro Dalcin   ierr = PetscTokenFind(token,&item);CHKERRQ(ierr);
10408e81d068SLisandro Dalcin   while (item) {
10418e81d068SLisandro Dalcin     ierr = PetscStrcmp(str,item,found);CHKERRQ(ierr);
10428e81d068SLisandro Dalcin     if (*found) break;
10438e81d068SLisandro Dalcin     ierr = PetscTokenFind(token,&item);CHKERRQ(ierr);
10448e81d068SLisandro Dalcin   }
10458e81d068SLisandro Dalcin   ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
10468e81d068SLisandro Dalcin   PetscFunctionReturn(0);
10478e81d068SLisandro Dalcin }
1048e5c89e4eSSatish Balay 
1049e5c89e4eSSatish Balay /*@C
1050e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
1051e5c89e4eSSatish Balay 
1052e5c89e4eSSatish Balay    Not Collective
1053e5c89e4eSSatish Balay 
1054e5c89e4eSSatish Balay    Output Parameter:
1055e5c89e4eSSatish Balay .  dir - the directory
1056e5c89e4eSSatish Balay 
1057e5c89e4eSSatish Balay    Level: developer
1058e5c89e4eSSatish Balay 
10596f013253SBarry Smith    Notes: Not for use in Fortran
10606f013253SBarry Smith 
1061e5c89e4eSSatish Balay @*/
10627087cfbeSBarry Smith PetscErrorCode  PetscGetPetscDir(const char *dir[])
1063e5c89e4eSSatish Balay {
1064e5c89e4eSSatish Balay   PetscFunctionBegin;
1065e5c89e4eSSatish Balay   *dir = PETSC_DIR;
1066e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1067e5c89e4eSSatish Balay }
1068e5c89e4eSSatish Balay 
1069e5c89e4eSSatish Balay /*@C
1070e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
1071e5c89e4eSSatish Balay 
1072e5c89e4eSSatish Balay    Not Collective
1073e5c89e4eSSatish Balay 
1074e5c89e4eSSatish Balay    Input Parameters:
1075e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
107671573d7dSBarry Smith .   aa - the string to look in
1077d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
1078e5c89e4eSSatish Balay -   len - the length of b
1079e5c89e4eSSatish Balay 
1080e5c89e4eSSatish Balay    Notes:
1081e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
1082d5649816SBarry Smith       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
1083e5c89e4eSSatish Balay       as well as any environmental variables.
1084e5c89e4eSSatish Balay 
10856f013253SBarry Smith       PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
1086acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
1087acc6cc86SBarry Smith 
10886f013253SBarry Smith       Not for use in Fortran
10896f013253SBarry Smith 
1090e5c89e4eSSatish Balay    Level: intermediate
1091e5c89e4eSSatish Balay 
1092e5c89e4eSSatish Balay @*/
10937087cfbeSBarry Smith PetscErrorCode  PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
1094e5c89e4eSSatish Balay {
1095e5c89e4eSSatish Balay   PetscErrorCode ierr;
1096e5c89e4eSSatish Balay   int            i = 0;
1097e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
109871573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
1099d5649816SBarry Smith   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0};
1100f489ac74SBarry Smith   char           *r[] = {0,0,0,0,0,0,0,0,0};
1101ace3abfcSBarry Smith   PetscBool      flag;
1102e5c89e4eSSatish Balay 
1103e5c89e4eSSatish Balay   PetscFunctionBegin;
1104e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
110571573d7dSBarry Smith   if (aa == b) {
110622982a5fSBarry Smith     ierr = PetscStrallocpy(aa,(char**)&a);CHKERRQ(ierr);
110771573d7dSBarry Smith   }
1108785e854fSJed Brown   ierr = PetscMalloc1(len,&work);CHKERRQ(ierr);
1109e5c89e4eSSatish Balay 
1110e5c89e4eSSatish Balay   /* get values for replaced variables */
1111f1d4cc8fSBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,&r[0]);CHKERRQ(ierr);
1112f1d4cc8fSBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,&r[1]);CHKERRQ(ierr);
1113f1d4cc8fSBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,&r[2]);CHKERRQ(ierr);
1114785e854fSJed Brown   ierr = PetscMalloc1(256,&r[3]);CHKERRQ(ierr);
1115785e854fSJed Brown   ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[4]);CHKERRQ(ierr);
1116785e854fSJed Brown   ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[5]);CHKERRQ(ierr);
1117785e854fSJed Brown   ierr = PetscMalloc1(256,&r[6]);CHKERRQ(ierr);
1118785e854fSJed Brown   ierr = PetscMalloc1(256,&r[7]);CHKERRQ(ierr);
1119f1d4cc8fSBarry Smith   ierr = PetscGetDisplay(r[3],256);CHKERRQ(ierr);
1120f1d4cc8fSBarry Smith   ierr = PetscGetHomeDirectory(r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1121f1d4cc8fSBarry Smith   ierr = PetscGetWorkingDirectory(r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1122f1d4cc8fSBarry Smith   ierr = PetscGetUserName(r[6],256);CHKERRQ(ierr);
1123f1d4cc8fSBarry Smith   ierr = PetscGetHostName(r[7],256);CHKERRQ(ierr);
1124487e5849SBarry Smith 
1125487e5849SBarry Smith   /* replace that are in environment */
1126487e5849SBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr);
1127487e5849SBarry Smith   if (flag) {
112831936d58SMatthew G. Knepley     ierr = PetscFree(r[2]);CHKERRQ(ierr);
1129f1d4cc8fSBarry Smith     ierr = PetscStrallocpy(env,&r[2]);CHKERRQ(ierr);
1130487e5849SBarry Smith   }
1131e5c89e4eSSatish Balay 
1132e5c89e4eSSatish Balay   /* replace the requested strings */
1133e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
1134e5c89e4eSSatish Balay   while (s[i]) {
1135e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
1136e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1137e5c89e4eSSatish Balay     while (par) {
1138e5c89e4eSSatish Balay       *par =  0;
1139e5c89e4eSSatish Balay       par += l;
1140e5c89e4eSSatish Balay 
1141e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
1142e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
1143e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
114417186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
1145e5c89e4eSSatish Balay       ierr = PetscStrcpy(work,b);CHKERRQ(ierr);
1146e5c89e4eSSatish Balay       ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr);
1147e5c89e4eSSatish Balay       ierr = PetscStrcat(work,par);CHKERRQ(ierr);
1148e5c89e4eSSatish Balay       ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr);
1149e5c89e4eSSatish Balay       ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1150e5c89e4eSSatish Balay     }
1151e5c89e4eSSatish Balay     i++;
1152e5c89e4eSSatish Balay   }
1153487e5849SBarry Smith   i = 0;
1154487e5849SBarry Smith   while (r[i]) {
1155e5c89e4eSSatish Balay     tfree = (char*)r[i];
1156e5c89e4eSSatish Balay     ierr  = PetscFree(tfree);CHKERRQ(ierr);
1157487e5849SBarry Smith     i++;
1158e5c89e4eSSatish Balay   }
1159e5c89e4eSSatish Balay 
1160e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
1161e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1162e5c89e4eSSatish Balay   while (par) {
1163e5c89e4eSSatish Balay     *par  = 0;
1164e5c89e4eSSatish Balay     par  += 2;
1165e5c89e4eSSatish Balay     ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
1166e5c89e4eSSatish Balay     ierr  = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
1167e5c89e4eSSatish Balay     *epar = 0;
1168e5c89e4eSSatish Balay     epar += 1;
1169e5c89e4eSSatish Balay     ierr  = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr);
11707ba3a57cSBarry Smith     if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
1171e5c89e4eSSatish Balay     ierr = PetscStrcat(work,env);CHKERRQ(ierr);
1172e5c89e4eSSatish Balay     ierr = PetscStrcat(work,epar);CHKERRQ(ierr);
1173e5c89e4eSSatish Balay     ierr = PetscStrcpy(b,work);CHKERRQ(ierr);
1174e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1175e5c89e4eSSatish Balay   }
1176e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
117771573d7dSBarry Smith   if (aa == b) {
117871573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
117971573d7dSBarry Smith   }
1180e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1181e5c89e4eSSatish Balay }
1182e5c89e4eSSatish Balay 
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 /*@C
12228e81d068SLisandro Dalcin    PetscEnumFind - searches enum list of strings for given string, using case insensitive matching
1223a53986e1SJed Brown 
1224a53986e1SJed Brown    Not Collective
1225a53986e1SJed Brown 
1226a53986e1SJed Brown    Input Parameters:
1227a53986e1SJed Brown +  enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL
1228a53986e1SJed Brown -  str - string to look for
1229a53986e1SJed Brown 
1230a53986e1SJed Brown    Output Parameters:
1231a53986e1SJed Brown +  value - index of matching string (if found)
1232a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1233a53986e1SJed Brown 
1234a53986e1SJed Brown    Notes:
1235a53986e1SJed Brown    Not for use in Fortran
1236a53986e1SJed Brown 
1237a53986e1SJed Brown    Level: advanced
1238a53986e1SJed Brown @*/
1239a53986e1SJed Brown PetscErrorCode PetscEnumFind(const char *const *enumlist,const char *str,PetscEnum *value,PetscBool *found)
1240a53986e1SJed Brown {
1241a53986e1SJed Brown   PetscErrorCode ierr;
1242d05ba7d2SLisandro Dalcin   PetscInt n = 0,evalue;
1243a53986e1SJed Brown   PetscBool efound;
1244a53986e1SJed Brown 
1245a53986e1SJed Brown   PetscFunctionBegin;
1246d05ba7d2SLisandro 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");
1247a53986e1SJed Brown   if (n < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
1248a53986e1SJed Brown   n -= 3; /* drop enum name, prefix, and null termination */
1249a53986e1SJed Brown   ierr = PetscEListFind(n,enumlist,str,&evalue,&efound);CHKERRQ(ierr);
1250cfb463b1SJed Brown   if (efound) *value = (PetscEnum)evalue;
1251a53986e1SJed Brown   if (found) *found = efound;
1252a53986e1SJed Brown   PetscFunctionReturn(0);
1253a53986e1SJed Brown }
1254