xref: /petsc/src/sys/utils/str.c (revision 675282fd4d801d41a0bc5d7c0eb3ff420dd13aed)
1e5c89e4eSSatish Balay #define PETSC_DLL
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 */
8d382aafbSBarry Smith #include "petscsys.h"                   /*I  "petscsys.h"   I*/
9e5c89e4eSSatish Balay #if defined(PETSC_HAVE_STRING_H)
10e5c89e4eSSatish Balay #include <string.h>
11e5c89e4eSSatish Balay #endif
12e5c89e4eSSatish Balay #if defined(PETSC_HAVE_STRINGS_H)
13e5c89e4eSSatish Balay #include <strings.h>
14e5c89e4eSSatish Balay #endif
15e5c89e4eSSatish Balay 
16e5c89e4eSSatish Balay #undef __FUNCT__
173c311c98SBarry Smith #define __FUNCT__ "PetscStrToArray"
183c311c98SBarry Smith /*@C
193c311c98SBarry Smith    PetscStrToArray - Seperates a string by its spaces and creates and array of strings
203c311c98SBarry Smith 
213c311c98SBarry Smith    Not Collective
223c311c98SBarry Smith 
233c311c98SBarry Smith    Input Parameters:
243c311c98SBarry Smith .  s - pointer to string
253c311c98SBarry Smith 
263c311c98SBarry Smith    Output Parameter:
273c311c98SBarry Smith +   argc - the number of entries in the array
283c311c98SBarry Smith -   args - an array of the entries with a null at the end
293c311c98SBarry Smith 
303c311c98SBarry Smith    Level: intermediate
313c311c98SBarry Smith 
323c311c98SBarry Smith    Notes: this may be called before PetscInitialize()
333c311c98SBarry Smith 
343c311c98SBarry Smith    Developer Notes: Using raw malloc()
353c311c98SBarry Smith 
363c311c98SBarry Smith @*/
373c311c98SBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscStrToArray(const char s[],int *argc,char ***args)
383c311c98SBarry Smith {
393c311c98SBarry Smith   int        i,n,*lens,cnt = 0;
403c311c98SBarry Smith   PetscTruth flg = PETSC_FALSE;
413c311c98SBarry Smith 
423c311c98SBarry Smith   n = strlen(s);
433c311c98SBarry Smith   *argc = 0;
443c311c98SBarry Smith   for (i=0; i<n; i++) {
453c311c98SBarry Smith     if (s[i] != ' ') break;
463c311c98SBarry Smith   }
473c311c98SBarry Smith   for (;i<n+1; i++) {
483c311c98SBarry Smith     if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
493c311c98SBarry Smith     else if (s[i] != ' ') {flg = PETSC_FALSE;}
503c311c98SBarry Smith   }
513c311c98SBarry Smith   (*args) = (char **) malloc((*argc)*sizeof(char**)); if (!*args) return PETSC_ERR_MEM;
52*675282fdSHong Zhang   lens    = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM;
533c311c98SBarry Smith   for (i=0; i<*argc; i++) lens[i] = 0;
543c311c98SBarry Smith 
553c311c98SBarry Smith   *argc = 0;
563c311c98SBarry Smith   for (i=0; i<n; i++) {
573c311c98SBarry Smith     if (s[i] != ' ') break;
583c311c98SBarry Smith   }
593c311c98SBarry Smith   for (;i<n+1; i++) {
603c311c98SBarry Smith     if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
613c311c98SBarry Smith     else if (s[i] != ' ') {lens[*argc]++;flg = PETSC_FALSE;}
623c311c98SBarry Smith   }
633c311c98SBarry Smith 
643c311c98SBarry Smith   for (i=0; i<*argc; i++) {
65*675282fdSHong Zhang     (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char)); if (!(*args)[i]) return PETSC_ERR_MEM;
663c311c98SBarry Smith   }
673c311c98SBarry Smith 
683c311c98SBarry Smith   *argc = 0;
693c311c98SBarry Smith   for (i=0; i<n; i++) {
703c311c98SBarry Smith     if (s[i] != ' ') break;
713c311c98SBarry Smith   }
723c311c98SBarry Smith   for (;i<n+1; i++) {
733c311c98SBarry Smith     if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
743c311c98SBarry Smith     else if (s[i] != ' ') {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;}
753c311c98SBarry Smith   }
763c311c98SBarry Smith   return 0;
773c311c98SBarry Smith }
783c311c98SBarry Smith 
793c311c98SBarry Smith #undef __FUNCT__
80e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrlen"
81e5c89e4eSSatish Balay /*@C
82e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
83e5c89e4eSSatish Balay 
84e5c89e4eSSatish Balay    Not Collective
85e5c89e4eSSatish Balay 
86e5c89e4eSSatish Balay    Input Parameters:
87e5c89e4eSSatish Balay .  s - pointer to string
88e5c89e4eSSatish Balay 
89e5c89e4eSSatish Balay    Output Parameter:
90e5c89e4eSSatish Balay .  len - length in bytes
91e5c89e4eSSatish Balay 
92e5c89e4eSSatish Balay    Level: intermediate
93e5c89e4eSSatish Balay 
94e5c89e4eSSatish Balay    Note:
95e5c89e4eSSatish Balay    This routine is analogous to strlen().
96e5c89e4eSSatish Balay 
97e5c89e4eSSatish Balay    Null string returns a length of zero
98e5c89e4eSSatish Balay 
99e5c89e4eSSatish Balay   Concepts: string length
100e5c89e4eSSatish Balay 
101e5c89e4eSSatish Balay @*/
102e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrlen(const char s[],size_t *len)
103e5c89e4eSSatish Balay {
104e5c89e4eSSatish Balay   PetscFunctionBegin;
105e5c89e4eSSatish Balay   if (!s) {
106e5c89e4eSSatish Balay     *len = 0;
107e5c89e4eSSatish Balay   } else {
108e5c89e4eSSatish Balay     *len = strlen(s);
109e5c89e4eSSatish Balay   }
110e5c89e4eSSatish Balay   PetscFunctionReturn(0);
111e5c89e4eSSatish Balay }
112e5c89e4eSSatish Balay 
113e5c89e4eSSatish Balay #undef __FUNCT__
114e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrallocpy"
115e5c89e4eSSatish Balay /*@C
116e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
117e5c89e4eSSatish Balay 
118e5c89e4eSSatish Balay    Not Collective
119e5c89e4eSSatish Balay 
120e5c89e4eSSatish Balay    Input Parameters:
121e5c89e4eSSatish Balay .  s - pointer to string
122e5c89e4eSSatish Balay 
123e5c89e4eSSatish Balay    Output Parameter:
124e5c89e4eSSatish Balay .  t - the copied string
125e5c89e4eSSatish Balay 
126e5c89e4eSSatish Balay    Level: intermediate
127e5c89e4eSSatish Balay 
128e5c89e4eSSatish Balay    Note:
129e5c89e4eSSatish Balay       Null string returns a new null string
130e5c89e4eSSatish Balay 
131e5c89e4eSSatish Balay   Concepts: string copy
132e5c89e4eSSatish Balay 
133e5c89e4eSSatish Balay @*/
134e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrallocpy(const char s[],char *t[])
135e5c89e4eSSatish Balay {
136e5c89e4eSSatish Balay   PetscErrorCode ierr;
137e5c89e4eSSatish Balay   size_t         len;
13871573d7dSBarry Smith   char           *tmp = 0;
139e5c89e4eSSatish Balay 
140e5c89e4eSSatish Balay   PetscFunctionBegin;
141e5c89e4eSSatish Balay   if (s) {
142e5c89e4eSSatish Balay     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
14371573d7dSBarry Smith     ierr = PetscMalloc((1+len)*sizeof(char),&tmp);CHKERRQ(ierr);
14471573d7dSBarry Smith     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
145e5c89e4eSSatish Balay   }
14671573d7dSBarry Smith   *t = tmp;
147e5c89e4eSSatish Balay   PetscFunctionReturn(0);
148e5c89e4eSSatish Balay }
149e5c89e4eSSatish Balay 
150e5c89e4eSSatish Balay #undef __FUNCT__
151e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcpy"
152e5c89e4eSSatish Balay /*@C
153e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
154e5c89e4eSSatish Balay 
155e5c89e4eSSatish Balay    Not Collective
156e5c89e4eSSatish Balay 
157e5c89e4eSSatish Balay    Input Parameters:
158e5c89e4eSSatish Balay .  t - pointer to string
159e5c89e4eSSatish Balay 
160e5c89e4eSSatish Balay    Output Parameter:
161e5c89e4eSSatish Balay .  s - the copied string
162e5c89e4eSSatish Balay 
163e5c89e4eSSatish Balay    Level: intermediate
164e5c89e4eSSatish Balay 
165e5c89e4eSSatish Balay    Note:
166e5c89e4eSSatish Balay      Null string returns a string starting with zero
167e5c89e4eSSatish Balay 
168e5c89e4eSSatish Balay   Concepts: string copy
169e5c89e4eSSatish Balay 
170e5c89e4eSSatish Balay .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat()
171e5c89e4eSSatish Balay 
172e5c89e4eSSatish Balay @*/
173acc6cc86SBarry Smith 
174e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrcpy(char s[],const char t[])
175e5c89e4eSSatish Balay {
176e5c89e4eSSatish Balay   PetscFunctionBegin;
17717186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
178e5c89e4eSSatish Balay   if (t) {strcpy(s,t);}
179e5c89e4eSSatish Balay   else if (s) {s[0] = 0;}
180e5c89e4eSSatish Balay   PetscFunctionReturn(0);
181e5c89e4eSSatish Balay }
182e5c89e4eSSatish Balay 
183e5c89e4eSSatish Balay #undef __FUNCT__
184e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncpy"
185e5c89e4eSSatish Balay /*@C
186e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
187e5c89e4eSSatish Balay 
188e5c89e4eSSatish Balay    Not Collective
189e5c89e4eSSatish Balay 
190e5c89e4eSSatish Balay    Input Parameters:
191e5c89e4eSSatish Balay +  t - pointer to string
192e5c89e4eSSatish Balay -  n - the length to copy
193e5c89e4eSSatish Balay 
194e5c89e4eSSatish Balay    Output Parameter:
195e5c89e4eSSatish Balay .  s - the copied string
196e5c89e4eSSatish Balay 
197e5c89e4eSSatish Balay    Level: intermediate
198e5c89e4eSSatish Balay 
199e5c89e4eSSatish Balay    Note:
200e5c89e4eSSatish Balay      Null string returns a string starting with zero
201e5c89e4eSSatish Balay 
202e5c89e4eSSatish Balay   Concepts: string copy
203e5c89e4eSSatish Balay 
204e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat()
205e5c89e4eSSatish Balay 
206e5c89e4eSSatish Balay @*/
207e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrncpy(char s[],const char t[],size_t n)
208e5c89e4eSSatish Balay {
209e5c89e4eSSatish Balay   PetscFunctionBegin;
21017186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
211e5c89e4eSSatish Balay   if (t) {strncpy(s,t,n);}
212e5c89e4eSSatish Balay   else if (s) {s[0] = 0;}
213e5c89e4eSSatish Balay   PetscFunctionReturn(0);
214e5c89e4eSSatish Balay }
215e5c89e4eSSatish Balay 
216e5c89e4eSSatish Balay #undef __FUNCT__
217e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcat"
218e5c89e4eSSatish Balay /*@C
219e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
220e5c89e4eSSatish Balay 
221e5c89e4eSSatish Balay    Not Collective
222e5c89e4eSSatish Balay 
223e5c89e4eSSatish Balay    Input Parameters:
224e5e2177aSMatthew Knepley +  s - string to be added to
225e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
226e5c89e4eSSatish Balay 
227e5c89e4eSSatish Balay    Level: intermediate
228e5c89e4eSSatish Balay 
229e5c89e4eSSatish Balay   Concepts: string copy
230e5c89e4eSSatish Balay 
231e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat()
232e5c89e4eSSatish Balay 
233e5c89e4eSSatish Balay @*/
234e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrcat(char s[],const char t[])
235e5c89e4eSSatish Balay {
236e5c89e4eSSatish Balay   PetscFunctionBegin;
2379b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
238e5c89e4eSSatish Balay   strcat(s,t);
239e5c89e4eSSatish Balay   PetscFunctionReturn(0);
240e5c89e4eSSatish Balay }
241e5c89e4eSSatish Balay 
242e5c89e4eSSatish Balay #undef __FUNCT__
243e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncat"
244e5c89e4eSSatish Balay /*@C
245e5c89e4eSSatish Balay    PetscStrncat - Concatenates a string onto a given string, up to a given length
246e5c89e4eSSatish Balay 
247e5c89e4eSSatish Balay    Not Collective
248e5c89e4eSSatish Balay 
249e5c89e4eSSatish Balay    Input Parameters:
250e5c89e4eSSatish Balay +  s - pointer to string to be added to end
251e5c89e4eSSatish Balay .  t - string to be added to
252e5c89e4eSSatish Balay .  n - maximum length to copy
253e5c89e4eSSatish Balay 
254e5c89e4eSSatish Balay    Level: intermediate
255e5c89e4eSSatish Balay 
256e5c89e4eSSatish Balay   Concepts: string copy
257e5c89e4eSSatish Balay 
258e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
259e5c89e4eSSatish Balay 
260e5c89e4eSSatish Balay @*/
261e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrncat(char s[],const char t[],size_t n)
262e5c89e4eSSatish Balay {
263e5c89e4eSSatish Balay   PetscFunctionBegin;
264e5c89e4eSSatish Balay   strncat(s,t,n);
265e5c89e4eSSatish Balay   PetscFunctionReturn(0);
266e5c89e4eSSatish Balay }
267e5c89e4eSSatish Balay 
268e5c89e4eSSatish Balay #undef __FUNCT__
269e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcmp"
270e5c89e4eSSatish Balay /*@C
271e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
272e5c89e4eSSatish Balay 
273e5c89e4eSSatish Balay    Not Collective
274e5c89e4eSSatish Balay 
275e5c89e4eSSatish Balay    Input Parameters:
276e5c89e4eSSatish Balay +  a - pointer to string first string
277e5c89e4eSSatish Balay -  b - pointer to second string
278e5c89e4eSSatish Balay 
279e5c89e4eSSatish Balay    Output Parameter:
280e5c89e4eSSatish Balay .  flg - if the two strings are equal
281e5c89e4eSSatish Balay 
282e5c89e4eSSatish Balay    Level: intermediate
283e5c89e4eSSatish Balay 
284e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
285e5c89e4eSSatish Balay 
286e5c89e4eSSatish Balay @*/
287e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrcmp(const char a[],const char b[],PetscTruth *flg)
288e5c89e4eSSatish Balay {
289e5c89e4eSSatish Balay   int c;
290e5c89e4eSSatish Balay 
291e5c89e4eSSatish Balay   PetscFunctionBegin;
292e5c89e4eSSatish Balay   if (!a && !b) {
293e5c89e4eSSatish Balay     *flg = PETSC_TRUE;
294e5c89e4eSSatish Balay   } else if (!a || !b) {
295e5c89e4eSSatish Balay     *flg = PETSC_FALSE;
296e5c89e4eSSatish Balay   } else {
297e5c89e4eSSatish Balay     c = strcmp(a,b);
298e5c89e4eSSatish Balay     if (c) *flg = PETSC_FALSE;
299e5c89e4eSSatish Balay     else   *flg = PETSC_TRUE;
300e5c89e4eSSatish Balay   }
301e5c89e4eSSatish Balay   PetscFunctionReturn(0);
302e5c89e4eSSatish Balay }
303e5c89e4eSSatish Balay 
304e5c89e4eSSatish Balay #undef __FUNCT__
305e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrgrt"
306e5c89e4eSSatish Balay /*@C
307e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
308e5c89e4eSSatish Balay 
309e5c89e4eSSatish Balay    Not Collective
310e5c89e4eSSatish Balay 
311e5c89e4eSSatish Balay    Input Parameters:
312e5c89e4eSSatish Balay +  a - pointer to first string
313e5c89e4eSSatish Balay -  b - pointer to second string
314e5c89e4eSSatish Balay 
315e5c89e4eSSatish Balay    Output Parameter:
316e5c89e4eSSatish Balay .  flg - if the first string is greater
317e5c89e4eSSatish Balay 
318e5c89e4eSSatish Balay    Notes:
319e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
320e5c89e4eSSatish Balay     all others
321e5c89e4eSSatish Balay 
322e5c89e4eSSatish Balay    Level: intermediate
323e5c89e4eSSatish Balay 
324e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
325e5c89e4eSSatish Balay 
326e5c89e4eSSatish Balay @*/
327e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrgrt(const char a[],const char b[],PetscTruth *t)
328e5c89e4eSSatish Balay {
329e5c89e4eSSatish Balay   int c;
330e5c89e4eSSatish Balay 
331e5c89e4eSSatish Balay   PetscFunctionBegin;
332e5c89e4eSSatish Balay   if (!a && !b) {
333e5c89e4eSSatish Balay     *t = PETSC_FALSE;
334e5c89e4eSSatish Balay   } else if (a && !b) {
335e5c89e4eSSatish Balay     *t = PETSC_TRUE;
336e5c89e4eSSatish Balay   } else if (!a && b) {
337e5c89e4eSSatish Balay     *t = PETSC_FALSE;
338e5c89e4eSSatish Balay   } else {
339e5c89e4eSSatish Balay     c = strcmp(a,b);
340e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
341e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
342e5c89e4eSSatish Balay   }
343e5c89e4eSSatish Balay   PetscFunctionReturn(0);
344e5c89e4eSSatish Balay }
345e5c89e4eSSatish Balay 
346e5c89e4eSSatish Balay #undef __FUNCT__
347e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcasecmp"
348e5c89e4eSSatish Balay /*@C
349e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
350e5c89e4eSSatish Balay      except possibly for case.
351e5c89e4eSSatish Balay 
352e5c89e4eSSatish Balay    Not Collective
353e5c89e4eSSatish Balay 
354e5c89e4eSSatish Balay    Input Parameters:
355e5c89e4eSSatish Balay +  a - pointer to first string
356e5c89e4eSSatish Balay -  b - pointer to second string
357e5c89e4eSSatish Balay 
358e5c89e4eSSatish Balay    Output Parameter:
359e5c89e4eSSatish Balay .  flg - if the two strings are the same
360e5c89e4eSSatish Balay 
361e5c89e4eSSatish Balay    Notes:
362e5c89e4eSSatish Balay     Null arguments are ok
363e5c89e4eSSatish Balay 
364e5c89e4eSSatish Balay    Level: intermediate
365e5c89e4eSSatish Balay 
366e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
367e5c89e4eSSatish Balay 
368e5c89e4eSSatish Balay @*/
369fbb3e65fSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrcasecmp(const char a[],const char b[],PetscTruth *t)
370e5c89e4eSSatish Balay {
371e5c89e4eSSatish Balay   int c;
372e5c89e4eSSatish Balay 
373e5c89e4eSSatish Balay   PetscFunctionBegin;
374e5c89e4eSSatish Balay   if (!a && !b) c = 0;
375e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
37632b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
37732b366c8SSatish Balay   else c = strcasecmp(a,b);
37832b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
379e5c89e4eSSatish Balay   else c = stricmp(a,b);
380e5c89e4eSSatish Balay #else
38132b366c8SSatish Balay   else {
38232b366c8SSatish Balay     char *aa,*bb;
38332b366c8SSatish Balay     PetscErrorCode ierr;
38432b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
38532b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
38632b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
38732b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
38832b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
389503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
390503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
39132b366c8SSatish Balay     PetscFunctionReturn(0);
39232b366c8SSatish Balay   }
393e5c89e4eSSatish Balay #endif
394e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
395e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
396e5c89e4eSSatish Balay   PetscFunctionReturn(0);
397e5c89e4eSSatish Balay }
398e5c89e4eSSatish Balay 
39932b366c8SSatish Balay 
40032b366c8SSatish Balay 
401e5c89e4eSSatish Balay #undef __FUNCT__
402e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncmp"
403e5c89e4eSSatish Balay /*@C
404e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
405e5c89e4eSSatish Balay 
406e5c89e4eSSatish Balay    Not Collective
407e5c89e4eSSatish Balay 
408e5c89e4eSSatish Balay    Input Parameters:
409e5c89e4eSSatish Balay +  a - pointer to first string
410e5c89e4eSSatish Balay .  b - pointer to second string
411e5c89e4eSSatish Balay -  n - length to compare up to
412e5c89e4eSSatish Balay 
413e5c89e4eSSatish Balay    Output Parameter:
414e5c89e4eSSatish Balay .  t - if the two strings are equal
415e5c89e4eSSatish Balay 
416e5c89e4eSSatish Balay    Level: intermediate
417e5c89e4eSSatish Balay 
418e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
419e5c89e4eSSatish Balay 
420e5c89e4eSSatish Balay @*/
421e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrncmp(const char a[],const char b[],size_t n,PetscTruth *t)
422e5c89e4eSSatish Balay {
423e5c89e4eSSatish Balay   int c;
424e5c89e4eSSatish Balay 
425e5c89e4eSSatish Balay   PetscFunctionBegin;
426e5c89e4eSSatish Balay   c = strncmp(a,b,n);
427e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
428e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
429e5c89e4eSSatish Balay   PetscFunctionReturn(0);
430e5c89e4eSSatish Balay }
431e5c89e4eSSatish Balay 
432e5c89e4eSSatish Balay #undef __FUNCT__
433e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrchr"
434e5c89e4eSSatish Balay /*@C
435e5c89e4eSSatish Balay    PetscStrchr - Locates first occurance of a character in a string
436e5c89e4eSSatish Balay 
437e5c89e4eSSatish Balay    Not Collective
438e5c89e4eSSatish Balay 
439e5c89e4eSSatish Balay    Input Parameters:
440e5c89e4eSSatish Balay +  a - pointer to string
441e5c89e4eSSatish Balay -  b - character
442e5c89e4eSSatish Balay 
443e5c89e4eSSatish Balay    Output Parameter:
444e5c89e4eSSatish Balay .  c - location of occurance, PETSC_NULL if not found
445e5c89e4eSSatish Balay 
446e5c89e4eSSatish Balay    Level: intermediate
447e5c89e4eSSatish Balay 
448e5c89e4eSSatish Balay @*/
449e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrchr(const char a[],char b,char *c[])
450e5c89e4eSSatish Balay {
451e5c89e4eSSatish Balay   PetscFunctionBegin;
452e5c89e4eSSatish Balay   *c = (char *)strchr(a,b);
453e5c89e4eSSatish Balay   PetscFunctionReturn(0);
454e5c89e4eSSatish Balay }
455e5c89e4eSSatish Balay 
456e5c89e4eSSatish Balay #undef __FUNCT__
457e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrrchr"
458e5c89e4eSSatish Balay /*@C
459e5c89e4eSSatish Balay    PetscStrrchr - Locates one location past the last occurance of a character in a string,
460e5c89e4eSSatish Balay       if the character is not found then returns entire string
461e5c89e4eSSatish Balay 
462e5c89e4eSSatish Balay    Not Collective
463e5c89e4eSSatish Balay 
464e5c89e4eSSatish Balay    Input Parameters:
465e5c89e4eSSatish Balay +  a - pointer to string
466e5c89e4eSSatish Balay -  b - character
467e5c89e4eSSatish Balay 
468e5c89e4eSSatish Balay    Output Parameter:
469e5c89e4eSSatish Balay .  tmp - location of occurance, a if not found
470e5c89e4eSSatish Balay 
471e5c89e4eSSatish Balay    Level: intermediate
472e5c89e4eSSatish Balay 
473e5c89e4eSSatish Balay @*/
474e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrrchr(const char a[],char b,char *tmp[])
475e5c89e4eSSatish Balay {
476e5c89e4eSSatish Balay   PetscFunctionBegin;
477e5c89e4eSSatish Balay   *tmp = (char *)strrchr(a,b);
478e5c89e4eSSatish Balay   if (!*tmp) *tmp = (char*)a; else *tmp = *tmp + 1;
479e5c89e4eSSatish Balay   PetscFunctionReturn(0);
480e5c89e4eSSatish Balay }
481e5c89e4eSSatish Balay 
482e5c89e4eSSatish Balay #undef __FUNCT__
483e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrtolower"
484e5c89e4eSSatish Balay /*@C
485e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
486e5c89e4eSSatish Balay 
487e5c89e4eSSatish Balay    Not Collective
488e5c89e4eSSatish Balay 
489e5c89e4eSSatish Balay    Input Parameters:
490e5c89e4eSSatish Balay .  a - pointer to string
491e5c89e4eSSatish Balay 
492e5c89e4eSSatish Balay    Level: intermediate
493e5c89e4eSSatish Balay 
494e5c89e4eSSatish Balay @*/
495e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrtolower(char a[])
496e5c89e4eSSatish Balay {
497e5c89e4eSSatish Balay   PetscFunctionBegin;
498e5c89e4eSSatish Balay   while (*a) {
499e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
500e5c89e4eSSatish Balay     a++;
501e5c89e4eSSatish Balay   }
502e5c89e4eSSatish Balay   PetscFunctionReturn(0);
503e5c89e4eSSatish Balay }
504e5c89e4eSSatish Balay 
5051d1a0024SBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
5061d1a0024SBarry Smith 
5071d1a0024SBarry Smith 
508e5c89e4eSSatish Balay #undef __FUNCT__
509e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenFind"
510e5c89e4eSSatish Balay /*@C
511e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
512e5c89e4eSSatish Balay 
513e5c89e4eSSatish Balay    Not Collective
514e5c89e4eSSatish Balay 
515e5c89e4eSSatish Balay    Input Parameters:
516e5c89e4eSSatish Balay .  a - pointer to token
517e5c89e4eSSatish Balay 
518e5c89e4eSSatish Balay    Output Parameter:
519e5c89e4eSSatish Balay .  result - location of occurance, PETSC_NULL if not found
520e5c89e4eSSatish Balay 
521e5c89e4eSSatish Balay    Notes:
522e5c89e4eSSatish Balay 
523e5c89e4eSSatish Balay      This version is different from the system version in that
524e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
525e5c89e4eSSatish Balay 
5264704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
5274704e885SBarry Smith    as a single token.
5284704e885SBarry Smith 
529e5c89e4eSSatish Balay    Level: intermediate
530e5c89e4eSSatish Balay 
531e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
532e5c89e4eSSatish Balay @*/
5331d1a0024SBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscTokenFind(PetscToken a,char *result[])
534e5c89e4eSSatish Balay {
5354704e885SBarry Smith   char *ptr = a->current,token;
536e5c89e4eSSatish Balay 
537e5c89e4eSSatish Balay   PetscFunctionBegin;
538e5c89e4eSSatish Balay   *result = a->current;
5394704e885SBarry Smith   if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);}
5404704e885SBarry Smith   token = a->token;
54190fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
542e5c89e4eSSatish Balay   while (ptr) {
5434704e885SBarry Smith     if (*ptr == token) {
544e5c89e4eSSatish Balay       *ptr++ = 0;
545e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
546e5c89e4eSSatish Balay       a->current = ptr;
547e5c89e4eSSatish Balay       break;
548e5c89e4eSSatish Balay     }
549e5c89e4eSSatish Balay     if (!*ptr) {
550e5c89e4eSSatish Balay       a->current = 0;
551e5c89e4eSSatish Balay       break;
552e5c89e4eSSatish Balay     }
553e5c89e4eSSatish Balay     ptr++;
554e5c89e4eSSatish Balay   }
555e5c89e4eSSatish Balay   PetscFunctionReturn(0);
556e5c89e4eSSatish Balay }
557e5c89e4eSSatish Balay 
558e5c89e4eSSatish Balay #undef __FUNCT__
559e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenCreate"
560e5c89e4eSSatish Balay /*@C
561e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
562e5c89e4eSSatish Balay 
563e5c89e4eSSatish Balay    Not Collective
564e5c89e4eSSatish Balay 
565e5c89e4eSSatish Balay    Input Parameters:
566e5c89e4eSSatish Balay +  string - the string to look in
567e5c89e4eSSatish Balay -  token - the character to look for
568e5c89e4eSSatish Balay 
569e5c89e4eSSatish Balay    Output Parameter:
570e5c89e4eSSatish Balay .  a - pointer to token
571e5c89e4eSSatish Balay 
572e5c89e4eSSatish Balay    Notes:
573e5c89e4eSSatish Balay 
574e5c89e4eSSatish Balay      This version is different from the system version in that
575e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
576e5c89e4eSSatish Balay 
577e5c89e4eSSatish Balay    Level: intermediate
578e5c89e4eSSatish Balay 
579e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
580e5c89e4eSSatish Balay @*/
5811d1a0024SBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscTokenCreate(const char a[],const char b,PetscToken *t)
582e5c89e4eSSatish Balay {
583e5c89e4eSSatish Balay   PetscErrorCode ierr;
584e5c89e4eSSatish Balay 
585e5c89e4eSSatish Balay   PetscFunctionBegin;
5861d1a0024SBarry Smith   ierr = PetscNew(struct _p_PetscToken,t);CHKERRQ(ierr);
587e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
588e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
589e5c89e4eSSatish Balay   (*t)->token   = b;
590e5c89e4eSSatish Balay   PetscFunctionReturn(0);
591e5c89e4eSSatish Balay }
592e5c89e4eSSatish Balay 
593e5c89e4eSSatish Balay #undef __FUNCT__
594e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenDestroy"
595e5c89e4eSSatish Balay /*@C
596e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
597e5c89e4eSSatish Balay 
598e5c89e4eSSatish Balay    Not Collective
599e5c89e4eSSatish Balay 
600e5c89e4eSSatish Balay    Input Parameters:
601e5c89e4eSSatish Balay .  a - pointer to token
602e5c89e4eSSatish Balay 
603e5c89e4eSSatish Balay    Level: intermediate
604e5c89e4eSSatish Balay 
605e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
606e5c89e4eSSatish Balay @*/
6071d1a0024SBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscTokenDestroy(PetscToken a)
608e5c89e4eSSatish Balay {
609e5c89e4eSSatish Balay   PetscErrorCode ierr;
610e5c89e4eSSatish Balay 
611e5c89e4eSSatish Balay   PetscFunctionBegin;
612e5c89e4eSSatish Balay   ierr = PetscFree(a->array);CHKERRQ(ierr);
613e5c89e4eSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
614e5c89e4eSSatish Balay   PetscFunctionReturn(0);
615e5c89e4eSSatish Balay }
616e5c89e4eSSatish Balay 
617e5c89e4eSSatish Balay #undef __FUNCT__
618e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrrstr"
619e5c89e4eSSatish Balay /*@C
620e5c89e4eSSatish Balay    PetscStrrstr - Locates last occurance of string in another string
621e5c89e4eSSatish Balay 
622e5c89e4eSSatish Balay    Not Collective
623e5c89e4eSSatish Balay 
624e5c89e4eSSatish Balay    Input Parameters:
625e5c89e4eSSatish Balay +  a - pointer to string
626e5c89e4eSSatish Balay -  b - string to find
627e5c89e4eSSatish Balay 
628e5c89e4eSSatish Balay    Output Parameter:
629e5c89e4eSSatish Balay .  tmp - location of occurance
630e5c89e4eSSatish Balay 
631e5c89e4eSSatish Balay    Level: intermediate
632e5c89e4eSSatish Balay 
633e5c89e4eSSatish Balay @*/
634e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrrstr(const char a[],const char b[],char *tmp[])
635e5c89e4eSSatish Balay {
636e5c89e4eSSatish Balay   const char *stmp = a, *ltmp = 0;
637e5c89e4eSSatish Balay 
638e5c89e4eSSatish Balay   PetscFunctionBegin;
639e5c89e4eSSatish Balay   while (stmp) {
640e5c89e4eSSatish Balay     stmp = (char *)strstr(stmp,b);
641e5c89e4eSSatish Balay     if (stmp) {ltmp = stmp;stmp++;}
642e5c89e4eSSatish Balay   }
643e5c89e4eSSatish Balay   *tmp = (char *)ltmp;
644e5c89e4eSSatish Balay   PetscFunctionReturn(0);
645e5c89e4eSSatish Balay }
646e5c89e4eSSatish Balay 
647e5c89e4eSSatish Balay #undef __FUNCT__
648e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrstr"
649e5c89e4eSSatish Balay /*@C
650e5c89e4eSSatish Balay    PetscStrstr - Locates first occurance of string in another string
651e5c89e4eSSatish Balay 
652e5c89e4eSSatish Balay    Not Collective
653e5c89e4eSSatish Balay 
654e5c89e4eSSatish Balay    Input Parameters:
655e5c89e4eSSatish Balay +  a - pointer to string
656e5c89e4eSSatish Balay -  b - string to find
657e5c89e4eSSatish Balay 
658e5c89e4eSSatish Balay    Output Parameter:
659e5c89e4eSSatish Balay .  tmp - location of occurance
660e5c89e4eSSatish Balay 
661e5c89e4eSSatish Balay    Level: intermediate
662e5c89e4eSSatish Balay 
663e5c89e4eSSatish Balay @*/
664e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrstr(const char a[],const char b[],char *tmp[])
665e5c89e4eSSatish Balay {
666e5c89e4eSSatish Balay   PetscFunctionBegin;
667e5c89e4eSSatish Balay   *tmp = (char *)strstr(a,b);
668e5c89e4eSSatish Balay   PetscFunctionReturn(0);
669e5c89e4eSSatish Balay }
670e5c89e4eSSatish Balay 
671e5c89e4eSSatish Balay #undef __FUNCT__
672e5c89e4eSSatish Balay #define __FUNCT__ "PetscGetPetscDir"
673e5c89e4eSSatish Balay /*@C
674e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
675e5c89e4eSSatish Balay 
676e5c89e4eSSatish Balay    Not Collective
677e5c89e4eSSatish Balay 
678e5c89e4eSSatish Balay    Output Parameter:
679e5c89e4eSSatish Balay .  dir - the directory
680e5c89e4eSSatish Balay 
681e5c89e4eSSatish Balay    Level: developer
682e5c89e4eSSatish Balay 
683e5c89e4eSSatish Balay @*/
684e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscGetPetscDir(const char *dir[])
685e5c89e4eSSatish Balay {
686e5c89e4eSSatish Balay   PetscFunctionBegin;
687e5c89e4eSSatish Balay   *dir = PETSC_DIR;
688e5c89e4eSSatish Balay   PetscFunctionReturn(0);
689e5c89e4eSSatish Balay }
690e5c89e4eSSatish Balay 
691e5c89e4eSSatish Balay #undef __FUNCT__
692e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrreplace"
693e5c89e4eSSatish Balay /*@C
694e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
695e5c89e4eSSatish Balay 
696e5c89e4eSSatish Balay    Not Collective
697e5c89e4eSSatish Balay 
698e5c89e4eSSatish Balay    Input Parameters:
699e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
70071573d7dSBarry Smith .   aa - the string to look in
701d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
702e5c89e4eSSatish Balay -   len - the length of b
703e5c89e4eSSatish Balay 
704e5c89e4eSSatish Balay    Notes:
705e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
706e5c89e4eSSatish Balay       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME} with appropriate values
707e5c89e4eSSatish Balay       as well as any environmental variables.
708e5c89e4eSSatish Balay 
709acc6cc86SBarry Smith       Note: PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
710acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
711acc6cc86SBarry Smith 
712e5c89e4eSSatish Balay    Level: intermediate
713e5c89e4eSSatish Balay 
714e5c89e4eSSatish Balay @*/
71571573d7dSBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
716e5c89e4eSSatish Balay {
717e5c89e4eSSatish Balay   PetscErrorCode ierr;
718e5c89e4eSSatish Balay   int            i = 0;
719e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
72071573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
721e5c89e4eSSatish Balay   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}",0};
722487e5849SBarry Smith   const char     *r[] = {0,0,0,0,0,0,0,0};
723e5c89e4eSSatish Balay   PetscTruth     flag;
724e5c89e4eSSatish Balay 
725e5c89e4eSSatish Balay   PetscFunctionBegin;
726e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
72771573d7dSBarry Smith   if (aa == b) {
72822982a5fSBarry Smith     ierr    = PetscStrallocpy(aa,(char **)&a);CHKERRQ(ierr);
72971573d7dSBarry Smith   }
730e5c89e4eSSatish Balay   ierr = PetscMalloc(len*sizeof(char*),&work);CHKERRQ(ierr);
731e5c89e4eSSatish Balay 
732e5c89e4eSSatish Balay   /* get values for replaced variables */
733487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr);
734487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr);
735487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr);
736487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[3]);CHKERRQ(ierr);
737487e5849SBarry Smith   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[4]);CHKERRQ(ierr);
738e5c89e4eSSatish Balay   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[5]);CHKERRQ(ierr);
739487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[6]);CHKERRQ(ierr);
740487e5849SBarry Smith   ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr);
741487e5849SBarry Smith   ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
742487e5849SBarry Smith   ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
743487e5849SBarry Smith   ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr);
744487e5849SBarry Smith 
745487e5849SBarry Smith   /* replace that are in environment */
746487e5849SBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr);
747487e5849SBarry Smith   if (flag) {
748487e5849SBarry Smith     ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr);
749487e5849SBarry Smith   }
750e5c89e4eSSatish Balay 
751e5c89e4eSSatish Balay   /* replace the requested strings */
752e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
753e5c89e4eSSatish Balay   while (s[i]) {
754e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
755e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
756e5c89e4eSSatish Balay     while (par) {
757e5c89e4eSSatish Balay       *par  =  0;
758e5c89e4eSSatish Balay       par  += l;
759e5c89e4eSSatish Balay 
760e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
761e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
762e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
76317186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
764e5c89e4eSSatish Balay       ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
765e5c89e4eSSatish Balay       ierr  = PetscStrcat(work,r[i]);CHKERRQ(ierr);
766e5c89e4eSSatish Balay       ierr  = PetscStrcat(work,par);CHKERRQ(ierr);
767e5c89e4eSSatish Balay       ierr  = PetscStrncpy(b,work,len);CHKERRQ(ierr);
768e5c89e4eSSatish Balay       ierr  = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
769e5c89e4eSSatish Balay     }
770e5c89e4eSSatish Balay     i++;
771e5c89e4eSSatish Balay   }
772487e5849SBarry Smith   i = 0;
773487e5849SBarry Smith   while (r[i]) {
774e5c89e4eSSatish Balay     tfree = (char*)r[i];
775e5c89e4eSSatish Balay     ierr = PetscFree(tfree);CHKERRQ(ierr);
776487e5849SBarry Smith     i++;
777e5c89e4eSSatish Balay   }
778e5c89e4eSSatish Balay 
779e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
780e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
781e5c89e4eSSatish Balay   while (par) {
782e5c89e4eSSatish Balay     *par = 0;
783e5c89e4eSSatish Balay     par += 2;
784e5c89e4eSSatish Balay     ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
785e5c89e4eSSatish Balay     ierr = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
786e5c89e4eSSatish Balay     *epar = 0;
787e5c89e4eSSatish Balay     epar += 1;
788e5c89e4eSSatish Balay     ierr = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr);
789e5c89e4eSSatish Balay     if (!flag) {
790e32f2f54SBarry Smith       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
791e5c89e4eSSatish Balay     }
792e5c89e4eSSatish Balay     ierr = PetscStrcat(work,env);CHKERRQ(ierr);
793e5c89e4eSSatish Balay     ierr = PetscStrcat(work,epar);CHKERRQ(ierr);
794e5c89e4eSSatish Balay     ierr = PetscStrcpy(b,work);CHKERRQ(ierr);
795e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
796e5c89e4eSSatish Balay   }
797e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
79871573d7dSBarry Smith   if (aa == b) {
79971573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
80071573d7dSBarry Smith   }
801e5c89e4eSSatish Balay   PetscFunctionReturn(0);
802e5c89e4eSSatish Balay }
803e5c89e4eSSatish Balay 
804e5c89e4eSSatish Balay 
805