xref: /petsc/src/sys/utils/str.c (revision d67fe73b814e98b751355dda2eadc2214e19abb5)
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*/
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
19*d67fe73bSBarry Smith    PetscStrToArray - Seperates a string by a charactor (for example ' ' or '\n') and creates an array of strings
203c311c98SBarry Smith 
213c311c98SBarry Smith    Not Collective
223c311c98SBarry Smith 
233c311c98SBarry Smith    Input Parameters:
24*d67fe73bSBarry Smith +  s - pointer to string
25*d67fe73bSBarry Smith -  sp - seperator charactor
263c311c98SBarry Smith 
273c311c98SBarry Smith    Output Parameter:
283c311c98SBarry Smith +   argc - the number of entries in the array
293c311c98SBarry Smith -   args - an array of the entries with a null at the end
303c311c98SBarry Smith 
313c311c98SBarry Smith    Level: intermediate
323c311c98SBarry Smith 
33301d30feSBarry Smith    Notes: this may be called before PetscInitialize() or after PetscFinalize()
343c311c98SBarry Smith 
356f013253SBarry Smith    Not for use in Fortran
366f013253SBarry Smith 
37b4cd4cebSBarry Smith    Developer Notes: Using raw malloc() and does not call error handlers since this may be used before PETSc is initialized. Used
38b4cd4cebSBarry Smith      to generate argc, args arguments passed to MPI_Init()
39301d30feSBarry Smith 
40b4cd4cebSBarry Smith .seealso: PetscStrToArrayDestroy(), PetscToken, PetscTokenCreate()
413c311c98SBarry Smith 
423c311c98SBarry Smith @*/
43*d67fe73bSBarry Smith PetscErrorCode  PetscStrToArray(const char s[],char sp,int *argc,char ***args)
443c311c98SBarry Smith {
453c311c98SBarry Smith   int        i,n,*lens,cnt = 0;
46ace3abfcSBarry Smith   PetscBool  flg = PETSC_FALSE;
473c311c98SBarry Smith 
4840a7e1efSBarry Smith   if (!s) n = 0;
4940a7e1efSBarry Smith   else    n = strlen(s);
503c311c98SBarry Smith   *argc = 0;
513c311c98SBarry Smith   for (i=0; i<n; i++) {
52*d67fe73bSBarry Smith     if (s[i] != sp) break;
533c311c98SBarry Smith   }
543c311c98SBarry Smith   for (;i<n+1; i++) {
55*d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
56*d67fe73bSBarry Smith     else if (s[i] != sp) {flg = PETSC_FALSE;}
573c311c98SBarry Smith   }
58301d30feSBarry Smith   (*args) = (char **) malloc(((*argc)+1)*sizeof(char**)); if (!*args) return PETSC_ERR_MEM;
5953e6e2c4SHong Zhang   lens    = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM;
603c311c98SBarry Smith   for (i=0; i<*argc; i++) lens[i] = 0;
613c311c98SBarry Smith 
623c311c98SBarry Smith   *argc = 0;
633c311c98SBarry Smith   for (i=0; i<n; i++) {
64*d67fe73bSBarry Smith     if (s[i] != sp) break;
653c311c98SBarry Smith   }
663c311c98SBarry Smith   for (;i<n+1; i++) {
67*d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
68*d67fe73bSBarry Smith     else if (s[i] != sp) {lens[*argc]++;flg = PETSC_FALSE;}
693c311c98SBarry Smith   }
703c311c98SBarry Smith 
713c311c98SBarry Smith   for (i=0; i<*argc; i++) {
72675282fdSHong Zhang     (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char)); if (!(*args)[i]) return PETSC_ERR_MEM;
733c311c98SBarry Smith   }
74301d30feSBarry Smith   (*args)[*argc] = 0;
753c311c98SBarry Smith 
763c311c98SBarry Smith   *argc = 0;
773c311c98SBarry Smith   for (i=0; i<n; i++) {
78*d67fe73bSBarry Smith     if (s[i] != sp) break;
793c311c98SBarry Smith   }
803c311c98SBarry Smith   for (;i<n+1; i++) {
81*d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
82*d67fe73bSBarry Smith     else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;}
833c311c98SBarry Smith   }
843c311c98SBarry Smith   return 0;
853c311c98SBarry Smith }
863c311c98SBarry Smith 
873c311c98SBarry Smith #undef __FUNCT__
88301d30feSBarry Smith #define __FUNCT__ "PetscStrToArrayDestroy"
89301d30feSBarry Smith /*@C
90301d30feSBarry Smith    PetscStrToArrayDestroy - Frees array created with PetscStrToArray().
91301d30feSBarry Smith 
92301d30feSBarry Smith    Not Collective
93301d30feSBarry Smith 
94301d30feSBarry Smith    Output Parameters:
95301d30feSBarry Smith +  argc - the number of arguments
96301d30feSBarry Smith -  args - the array of arguments
97301d30feSBarry Smith 
98301d30feSBarry Smith    Level: intermediate
99301d30feSBarry Smith 
100301d30feSBarry Smith    Concepts: command line arguments
101301d30feSBarry Smith 
102301d30feSBarry Smith    Notes: This may be called before PetscInitialize() or after PetscFinalize()
103301d30feSBarry Smith 
1046f013253SBarry Smith    Not for use in Fortran
1056f013253SBarry Smith 
106301d30feSBarry Smith .seealso: PetscStrToArray()
107301d30feSBarry Smith 
108301d30feSBarry Smith @*/
1097087cfbeSBarry Smith PetscErrorCode  PetscStrToArrayDestroy(int argc,char **args)
110301d30feSBarry Smith {
111301d30feSBarry Smith   PetscInt i;
112301d30feSBarry Smith 
113301d30feSBarry Smith   for (i=0; i<argc; i++) {
114301d30feSBarry Smith     free(args[i]);
115301d30feSBarry Smith   }
116301d30feSBarry Smith   free(args);
117301d30feSBarry Smith   return 0;
118301d30feSBarry Smith }
119301d30feSBarry Smith 
120301d30feSBarry Smith #undef __FUNCT__
121e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrlen"
122e5c89e4eSSatish Balay /*@C
123e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
124e5c89e4eSSatish Balay 
125e5c89e4eSSatish Balay    Not Collective
126e5c89e4eSSatish Balay 
127e5c89e4eSSatish Balay    Input Parameters:
128e5c89e4eSSatish Balay .  s - pointer to string
129e5c89e4eSSatish Balay 
130e5c89e4eSSatish Balay    Output Parameter:
131e5c89e4eSSatish Balay .  len - length in bytes
132e5c89e4eSSatish Balay 
133e5c89e4eSSatish Balay    Level: intermediate
134e5c89e4eSSatish Balay 
135e5c89e4eSSatish Balay    Note:
136e5c89e4eSSatish Balay    This routine is analogous to strlen().
137e5c89e4eSSatish Balay 
138e5c89e4eSSatish Balay    Null string returns a length of zero
139e5c89e4eSSatish Balay 
1406f013253SBarry Smith    Not for use in Fortran
1416f013253SBarry Smith 
142e5c89e4eSSatish Balay   Concepts: string length
143e5c89e4eSSatish Balay 
144e5c89e4eSSatish Balay @*/
1457087cfbeSBarry Smith PetscErrorCode  PetscStrlen(const char s[],size_t *len)
146e5c89e4eSSatish Balay {
147e5c89e4eSSatish Balay   PetscFunctionBegin;
148e5c89e4eSSatish Balay   if (!s) {
149e5c89e4eSSatish Balay     *len = 0;
150e5c89e4eSSatish Balay   } else {
151e5c89e4eSSatish Balay     *len = strlen(s);
152e5c89e4eSSatish Balay   }
153e5c89e4eSSatish Balay   PetscFunctionReturn(0);
154e5c89e4eSSatish Balay }
155e5c89e4eSSatish Balay 
156e5c89e4eSSatish Balay #undef __FUNCT__
157e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrallocpy"
158e5c89e4eSSatish Balay /*@C
159e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
160e5c89e4eSSatish Balay 
161e5c89e4eSSatish Balay    Not Collective
162e5c89e4eSSatish Balay 
163e5c89e4eSSatish Balay    Input Parameters:
164e5c89e4eSSatish Balay .  s - pointer to string
165e5c89e4eSSatish Balay 
166e5c89e4eSSatish Balay    Output Parameter:
167e5c89e4eSSatish Balay .  t - the copied string
168e5c89e4eSSatish Balay 
169e5c89e4eSSatish Balay    Level: intermediate
170e5c89e4eSSatish Balay 
171e5c89e4eSSatish Balay    Note:
172e5c89e4eSSatish Balay       Null string returns a new null string
173e5c89e4eSSatish Balay 
1746f013253SBarry Smith       Not for use in Fortran
1756f013253SBarry Smith 
176e5c89e4eSSatish Balay   Concepts: string copy
177e5c89e4eSSatish Balay 
178e5c89e4eSSatish Balay @*/
1797087cfbeSBarry Smith PetscErrorCode  PetscStrallocpy(const char s[],char *t[])
180e5c89e4eSSatish Balay {
181e5c89e4eSSatish Balay   PetscErrorCode ierr;
182e5c89e4eSSatish Balay   size_t         len;
18371573d7dSBarry Smith   char           *tmp = 0;
184e5c89e4eSSatish Balay 
185e5c89e4eSSatish Balay   PetscFunctionBegin;
186e5c89e4eSSatish Balay   if (s) {
187e5c89e4eSSatish Balay     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
18871573d7dSBarry Smith     ierr = PetscMalloc((1+len)*sizeof(char),&tmp);CHKERRQ(ierr);
18971573d7dSBarry Smith     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
190e5c89e4eSSatish Balay   }
19171573d7dSBarry Smith   *t = tmp;
192e5c89e4eSSatish Balay   PetscFunctionReturn(0);
193e5c89e4eSSatish Balay }
194e5c89e4eSSatish Balay 
195e5c89e4eSSatish Balay #undef __FUNCT__
19647340559SBarry Smith #define __FUNCT__ "PetscStrArrayallocpy"
19747340559SBarry Smith /*@C
19847340559SBarry Smith    PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
19947340559SBarry Smith 
20047340559SBarry Smith    Not Collective
20147340559SBarry Smith 
20247340559SBarry Smith    Input Parameters:
20347340559SBarry Smith .  s - pointer to array of strings (final string is a null)
20447340559SBarry Smith 
20547340559SBarry Smith    Output Parameter:
20647340559SBarry Smith .  t - the copied array string
20747340559SBarry Smith 
20847340559SBarry Smith    Level: intermediate
20947340559SBarry Smith 
21047340559SBarry Smith    Note:
21147340559SBarry Smith       Not for use in Fortran
21247340559SBarry Smith 
21347340559SBarry Smith   Concepts: string copy
21447340559SBarry Smith 
21547340559SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
21647340559SBarry Smith 
21747340559SBarry Smith @*/
21847340559SBarry Smith PetscErrorCode  PetscStrArrayallocpy(const char *const*list,char ***t)
21947340559SBarry Smith {
22047340559SBarry Smith   PetscErrorCode ierr;
22147340559SBarry Smith   PetscInt       i,n = 0;
22247340559SBarry Smith 
22347340559SBarry Smith   PetscFunctionBegin;
22447340559SBarry Smith   while (list[n++]) ;
22547340559SBarry Smith   ierr = PetscMalloc((n+1)*sizeof(char**),t);CHKERRQ(ierr);
22647340559SBarry Smith   for (i=0; i<n; i++) {
22747340559SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
22847340559SBarry Smith   }
22947340559SBarry Smith   (*t)[n] = PETSC_NULL;
23047340559SBarry Smith   PetscFunctionReturn(0);
23147340559SBarry Smith }
23247340559SBarry Smith 
23347340559SBarry Smith #undef __FUNCT__
23447340559SBarry Smith #define __FUNCT__ "PetscStrArrayDestroy"
23547340559SBarry Smith /*@C
23647340559SBarry Smith    PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
23747340559SBarry Smith 
23847340559SBarry Smith    Not Collective
23947340559SBarry Smith 
24047340559SBarry Smith    Output Parameters:
24147340559SBarry Smith .   list - array of strings
24247340559SBarry Smith 
24347340559SBarry Smith    Level: intermediate
24447340559SBarry Smith 
24547340559SBarry Smith    Concepts: command line arguments
24647340559SBarry Smith 
24747340559SBarry Smith    Notes: Not for use in Fortran
24847340559SBarry Smith 
24947340559SBarry Smith .seealso: PetscStrArrayallocpy()
25047340559SBarry Smith 
25147340559SBarry Smith @*/
2526fed8037SJed Brown PetscErrorCode PetscStrArrayDestroy(char ***list)
25347340559SBarry Smith {
25447340559SBarry Smith   PetscInt       n = 0;
25547340559SBarry Smith   PetscErrorCode ierr;
25647340559SBarry Smith 
2576fed8037SJed Brown   PetscFunctionBegin;
2586fed8037SJed Brown   if (!*list) PetscFunctionReturn(0);
2596fed8037SJed Brown   while ((*list)[n]) {
2606fed8037SJed Brown     ierr = PetscFree((*list)[n]);CHKERRQ(ierr);
26147340559SBarry Smith     n++;
26247340559SBarry Smith   }
2636fed8037SJed Brown   ierr = PetscFree(*list);CHKERRQ(ierr);
2646fed8037SJed Brown   PetscFunctionReturn(0);
26547340559SBarry Smith }
26647340559SBarry Smith 
26747340559SBarry Smith #undef __FUNCT__
268e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcpy"
269e5c89e4eSSatish Balay /*@C
270e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
271e5c89e4eSSatish Balay 
272e5c89e4eSSatish Balay    Not Collective
273e5c89e4eSSatish Balay 
274e5c89e4eSSatish Balay    Input Parameters:
275e5c89e4eSSatish Balay .  t - pointer to string
276e5c89e4eSSatish Balay 
277e5c89e4eSSatish Balay    Output Parameter:
278e5c89e4eSSatish Balay .  s - the copied string
279e5c89e4eSSatish Balay 
280e5c89e4eSSatish Balay    Level: intermediate
281e5c89e4eSSatish Balay 
2826f013253SBarry Smith    Notes:
283e5c89e4eSSatish Balay      Null string returns a string starting with zero
284e5c89e4eSSatish Balay 
2856f013253SBarry Smith      Not for use in Fortran
2866f013253SBarry Smith 
287e5c89e4eSSatish Balay   Concepts: string copy
288e5c89e4eSSatish Balay 
289e5c89e4eSSatish Balay .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat()
290e5c89e4eSSatish Balay 
291e5c89e4eSSatish Balay @*/
292acc6cc86SBarry Smith 
2937087cfbeSBarry Smith PetscErrorCode  PetscStrcpy(char s[],const char t[])
294e5c89e4eSSatish Balay {
295e5c89e4eSSatish Balay   PetscFunctionBegin;
29617186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
297e5c89e4eSSatish Balay   if (t) {strcpy(s,t);}
298e5c89e4eSSatish Balay   else if (s) {s[0] = 0;}
299e5c89e4eSSatish Balay   PetscFunctionReturn(0);
300e5c89e4eSSatish Balay }
301e5c89e4eSSatish Balay 
302e5c89e4eSSatish Balay #undef __FUNCT__
303e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncpy"
304e5c89e4eSSatish Balay /*@C
305e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
306e5c89e4eSSatish Balay 
307e5c89e4eSSatish Balay    Not Collective
308e5c89e4eSSatish Balay 
309e5c89e4eSSatish Balay    Input Parameters:
310e5c89e4eSSatish Balay +  t - pointer to string
311e5c89e4eSSatish Balay -  n - the length to copy
312e5c89e4eSSatish Balay 
313e5c89e4eSSatish Balay    Output Parameter:
314e5c89e4eSSatish Balay .  s - the copied string
315e5c89e4eSSatish Balay 
316e5c89e4eSSatish Balay    Level: intermediate
317e5c89e4eSSatish Balay 
318e5c89e4eSSatish Balay    Note:
319e5c89e4eSSatish Balay      Null string returns a string starting with zero
320e5c89e4eSSatish Balay 
321e5c89e4eSSatish Balay   Concepts: string copy
322e5c89e4eSSatish Balay 
323e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat()
324e5c89e4eSSatish Balay 
325e5c89e4eSSatish Balay @*/
3267087cfbeSBarry Smith PetscErrorCode  PetscStrncpy(char s[],const char t[],size_t n)
327e5c89e4eSSatish Balay {
328e5c89e4eSSatish Balay   PetscFunctionBegin;
32917186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
330e5c89e4eSSatish Balay   if (t) {strncpy(s,t,n);}
331e5c89e4eSSatish Balay   else if (s) {s[0] = 0;}
332e5c89e4eSSatish Balay   PetscFunctionReturn(0);
333e5c89e4eSSatish Balay }
334e5c89e4eSSatish Balay 
335e5c89e4eSSatish Balay #undef __FUNCT__
336e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcat"
337e5c89e4eSSatish Balay /*@C
338e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
339e5c89e4eSSatish Balay 
340e5c89e4eSSatish Balay    Not Collective
341e5c89e4eSSatish Balay 
342e5c89e4eSSatish Balay    Input Parameters:
343e5e2177aSMatthew Knepley +  s - string to be added to
344e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
345e5c89e4eSSatish Balay 
346e5c89e4eSSatish Balay    Level: intermediate
347e5c89e4eSSatish Balay 
3486f013253SBarry Smith    Notes: Not for use in Fortran
3496f013253SBarry Smith 
350e5c89e4eSSatish Balay   Concepts: string copy
351e5c89e4eSSatish Balay 
352e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat()
353e5c89e4eSSatish Balay 
354e5c89e4eSSatish Balay @*/
3557087cfbeSBarry Smith PetscErrorCode  PetscStrcat(char s[],const char t[])
356e5c89e4eSSatish Balay {
357e5c89e4eSSatish Balay   PetscFunctionBegin;
3589b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
359e5c89e4eSSatish Balay   strcat(s,t);
360e5c89e4eSSatish Balay   PetscFunctionReturn(0);
361e5c89e4eSSatish Balay }
362e5c89e4eSSatish Balay 
363e5c89e4eSSatish Balay #undef __FUNCT__
364e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncat"
365e5c89e4eSSatish Balay /*@C
366e5c89e4eSSatish Balay    PetscStrncat - Concatenates a string onto a given string, up to a given length
367e5c89e4eSSatish Balay 
368e5c89e4eSSatish Balay    Not Collective
369e5c89e4eSSatish Balay 
370e5c89e4eSSatish Balay    Input Parameters:
371e5c89e4eSSatish Balay +  s - pointer to string to be added to end
372e5c89e4eSSatish Balay .  t - string to be added to
373e5c89e4eSSatish Balay .  n - maximum length to copy
374e5c89e4eSSatish Balay 
375e5c89e4eSSatish Balay    Level: intermediate
376e5c89e4eSSatish Balay 
3776f013253SBarry Smith   Notes:    Not for use in Fortran
3786f013253SBarry Smith 
379e5c89e4eSSatish Balay   Concepts: string copy
380e5c89e4eSSatish Balay 
381e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
382e5c89e4eSSatish Balay 
383e5c89e4eSSatish Balay @*/
3847087cfbeSBarry Smith PetscErrorCode  PetscStrncat(char s[],const char t[],size_t n)
385e5c89e4eSSatish Balay {
386e5c89e4eSSatish Balay   PetscFunctionBegin;
387e5c89e4eSSatish Balay   strncat(s,t,n);
388e5c89e4eSSatish Balay   PetscFunctionReturn(0);
389e5c89e4eSSatish Balay }
390e5c89e4eSSatish Balay 
391e5c89e4eSSatish Balay #undef __FUNCT__
392e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcmp"
393e5c89e4eSSatish Balay /*@C
394e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
395e5c89e4eSSatish Balay 
396e5c89e4eSSatish Balay    Not Collective
397e5c89e4eSSatish Balay 
398e5c89e4eSSatish Balay    Input Parameters:
399e5c89e4eSSatish Balay +  a - pointer to string first string
400e5c89e4eSSatish Balay -  b - pointer to second string
401e5c89e4eSSatish Balay 
402e5c89e4eSSatish Balay    Output Parameter:
4038c74ee41SBarry Smith .  flg - PETSC_TRUE if the two strings are equal
404e5c89e4eSSatish Balay 
405e5c89e4eSSatish Balay    Level: intermediate
406e5c89e4eSSatish Balay 
4076f013253SBarry Smith    Notes:    Not for use in Fortran
4086f013253SBarry Smith 
409e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
410e5c89e4eSSatish Balay 
411e5c89e4eSSatish Balay @*/
4127087cfbeSBarry Smith PetscErrorCode  PetscStrcmp(const char a[],const char b[],PetscBool  *flg)
413e5c89e4eSSatish Balay {
414e5c89e4eSSatish Balay   int c;
415e5c89e4eSSatish Balay 
416e5c89e4eSSatish Balay   PetscFunctionBegin;
417e5c89e4eSSatish Balay   if (!a && !b) {
418e5c89e4eSSatish Balay     *flg = PETSC_TRUE;
419e5c89e4eSSatish Balay   } else if (!a || !b) {
420e5c89e4eSSatish Balay     *flg = PETSC_FALSE;
421e5c89e4eSSatish Balay   } else {
422e5c89e4eSSatish Balay     c = strcmp(a,b);
423e5c89e4eSSatish Balay     if (c) *flg = PETSC_FALSE;
424e5c89e4eSSatish Balay     else   *flg = PETSC_TRUE;
425e5c89e4eSSatish Balay   }
426e5c89e4eSSatish Balay   PetscFunctionReturn(0);
427e5c89e4eSSatish Balay }
428e5c89e4eSSatish Balay 
429e5c89e4eSSatish Balay #undef __FUNCT__
430e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrgrt"
431e5c89e4eSSatish Balay /*@C
432e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
433e5c89e4eSSatish Balay 
434e5c89e4eSSatish Balay    Not Collective
435e5c89e4eSSatish Balay 
436e5c89e4eSSatish Balay    Input Parameters:
437e5c89e4eSSatish Balay +  a - pointer to first string
438e5c89e4eSSatish Balay -  b - pointer to second string
439e5c89e4eSSatish Balay 
440e5c89e4eSSatish Balay    Output Parameter:
441e5c89e4eSSatish Balay .  flg - if the first string is greater
442e5c89e4eSSatish Balay 
443e5c89e4eSSatish Balay    Notes:
444e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
445e5c89e4eSSatish Balay     all others
446e5c89e4eSSatish Balay 
4476f013253SBarry Smith    Not for use in Fortran
4486f013253SBarry Smith 
449e5c89e4eSSatish Balay    Level: intermediate
450e5c89e4eSSatish Balay 
451e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
452e5c89e4eSSatish Balay 
453e5c89e4eSSatish Balay @*/
4547087cfbeSBarry Smith PetscErrorCode  PetscStrgrt(const char a[],const char b[],PetscBool  *t)
455e5c89e4eSSatish Balay {
456e5c89e4eSSatish Balay   int c;
457e5c89e4eSSatish Balay 
458e5c89e4eSSatish Balay   PetscFunctionBegin;
459e5c89e4eSSatish Balay   if (!a && !b) {
460e5c89e4eSSatish Balay     *t = PETSC_FALSE;
461e5c89e4eSSatish Balay   } else if (a && !b) {
462e5c89e4eSSatish Balay     *t = PETSC_TRUE;
463e5c89e4eSSatish Balay   } else if (!a && b) {
464e5c89e4eSSatish Balay     *t = PETSC_FALSE;
465e5c89e4eSSatish Balay   } else {
466e5c89e4eSSatish Balay     c = strcmp(a,b);
467e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
468e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
469e5c89e4eSSatish Balay   }
470e5c89e4eSSatish Balay   PetscFunctionReturn(0);
471e5c89e4eSSatish Balay }
472e5c89e4eSSatish Balay 
473e5c89e4eSSatish Balay #undef __FUNCT__
474e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcasecmp"
475e5c89e4eSSatish Balay /*@C
476e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
477e5c89e4eSSatish Balay      except possibly for case.
478e5c89e4eSSatish Balay 
479e5c89e4eSSatish Balay    Not Collective
480e5c89e4eSSatish Balay 
481e5c89e4eSSatish Balay    Input Parameters:
482e5c89e4eSSatish Balay +  a - pointer to first string
483e5c89e4eSSatish Balay -  b - pointer to second string
484e5c89e4eSSatish Balay 
485e5c89e4eSSatish Balay    Output Parameter:
486e5c89e4eSSatish Balay .  flg - if the two strings are the same
487e5c89e4eSSatish Balay 
488e5c89e4eSSatish Balay    Notes:
489e5c89e4eSSatish Balay     Null arguments are ok
490e5c89e4eSSatish Balay 
4916f013253SBarry Smith    Not for use in Fortran
4926f013253SBarry Smith 
493e5c89e4eSSatish Balay    Level: intermediate
494e5c89e4eSSatish Balay 
495e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
496e5c89e4eSSatish Balay 
497e5c89e4eSSatish Balay @*/
4987087cfbeSBarry Smith PetscErrorCode  PetscStrcasecmp(const char a[],const char b[],PetscBool  *t)
499e5c89e4eSSatish Balay {
500e5c89e4eSSatish Balay   int c;
501e5c89e4eSSatish Balay 
502e5c89e4eSSatish Balay   PetscFunctionBegin;
503e5c89e4eSSatish Balay   if (!a && !b) c = 0;
504e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
50532b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
50632b366c8SSatish Balay   else c = strcasecmp(a,b);
50732b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
508e5c89e4eSSatish Balay   else c = stricmp(a,b);
509e5c89e4eSSatish Balay #else
51032b366c8SSatish Balay   else {
51132b366c8SSatish Balay     char           *aa,*bb;
51232b366c8SSatish Balay     PetscErrorCode ierr;
51332b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
51432b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
51532b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
51632b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
51732b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
518503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
519503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
52032b366c8SSatish Balay     PetscFunctionReturn(0);
52132b366c8SSatish Balay   }
522e5c89e4eSSatish Balay #endif
523e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
524e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
525e5c89e4eSSatish Balay   PetscFunctionReturn(0);
526e5c89e4eSSatish Balay }
527e5c89e4eSSatish Balay 
52832b366c8SSatish Balay 
52932b366c8SSatish Balay 
530e5c89e4eSSatish Balay #undef __FUNCT__
531e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncmp"
532e5c89e4eSSatish Balay /*@C
533e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
534e5c89e4eSSatish Balay 
535e5c89e4eSSatish Balay    Not Collective
536e5c89e4eSSatish Balay 
537e5c89e4eSSatish Balay    Input Parameters:
538e5c89e4eSSatish Balay +  a - pointer to first string
539e5c89e4eSSatish Balay .  b - pointer to second string
540e5c89e4eSSatish Balay -  n - length to compare up to
541e5c89e4eSSatish Balay 
542e5c89e4eSSatish Balay    Output Parameter:
543e5c89e4eSSatish Balay .  t - if the two strings are equal
544e5c89e4eSSatish Balay 
545e5c89e4eSSatish Balay    Level: intermediate
546e5c89e4eSSatish Balay 
5476f013253SBarry Smith    Notes:    Not for use in Fortran
5486f013253SBarry Smith 
549e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
550e5c89e4eSSatish Balay 
551e5c89e4eSSatish Balay @*/
5527087cfbeSBarry Smith PetscErrorCode  PetscStrncmp(const char a[],const char b[],size_t n,PetscBool  *t)
553e5c89e4eSSatish Balay {
554e5c89e4eSSatish Balay   int c;
555e5c89e4eSSatish Balay 
556e5c89e4eSSatish Balay   PetscFunctionBegin;
557e5c89e4eSSatish Balay   c = strncmp(a,b,n);
558e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
559e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
560e5c89e4eSSatish Balay   PetscFunctionReturn(0);
561e5c89e4eSSatish Balay }
562e5c89e4eSSatish Balay 
563e5c89e4eSSatish Balay #undef __FUNCT__
564e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrchr"
565e5c89e4eSSatish Balay /*@C
566e5c89e4eSSatish Balay    PetscStrchr - Locates first occurance of a character in a string
567e5c89e4eSSatish Balay 
568e5c89e4eSSatish Balay    Not Collective
569e5c89e4eSSatish Balay 
570e5c89e4eSSatish Balay    Input Parameters:
571e5c89e4eSSatish Balay +  a - pointer to string
572e5c89e4eSSatish Balay -  b - character
573e5c89e4eSSatish Balay 
574e5c89e4eSSatish Balay    Output Parameter:
575e5c89e4eSSatish Balay .  c - location of occurance, PETSC_NULL if not found
576e5c89e4eSSatish Balay 
577e5c89e4eSSatish Balay    Level: intermediate
578e5c89e4eSSatish Balay 
5796f013253SBarry Smith    Notes:    Not for use in Fortran
5806f013253SBarry Smith 
581e5c89e4eSSatish Balay @*/
5827087cfbeSBarry Smith PetscErrorCode  PetscStrchr(const char a[],char b,char *c[])
583e5c89e4eSSatish Balay {
584e5c89e4eSSatish Balay   PetscFunctionBegin;
585e5c89e4eSSatish Balay   *c = (char *)strchr(a,b);
586e5c89e4eSSatish Balay   PetscFunctionReturn(0);
587e5c89e4eSSatish Balay }
588e5c89e4eSSatish Balay 
589e5c89e4eSSatish Balay #undef __FUNCT__
590e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrrchr"
591e5c89e4eSSatish Balay /*@C
592e5c89e4eSSatish Balay    PetscStrrchr - Locates one location past the last occurance of a character in a string,
593e5c89e4eSSatish Balay       if the character is not found then returns entire string
594e5c89e4eSSatish Balay 
595e5c89e4eSSatish Balay    Not Collective
596e5c89e4eSSatish Balay 
597e5c89e4eSSatish Balay    Input Parameters:
598e5c89e4eSSatish Balay +  a - pointer to string
599e5c89e4eSSatish Balay -  b - character
600e5c89e4eSSatish Balay 
601e5c89e4eSSatish Balay    Output Parameter:
602e5c89e4eSSatish Balay .  tmp - location of occurance, a if not found
603e5c89e4eSSatish Balay 
604e5c89e4eSSatish Balay    Level: intermediate
605e5c89e4eSSatish Balay 
6066f013253SBarry Smith    Notes:    Not for use in Fortran
6076f013253SBarry Smith 
608e5c89e4eSSatish Balay @*/
6097087cfbeSBarry Smith PetscErrorCode  PetscStrrchr(const char a[],char b,char *tmp[])
610e5c89e4eSSatish Balay {
611e5c89e4eSSatish Balay   PetscFunctionBegin;
612e5c89e4eSSatish Balay   *tmp = (char *)strrchr(a,b);
613e5c89e4eSSatish Balay   if (!*tmp) *tmp = (char*)a; else *tmp = *tmp + 1;
614e5c89e4eSSatish Balay   PetscFunctionReturn(0);
615e5c89e4eSSatish Balay }
616e5c89e4eSSatish Balay 
617e5c89e4eSSatish Balay #undef __FUNCT__
618e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrtolower"
619e5c89e4eSSatish Balay /*@C
620e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
621e5c89e4eSSatish Balay 
622e5c89e4eSSatish Balay    Not Collective
623e5c89e4eSSatish Balay 
624e5c89e4eSSatish Balay    Input Parameters:
625e5c89e4eSSatish Balay .  a - pointer to string
626e5c89e4eSSatish Balay 
627e5c89e4eSSatish Balay    Level: intermediate
628e5c89e4eSSatish Balay 
6296f013253SBarry Smith    Notes:    Not for use in Fortran
6306f013253SBarry Smith 
631e5c89e4eSSatish Balay @*/
6327087cfbeSBarry Smith PetscErrorCode  PetscStrtolower(char a[])
633e5c89e4eSSatish Balay {
634e5c89e4eSSatish Balay   PetscFunctionBegin;
635e5c89e4eSSatish Balay   while (*a) {
636e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
637e5c89e4eSSatish Balay     a++;
638e5c89e4eSSatish Balay   }
639e5c89e4eSSatish Balay   PetscFunctionReturn(0);
640e5c89e4eSSatish Balay }
641e5c89e4eSSatish Balay 
6427ba3a57cSBarry Smith #undef __FUNCT__
6437ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswith"
6447ba3a57cSBarry Smith /*@C
6457ba3a57cSBarry Smith    PetscStrendswith - Determines if a string ends with a certain string
6461d1a0024SBarry Smith 
6477ba3a57cSBarry Smith    Not Collective
6487ba3a57cSBarry Smith 
6497ba3a57cSBarry Smith    Input Parameters:
6507ba3a57cSBarry Smith +  a - pointer to string
6517ba3a57cSBarry Smith -  b - string to endwith
6527ba3a57cSBarry Smith 
6537ba3a57cSBarry Smith    Output Parameter:
6547ba3a57cSBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
6557ba3a57cSBarry Smith 
6567ba3a57cSBarry Smith    Notes:     Not for use in Fortran
6577ba3a57cSBarry Smith 
6587ba3a57cSBarry Smith    Level: intermediate
6597ba3a57cSBarry Smith 
6607ba3a57cSBarry Smith @*/
6617ba3a57cSBarry Smith PetscErrorCode  PetscStrendswith(const char a[],const char b[],PetscBool *flg)
6627ba3a57cSBarry Smith {
6637ba3a57cSBarry Smith   char           *test;
6647ba3a57cSBarry Smith   PetscErrorCode ierr;
6657ba3a57cSBarry Smith   size_t         na,nb;
6667ba3a57cSBarry Smith 
6677ba3a57cSBarry Smith   PetscFunctionBegin;
6687ba3a57cSBarry Smith   *flg = PETSC_FALSE;
6697ba3a57cSBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
6707ba3a57cSBarry Smith   if (test) {
6717ba3a57cSBarry Smith     ierr = PetscStrlen(a,&na);CHKERRQ(ierr);
6727ba3a57cSBarry Smith     ierr = PetscStrlen(b,&nb);CHKERRQ(ierr);
6737ba3a57cSBarry Smith     if (a+na-nb == test) *flg = PETSC_TRUE;
6747ba3a57cSBarry Smith   }
6757ba3a57cSBarry Smith   PetscFunctionReturn(0);
6767ba3a57cSBarry Smith }
6777ba3a57cSBarry Smith 
6787ba3a57cSBarry Smith #undef __FUNCT__
6797ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswithwhich"
6807ba3a57cSBarry Smith /*@C
6817ba3a57cSBarry Smith    PetscStrendswithwhich - Determines if a string ends with one of several possible strings
6827ba3a57cSBarry Smith 
6837ba3a57cSBarry Smith    Not Collective
6847ba3a57cSBarry Smith 
6857ba3a57cSBarry Smith    Input Parameters:
6867ba3a57cSBarry Smith +  a - pointer to string
6877ba3a57cSBarry Smith -  bs - strings to endwith (last entry must be null)
6887ba3a57cSBarry Smith 
6897ba3a57cSBarry Smith    Output Parameter:
6907ba3a57cSBarry Smith .  cnt - the index of the string it ends with or 1+the last possible index
6917ba3a57cSBarry Smith 
6927ba3a57cSBarry Smith    Notes:     Not for use in Fortran
6937ba3a57cSBarry Smith 
6947ba3a57cSBarry Smith    Level: intermediate
6957ba3a57cSBarry Smith 
6967ba3a57cSBarry Smith @*/
6977ba3a57cSBarry Smith PetscErrorCode  PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt)
6987ba3a57cSBarry Smith {
6997ba3a57cSBarry Smith   PetscBool      flg;
7007ba3a57cSBarry Smith   PetscErrorCode ierr;
7017ba3a57cSBarry Smith 
7027ba3a57cSBarry Smith   PetscFunctionBegin;
7037ba3a57cSBarry Smith   *cnt = 0;
7047ba3a57cSBarry Smith   while (bs[*cnt]) {
7057ba3a57cSBarry Smith     ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr);
7067ba3a57cSBarry Smith     if (flg) PetscFunctionReturn(0);
7077ba3a57cSBarry Smith     *cnt += 1;
7087ba3a57cSBarry Smith   }
7097ba3a57cSBarry Smith   PetscFunctionReturn(0);
7107ba3a57cSBarry Smith }
7117ba3a57cSBarry Smith 
7127ba3a57cSBarry Smith #undef __FUNCT__
7137ba3a57cSBarry Smith #define __FUNCT__ "PetscStrrstr"
7147ba3a57cSBarry Smith /*@C
7157ba3a57cSBarry Smith    PetscStrrstr - Locates last occurance of string in another string
7167ba3a57cSBarry Smith 
7177ba3a57cSBarry Smith    Not Collective
7187ba3a57cSBarry Smith 
7197ba3a57cSBarry Smith    Input Parameters:
7207ba3a57cSBarry Smith +  a - pointer to string
7217ba3a57cSBarry Smith -  b - string to find
7227ba3a57cSBarry Smith 
7237ba3a57cSBarry Smith    Output Parameter:
7247ba3a57cSBarry Smith .  tmp - location of occurance
7257ba3a57cSBarry Smith 
7267ba3a57cSBarry Smith    Notes:     Not for use in Fortran
7277ba3a57cSBarry Smith 
7287ba3a57cSBarry Smith    Level: intermediate
7297ba3a57cSBarry Smith 
7307ba3a57cSBarry Smith @*/
7317ba3a57cSBarry Smith PetscErrorCode  PetscStrrstr(const char a[],const char b[],char *tmp[])
7327ba3a57cSBarry Smith {
7337ba3a57cSBarry Smith   const char *stmp = a, *ltmp = 0;
7347ba3a57cSBarry Smith 
7357ba3a57cSBarry Smith   PetscFunctionBegin;
7367ba3a57cSBarry Smith   while (stmp) {
7377ba3a57cSBarry Smith     stmp = (char *)strstr(stmp,b);
7387ba3a57cSBarry Smith     if (stmp) {ltmp = stmp;stmp++;}
7397ba3a57cSBarry Smith   }
7407ba3a57cSBarry Smith   *tmp = (char *)ltmp;
7417ba3a57cSBarry Smith   PetscFunctionReturn(0);
7427ba3a57cSBarry Smith }
7437ba3a57cSBarry Smith 
7447ba3a57cSBarry Smith #undef __FUNCT__
7457ba3a57cSBarry Smith #define __FUNCT__ "PetscStrstr"
7467ba3a57cSBarry Smith /*@C
7477ba3a57cSBarry Smith    PetscStrstr - Locates first occurance of string in another string
7487ba3a57cSBarry Smith 
7497ba3a57cSBarry Smith    Not Collective
7507ba3a57cSBarry Smith 
7517ba3a57cSBarry Smith    Input Parameters:
752160f4796SJed Brown +  haystack - string to search
753160f4796SJed Brown -  needle - string to find
7547ba3a57cSBarry Smith 
7557ba3a57cSBarry Smith    Output Parameter:
7567ba3a57cSBarry Smith .  tmp - location of occurance, is a PETSC_NULL if the string is not found
7577ba3a57cSBarry Smith 
7587ba3a57cSBarry Smith    Notes: Not for use in Fortran
7597ba3a57cSBarry Smith 
7607ba3a57cSBarry Smith    Level: intermediate
7617ba3a57cSBarry Smith 
7627ba3a57cSBarry Smith @*/
763160f4796SJed Brown PetscErrorCode  PetscStrstr(const char haystack[],const char needle[],char *tmp[])
7647ba3a57cSBarry Smith {
7657ba3a57cSBarry Smith   PetscFunctionBegin;
766160f4796SJed Brown   *tmp = (char *)strstr(haystack,needle);
7677ba3a57cSBarry Smith   PetscFunctionReturn(0);
7687ba3a57cSBarry Smith }
7697ba3a57cSBarry Smith 
7707ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
7711d1a0024SBarry Smith 
772e5c89e4eSSatish Balay #undef __FUNCT__
773e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenFind"
774e5c89e4eSSatish Balay /*@C
775e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
776e5c89e4eSSatish Balay 
777e5c89e4eSSatish Balay    Not Collective
778e5c89e4eSSatish Balay 
779e5c89e4eSSatish Balay    Input Parameters:
780e5c89e4eSSatish Balay .  a - pointer to token
781e5c89e4eSSatish Balay 
782e5c89e4eSSatish Balay    Output Parameter:
783e5c89e4eSSatish Balay .  result - location of occurance, PETSC_NULL if not found
784e5c89e4eSSatish Balay 
785e5c89e4eSSatish Balay    Notes:
786e5c89e4eSSatish Balay 
787e5c89e4eSSatish Balay      This version is different from the system version in that
788e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
789e5c89e4eSSatish Balay 
7904704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
7914704e885SBarry Smith    as a single token.
7924704e885SBarry Smith 
7936f013253SBarry Smith     Not for use in Fortran
7946f013253SBarry Smith 
795e5c89e4eSSatish Balay    Level: intermediate
796e5c89e4eSSatish Balay 
7976f013253SBarry Smith 
798e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
799e5c89e4eSSatish Balay @*/
8007087cfbeSBarry Smith PetscErrorCode  PetscTokenFind(PetscToken a,char *result[])
801e5c89e4eSSatish Balay {
8024704e885SBarry Smith   char *ptr = a->current,token;
803e5c89e4eSSatish Balay 
804e5c89e4eSSatish Balay   PetscFunctionBegin;
805e5c89e4eSSatish Balay   *result = a->current;
8064704e885SBarry Smith   if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);}
8074704e885SBarry Smith   token = a->token;
80890fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
809e5c89e4eSSatish Balay   while (ptr) {
8104704e885SBarry Smith     if (*ptr == token) {
811e5c89e4eSSatish Balay       *ptr++ = 0;
812e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
813e5c89e4eSSatish Balay       a->current = ptr;
814e5c89e4eSSatish Balay       break;
815e5c89e4eSSatish Balay     }
816e5c89e4eSSatish Balay     if (!*ptr) {
817e5c89e4eSSatish Balay       a->current = 0;
818e5c89e4eSSatish Balay       break;
819e5c89e4eSSatish Balay     }
820e5c89e4eSSatish Balay     ptr++;
821e5c89e4eSSatish Balay   }
822e5c89e4eSSatish Balay   PetscFunctionReturn(0);
823e5c89e4eSSatish Balay }
824e5c89e4eSSatish Balay 
825e5c89e4eSSatish Balay #undef __FUNCT__
826e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenCreate"
827e5c89e4eSSatish Balay /*@C
828e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
829e5c89e4eSSatish Balay 
830e5c89e4eSSatish Balay    Not Collective
831e5c89e4eSSatish Balay 
832e5c89e4eSSatish Balay    Input Parameters:
833e5c89e4eSSatish Balay +  string - the string to look in
834e5c89e4eSSatish Balay -  token - the character to look for
835e5c89e4eSSatish Balay 
836e5c89e4eSSatish Balay    Output Parameter:
837e5c89e4eSSatish Balay .  a - pointer to token
838e5c89e4eSSatish Balay 
839e5c89e4eSSatish Balay    Notes:
840e5c89e4eSSatish Balay 
841e5c89e4eSSatish Balay      This version is different from the system version in that
842e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
843e5c89e4eSSatish Balay 
8446f013253SBarry Smith     Not for use in Fortran
8456f013253SBarry Smith 
846e5c89e4eSSatish Balay    Level: intermediate
847e5c89e4eSSatish Balay 
848e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
849e5c89e4eSSatish Balay @*/
8507087cfbeSBarry Smith PetscErrorCode  PetscTokenCreate(const char a[],const char b,PetscToken *t)
851e5c89e4eSSatish Balay {
852e5c89e4eSSatish Balay   PetscErrorCode ierr;
853e5c89e4eSSatish Balay 
854e5c89e4eSSatish Balay   PetscFunctionBegin;
8551d1a0024SBarry Smith   ierr = PetscNew(struct _p_PetscToken,t);CHKERRQ(ierr);
856e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
857e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
858e5c89e4eSSatish Balay   (*t)->token   = b;
859e5c89e4eSSatish Balay   PetscFunctionReturn(0);
860e5c89e4eSSatish Balay }
861e5c89e4eSSatish Balay 
862e5c89e4eSSatish Balay #undef __FUNCT__
863e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenDestroy"
864e5c89e4eSSatish Balay /*@C
865e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
866e5c89e4eSSatish Balay 
867e5c89e4eSSatish Balay    Not Collective
868e5c89e4eSSatish Balay 
869e5c89e4eSSatish Balay    Input Parameters:
870e5c89e4eSSatish Balay .  a - pointer to token
871e5c89e4eSSatish Balay 
872e5c89e4eSSatish Balay    Level: intermediate
873e5c89e4eSSatish Balay 
8746f013253SBarry Smith    Notes:     Not for use in Fortran
8756f013253SBarry Smith 
876e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
877e5c89e4eSSatish Balay @*/
8788c74ee41SBarry Smith PetscErrorCode  PetscTokenDestroy(PetscToken *a)
879e5c89e4eSSatish Balay {
880e5c89e4eSSatish Balay   PetscErrorCode ierr;
881e5c89e4eSSatish Balay 
882e5c89e4eSSatish Balay   PetscFunctionBegin;
8838c74ee41SBarry Smith   if (!*a) PetscFunctionReturn(0);
8848c74ee41SBarry Smith   ierr = PetscFree((*a)->array);CHKERRQ(ierr);
8858c74ee41SBarry Smith   ierr = PetscFree(*a);CHKERRQ(ierr);
886e5c89e4eSSatish Balay   PetscFunctionReturn(0);
887e5c89e4eSSatish Balay }
888e5c89e4eSSatish Balay 
889e5c89e4eSSatish Balay 
890e5c89e4eSSatish Balay #undef __FUNCT__
891e5c89e4eSSatish Balay #define __FUNCT__ "PetscGetPetscDir"
892e5c89e4eSSatish Balay /*@C
893e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
894e5c89e4eSSatish Balay 
895e5c89e4eSSatish Balay    Not Collective
896e5c89e4eSSatish Balay 
897e5c89e4eSSatish Balay    Output Parameter:
898e5c89e4eSSatish Balay .  dir - the directory
899e5c89e4eSSatish Balay 
900e5c89e4eSSatish Balay    Level: developer
901e5c89e4eSSatish Balay 
9026f013253SBarry Smith    Notes: Not for use in Fortran
9036f013253SBarry Smith 
904e5c89e4eSSatish Balay @*/
9057087cfbeSBarry Smith PetscErrorCode  PetscGetPetscDir(const char *dir[])
906e5c89e4eSSatish Balay {
907e5c89e4eSSatish Balay   PetscFunctionBegin;
908e5c89e4eSSatish Balay   *dir = PETSC_DIR;
909e5c89e4eSSatish Balay   PetscFunctionReturn(0);
910e5c89e4eSSatish Balay }
911e5c89e4eSSatish Balay 
912e5c89e4eSSatish Balay #undef __FUNCT__
913e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrreplace"
914e5c89e4eSSatish Balay /*@C
915e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
916e5c89e4eSSatish Balay 
917e5c89e4eSSatish Balay    Not Collective
918e5c89e4eSSatish Balay 
919e5c89e4eSSatish Balay    Input Parameters:
920e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
92171573d7dSBarry Smith .   aa - the string to look in
922d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
923e5c89e4eSSatish Balay -   len - the length of b
924e5c89e4eSSatish Balay 
925e5c89e4eSSatish Balay    Notes:
926e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
927d5649816SBarry Smith       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
928e5c89e4eSSatish Balay       as well as any environmental variables.
929e5c89e4eSSatish Balay 
9306f013253SBarry Smith       PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
931acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
932acc6cc86SBarry Smith 
9336f013253SBarry Smith       Not for use in Fortran
9346f013253SBarry Smith 
935e5c89e4eSSatish Balay    Level: intermediate
936e5c89e4eSSatish Balay 
937e5c89e4eSSatish Balay @*/
9387087cfbeSBarry Smith PetscErrorCode  PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
939e5c89e4eSSatish Balay {
940e5c89e4eSSatish Balay   PetscErrorCode ierr;
941e5c89e4eSSatish Balay   int            i = 0;
942e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
94371573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
944d5649816SBarry Smith   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0};
945d5649816SBarry Smith   const char     *r[] = {0,0,0,0,0,0,0,0,0};
946ace3abfcSBarry Smith   PetscBool      flag;
947e5c89e4eSSatish Balay 
948e5c89e4eSSatish Balay   PetscFunctionBegin;
949e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
95071573d7dSBarry Smith   if (aa == b) {
95122982a5fSBarry Smith     ierr    = PetscStrallocpy(aa,(char **)&a);CHKERRQ(ierr);
95271573d7dSBarry Smith   }
953e5c89e4eSSatish Balay   ierr = PetscMalloc(len*sizeof(char*),&work);CHKERRQ(ierr);
954e5c89e4eSSatish Balay 
955e5c89e4eSSatish Balay   /* get values for replaced variables */
956487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr);
957487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr);
958487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr);
959487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[3]);CHKERRQ(ierr);
960487e5849SBarry Smith   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[4]);CHKERRQ(ierr);
961e5c89e4eSSatish Balay   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[5]);CHKERRQ(ierr);
962487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[6]);CHKERRQ(ierr);
963d5649816SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[7]);CHKERRQ(ierr);
964487e5849SBarry Smith   ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr);
965487e5849SBarry Smith   ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
966487e5849SBarry Smith   ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
967487e5849SBarry Smith   ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr);
968d5649816SBarry Smith   ierr = PetscGetHostName((char*)r[7],256);CHKERRQ(ierr);
969487e5849SBarry Smith 
970487e5849SBarry Smith   /* replace that are in environment */
971487e5849SBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr);
972487e5849SBarry Smith   if (flag) {
973487e5849SBarry Smith     ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr);
974487e5849SBarry Smith   }
975e5c89e4eSSatish Balay 
976e5c89e4eSSatish Balay   /* replace the requested strings */
977e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
978e5c89e4eSSatish Balay   while (s[i]) {
979e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
980e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
981e5c89e4eSSatish Balay     while (par) {
982e5c89e4eSSatish Balay       *par  =  0;
983e5c89e4eSSatish Balay       par  += l;
984e5c89e4eSSatish Balay 
985e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
986e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
987e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
98817186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
989e5c89e4eSSatish Balay       ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
990e5c89e4eSSatish Balay       ierr  = PetscStrcat(work,r[i]);CHKERRQ(ierr);
991e5c89e4eSSatish Balay       ierr  = PetscStrcat(work,par);CHKERRQ(ierr);
992e5c89e4eSSatish Balay       ierr  = PetscStrncpy(b,work,len);CHKERRQ(ierr);
993e5c89e4eSSatish Balay       ierr  = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
994e5c89e4eSSatish Balay     }
995e5c89e4eSSatish Balay     i++;
996e5c89e4eSSatish Balay   }
997487e5849SBarry Smith   i = 0;
998487e5849SBarry Smith   while (r[i]) {
999e5c89e4eSSatish Balay     tfree = (char*)r[i];
1000e5c89e4eSSatish Balay     ierr = PetscFree(tfree);CHKERRQ(ierr);
1001487e5849SBarry Smith     i++;
1002e5c89e4eSSatish Balay   }
1003e5c89e4eSSatish Balay 
1004e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
1005e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1006e5c89e4eSSatish Balay   while (par) {
1007e5c89e4eSSatish Balay     *par = 0;
1008e5c89e4eSSatish Balay     par += 2;
1009e5c89e4eSSatish Balay     ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
1010e5c89e4eSSatish Balay     ierr = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
1011e5c89e4eSSatish Balay     *epar = 0;
1012e5c89e4eSSatish Balay     epar += 1;
1013e5c89e4eSSatish Balay     ierr = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr);
10147ba3a57cSBarry Smith     if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
1015e5c89e4eSSatish Balay     ierr = PetscStrcat(work,env);CHKERRQ(ierr);
1016e5c89e4eSSatish Balay     ierr = PetscStrcat(work,epar);CHKERRQ(ierr);
1017e5c89e4eSSatish Balay     ierr = PetscStrcpy(b,work);CHKERRQ(ierr);
1018e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1019e5c89e4eSSatish Balay   }
1020e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
102171573d7dSBarry Smith   if (aa == b) {
102271573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
102371573d7dSBarry Smith   }
1024e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1025e5c89e4eSSatish Balay }
1026e5c89e4eSSatish Balay 
1027e5c89e4eSSatish Balay 
1028