xref: /petsc/src/sys/utils/str.c (revision e0ffd71f47fcc4029f6759c19bf7e02dd09d54e9)
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 
3195452b02SPatrick Sanan    Notes:
3295452b02SPatrick Sanan     this may be called before PetscInitialize() or after PetscFinalize()
333c311c98SBarry Smith 
346f013253SBarry Smith    Not for use in Fortran
356f013253SBarry Smith 
3695452b02SPatrick Sanan    Developer Notes:
3795452b02SPatrick Sanan     Using raw malloc() and does not call error handlers since this may be used before PETSc is initialized. Used
38b4cd4cebSBarry Smith      to generate argc, args arguments passed to MPI_Init()
39301d30feSBarry Smith 
40b4cd4cebSBarry Smith .seealso: PetscStrToArrayDestroy(), PetscToken, PetscTokenCreate()
413c311c98SBarry Smith 
423c311c98SBarry Smith @*/
43d67fe73bSBarry Smith PetscErrorCode  PetscStrToArray(const char s[],char sp,int *argc,char ***args)
443c311c98SBarry Smith {
45c3bcdc7eSBarry Smith   int       i,j,n,*lens,cnt = 0;
46ace3abfcSBarry Smith   PetscBool flg = PETSC_FALSE;
473c311c98SBarry Smith 
4840a7e1efSBarry Smith   if (!s) n = 0;
4940a7e1efSBarry Smith   else    n = strlen(s);
503c311c98SBarry Smith   *argc = 0;
5161528463SBarry Smith   *args = NULL;
52acf7dc08SSatish Balay   for (; n>0; n--) {   /* remove separator chars at the end - and will empty the string if all chars are separator chars */
53acf7dc08SSatish Balay     if (s[n-1] != sp) break;
54acf7dc08SSatish Balay   }
554996c5bdSBarry Smith   if (!n) {
564996c5bdSBarry Smith     return(0);
574996c5bdSBarry Smith   }
583c311c98SBarry Smith   for (i=0; i<n; i++) {
59d67fe73bSBarry Smith     if (s[i] != sp) break;
603c311c98SBarry Smith   }
613c311c98SBarry Smith   for (;i<n+1; i++) {
62d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
63d67fe73bSBarry Smith     else if (s[i] != sp) {flg = PETSC_FALSE;}
643c311c98SBarry Smith   }
65a2ea699eSBarry Smith   (*args) = (char**) malloc(((*argc)+1)*sizeof(char*)); if (!*args) return PETSC_ERR_MEM;
6653e6e2c4SHong Zhang   lens    = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM;
673c311c98SBarry Smith   for (i=0; i<*argc; i++) lens[i] = 0;
683c311c98SBarry Smith 
693c311c98SBarry Smith   *argc = 0;
703c311c98SBarry Smith   for (i=0; i<n; i++) {
71d67fe73bSBarry Smith     if (s[i] != sp) break;
723c311c98SBarry Smith   }
737dd9f305SSatish Balay   for (;i<n+1; i++) {
74d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
75d67fe73bSBarry Smith     else if (s[i] != sp) {lens[*argc]++;flg = PETSC_FALSE;}
763c311c98SBarry Smith   }
773c311c98SBarry Smith 
783c311c98SBarry Smith   for (i=0; i<*argc; i++) {
79c3bcdc7eSBarry Smith     (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char));
80c3bcdc7eSBarry Smith     if (!(*args)[i]) {
81c3bcdc7eSBarry Smith       free(lens);
82c3bcdc7eSBarry Smith       for (j=0; j<i; j++) free((*args)[j]);
83c3bcdc7eSBarry Smith       free(*args);
84c3bcdc7eSBarry Smith       return PETSC_ERR_MEM;
85c3bcdc7eSBarry Smith     }
863c311c98SBarry Smith   }
87a2ea699eSBarry Smith   free(lens);
88301d30feSBarry Smith   (*args)[*argc] = 0;
893c311c98SBarry Smith 
903c311c98SBarry Smith   *argc = 0;
913c311c98SBarry Smith   for (i=0; i<n; i++) {
92d67fe73bSBarry Smith     if (s[i] != sp) break;
933c311c98SBarry Smith   }
943c311c98SBarry Smith   for (;i<n+1; i++) {
95d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
96d67fe73bSBarry Smith     else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;}
973c311c98SBarry Smith   }
983c311c98SBarry Smith   return 0;
993c311c98SBarry Smith }
1003c311c98SBarry Smith 
101301d30feSBarry Smith /*@C
102301d30feSBarry Smith    PetscStrToArrayDestroy - Frees array created with PetscStrToArray().
103301d30feSBarry Smith 
104301d30feSBarry Smith    Not Collective
105301d30feSBarry Smith 
106301d30feSBarry Smith    Output Parameters:
107301d30feSBarry Smith +  argc - the number of arguments
108301d30feSBarry Smith -  args - the array of arguments
109301d30feSBarry Smith 
110301d30feSBarry Smith    Level: intermediate
111301d30feSBarry Smith 
112301d30feSBarry Smith    Concepts: command line arguments
113301d30feSBarry Smith 
11495452b02SPatrick Sanan    Notes:
11595452b02SPatrick Sanan     This may be called before PetscInitialize() or after PetscFinalize()
116301d30feSBarry Smith 
1176f013253SBarry Smith    Not for use in Fortran
1186f013253SBarry Smith 
119301d30feSBarry Smith .seealso: PetscStrToArray()
120301d30feSBarry Smith 
121301d30feSBarry Smith @*/
1227087cfbeSBarry Smith PetscErrorCode  PetscStrToArrayDestroy(int argc,char **args)
123301d30feSBarry Smith {
124301d30feSBarry Smith   PetscInt i;
125301d30feSBarry Smith 
126a297a907SKarl Rupp   for (i=0; i<argc; i++) free(args[i]);
127a297a907SKarl Rupp   if (args) free(args);
128301d30feSBarry Smith   return 0;
129301d30feSBarry Smith }
130301d30feSBarry Smith 
131e5c89e4eSSatish Balay /*@C
132e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
133e5c89e4eSSatish Balay 
134e5c89e4eSSatish Balay    Not Collective
135e5c89e4eSSatish Balay 
136e5c89e4eSSatish Balay    Input Parameters:
137e5c89e4eSSatish Balay .  s - pointer to string
138e5c89e4eSSatish Balay 
139e5c89e4eSSatish Balay    Output Parameter:
140e5c89e4eSSatish Balay .  len - length in bytes
141e5c89e4eSSatish Balay 
142e5c89e4eSSatish Balay    Level: intermediate
143e5c89e4eSSatish Balay 
144e5c89e4eSSatish Balay    Note:
145e5c89e4eSSatish Balay    This routine is analogous to strlen().
146e5c89e4eSSatish Balay 
147e5c89e4eSSatish Balay    Null string returns a length of zero
148e5c89e4eSSatish Balay 
1496f013253SBarry Smith    Not for use in Fortran
1506f013253SBarry Smith 
151e5c89e4eSSatish Balay   Concepts: string length
152e5c89e4eSSatish Balay 
153e5c89e4eSSatish Balay @*/
1547087cfbeSBarry Smith PetscErrorCode  PetscStrlen(const char s[],size_t *len)
155e5c89e4eSSatish Balay {
156e5c89e4eSSatish Balay   PetscFunctionBegin;
157a297a907SKarl Rupp   if (!s) *len = 0;
158a297a907SKarl Rupp   else    *len = strlen(s);
159e5c89e4eSSatish Balay   PetscFunctionReturn(0);
160e5c89e4eSSatish Balay }
161e5c89e4eSSatish Balay 
162e5c89e4eSSatish Balay /*@C
163e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
164e5c89e4eSSatish Balay 
165e5c89e4eSSatish Balay    Not Collective
166e5c89e4eSSatish Balay 
167e5c89e4eSSatish Balay    Input Parameters:
168e5c89e4eSSatish Balay .  s - pointer to string
169e5c89e4eSSatish Balay 
170e5c89e4eSSatish Balay    Output Parameter:
171e5c89e4eSSatish Balay .  t - the copied string
172e5c89e4eSSatish Balay 
173e5c89e4eSSatish Balay    Level: intermediate
174e5c89e4eSSatish Balay 
175e5c89e4eSSatish Balay    Note:
176e5c89e4eSSatish Balay       Null string returns a new null string
177e5c89e4eSSatish Balay 
1786f013253SBarry Smith       Not for use in Fortran
1796f013253SBarry Smith 
180e5c89e4eSSatish Balay   Concepts: string copy
181e5c89e4eSSatish Balay 
182e5c89e4eSSatish Balay @*/
1837087cfbeSBarry Smith PetscErrorCode  PetscStrallocpy(const char s[],char *t[])
184e5c89e4eSSatish Balay {
185e5c89e4eSSatish Balay   PetscErrorCode ierr;
186e5c89e4eSSatish Balay   size_t         len;
18771573d7dSBarry Smith   char           *tmp = 0;
188e5c89e4eSSatish Balay 
189e5c89e4eSSatish Balay   PetscFunctionBegin;
190e5c89e4eSSatish Balay   if (s) {
191e5c89e4eSSatish Balay     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
192854ce69bSBarry Smith     ierr = PetscMalloc1(1+len,&tmp);CHKERRQ(ierr);
19371573d7dSBarry Smith     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
194e5c89e4eSSatish Balay   }
19571573d7dSBarry Smith   *t = tmp;
196e5c89e4eSSatish Balay   PetscFunctionReturn(0);
197e5c89e4eSSatish Balay }
198e5c89e4eSSatish Balay 
19947340559SBarry Smith /*@C
20047340559SBarry Smith    PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
20147340559SBarry Smith 
20247340559SBarry Smith    Not Collective
20347340559SBarry Smith 
20447340559SBarry Smith    Input Parameters:
20547340559SBarry Smith .  s - pointer to array of strings (final string is a null)
20647340559SBarry Smith 
20747340559SBarry Smith    Output Parameter:
20847340559SBarry Smith .  t - the copied array string
20947340559SBarry Smith 
21047340559SBarry Smith    Level: intermediate
21147340559SBarry Smith 
21247340559SBarry Smith    Note:
21347340559SBarry Smith       Not for use in Fortran
21447340559SBarry Smith 
21547340559SBarry Smith   Concepts: string copy
21647340559SBarry Smith 
21747340559SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
21847340559SBarry Smith 
21947340559SBarry Smith @*/
22047340559SBarry Smith PetscErrorCode  PetscStrArrayallocpy(const char *const *list,char ***t)
22147340559SBarry Smith {
22247340559SBarry Smith   PetscErrorCode ierr;
22347340559SBarry Smith   PetscInt       i,n = 0;
22447340559SBarry Smith 
22547340559SBarry Smith   PetscFunctionBegin;
22647340559SBarry Smith   while (list[n++]) ;
227854ce69bSBarry Smith   ierr = PetscMalloc1(n+1,t);CHKERRQ(ierr);
22847340559SBarry Smith   for (i=0; i<n; i++) {
22947340559SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
23047340559SBarry Smith   }
2310298fd71SBarry Smith   (*t)[n] = NULL;
23247340559SBarry Smith   PetscFunctionReturn(0);
23347340559SBarry Smith }
23447340559SBarry Smith 
23547340559SBarry Smith /*@C
23647340559SBarry Smith    PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
23747340559SBarry Smith 
23847340559SBarry Smith    Not Collective
23947340559SBarry Smith 
24047340559SBarry Smith    Output Parameters:
24147340559SBarry Smith .   list - array of strings
24247340559SBarry Smith 
24347340559SBarry Smith    Level: intermediate
24447340559SBarry Smith 
24547340559SBarry Smith    Concepts: command line arguments
24647340559SBarry Smith 
24795452b02SPatrick Sanan    Notes:
24895452b02SPatrick Sanan     Not for use in Fortran
24947340559SBarry Smith 
25047340559SBarry Smith .seealso: PetscStrArrayallocpy()
25147340559SBarry Smith 
25247340559SBarry Smith @*/
2536fed8037SJed Brown PetscErrorCode PetscStrArrayDestroy(char ***list)
25447340559SBarry Smith {
25547340559SBarry Smith   PetscInt       n = 0;
25647340559SBarry Smith   PetscErrorCode ierr;
25747340559SBarry Smith 
2586fed8037SJed Brown   PetscFunctionBegin;
2596fed8037SJed Brown   if (!*list) PetscFunctionReturn(0);
2606fed8037SJed Brown   while ((*list)[n]) {
2616fed8037SJed Brown     ierr = PetscFree((*list)[n]);CHKERRQ(ierr);
26247340559SBarry Smith     n++;
26347340559SBarry Smith   }
2646fed8037SJed Brown   ierr = PetscFree(*list);CHKERRQ(ierr);
2656fed8037SJed Brown   PetscFunctionReturn(0);
26647340559SBarry Smith }
26747340559SBarry Smith 
2686991f827SBarry Smith /*@C
2696991f827SBarry Smith    PetscStrNArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
2706991f827SBarry Smith 
2716991f827SBarry Smith    Not Collective
2726991f827SBarry Smith 
2736991f827SBarry Smith    Input Parameters:
2746991f827SBarry Smith +  n - the number of string entries
2756991f827SBarry Smith -  s - pointer to array of strings
2766991f827SBarry Smith 
2776991f827SBarry Smith    Output Parameter:
2786991f827SBarry Smith .  t - the copied array string
2796991f827SBarry Smith 
2806991f827SBarry Smith    Level: intermediate
2816991f827SBarry Smith 
2826991f827SBarry Smith    Note:
2836991f827SBarry Smith       Not for use in Fortran
2846991f827SBarry Smith 
2856991f827SBarry Smith   Concepts: string copy
2866991f827SBarry Smith 
2876991f827SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
2886991f827SBarry Smith 
2896991f827SBarry Smith @*/
2906991f827SBarry Smith PetscErrorCode  PetscStrNArrayallocpy(PetscInt n,const char *const *list,char ***t)
2916991f827SBarry Smith {
2926991f827SBarry Smith   PetscErrorCode ierr;
2936991f827SBarry Smith   PetscInt       i;
2946991f827SBarry Smith 
2956991f827SBarry Smith   PetscFunctionBegin;
2966991f827SBarry Smith   ierr = PetscMalloc1(n,t);CHKERRQ(ierr);
2976991f827SBarry Smith   for (i=0; i<n; i++) {
2986991f827SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
2996991f827SBarry Smith   }
3006991f827SBarry Smith   PetscFunctionReturn(0);
3016991f827SBarry Smith }
3026991f827SBarry Smith 
3036991f827SBarry Smith /*@C
3046991f827SBarry Smith    PetscStrNArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
3056991f827SBarry Smith 
3066991f827SBarry Smith    Not Collective
3076991f827SBarry Smith 
3086991f827SBarry Smith    Output Parameters:
3096991f827SBarry Smith +   n - number of string entries
3106991f827SBarry Smith -   list - array of strings
3116991f827SBarry Smith 
3126991f827SBarry Smith    Level: intermediate
3136991f827SBarry Smith 
31495452b02SPatrick Sanan    Notes:
31595452b02SPatrick Sanan     Not for use in Fortran
3166991f827SBarry Smith 
3176991f827SBarry Smith .seealso: PetscStrArrayallocpy()
3186991f827SBarry Smith 
3196991f827SBarry Smith @*/
3206991f827SBarry Smith PetscErrorCode PetscStrNArrayDestroy(PetscInt n,char ***list)
3216991f827SBarry Smith {
3226991f827SBarry Smith   PetscErrorCode ierr;
3236991f827SBarry Smith   PetscInt       i;
3246991f827SBarry Smith 
3256991f827SBarry Smith   PetscFunctionBegin;
3266991f827SBarry Smith   if (!*list) PetscFunctionReturn(0);
3276991f827SBarry Smith   for (i=0; i<n; i++){
3286991f827SBarry Smith     ierr = PetscFree((*list)[i]);CHKERRQ(ierr);
3296991f827SBarry Smith   }
3306991f827SBarry Smith   ierr = PetscFree(*list);CHKERRQ(ierr);
3316991f827SBarry Smith   PetscFunctionReturn(0);
3326991f827SBarry Smith }
3336991f827SBarry Smith 
334e5c89e4eSSatish Balay /*@C
335e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
336e5c89e4eSSatish Balay 
337e5c89e4eSSatish Balay    Not Collective
338e5c89e4eSSatish Balay 
339e5c89e4eSSatish Balay    Input Parameters:
340e5c89e4eSSatish Balay .  t - pointer to string
341e5c89e4eSSatish Balay 
342e5c89e4eSSatish Balay    Output Parameter:
343e5c89e4eSSatish Balay .  s - the copied string
344e5c89e4eSSatish Balay 
345e5c89e4eSSatish Balay    Level: intermediate
346e5c89e4eSSatish Balay 
3476f013253SBarry Smith    Notes:
348e5c89e4eSSatish Balay      Null string returns a string starting with zero
349e5c89e4eSSatish Balay 
3506f013253SBarry Smith      Not for use in Fortran
3516f013253SBarry Smith 
352e5c89e4eSSatish Balay   Concepts: string copy
353e5c89e4eSSatish Balay 
354a126751eSBarry Smith .seealso: PetscStrncpy(), PetscStrcat(), PetscStrlcat()
355e5c89e4eSSatish Balay 
356e5c89e4eSSatish Balay @*/
357acc6cc86SBarry Smith 
3587087cfbeSBarry Smith PetscErrorCode  PetscStrcpy(char s[],const char t[])
359e5c89e4eSSatish Balay {
360e5c89e4eSSatish Balay   PetscFunctionBegin;
36117186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
362a297a907SKarl Rupp   if (t) strcpy(s,t);
363a297a907SKarl Rupp   else if (s) s[0] = 0;
364e5c89e4eSSatish Balay   PetscFunctionReturn(0);
365e5c89e4eSSatish Balay }
366e5c89e4eSSatish Balay 
367e5c89e4eSSatish Balay /*@C
368e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
369e5c89e4eSSatish Balay 
370e5c89e4eSSatish Balay    Not Collective
371e5c89e4eSSatish Balay 
372e5c89e4eSSatish Balay    Input Parameters:
373e5c89e4eSSatish Balay +  t - pointer to string
374e5c89e4eSSatish Balay -  n - the length to copy
375e5c89e4eSSatish Balay 
376e5c89e4eSSatish Balay    Output Parameter:
377e5c89e4eSSatish Balay .  s - the copied string
378e5c89e4eSSatish Balay 
379e5c89e4eSSatish Balay    Level: intermediate
380e5c89e4eSSatish Balay 
381e5c89e4eSSatish Balay    Note:
382e5c89e4eSSatish Balay      Null string returns a string starting with zero
383e5c89e4eSSatish Balay 
384ff32304bSBarry Smith      If the string that is being copied is of length n or larger then the entire string is not
3851b6ef838SBarry Smith      copied and the final location of s is set to NULL. This is different then the behavior of
3861b6ef838SBarry Smith      strncpy() which leaves s non-terminated if there is not room for the entire string.
387ff32304bSBarry Smith 
388e5c89e4eSSatish Balay   Concepts: string copy
389e5c89e4eSSatish Balay 
39062a5de14SBarry Smith   Developers Note: Should this be PetscStrlcpy() to reflect its behavior which is like strlcpy() not strncpy()
39162a5de14SBarry Smith 
392a126751eSBarry Smith .seealso: PetscStrcpy(), PetscStrcat(), PetscStrlcat()
393e5c89e4eSSatish Balay 
394e5c89e4eSSatish Balay @*/
3957087cfbeSBarry Smith PetscErrorCode  PetscStrncpy(char s[],const char t[],size_t n)
396e5c89e4eSSatish Balay {
397e5c89e4eSSatish Balay   PetscFunctionBegin;
39817186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
39962a5de14SBarry 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");
400ff32304bSBarry Smith   if (t) {
4018dc57659SBarry Smith     if (n > 1) {
4022c26941aSBarry Smith       strncpy(s,t,n-1);
403ff32304bSBarry Smith       s[n-1] = '\0';
4048dc57659SBarry Smith     } else {
4058dc57659SBarry Smith       s[0] = '\0';
4068dc57659SBarry Smith     }
407ff32304bSBarry Smith   } else if (s) s[0] = 0;
408e5c89e4eSSatish Balay   PetscFunctionReturn(0);
409e5c89e4eSSatish Balay }
410e5c89e4eSSatish Balay 
411e5c89e4eSSatish Balay /*@C
412e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
413e5c89e4eSSatish Balay 
414e5c89e4eSSatish Balay    Not Collective
415e5c89e4eSSatish Balay 
416e5c89e4eSSatish Balay    Input Parameters:
417e5e2177aSMatthew Knepley +  s - string to be added to
418e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
419e5c89e4eSSatish Balay 
420e5c89e4eSSatish Balay    Level: intermediate
421e5c89e4eSSatish Balay 
42295452b02SPatrick Sanan    Notes:
42395452b02SPatrick Sanan     Not for use in Fortran
4246f013253SBarry Smith 
425e5c89e4eSSatish Balay   Concepts: string copy
426e5c89e4eSSatish Balay 
427a126751eSBarry Smith .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrlcat()
428e5c89e4eSSatish Balay 
429e5c89e4eSSatish Balay @*/
4307087cfbeSBarry Smith PetscErrorCode  PetscStrcat(char s[],const char t[])
431e5c89e4eSSatish Balay {
432e5c89e4eSSatish Balay   PetscFunctionBegin;
4339b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
434e5c89e4eSSatish Balay   strcat(s,t);
435e5c89e4eSSatish Balay   PetscFunctionReturn(0);
436e5c89e4eSSatish Balay }
437e5c89e4eSSatish Balay 
438e5c89e4eSSatish Balay /*@C
439a126751eSBarry Smith    PetscStrlcat - Concatenates a string onto a given string, up to a given length
440e5c89e4eSSatish Balay 
441e5c89e4eSSatish Balay    Not Collective
442e5c89e4eSSatish Balay 
443e5c89e4eSSatish Balay    Input Parameters:
444*e0ffd71fSBarry Smith +  s - pointer to string to be added to at end
445e5c89e4eSSatish Balay .  t - string to be added to
44624a58d73SPatrick Sanan -  n - length of the original allocated string
447e5c89e4eSSatish Balay 
448e5c89e4eSSatish Balay    Level: intermediate
449e5c89e4eSSatish Balay 
45024a58d73SPatrick Sanan   Notes:
45124a58d73SPatrick Sanan   Not for use in Fortran
4526f013253SBarry Smith 
45324a58d73SPatrick Sanan   Unlike the system call strncat(), the length passed in is the length of the
45424a58d73SPatrick Sanan   original allocated space, not the length of the left-over space. This is
45524a58d73SPatrick Sanan   similar to the BSD system call strlcat().
456153a8027SBarry Smith 
457e5c89e4eSSatish Balay   Concepts: string copy
458e5c89e4eSSatish Balay 
459e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
460e5c89e4eSSatish Balay 
461e5c89e4eSSatish Balay @*/
462a126751eSBarry Smith PetscErrorCode  PetscStrlcat(char s[],const char t[],size_t n)
463e5c89e4eSSatish Balay {
464153a8027SBarry Smith   size_t         len;
465153a8027SBarry Smith   PetscErrorCode ierr;
466153a8027SBarry Smith 
467e5c89e4eSSatish Balay   PetscFunctionBegin;
468681eeb0aSBarry Smith   if (t && !n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"String buffer length must be positive");
469*e0ffd71fSBarry Smith   if (!t) PetscFunctionReturn(0);
470153a8027SBarry Smith   ierr = PetscStrlen(t,&len);CHKERRQ(ierr);
471153a8027SBarry Smith   strncat(s,t,n - len);
472681eeb0aSBarry Smith   s[n-1] = 0;
473e5c89e4eSSatish Balay   PetscFunctionReturn(0);
474e5c89e4eSSatish Balay }
475e5c89e4eSSatish Balay 
476573b0fb4SBarry Smith /*
477573b0fb4SBarry Smith    Only to be used with PetscCheck__FUNCT__()!
478573b0fb4SBarry Smith 
479573b0fb4SBarry Smith */
480573b0fb4SBarry Smith void  PetscStrcmpNoError(const char a[],const char b[],PetscBool  *flg)
481573b0fb4SBarry Smith {
482573b0fb4SBarry Smith   int c;
483573b0fb4SBarry Smith 
484573b0fb4SBarry Smith   if (!a && !b)      *flg = PETSC_TRUE;
485573b0fb4SBarry Smith   else if (!a || !b) *flg = PETSC_FALSE;
486573b0fb4SBarry Smith   else {
487573b0fb4SBarry Smith     c = strcmp(a,b);
488573b0fb4SBarry Smith     if (c) *flg = PETSC_FALSE;
489573b0fb4SBarry Smith     else   *flg = PETSC_TRUE;
490573b0fb4SBarry Smith   }
491573b0fb4SBarry Smith }
492573b0fb4SBarry Smith 
493e5c89e4eSSatish Balay /*@C
494e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
495e5c89e4eSSatish Balay 
496e5c89e4eSSatish Balay    Not Collective
497e5c89e4eSSatish Balay 
498e5c89e4eSSatish Balay    Input Parameters:
499e5c89e4eSSatish Balay +  a - pointer to string first string
500e5c89e4eSSatish Balay -  b - pointer to second string
501e5c89e4eSSatish Balay 
502e5c89e4eSSatish Balay    Output Parameter:
5038c74ee41SBarry Smith .  flg - PETSC_TRUE if the two strings are equal
504e5c89e4eSSatish Balay 
505e5c89e4eSSatish Balay    Level: intermediate
506e5c89e4eSSatish Balay 
50795452b02SPatrick Sanan    Notes:
50895452b02SPatrick Sanan     Not for use in Fortran
5096f013253SBarry Smith 
510e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
511e5c89e4eSSatish Balay 
512e5c89e4eSSatish Balay @*/
5137087cfbeSBarry Smith PetscErrorCode  PetscStrcmp(const char a[],const char b[],PetscBool  *flg)
514e5c89e4eSSatish Balay {
515e5c89e4eSSatish Balay   int c;
516e5c89e4eSSatish Balay 
517e5c89e4eSSatish Balay   PetscFunctionBegin;
518a297a907SKarl Rupp   if (!a && !b)      *flg = PETSC_TRUE;
519a297a907SKarl Rupp   else if (!a || !b) *flg = PETSC_FALSE;
520a297a907SKarl Rupp   else {
521e5c89e4eSSatish Balay     c = strcmp(a,b);
522e5c89e4eSSatish Balay     if (c) *flg = PETSC_FALSE;
523e5c89e4eSSatish Balay     else   *flg = PETSC_TRUE;
524e5c89e4eSSatish Balay   }
525e5c89e4eSSatish Balay   PetscFunctionReturn(0);
526e5c89e4eSSatish Balay }
527e5c89e4eSSatish Balay 
528e5c89e4eSSatish Balay /*@C
529e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
530e5c89e4eSSatish Balay 
531e5c89e4eSSatish Balay    Not Collective
532e5c89e4eSSatish Balay 
533e5c89e4eSSatish Balay    Input Parameters:
534e5c89e4eSSatish Balay +  a - pointer to first string
535e5c89e4eSSatish Balay -  b - pointer to second string
536e5c89e4eSSatish Balay 
537e5c89e4eSSatish Balay    Output Parameter:
538e5c89e4eSSatish Balay .  flg - if the first string is greater
539e5c89e4eSSatish Balay 
540e5c89e4eSSatish Balay    Notes:
541e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
542e5c89e4eSSatish Balay     all others
543e5c89e4eSSatish Balay 
5446f013253SBarry Smith    Not for use in Fortran
5456f013253SBarry Smith 
546e5c89e4eSSatish Balay    Level: intermediate
547e5c89e4eSSatish Balay 
548e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
549e5c89e4eSSatish Balay 
550e5c89e4eSSatish Balay @*/
5517087cfbeSBarry Smith PetscErrorCode  PetscStrgrt(const char a[],const char b[],PetscBool  *t)
552e5c89e4eSSatish Balay {
553e5c89e4eSSatish Balay   int c;
554e5c89e4eSSatish Balay 
555e5c89e4eSSatish Balay   PetscFunctionBegin;
556a297a907SKarl Rupp   if (!a && !b) *t = PETSC_FALSE;
557a297a907SKarl Rupp   else if (a && !b) *t = PETSC_TRUE;
558a297a907SKarl Rupp   else if (!a && b) *t = PETSC_FALSE;
559a297a907SKarl Rupp   else {
560e5c89e4eSSatish Balay     c = strcmp(a,b);
561e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
562e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
563e5c89e4eSSatish Balay   }
564e5c89e4eSSatish Balay   PetscFunctionReturn(0);
565e5c89e4eSSatish Balay }
566e5c89e4eSSatish Balay 
567e5c89e4eSSatish Balay /*@C
568e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
569e5c89e4eSSatish Balay      except possibly for case.
570e5c89e4eSSatish Balay 
571e5c89e4eSSatish Balay    Not Collective
572e5c89e4eSSatish Balay 
573e5c89e4eSSatish Balay    Input Parameters:
574e5c89e4eSSatish Balay +  a - pointer to first string
575e5c89e4eSSatish Balay -  b - pointer to second string
576e5c89e4eSSatish Balay 
577e5c89e4eSSatish Balay    Output Parameter:
578e5c89e4eSSatish Balay .  flg - if the two strings are the same
579e5c89e4eSSatish Balay 
580e5c89e4eSSatish Balay    Notes:
581e5c89e4eSSatish Balay     Null arguments are ok
582e5c89e4eSSatish Balay 
5836f013253SBarry Smith    Not for use in Fortran
5846f013253SBarry Smith 
585e5c89e4eSSatish Balay    Level: intermediate
586e5c89e4eSSatish Balay 
587e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
588e5c89e4eSSatish Balay 
589e5c89e4eSSatish Balay @*/
5907087cfbeSBarry Smith PetscErrorCode  PetscStrcasecmp(const char a[],const char b[],PetscBool  *t)
591e5c89e4eSSatish Balay {
592e5c89e4eSSatish Balay   int c;
593e5c89e4eSSatish Balay 
594e5c89e4eSSatish Balay   PetscFunctionBegin;
595e5c89e4eSSatish Balay   if (!a && !b) c = 0;
596e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
59732b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
59832b366c8SSatish Balay   else c = strcasecmp(a,b);
59932b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
600e5c89e4eSSatish Balay   else c = stricmp(a,b);
601e5c89e4eSSatish Balay #else
60232b366c8SSatish Balay   else {
60332b366c8SSatish Balay     char           *aa,*bb;
60432b366c8SSatish Balay     PetscErrorCode ierr;
60532b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
60632b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
60732b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
60832b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
60932b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
610503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
611503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
61232b366c8SSatish Balay     PetscFunctionReturn(0);
61332b366c8SSatish Balay   }
614e5c89e4eSSatish Balay #endif
615e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
616e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
617e5c89e4eSSatish Balay   PetscFunctionReturn(0);
618e5c89e4eSSatish Balay }
619e5c89e4eSSatish Balay 
62032b366c8SSatish Balay 
62132b366c8SSatish Balay 
622e5c89e4eSSatish Balay /*@C
623e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
624e5c89e4eSSatish Balay 
625e5c89e4eSSatish Balay    Not Collective
626e5c89e4eSSatish Balay 
627e5c89e4eSSatish Balay    Input Parameters:
628e5c89e4eSSatish Balay +  a - pointer to first string
629e5c89e4eSSatish Balay .  b - pointer to second string
630e5c89e4eSSatish Balay -  n - length to compare up to
631e5c89e4eSSatish Balay 
632e5c89e4eSSatish Balay    Output Parameter:
633e5c89e4eSSatish Balay .  t - if the two strings are equal
634e5c89e4eSSatish Balay 
635e5c89e4eSSatish Balay    Level: intermediate
636e5c89e4eSSatish Balay 
63795452b02SPatrick Sanan    Notes:
63895452b02SPatrick Sanan     Not for use in Fortran
6396f013253SBarry Smith 
640e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
641e5c89e4eSSatish Balay 
642e5c89e4eSSatish Balay @*/
6437087cfbeSBarry Smith PetscErrorCode  PetscStrncmp(const char a[],const char b[],size_t n,PetscBool  *t)
644e5c89e4eSSatish Balay {
645e5c89e4eSSatish Balay   int c;
646e5c89e4eSSatish Balay 
647e5c89e4eSSatish Balay   PetscFunctionBegin;
648e5c89e4eSSatish Balay   c = strncmp(a,b,n);
649e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
650e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
651e5c89e4eSSatish Balay   PetscFunctionReturn(0);
652e5c89e4eSSatish Balay }
653e5c89e4eSSatish Balay 
654e5c89e4eSSatish Balay /*@C
655e5c89e4eSSatish Balay    PetscStrchr - Locates first occurance of a character in a string
656e5c89e4eSSatish Balay 
657e5c89e4eSSatish Balay    Not Collective
658e5c89e4eSSatish Balay 
659e5c89e4eSSatish Balay    Input Parameters:
660e5c89e4eSSatish Balay +  a - pointer to string
661e5c89e4eSSatish Balay -  b - character
662e5c89e4eSSatish Balay 
663e5c89e4eSSatish Balay    Output Parameter:
6640298fd71SBarry Smith .  c - location of occurance, NULL if not found
665e5c89e4eSSatish Balay 
666e5c89e4eSSatish Balay    Level: intermediate
667e5c89e4eSSatish Balay 
66895452b02SPatrick Sanan    Notes:
66995452b02SPatrick Sanan     Not for use in Fortran
6706f013253SBarry Smith 
671e5c89e4eSSatish Balay @*/
6727087cfbeSBarry Smith PetscErrorCode  PetscStrchr(const char a[],char b,char *c[])
673e5c89e4eSSatish Balay {
674e5c89e4eSSatish Balay   PetscFunctionBegin;
675e5c89e4eSSatish Balay   *c = (char*)strchr(a,b);
676e5c89e4eSSatish Balay   PetscFunctionReturn(0);
677e5c89e4eSSatish Balay }
678e5c89e4eSSatish Balay 
679e5c89e4eSSatish Balay /*@C
680e5c89e4eSSatish Balay    PetscStrrchr - Locates one location past the last occurance of a character in a string,
681e5c89e4eSSatish Balay       if the character is not found then returns entire string
682e5c89e4eSSatish Balay 
683e5c89e4eSSatish Balay    Not Collective
684e5c89e4eSSatish Balay 
685e5c89e4eSSatish Balay    Input Parameters:
686e5c89e4eSSatish Balay +  a - pointer to string
687e5c89e4eSSatish Balay -  b - character
688e5c89e4eSSatish Balay 
689e5c89e4eSSatish Balay    Output Parameter:
690e5c89e4eSSatish Balay .  tmp - location of occurance, a if not found
691e5c89e4eSSatish Balay 
692e5c89e4eSSatish Balay    Level: intermediate
693e5c89e4eSSatish Balay 
69495452b02SPatrick Sanan    Notes:
69595452b02SPatrick Sanan     Not for use in Fortran
6966f013253SBarry Smith 
697e5c89e4eSSatish Balay @*/
6987087cfbeSBarry Smith PetscErrorCode  PetscStrrchr(const char a[],char b,char *tmp[])
699e5c89e4eSSatish Balay {
700e5c89e4eSSatish Balay   PetscFunctionBegin;
701e5c89e4eSSatish Balay   *tmp = (char*)strrchr(a,b);
702a297a907SKarl Rupp   if (!*tmp) *tmp = (char*)a;
703a297a907SKarl Rupp   else *tmp = *tmp + 1;
704e5c89e4eSSatish Balay   PetscFunctionReturn(0);
705e5c89e4eSSatish Balay }
706e5c89e4eSSatish Balay 
707e5c89e4eSSatish Balay /*@C
708e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
709e5c89e4eSSatish Balay 
710e5c89e4eSSatish Balay    Not Collective
711e5c89e4eSSatish Balay 
712e5c89e4eSSatish Balay    Input Parameters:
713e5c89e4eSSatish Balay .  a - pointer to string
714e5c89e4eSSatish Balay 
715e5c89e4eSSatish Balay    Level: intermediate
716e5c89e4eSSatish Balay 
71795452b02SPatrick Sanan    Notes:
71895452b02SPatrick Sanan     Not for use in Fortran
7196f013253SBarry Smith 
720e5c89e4eSSatish Balay @*/
7217087cfbeSBarry Smith PetscErrorCode  PetscStrtolower(char a[])
722e5c89e4eSSatish Balay {
723e5c89e4eSSatish Balay   PetscFunctionBegin;
724e5c89e4eSSatish Balay   while (*a) {
725e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
726e5c89e4eSSatish Balay     a++;
727e5c89e4eSSatish Balay   }
728e5c89e4eSSatish Balay   PetscFunctionReturn(0);
729e5c89e4eSSatish Balay }
730e5c89e4eSSatish Balay 
7312f234a98SBarry Smith /*@C
7326e3a5469SBarry Smith    PetscStrtoupper - Converts string to upper case
7332f234a98SBarry Smith 
7342f234a98SBarry Smith    Not Collective
7352f234a98SBarry Smith 
7362f234a98SBarry Smith    Input Parameters:
7372f234a98SBarry Smith .  a - pointer to string
7382f234a98SBarry Smith 
7392f234a98SBarry Smith    Level: intermediate
7402f234a98SBarry Smith 
74195452b02SPatrick Sanan    Notes:
74295452b02SPatrick Sanan     Not for use in Fortran
7432f234a98SBarry Smith 
7442f234a98SBarry Smith @*/
7452f234a98SBarry Smith PetscErrorCode  PetscStrtoupper(char a[])
7462f234a98SBarry Smith {
7472f234a98SBarry Smith   PetscFunctionBegin;
7482f234a98SBarry Smith   while (*a) {
7492f234a98SBarry Smith     if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a';
7502f234a98SBarry Smith     a++;
7512f234a98SBarry Smith   }
7522f234a98SBarry Smith   PetscFunctionReturn(0);
7532f234a98SBarry Smith }
7542f234a98SBarry Smith 
7557ba3a57cSBarry Smith /*@C
7567ba3a57cSBarry Smith    PetscStrendswith - Determines if a string ends with a certain string
7571d1a0024SBarry Smith 
7587ba3a57cSBarry Smith    Not Collective
7597ba3a57cSBarry Smith 
7607ba3a57cSBarry Smith    Input Parameters:
7617ba3a57cSBarry Smith +  a - pointer to string
7627ba3a57cSBarry Smith -  b - string to endwith
7637ba3a57cSBarry Smith 
7647ba3a57cSBarry Smith    Output Parameter:
7657ba3a57cSBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
7667ba3a57cSBarry Smith 
76795452b02SPatrick Sanan    Notes:
76895452b02SPatrick Sanan     Not for use in Fortran
7697ba3a57cSBarry Smith 
7707ba3a57cSBarry Smith    Level: intermediate
7717ba3a57cSBarry Smith 
7727ba3a57cSBarry Smith @*/
7737ba3a57cSBarry Smith PetscErrorCode  PetscStrendswith(const char a[],const char b[],PetscBool *flg)
7747ba3a57cSBarry Smith {
7757ba3a57cSBarry Smith   char           *test;
7767ba3a57cSBarry Smith   PetscErrorCode ierr;
7777ba3a57cSBarry Smith   size_t         na,nb;
7787ba3a57cSBarry Smith 
7797ba3a57cSBarry Smith   PetscFunctionBegin;
7807ba3a57cSBarry Smith   *flg = PETSC_FALSE;
7817ba3a57cSBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
7827ba3a57cSBarry Smith   if (test) {
7837ba3a57cSBarry Smith     ierr = PetscStrlen(a,&na);CHKERRQ(ierr);
7847ba3a57cSBarry Smith     ierr = PetscStrlen(b,&nb);CHKERRQ(ierr);
7857ba3a57cSBarry Smith     if (a+na-nb == test) *flg = PETSC_TRUE;
7867ba3a57cSBarry Smith   }
7877ba3a57cSBarry Smith   PetscFunctionReturn(0);
7887ba3a57cSBarry Smith }
7897ba3a57cSBarry Smith 
7902c9581d2SBarry Smith /*@C
7912c9581d2SBarry Smith    PetscStrbeginswith - Determines if a string begins with a certain string
7922c9581d2SBarry Smith 
7932c9581d2SBarry Smith    Not Collective
7942c9581d2SBarry Smith 
7952c9581d2SBarry Smith    Input Parameters:
7962c9581d2SBarry Smith +  a - pointer to string
7972c9581d2SBarry Smith -  b - string to begin with
7982c9581d2SBarry Smith 
7992c9581d2SBarry Smith    Output Parameter:
8002c9581d2SBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
8012c9581d2SBarry Smith 
80295452b02SPatrick Sanan    Notes:
80395452b02SPatrick Sanan     Not for use in Fortran
8042c9581d2SBarry Smith 
8052c9581d2SBarry Smith    Level: intermediate
8062c9581d2SBarry Smith 
8076e3a5469SBarry Smith .seealso: PetscStrendswithwhich(), PetscStrendswith(), PetscStrtoupper, PetscStrtolower(), PetscStrrchr(), PetscStrchr(),
8086e3a5469SBarry Smith           PetscStrncmp(), PetscStrlen(), PetscStrncmp(), PetscStrcmp()
8096e3a5469SBarry Smith 
8102c9581d2SBarry Smith @*/
8112c9581d2SBarry Smith PetscErrorCode  PetscStrbeginswith(const char a[],const char b[],PetscBool *flg)
8122c9581d2SBarry Smith {
8132c9581d2SBarry Smith   char           *test;
8142c9581d2SBarry Smith   PetscErrorCode ierr;
8152c9581d2SBarry Smith 
8162c9581d2SBarry Smith   PetscFunctionBegin;
8172c9581d2SBarry Smith   *flg = PETSC_FALSE;
8182c9581d2SBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
819a297a907SKarl Rupp   if (test && (test == a)) *flg = PETSC_TRUE;
8202c9581d2SBarry Smith   PetscFunctionReturn(0);
8212c9581d2SBarry Smith }
8222c9581d2SBarry Smith 
8232c9581d2SBarry Smith 
8247ba3a57cSBarry Smith /*@C
8257ba3a57cSBarry Smith    PetscStrendswithwhich - Determines if a string ends with one of several possible strings
8267ba3a57cSBarry Smith 
8277ba3a57cSBarry Smith    Not Collective
8287ba3a57cSBarry Smith 
8297ba3a57cSBarry Smith    Input Parameters:
8307ba3a57cSBarry Smith +  a - pointer to string
8317ba3a57cSBarry Smith -  bs - strings to endwith (last entry must be null)
8327ba3a57cSBarry Smith 
8337ba3a57cSBarry Smith    Output Parameter:
8347ba3a57cSBarry Smith .  cnt - the index of the string it ends with or 1+the last possible index
8357ba3a57cSBarry Smith 
83695452b02SPatrick Sanan    Notes:
83795452b02SPatrick Sanan     Not for use in Fortran
8387ba3a57cSBarry Smith 
8397ba3a57cSBarry Smith    Level: intermediate
8407ba3a57cSBarry Smith 
8417ba3a57cSBarry Smith @*/
8427ba3a57cSBarry Smith PetscErrorCode  PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt)
8437ba3a57cSBarry Smith {
8447ba3a57cSBarry Smith   PetscBool      flg;
8457ba3a57cSBarry Smith   PetscErrorCode ierr;
8467ba3a57cSBarry Smith 
8477ba3a57cSBarry Smith   PetscFunctionBegin;
8487ba3a57cSBarry Smith   *cnt = 0;
8497ba3a57cSBarry Smith   while (bs[*cnt]) {
8507ba3a57cSBarry Smith     ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr);
8517ba3a57cSBarry Smith     if (flg) PetscFunctionReturn(0);
8527ba3a57cSBarry Smith     *cnt += 1;
8537ba3a57cSBarry Smith   }
8547ba3a57cSBarry Smith   PetscFunctionReturn(0);
8557ba3a57cSBarry Smith }
8567ba3a57cSBarry Smith 
8577ba3a57cSBarry Smith /*@C
8587ba3a57cSBarry Smith    PetscStrrstr - Locates last occurance of string in another string
8597ba3a57cSBarry Smith 
8607ba3a57cSBarry Smith    Not Collective
8617ba3a57cSBarry Smith 
8627ba3a57cSBarry Smith    Input Parameters:
8637ba3a57cSBarry Smith +  a - pointer to string
8647ba3a57cSBarry Smith -  b - string to find
8657ba3a57cSBarry Smith 
8667ba3a57cSBarry Smith    Output Parameter:
8677ba3a57cSBarry Smith .  tmp - location of occurance
8687ba3a57cSBarry Smith 
86995452b02SPatrick Sanan    Notes:
87095452b02SPatrick Sanan     Not for use in Fortran
8717ba3a57cSBarry Smith 
8727ba3a57cSBarry Smith    Level: intermediate
8737ba3a57cSBarry Smith 
8747ba3a57cSBarry Smith @*/
8757ba3a57cSBarry Smith PetscErrorCode  PetscStrrstr(const char a[],const char b[],char *tmp[])
8767ba3a57cSBarry Smith {
8777ba3a57cSBarry Smith   const char *stmp = a, *ltmp = 0;
8787ba3a57cSBarry Smith 
8797ba3a57cSBarry Smith   PetscFunctionBegin;
8807ba3a57cSBarry Smith   while (stmp) {
8817ba3a57cSBarry Smith     stmp = (char*)strstr(stmp,b);
8827ba3a57cSBarry Smith     if (stmp) {ltmp = stmp;stmp++;}
8837ba3a57cSBarry Smith   }
8847ba3a57cSBarry Smith   *tmp = (char*)ltmp;
8857ba3a57cSBarry Smith   PetscFunctionReturn(0);
8867ba3a57cSBarry Smith }
8877ba3a57cSBarry Smith 
8887ba3a57cSBarry Smith /*@C
8897ba3a57cSBarry Smith    PetscStrstr - Locates first occurance of string in another string
8907ba3a57cSBarry Smith 
8917ba3a57cSBarry Smith    Not Collective
8927ba3a57cSBarry Smith 
8937ba3a57cSBarry Smith    Input Parameters:
894160f4796SJed Brown +  haystack - string to search
895160f4796SJed Brown -  needle - string to find
8967ba3a57cSBarry Smith 
8977ba3a57cSBarry Smith    Output Parameter:
8980298fd71SBarry Smith .  tmp - location of occurance, is a NULL if the string is not found
8997ba3a57cSBarry Smith 
90095452b02SPatrick Sanan    Notes:
90195452b02SPatrick Sanan     Not for use in Fortran
9027ba3a57cSBarry Smith 
9037ba3a57cSBarry Smith    Level: intermediate
9047ba3a57cSBarry Smith 
9057ba3a57cSBarry Smith @*/
906160f4796SJed Brown PetscErrorCode  PetscStrstr(const char haystack[],const char needle[],char *tmp[])
9077ba3a57cSBarry Smith {
9087ba3a57cSBarry Smith   PetscFunctionBegin;
909160f4796SJed Brown   *tmp = (char*)strstr(haystack,needle);
9107ba3a57cSBarry Smith   PetscFunctionReturn(0);
9117ba3a57cSBarry Smith }
9127ba3a57cSBarry Smith 
9137ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
9141d1a0024SBarry Smith 
915e5c89e4eSSatish Balay /*@C
916e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
917e5c89e4eSSatish Balay 
918e5c89e4eSSatish Balay    Not Collective
919e5c89e4eSSatish Balay 
920e5c89e4eSSatish Balay    Input Parameters:
921e5c89e4eSSatish Balay .  a - pointer to token
922e5c89e4eSSatish Balay 
923e5c89e4eSSatish Balay    Output Parameter:
9240298fd71SBarry Smith .  result - location of occurance, NULL if not found
925e5c89e4eSSatish Balay 
926e5c89e4eSSatish Balay    Notes:
927e5c89e4eSSatish Balay 
928e5c89e4eSSatish Balay      This version is different from the system version in that
929e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
930e5c89e4eSSatish Balay 
9314704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
9324704e885SBarry Smith    as a single token.
9334704e885SBarry Smith 
9343a9c465aSBarry 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
9353a9c465aSBarry Smith    second will return a null terminated y
9363a9c465aSBarry Smith 
9373a9c465aSBarry 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
9383a9c465aSBarry Smith 
9396f013253SBarry Smith     Not for use in Fortran
9406f013253SBarry Smith 
941e5c89e4eSSatish Balay    Level: intermediate
942e5c89e4eSSatish Balay 
9436f013253SBarry Smith 
944e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
945e5c89e4eSSatish Balay @*/
9467087cfbeSBarry Smith PetscErrorCode  PetscTokenFind(PetscToken a,char *result[])
947e5c89e4eSSatish Balay {
9484704e885SBarry Smith   char *ptr = a->current,token;
949e5c89e4eSSatish Balay 
950e5c89e4eSSatish Balay   PetscFunctionBegin;
951e5c89e4eSSatish Balay   *result = a->current;
9524704e885SBarry Smith   if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);}
9534704e885SBarry Smith   token = a->token;
95490fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
955e5c89e4eSSatish Balay   while (ptr) {
9564704e885SBarry Smith     if (*ptr == token) {
957e5c89e4eSSatish Balay       *ptr++ = 0;
958e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
959e5c89e4eSSatish Balay       a->current = ptr;
960e5c89e4eSSatish Balay       break;
961e5c89e4eSSatish Balay     }
962e5c89e4eSSatish Balay     if (!*ptr) {
963e5c89e4eSSatish Balay       a->current = 0;
964e5c89e4eSSatish Balay       break;
965e5c89e4eSSatish Balay     }
966e5c89e4eSSatish Balay     ptr++;
967e5c89e4eSSatish Balay   }
968e5c89e4eSSatish Balay   PetscFunctionReturn(0);
969e5c89e4eSSatish Balay }
970e5c89e4eSSatish Balay 
971e5c89e4eSSatish Balay /*@C
972e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
973e5c89e4eSSatish Balay 
974e5c89e4eSSatish Balay    Not Collective
975e5c89e4eSSatish Balay 
976e5c89e4eSSatish Balay    Input Parameters:
977e5c89e4eSSatish Balay +  string - the string to look in
9783a9c465aSBarry Smith -  b - the separator character
979e5c89e4eSSatish Balay 
980e5c89e4eSSatish Balay    Output Parameter:
9813a9c465aSBarry Smith .  t- the token object
982e5c89e4eSSatish Balay 
983e5c89e4eSSatish Balay    Notes:
984e5c89e4eSSatish Balay 
985e5c89e4eSSatish Balay      This version is different from the system version in that
986e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
987e5c89e4eSSatish Balay 
9886f013253SBarry Smith     Not for use in Fortran
9896f013253SBarry Smith 
990e5c89e4eSSatish Balay    Level: intermediate
991e5c89e4eSSatish Balay 
992e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
993e5c89e4eSSatish Balay @*/
9947087cfbeSBarry Smith PetscErrorCode  PetscTokenCreate(const char a[],const char b,PetscToken *t)
995e5c89e4eSSatish Balay {
996e5c89e4eSSatish Balay   PetscErrorCode ierr;
997e5c89e4eSSatish Balay 
998e5c89e4eSSatish Balay   PetscFunctionBegin;
999b00a9115SJed Brown   ierr = PetscNew(t);CHKERRQ(ierr);
1000e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
1001a297a907SKarl Rupp 
1002e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
1003e5c89e4eSSatish Balay   (*t)->token   = b;
1004e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1005e5c89e4eSSatish Balay }
1006e5c89e4eSSatish Balay 
1007e5c89e4eSSatish Balay /*@C
1008e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
1009e5c89e4eSSatish Balay 
1010e5c89e4eSSatish Balay    Not Collective
1011e5c89e4eSSatish Balay 
1012e5c89e4eSSatish Balay    Input Parameters:
1013e5c89e4eSSatish Balay .  a - pointer to token
1014e5c89e4eSSatish Balay 
1015e5c89e4eSSatish Balay    Level: intermediate
1016e5c89e4eSSatish Balay 
101795452b02SPatrick Sanan    Notes:
101895452b02SPatrick Sanan     Not for use in Fortran
10196f013253SBarry Smith 
1020e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
1021e5c89e4eSSatish Balay @*/
10228c74ee41SBarry Smith PetscErrorCode  PetscTokenDestroy(PetscToken *a)
1023e5c89e4eSSatish Balay {
1024e5c89e4eSSatish Balay   PetscErrorCode ierr;
1025e5c89e4eSSatish Balay 
1026e5c89e4eSSatish Balay   PetscFunctionBegin;
10278c74ee41SBarry Smith   if (!*a) PetscFunctionReturn(0);
10288c74ee41SBarry Smith   ierr = PetscFree((*a)->array);CHKERRQ(ierr);
10298c74ee41SBarry Smith   ierr = PetscFree(*a);CHKERRQ(ierr);
1030e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1031e5c89e4eSSatish Balay }
1032e5c89e4eSSatish Balay 
10338e81d068SLisandro Dalcin /*@C
10348e81d068SLisandro Dalcin    PetscStrInList - search string in character-delimited list
10358e81d068SLisandro Dalcin 
10368e81d068SLisandro Dalcin    Not Collective
10378e81d068SLisandro Dalcin 
10388e81d068SLisandro Dalcin    Input Parameters:
10398e81d068SLisandro Dalcin +  str - the string to look for
10408e81d068SLisandro Dalcin .  list - the list to search in
10418e81d068SLisandro Dalcin -  sep - the separator character
10428e81d068SLisandro Dalcin 
10438e81d068SLisandro Dalcin    Output Parameter:
10448e81d068SLisandro Dalcin .  found - whether str is in list
10458e81d068SLisandro Dalcin 
10468e81d068SLisandro Dalcin    Level: intermediate
10478e81d068SLisandro Dalcin 
104895452b02SPatrick Sanan    Notes:
104995452b02SPatrick Sanan     Not for use in Fortran
10508e81d068SLisandro Dalcin 
10518e81d068SLisandro Dalcin .seealso: PetscTokenCreate(), PetscTokenFind(), PetscStrcmp()
10528e81d068SLisandro Dalcin @*/
10538e81d068SLisandro Dalcin PetscErrorCode PetscStrInList(const char str[],const char list[],char sep,PetscBool *found)
10548e81d068SLisandro Dalcin {
10558e81d068SLisandro Dalcin   PetscToken     token;
10568e81d068SLisandro Dalcin   char           *item;
10578e81d068SLisandro Dalcin   PetscErrorCode ierr;
10588e81d068SLisandro Dalcin 
10598e81d068SLisandro Dalcin   PetscFunctionBegin;
10608e81d068SLisandro Dalcin   *found = PETSC_FALSE;
10618e81d068SLisandro Dalcin   ierr = PetscTokenCreate(list,sep,&token);CHKERRQ(ierr);
10628e81d068SLisandro Dalcin   ierr = PetscTokenFind(token,&item);CHKERRQ(ierr);
10638e81d068SLisandro Dalcin   while (item) {
10648e81d068SLisandro Dalcin     ierr = PetscStrcmp(str,item,found);CHKERRQ(ierr);
10658e81d068SLisandro Dalcin     if (*found) break;
10668e81d068SLisandro Dalcin     ierr = PetscTokenFind(token,&item);CHKERRQ(ierr);
10678e81d068SLisandro Dalcin   }
10688e81d068SLisandro Dalcin   ierr = PetscTokenDestroy(&token);CHKERRQ(ierr);
10698e81d068SLisandro Dalcin   PetscFunctionReturn(0);
10708e81d068SLisandro Dalcin }
1071e5c89e4eSSatish Balay 
1072e5c89e4eSSatish Balay /*@C
1073e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
1074e5c89e4eSSatish Balay 
1075e5c89e4eSSatish Balay    Not Collective
1076e5c89e4eSSatish Balay 
1077e5c89e4eSSatish Balay    Output Parameter:
1078e5c89e4eSSatish Balay .  dir - the directory
1079e5c89e4eSSatish Balay 
1080e5c89e4eSSatish Balay    Level: developer
1081e5c89e4eSSatish Balay 
108295452b02SPatrick Sanan    Notes:
108395452b02SPatrick Sanan     Not for use in Fortran
10846f013253SBarry Smith 
1085e5c89e4eSSatish Balay @*/
10867087cfbeSBarry Smith PetscErrorCode  PetscGetPetscDir(const char *dir[])
1087e5c89e4eSSatish Balay {
1088e5c89e4eSSatish Balay   PetscFunctionBegin;
1089e5c89e4eSSatish Balay   *dir = PETSC_DIR;
1090e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1091e5c89e4eSSatish Balay }
1092e5c89e4eSSatish Balay 
1093e5c89e4eSSatish Balay /*@C
1094e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
1095e5c89e4eSSatish Balay 
1096e5c89e4eSSatish Balay    Not Collective
1097e5c89e4eSSatish Balay 
1098e5c89e4eSSatish Balay    Input Parameters:
1099e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
110071573d7dSBarry Smith .   aa - the string to look in
1101d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
1102e5c89e4eSSatish Balay -   len - the length of b
1103e5c89e4eSSatish Balay 
1104e5c89e4eSSatish Balay    Notes:
1105e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
1106d5649816SBarry Smith       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
1107e5c89e4eSSatish Balay       as well as any environmental variables.
1108e5c89e4eSSatish Balay 
11096f013253SBarry Smith       PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
1110acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
1111acc6cc86SBarry Smith 
11126f013253SBarry Smith       Not for use in Fortran
11136f013253SBarry Smith 
1114e5c89e4eSSatish Balay    Level: intermediate
1115e5c89e4eSSatish Balay 
1116e5c89e4eSSatish Balay @*/
11177087cfbeSBarry Smith PetscErrorCode  PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
1118e5c89e4eSSatish Balay {
1119e5c89e4eSSatish Balay   PetscErrorCode ierr;
1120e5c89e4eSSatish Balay   int            i = 0;
1121e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
112271573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
1123d5649816SBarry Smith   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0};
1124f489ac74SBarry Smith   char           *r[] = {0,0,0,0,0,0,0,0,0};
1125ace3abfcSBarry Smith   PetscBool      flag;
1126e5c89e4eSSatish Balay 
1127e5c89e4eSSatish Balay   PetscFunctionBegin;
1128e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
112971573d7dSBarry Smith   if (aa == b) {
113022982a5fSBarry Smith     ierr = PetscStrallocpy(aa,(char**)&a);CHKERRQ(ierr);
113171573d7dSBarry Smith   }
1132785e854fSJed Brown   ierr = PetscMalloc1(len,&work);CHKERRQ(ierr);
1133e5c89e4eSSatish Balay 
1134e5c89e4eSSatish Balay   /* get values for replaced variables */
1135f1d4cc8fSBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,&r[0]);CHKERRQ(ierr);
1136f1d4cc8fSBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,&r[1]);CHKERRQ(ierr);
1137f1d4cc8fSBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,&r[2]);CHKERRQ(ierr);
1138785e854fSJed Brown   ierr = PetscMalloc1(256,&r[3]);CHKERRQ(ierr);
1139785e854fSJed Brown   ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[4]);CHKERRQ(ierr);
1140785e854fSJed Brown   ierr = PetscMalloc1(PETSC_MAX_PATH_LEN,&r[5]);CHKERRQ(ierr);
1141785e854fSJed Brown   ierr = PetscMalloc1(256,&r[6]);CHKERRQ(ierr);
1142785e854fSJed Brown   ierr = PetscMalloc1(256,&r[7]);CHKERRQ(ierr);
1143f1d4cc8fSBarry Smith   ierr = PetscGetDisplay(r[3],256);CHKERRQ(ierr);
1144f1d4cc8fSBarry Smith   ierr = PetscGetHomeDirectory(r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1145f1d4cc8fSBarry Smith   ierr = PetscGetWorkingDirectory(r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1146f1d4cc8fSBarry Smith   ierr = PetscGetUserName(r[6],256);CHKERRQ(ierr);
1147f1d4cc8fSBarry Smith   ierr = PetscGetHostName(r[7],256);CHKERRQ(ierr);
1148487e5849SBarry Smith 
1149487e5849SBarry Smith   /* replace that are in environment */
1150487e5849SBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr);
1151487e5849SBarry Smith   if (flag) {
115231936d58SMatthew G. Knepley     ierr = PetscFree(r[2]);CHKERRQ(ierr);
1153f1d4cc8fSBarry Smith     ierr = PetscStrallocpy(env,&r[2]);CHKERRQ(ierr);
1154487e5849SBarry Smith   }
1155e5c89e4eSSatish Balay 
1156e5c89e4eSSatish Balay   /* replace the requested strings */
1157e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
1158e5c89e4eSSatish Balay   while (s[i]) {
1159e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
1160e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1161e5c89e4eSSatish Balay     while (par) {
1162e5c89e4eSSatish Balay       *par =  0;
1163e5c89e4eSSatish Balay       par += l;
1164e5c89e4eSSatish Balay 
1165e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
1166e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
1167e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
116817186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
1169e5c89e4eSSatish Balay       ierr = PetscStrcpy(work,b);CHKERRQ(ierr);
1170e5c89e4eSSatish Balay       ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr);
1171e5c89e4eSSatish Balay       ierr = PetscStrcat(work,par);CHKERRQ(ierr);
1172e5c89e4eSSatish Balay       ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr);
1173e5c89e4eSSatish Balay       ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1174e5c89e4eSSatish Balay     }
1175e5c89e4eSSatish Balay     i++;
1176e5c89e4eSSatish Balay   }
1177487e5849SBarry Smith   i = 0;
1178487e5849SBarry Smith   while (r[i]) {
1179e5c89e4eSSatish Balay     tfree = (char*)r[i];
1180e5c89e4eSSatish Balay     ierr  = PetscFree(tfree);CHKERRQ(ierr);
1181487e5849SBarry Smith     i++;
1182e5c89e4eSSatish Balay   }
1183e5c89e4eSSatish Balay 
1184e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
1185e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1186e5c89e4eSSatish Balay   while (par) {
1187e5c89e4eSSatish Balay     *par  = 0;
1188e5c89e4eSSatish Balay     par  += 2;
1189e5c89e4eSSatish Balay     ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
1190e5c89e4eSSatish Balay     ierr  = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
1191e5c89e4eSSatish Balay     *epar = 0;
1192e5c89e4eSSatish Balay     epar += 1;
1193e5c89e4eSSatish Balay     ierr  = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr);
11947ba3a57cSBarry Smith     if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
1195e5c89e4eSSatish Balay     ierr = PetscStrcat(work,env);CHKERRQ(ierr);
1196e5c89e4eSSatish Balay     ierr = PetscStrcat(work,epar);CHKERRQ(ierr);
1197e5c89e4eSSatish Balay     ierr = PetscStrcpy(b,work);CHKERRQ(ierr);
1198e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1199e5c89e4eSSatish Balay   }
1200e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
120171573d7dSBarry Smith   if (aa == b) {
120271573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
120371573d7dSBarry Smith   }
1204e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1205e5c89e4eSSatish Balay }
1206e5c89e4eSSatish Balay 
1207a53986e1SJed Brown /*@C
1208a53986e1SJed Brown    PetscEListFind - searches list of strings for given string, using case insensitive matching
1209e5c89e4eSSatish Balay 
1210a53986e1SJed Brown    Not Collective
1211a53986e1SJed Brown 
1212a53986e1SJed Brown    Input Parameters:
1213a53986e1SJed Brown +  n - number of strings in
1214a53986e1SJed Brown .  list - list of strings to search
1215a53986e1SJed Brown -  str - string to look for, empty string "" accepts default (first entry in list)
1216a53986e1SJed Brown 
1217a53986e1SJed Brown    Output Parameters:
1218a53986e1SJed Brown +  value - index of matching string (if found)
1219a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1220a53986e1SJed Brown 
1221a53986e1SJed Brown    Notes:
1222a53986e1SJed Brown    Not for use in Fortran
1223a53986e1SJed Brown 
1224a53986e1SJed Brown    Level: advanced
1225a53986e1SJed Brown @*/
1226a53986e1SJed Brown PetscErrorCode PetscEListFind(PetscInt n,const char *const *list,const char *str,PetscInt *value,PetscBool *found)
1227a53986e1SJed Brown {
1228a53986e1SJed Brown   PetscErrorCode ierr;
1229a53986e1SJed Brown   PetscBool matched;
1230a53986e1SJed Brown   PetscInt i;
1231a53986e1SJed Brown 
1232a53986e1SJed Brown   PetscFunctionBegin;
1233a53986e1SJed Brown   if (found) *found = PETSC_FALSE;
1234a53986e1SJed Brown   for (i=0; i<n; i++) {
1235a53986e1SJed Brown     ierr = PetscStrcasecmp(str,list[i],&matched);CHKERRQ(ierr);
1236a53986e1SJed Brown     if (matched || !str[0]) {
1237a53986e1SJed Brown       if (found) *found = PETSC_TRUE;
1238a53986e1SJed Brown       *value = i;
1239a53986e1SJed Brown       break;
1240a53986e1SJed Brown     }
1241a53986e1SJed Brown   }
1242a53986e1SJed Brown   PetscFunctionReturn(0);
1243a53986e1SJed Brown }
1244a53986e1SJed Brown 
1245a53986e1SJed Brown /*@C
12468e81d068SLisandro Dalcin    PetscEnumFind - searches enum list of strings for given string, using case insensitive matching
1247a53986e1SJed Brown 
1248a53986e1SJed Brown    Not Collective
1249a53986e1SJed Brown 
1250a53986e1SJed Brown    Input Parameters:
1251a53986e1SJed Brown +  enumlist - list of strings to search, followed by enum name, then enum prefix, then NUL
1252a53986e1SJed Brown -  str - string to look for
1253a53986e1SJed Brown 
1254a53986e1SJed Brown    Output Parameters:
1255a53986e1SJed Brown +  value - index of matching string (if found)
1256a53986e1SJed Brown -  found - boolean indicating whether string was found (can be NULL)
1257a53986e1SJed Brown 
1258a53986e1SJed Brown    Notes:
1259a53986e1SJed Brown    Not for use in Fortran
1260a53986e1SJed Brown 
1261a53986e1SJed Brown    Level: advanced
1262a53986e1SJed Brown @*/
1263a53986e1SJed Brown PetscErrorCode PetscEnumFind(const char *const *enumlist,const char *str,PetscEnum *value,PetscBool *found)
1264a53986e1SJed Brown {
1265a53986e1SJed Brown   PetscErrorCode ierr;
1266d05ba7d2SLisandro Dalcin   PetscInt n = 0,evalue;
1267a53986e1SJed Brown   PetscBool efound;
1268a53986e1SJed Brown 
1269a53986e1SJed Brown   PetscFunctionBegin;
1270d05ba7d2SLisandro 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");
1271a53986e1SJed Brown   if (n < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix");
1272a53986e1SJed Brown   n -= 3; /* drop enum name, prefix, and null termination */
1273a53986e1SJed Brown   ierr = PetscEListFind(n,enumlist,str,&evalue,&efound);CHKERRQ(ierr);
1274cfb463b1SJed Brown   if (efound) *value = (PetscEnum)evalue;
1275a53986e1SJed Brown   if (found) *found = efound;
1276a53986e1SJed Brown   PetscFunctionReturn(0);
1277a53986e1SJed Brown }
1278