xref: /petsc/src/sys/utils/str.c (revision 0298fd7132830bec7daee99a80be0eddb2b310a5)
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
19d67fe73bSBarry 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:
24d67fe73bSBarry Smith +  s - pointer to string
25a2ea699eSBarry Smith -  sp - separator 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 @*/
43d67fe73bSBarry 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;
514996c5bdSBarry Smith   if (!n) {
524996c5bdSBarry Smith     *args = 0;
534996c5bdSBarry Smith     return(0);
544996c5bdSBarry Smith   }
553c311c98SBarry Smith   for (i=0; i<n; i++) {
56d67fe73bSBarry Smith     if (s[i] != sp) break;
573c311c98SBarry Smith   }
583c311c98SBarry Smith   for (;i<n+1; i++) {
59d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
60d67fe73bSBarry Smith     else if (s[i] != sp) {flg = PETSC_FALSE;}
613c311c98SBarry Smith   }
62a2ea699eSBarry Smith   (*args) = (char**) malloc(((*argc)+1)*sizeof(char*)); if (!*args) return PETSC_ERR_MEM;
6353e6e2c4SHong Zhang   lens    = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM;
643c311c98SBarry Smith   for (i=0; i<*argc; i++) lens[i] = 0;
653c311c98SBarry Smith 
663c311c98SBarry Smith   *argc = 0;
673c311c98SBarry Smith   for (i=0; i<n; i++) {
68d67fe73bSBarry Smith     if (s[i] != sp) break;
693c311c98SBarry Smith   }
703c311c98SBarry Smith   for (;i<n+1; i++) {
71d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
72d67fe73bSBarry Smith     else if (s[i] != sp) {lens[*argc]++;flg = PETSC_FALSE;}
733c311c98SBarry Smith   }
743c311c98SBarry Smith 
753c311c98SBarry Smith   for (i=0; i<*argc; i++) {
76675282fdSHong Zhang     (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char)); if (!(*args)[i]) return PETSC_ERR_MEM;
773c311c98SBarry Smith   }
78a2ea699eSBarry Smith   free(lens);
79301d30feSBarry Smith   (*args)[*argc] = 0;
803c311c98SBarry Smith 
813c311c98SBarry Smith   *argc = 0;
823c311c98SBarry Smith   for (i=0; i<n; i++) {
83d67fe73bSBarry Smith     if (s[i] != sp) break;
843c311c98SBarry Smith   }
853c311c98SBarry Smith   for (;i<n+1; i++) {
86d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
87d67fe73bSBarry Smith     else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;}
883c311c98SBarry Smith   }
893c311c98SBarry Smith   return 0;
903c311c98SBarry Smith }
913c311c98SBarry Smith 
923c311c98SBarry Smith #undef __FUNCT__
93301d30feSBarry Smith #define __FUNCT__ "PetscStrToArrayDestroy"
94301d30feSBarry Smith /*@C
95301d30feSBarry Smith    PetscStrToArrayDestroy - Frees array created with PetscStrToArray().
96301d30feSBarry Smith 
97301d30feSBarry Smith    Not Collective
98301d30feSBarry Smith 
99301d30feSBarry Smith    Output Parameters:
100301d30feSBarry Smith +  argc - the number of arguments
101301d30feSBarry Smith -  args - the array of arguments
102301d30feSBarry Smith 
103301d30feSBarry Smith    Level: intermediate
104301d30feSBarry Smith 
105301d30feSBarry Smith    Concepts: command line arguments
106301d30feSBarry Smith 
107301d30feSBarry Smith    Notes: This may be called before PetscInitialize() or after PetscFinalize()
108301d30feSBarry Smith 
1096f013253SBarry Smith    Not for use in Fortran
1106f013253SBarry Smith 
111301d30feSBarry Smith .seealso: PetscStrToArray()
112301d30feSBarry Smith 
113301d30feSBarry Smith @*/
1147087cfbeSBarry Smith PetscErrorCode  PetscStrToArrayDestroy(int argc,char **args)
115301d30feSBarry Smith {
116301d30feSBarry Smith   PetscInt i;
117301d30feSBarry Smith 
118a297a907SKarl Rupp   for (i=0; i<argc; i++) free(args[i]);
119a297a907SKarl Rupp   if (args) free(args);
120301d30feSBarry Smith   return 0;
121301d30feSBarry Smith }
122301d30feSBarry Smith 
123301d30feSBarry Smith #undef __FUNCT__
124e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrlen"
125e5c89e4eSSatish Balay /*@C
126e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
127e5c89e4eSSatish Balay 
128e5c89e4eSSatish Balay    Not Collective
129e5c89e4eSSatish Balay 
130e5c89e4eSSatish Balay    Input Parameters:
131e5c89e4eSSatish Balay .  s - pointer to string
132e5c89e4eSSatish Balay 
133e5c89e4eSSatish Balay    Output Parameter:
134e5c89e4eSSatish Balay .  len - length in bytes
135e5c89e4eSSatish Balay 
136e5c89e4eSSatish Balay    Level: intermediate
137e5c89e4eSSatish Balay 
138e5c89e4eSSatish Balay    Note:
139e5c89e4eSSatish Balay    This routine is analogous to strlen().
140e5c89e4eSSatish Balay 
141e5c89e4eSSatish Balay    Null string returns a length of zero
142e5c89e4eSSatish Balay 
1436f013253SBarry Smith    Not for use in Fortran
1446f013253SBarry Smith 
145e5c89e4eSSatish Balay   Concepts: string length
146e5c89e4eSSatish Balay 
147e5c89e4eSSatish Balay @*/
1487087cfbeSBarry Smith PetscErrorCode  PetscStrlen(const char s[],size_t *len)
149e5c89e4eSSatish Balay {
150e5c89e4eSSatish Balay   PetscFunctionBegin;
151a297a907SKarl Rupp   if (!s) *len = 0;
152a297a907SKarl Rupp   else    *len = strlen(s);
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   }
229*0298fd71SBarry Smith   (*t)[n] = 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");
297a297a907SKarl Rupp   if (t) strcpy(s,t);
298a297a907SKarl Rupp   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");
330a297a907SKarl Rupp   if (t) strncpy(s,t,n);
331a297a907SKarl Rupp   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;
417a297a907SKarl Rupp   if (!a && !b)      *flg = PETSC_TRUE;
418a297a907SKarl Rupp   else if (!a || !b) *flg = PETSC_FALSE;
419a297a907SKarl Rupp   else {
420e5c89e4eSSatish Balay     c = strcmp(a,b);
421e5c89e4eSSatish Balay     if (c) *flg = PETSC_FALSE;
422e5c89e4eSSatish Balay     else   *flg = PETSC_TRUE;
423e5c89e4eSSatish Balay   }
424e5c89e4eSSatish Balay   PetscFunctionReturn(0);
425e5c89e4eSSatish Balay }
426e5c89e4eSSatish Balay 
427e5c89e4eSSatish Balay #undef __FUNCT__
428e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrgrt"
429e5c89e4eSSatish Balay /*@C
430e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
431e5c89e4eSSatish Balay 
432e5c89e4eSSatish Balay    Not Collective
433e5c89e4eSSatish Balay 
434e5c89e4eSSatish Balay    Input Parameters:
435e5c89e4eSSatish Balay +  a - pointer to first string
436e5c89e4eSSatish Balay -  b - pointer to second string
437e5c89e4eSSatish Balay 
438e5c89e4eSSatish Balay    Output Parameter:
439e5c89e4eSSatish Balay .  flg - if the first string is greater
440e5c89e4eSSatish Balay 
441e5c89e4eSSatish Balay    Notes:
442e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
443e5c89e4eSSatish Balay     all others
444e5c89e4eSSatish Balay 
4456f013253SBarry Smith    Not for use in Fortran
4466f013253SBarry Smith 
447e5c89e4eSSatish Balay    Level: intermediate
448e5c89e4eSSatish Balay 
449e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
450e5c89e4eSSatish Balay 
451e5c89e4eSSatish Balay @*/
4527087cfbeSBarry Smith PetscErrorCode  PetscStrgrt(const char a[],const char b[],PetscBool  *t)
453e5c89e4eSSatish Balay {
454e5c89e4eSSatish Balay   int c;
455e5c89e4eSSatish Balay 
456e5c89e4eSSatish Balay   PetscFunctionBegin;
457a297a907SKarl Rupp   if (!a && !b) *t = PETSC_FALSE;
458a297a907SKarl Rupp   else if (a && !b) *t = PETSC_TRUE;
459a297a907SKarl Rupp   else if (!a && b) *t = PETSC_FALSE;
460a297a907SKarl Rupp   else {
461e5c89e4eSSatish Balay     c = strcmp(a,b);
462e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
463e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
464e5c89e4eSSatish Balay   }
465e5c89e4eSSatish Balay   PetscFunctionReturn(0);
466e5c89e4eSSatish Balay }
467e5c89e4eSSatish Balay 
468e5c89e4eSSatish Balay #undef __FUNCT__
469e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcasecmp"
470e5c89e4eSSatish Balay /*@C
471e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
472e5c89e4eSSatish Balay      except possibly for case.
473e5c89e4eSSatish Balay 
474e5c89e4eSSatish Balay    Not Collective
475e5c89e4eSSatish Balay 
476e5c89e4eSSatish Balay    Input Parameters:
477e5c89e4eSSatish Balay +  a - pointer to first string
478e5c89e4eSSatish Balay -  b - pointer to second string
479e5c89e4eSSatish Balay 
480e5c89e4eSSatish Balay    Output Parameter:
481e5c89e4eSSatish Balay .  flg - if the two strings are the same
482e5c89e4eSSatish Balay 
483e5c89e4eSSatish Balay    Notes:
484e5c89e4eSSatish Balay     Null arguments are ok
485e5c89e4eSSatish Balay 
4866f013253SBarry Smith    Not for use in Fortran
4876f013253SBarry Smith 
488e5c89e4eSSatish Balay    Level: intermediate
489e5c89e4eSSatish Balay 
490e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
491e5c89e4eSSatish Balay 
492e5c89e4eSSatish Balay @*/
4937087cfbeSBarry Smith PetscErrorCode  PetscStrcasecmp(const char a[],const char b[],PetscBool  *t)
494e5c89e4eSSatish Balay {
495e5c89e4eSSatish Balay   int c;
496e5c89e4eSSatish Balay 
497e5c89e4eSSatish Balay   PetscFunctionBegin;
498e5c89e4eSSatish Balay   if (!a && !b) c = 0;
499e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
50032b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
50132b366c8SSatish Balay   else c = strcasecmp(a,b);
50232b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
503e5c89e4eSSatish Balay   else c = stricmp(a,b);
504e5c89e4eSSatish Balay #else
50532b366c8SSatish Balay   else {
50632b366c8SSatish Balay     char           *aa,*bb;
50732b366c8SSatish Balay     PetscErrorCode ierr;
50832b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
50932b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
51032b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
51132b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
51232b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
513503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
514503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
51532b366c8SSatish Balay     PetscFunctionReturn(0);
51632b366c8SSatish Balay   }
517e5c89e4eSSatish Balay #endif
518e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
519e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
520e5c89e4eSSatish Balay   PetscFunctionReturn(0);
521e5c89e4eSSatish Balay }
522e5c89e4eSSatish Balay 
52332b366c8SSatish Balay 
52432b366c8SSatish Balay 
525e5c89e4eSSatish Balay #undef __FUNCT__
526e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncmp"
527e5c89e4eSSatish Balay /*@C
528e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
529e5c89e4eSSatish Balay 
530e5c89e4eSSatish Balay    Not Collective
531e5c89e4eSSatish Balay 
532e5c89e4eSSatish Balay    Input Parameters:
533e5c89e4eSSatish Balay +  a - pointer to first string
534e5c89e4eSSatish Balay .  b - pointer to second string
535e5c89e4eSSatish Balay -  n - length to compare up to
536e5c89e4eSSatish Balay 
537e5c89e4eSSatish Balay    Output Parameter:
538e5c89e4eSSatish Balay .  t - if the two strings are equal
539e5c89e4eSSatish Balay 
540e5c89e4eSSatish Balay    Level: intermediate
541e5c89e4eSSatish Balay 
5426f013253SBarry Smith    Notes:    Not for use in Fortran
5436f013253SBarry Smith 
544e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
545e5c89e4eSSatish Balay 
546e5c89e4eSSatish Balay @*/
5477087cfbeSBarry Smith PetscErrorCode  PetscStrncmp(const char a[],const char b[],size_t n,PetscBool  *t)
548e5c89e4eSSatish Balay {
549e5c89e4eSSatish Balay   int c;
550e5c89e4eSSatish Balay 
551e5c89e4eSSatish Balay   PetscFunctionBegin;
552e5c89e4eSSatish Balay   c = strncmp(a,b,n);
553e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
554e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
555e5c89e4eSSatish Balay   PetscFunctionReturn(0);
556e5c89e4eSSatish Balay }
557e5c89e4eSSatish Balay 
558e5c89e4eSSatish Balay #undef __FUNCT__
559e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrchr"
560e5c89e4eSSatish Balay /*@C
561e5c89e4eSSatish Balay    PetscStrchr - Locates first occurance of a character in a string
562e5c89e4eSSatish Balay 
563e5c89e4eSSatish Balay    Not Collective
564e5c89e4eSSatish Balay 
565e5c89e4eSSatish Balay    Input Parameters:
566e5c89e4eSSatish Balay +  a - pointer to string
567e5c89e4eSSatish Balay -  b - character
568e5c89e4eSSatish Balay 
569e5c89e4eSSatish Balay    Output Parameter:
570*0298fd71SBarry Smith .  c - location of occurance, NULL if not found
571e5c89e4eSSatish Balay 
572e5c89e4eSSatish Balay    Level: intermediate
573e5c89e4eSSatish Balay 
5746f013253SBarry Smith    Notes:    Not for use in Fortran
5756f013253SBarry Smith 
576e5c89e4eSSatish Balay @*/
5777087cfbeSBarry Smith PetscErrorCode  PetscStrchr(const char a[],char b,char *c[])
578e5c89e4eSSatish Balay {
579e5c89e4eSSatish Balay   PetscFunctionBegin;
580e5c89e4eSSatish Balay   *c = (char*)strchr(a,b);
581e5c89e4eSSatish Balay   PetscFunctionReturn(0);
582e5c89e4eSSatish Balay }
583e5c89e4eSSatish Balay 
584e5c89e4eSSatish Balay #undef __FUNCT__
585e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrrchr"
586e5c89e4eSSatish Balay /*@C
587e5c89e4eSSatish Balay    PetscStrrchr - Locates one location past the last occurance of a character in a string,
588e5c89e4eSSatish Balay       if the character is not found then returns entire string
589e5c89e4eSSatish Balay 
590e5c89e4eSSatish Balay    Not Collective
591e5c89e4eSSatish Balay 
592e5c89e4eSSatish Balay    Input Parameters:
593e5c89e4eSSatish Balay +  a - pointer to string
594e5c89e4eSSatish Balay -  b - character
595e5c89e4eSSatish Balay 
596e5c89e4eSSatish Balay    Output Parameter:
597e5c89e4eSSatish Balay .  tmp - location of occurance, a if not found
598e5c89e4eSSatish Balay 
599e5c89e4eSSatish Balay    Level: intermediate
600e5c89e4eSSatish Balay 
6016f013253SBarry Smith    Notes:    Not for use in Fortran
6026f013253SBarry Smith 
603e5c89e4eSSatish Balay @*/
6047087cfbeSBarry Smith PetscErrorCode  PetscStrrchr(const char a[],char b,char *tmp[])
605e5c89e4eSSatish Balay {
606e5c89e4eSSatish Balay   PetscFunctionBegin;
607e5c89e4eSSatish Balay   *tmp = (char*)strrchr(a,b);
608a297a907SKarl Rupp   if (!*tmp) *tmp = (char*)a;
609a297a907SKarl Rupp   else *tmp = *tmp + 1;
610e5c89e4eSSatish Balay   PetscFunctionReturn(0);
611e5c89e4eSSatish Balay }
612e5c89e4eSSatish Balay 
613e5c89e4eSSatish Balay #undef __FUNCT__
614e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrtolower"
615e5c89e4eSSatish Balay /*@C
616e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
617e5c89e4eSSatish Balay 
618e5c89e4eSSatish Balay    Not Collective
619e5c89e4eSSatish Balay 
620e5c89e4eSSatish Balay    Input Parameters:
621e5c89e4eSSatish Balay .  a - pointer to string
622e5c89e4eSSatish Balay 
623e5c89e4eSSatish Balay    Level: intermediate
624e5c89e4eSSatish Balay 
6256f013253SBarry Smith    Notes:    Not for use in Fortran
6266f013253SBarry Smith 
627e5c89e4eSSatish Balay @*/
6287087cfbeSBarry Smith PetscErrorCode  PetscStrtolower(char a[])
629e5c89e4eSSatish Balay {
630e5c89e4eSSatish Balay   PetscFunctionBegin;
631e5c89e4eSSatish Balay   while (*a) {
632e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
633e5c89e4eSSatish Balay     a++;
634e5c89e4eSSatish Balay   }
635e5c89e4eSSatish Balay   PetscFunctionReturn(0);
636e5c89e4eSSatish Balay }
637e5c89e4eSSatish Balay 
6387ba3a57cSBarry Smith #undef __FUNCT__
6392f234a98SBarry Smith #define __FUNCT__ "PetscStrtoupper"
6402f234a98SBarry Smith /*@C
6412f234a98SBarry Smith    PetscStrtolower - Converts string to upper case
6422f234a98SBarry Smith 
6432f234a98SBarry Smith    Not Collective
6442f234a98SBarry Smith 
6452f234a98SBarry Smith    Input Parameters:
6462f234a98SBarry Smith .  a - pointer to string
6472f234a98SBarry Smith 
6482f234a98SBarry Smith    Level: intermediate
6492f234a98SBarry Smith 
6502f234a98SBarry Smith    Notes:    Not for use in Fortran
6512f234a98SBarry Smith 
6522f234a98SBarry Smith @*/
6532f234a98SBarry Smith PetscErrorCode  PetscStrtoupper(char a[])
6542f234a98SBarry Smith {
6552f234a98SBarry Smith   PetscFunctionBegin;
6562f234a98SBarry Smith   while (*a) {
6572f234a98SBarry Smith     if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a';
6582f234a98SBarry Smith     a++;
6592f234a98SBarry Smith   }
6602f234a98SBarry Smith   PetscFunctionReturn(0);
6612f234a98SBarry Smith }
6622f234a98SBarry Smith 
6632f234a98SBarry Smith #undef __FUNCT__
6647ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswith"
6657ba3a57cSBarry Smith /*@C
6667ba3a57cSBarry Smith    PetscStrendswith - Determines if a string ends with a certain string
6671d1a0024SBarry Smith 
6687ba3a57cSBarry Smith    Not Collective
6697ba3a57cSBarry Smith 
6707ba3a57cSBarry Smith    Input Parameters:
6717ba3a57cSBarry Smith +  a - pointer to string
6727ba3a57cSBarry Smith -  b - string to endwith
6737ba3a57cSBarry Smith 
6747ba3a57cSBarry Smith    Output Parameter:
6757ba3a57cSBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
6767ba3a57cSBarry Smith 
6777ba3a57cSBarry Smith    Notes:     Not for use in Fortran
6787ba3a57cSBarry Smith 
6797ba3a57cSBarry Smith    Level: intermediate
6807ba3a57cSBarry Smith 
6817ba3a57cSBarry Smith @*/
6827ba3a57cSBarry Smith PetscErrorCode  PetscStrendswith(const char a[],const char b[],PetscBool *flg)
6837ba3a57cSBarry Smith {
6847ba3a57cSBarry Smith   char           *test;
6857ba3a57cSBarry Smith   PetscErrorCode ierr;
6867ba3a57cSBarry Smith   size_t         na,nb;
6877ba3a57cSBarry Smith 
6887ba3a57cSBarry Smith   PetscFunctionBegin;
6897ba3a57cSBarry Smith   *flg = PETSC_FALSE;
6907ba3a57cSBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
6917ba3a57cSBarry Smith   if (test) {
6927ba3a57cSBarry Smith     ierr = PetscStrlen(a,&na);CHKERRQ(ierr);
6937ba3a57cSBarry Smith     ierr = PetscStrlen(b,&nb);CHKERRQ(ierr);
6947ba3a57cSBarry Smith     if (a+na-nb == test) *flg = PETSC_TRUE;
6957ba3a57cSBarry Smith   }
6967ba3a57cSBarry Smith   PetscFunctionReturn(0);
6977ba3a57cSBarry Smith }
6987ba3a57cSBarry Smith 
6997ba3a57cSBarry Smith #undef __FUNCT__
7002c9581d2SBarry Smith #define __FUNCT__ "PetscStrbeginswith"
7012c9581d2SBarry Smith /*@C
7022c9581d2SBarry Smith    PetscStrbeginswith - Determines if a string begins with a certain string
7032c9581d2SBarry Smith 
7042c9581d2SBarry Smith    Not Collective
7052c9581d2SBarry Smith 
7062c9581d2SBarry Smith    Input Parameters:
7072c9581d2SBarry Smith +  a - pointer to string
7082c9581d2SBarry Smith -  b - string to beginwith
7092c9581d2SBarry Smith 
7102c9581d2SBarry Smith    Output Parameter:
7112c9581d2SBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
7122c9581d2SBarry Smith 
7132c9581d2SBarry Smith    Notes:     Not for use in Fortran
7142c9581d2SBarry Smith 
7152c9581d2SBarry Smith    Level: intermediate
7162c9581d2SBarry Smith 
7172c9581d2SBarry Smith @*/
7182c9581d2SBarry Smith PetscErrorCode  PetscStrbeginswith(const char a[],const char b[],PetscBool *flg)
7192c9581d2SBarry Smith {
7202c9581d2SBarry Smith   char           *test;
7212c9581d2SBarry Smith   PetscErrorCode ierr;
7222c9581d2SBarry Smith 
7232c9581d2SBarry Smith   PetscFunctionBegin;
7242c9581d2SBarry Smith   *flg = PETSC_FALSE;
7252c9581d2SBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
726a297a907SKarl Rupp   if (test && (test == a)) *flg = PETSC_TRUE;
7272c9581d2SBarry Smith   PetscFunctionReturn(0);
7282c9581d2SBarry Smith }
7292c9581d2SBarry Smith 
7302c9581d2SBarry Smith 
7312c9581d2SBarry Smith #undef __FUNCT__
7327ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswithwhich"
7337ba3a57cSBarry Smith /*@C
7347ba3a57cSBarry Smith    PetscStrendswithwhich - Determines if a string ends with one of several possible strings
7357ba3a57cSBarry Smith 
7367ba3a57cSBarry Smith    Not Collective
7377ba3a57cSBarry Smith 
7387ba3a57cSBarry Smith    Input Parameters:
7397ba3a57cSBarry Smith +  a - pointer to string
7407ba3a57cSBarry Smith -  bs - strings to endwith (last entry must be null)
7417ba3a57cSBarry Smith 
7427ba3a57cSBarry Smith    Output Parameter:
7437ba3a57cSBarry Smith .  cnt - the index of the string it ends with or 1+the last possible index
7447ba3a57cSBarry Smith 
7457ba3a57cSBarry Smith    Notes:     Not for use in Fortran
7467ba3a57cSBarry Smith 
7477ba3a57cSBarry Smith    Level: intermediate
7487ba3a57cSBarry Smith 
7497ba3a57cSBarry Smith @*/
7507ba3a57cSBarry Smith PetscErrorCode  PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt)
7517ba3a57cSBarry Smith {
7527ba3a57cSBarry Smith   PetscBool      flg;
7537ba3a57cSBarry Smith   PetscErrorCode ierr;
7547ba3a57cSBarry Smith 
7557ba3a57cSBarry Smith   PetscFunctionBegin;
7567ba3a57cSBarry Smith   *cnt = 0;
7577ba3a57cSBarry Smith   while (bs[*cnt]) {
7587ba3a57cSBarry Smith     ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr);
7597ba3a57cSBarry Smith     if (flg) PetscFunctionReturn(0);
7607ba3a57cSBarry Smith     *cnt += 1;
7617ba3a57cSBarry Smith   }
7627ba3a57cSBarry Smith   PetscFunctionReturn(0);
7637ba3a57cSBarry Smith }
7647ba3a57cSBarry Smith 
7657ba3a57cSBarry Smith #undef __FUNCT__
7667ba3a57cSBarry Smith #define __FUNCT__ "PetscStrrstr"
7677ba3a57cSBarry Smith /*@C
7687ba3a57cSBarry Smith    PetscStrrstr - Locates last occurance of string in another string
7697ba3a57cSBarry Smith 
7707ba3a57cSBarry Smith    Not Collective
7717ba3a57cSBarry Smith 
7727ba3a57cSBarry Smith    Input Parameters:
7737ba3a57cSBarry Smith +  a - pointer to string
7747ba3a57cSBarry Smith -  b - string to find
7757ba3a57cSBarry Smith 
7767ba3a57cSBarry Smith    Output Parameter:
7777ba3a57cSBarry Smith .  tmp - location of occurance
7787ba3a57cSBarry Smith 
7797ba3a57cSBarry Smith    Notes:     Not for use in Fortran
7807ba3a57cSBarry Smith 
7817ba3a57cSBarry Smith    Level: intermediate
7827ba3a57cSBarry Smith 
7837ba3a57cSBarry Smith @*/
7847ba3a57cSBarry Smith PetscErrorCode  PetscStrrstr(const char a[],const char b[],char *tmp[])
7857ba3a57cSBarry Smith {
7867ba3a57cSBarry Smith   const char *stmp = a, *ltmp = 0;
7877ba3a57cSBarry Smith 
7887ba3a57cSBarry Smith   PetscFunctionBegin;
7897ba3a57cSBarry Smith   while (stmp) {
7907ba3a57cSBarry Smith     stmp = (char*)strstr(stmp,b);
7917ba3a57cSBarry Smith     if (stmp) {ltmp = stmp;stmp++;}
7927ba3a57cSBarry Smith   }
7937ba3a57cSBarry Smith   *tmp = (char*)ltmp;
7947ba3a57cSBarry Smith   PetscFunctionReturn(0);
7957ba3a57cSBarry Smith }
7967ba3a57cSBarry Smith 
7977ba3a57cSBarry Smith #undef __FUNCT__
7987ba3a57cSBarry Smith #define __FUNCT__ "PetscStrstr"
7997ba3a57cSBarry Smith /*@C
8007ba3a57cSBarry Smith    PetscStrstr - Locates first occurance of string in another string
8017ba3a57cSBarry Smith 
8027ba3a57cSBarry Smith    Not Collective
8037ba3a57cSBarry Smith 
8047ba3a57cSBarry Smith    Input Parameters:
805160f4796SJed Brown +  haystack - string to search
806160f4796SJed Brown -  needle - string to find
8077ba3a57cSBarry Smith 
8087ba3a57cSBarry Smith    Output Parameter:
809*0298fd71SBarry Smith .  tmp - location of occurance, is a NULL if the string is not found
8107ba3a57cSBarry Smith 
8117ba3a57cSBarry Smith    Notes: Not for use in Fortran
8127ba3a57cSBarry Smith 
8137ba3a57cSBarry Smith    Level: intermediate
8147ba3a57cSBarry Smith 
8157ba3a57cSBarry Smith @*/
816160f4796SJed Brown PetscErrorCode  PetscStrstr(const char haystack[],const char needle[],char *tmp[])
8177ba3a57cSBarry Smith {
8187ba3a57cSBarry Smith   PetscFunctionBegin;
819160f4796SJed Brown   *tmp = (char*)strstr(haystack,needle);
8207ba3a57cSBarry Smith   PetscFunctionReturn(0);
8217ba3a57cSBarry Smith }
8227ba3a57cSBarry Smith 
8237ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
8241d1a0024SBarry Smith 
825e5c89e4eSSatish Balay #undef __FUNCT__
826e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenFind"
827e5c89e4eSSatish Balay /*@C
828e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
829e5c89e4eSSatish Balay 
830e5c89e4eSSatish Balay    Not Collective
831e5c89e4eSSatish Balay 
832e5c89e4eSSatish Balay    Input Parameters:
833e5c89e4eSSatish Balay .  a - pointer to token
834e5c89e4eSSatish Balay 
835e5c89e4eSSatish Balay    Output Parameter:
836*0298fd71SBarry Smith .  result - location of occurance, NULL if not found
837e5c89e4eSSatish Balay 
838e5c89e4eSSatish Balay    Notes:
839e5c89e4eSSatish Balay 
840e5c89e4eSSatish Balay      This version is different from the system version in that
841e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
842e5c89e4eSSatish Balay 
8434704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
8444704e885SBarry Smith    as a single token.
8454704e885SBarry Smith 
8466f013253SBarry Smith     Not for use in Fortran
8476f013253SBarry Smith 
848e5c89e4eSSatish Balay    Level: intermediate
849e5c89e4eSSatish Balay 
8506f013253SBarry Smith 
851e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
852e5c89e4eSSatish Balay @*/
8537087cfbeSBarry Smith PetscErrorCode  PetscTokenFind(PetscToken a,char *result[])
854e5c89e4eSSatish Balay {
8554704e885SBarry Smith   char *ptr = a->current,token;
856e5c89e4eSSatish Balay 
857e5c89e4eSSatish Balay   PetscFunctionBegin;
858e5c89e4eSSatish Balay   *result = a->current;
8594704e885SBarry Smith   if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);}
8604704e885SBarry Smith   token = a->token;
86190fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
862e5c89e4eSSatish Balay   while (ptr) {
8634704e885SBarry Smith     if (*ptr == token) {
864e5c89e4eSSatish Balay       *ptr++ = 0;
865e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
866e5c89e4eSSatish Balay       a->current = ptr;
867e5c89e4eSSatish Balay       break;
868e5c89e4eSSatish Balay     }
869e5c89e4eSSatish Balay     if (!*ptr) {
870e5c89e4eSSatish Balay       a->current = 0;
871e5c89e4eSSatish Balay       break;
872e5c89e4eSSatish Balay     }
873e5c89e4eSSatish Balay     ptr++;
874e5c89e4eSSatish Balay   }
875e5c89e4eSSatish Balay   PetscFunctionReturn(0);
876e5c89e4eSSatish Balay }
877e5c89e4eSSatish Balay 
878e5c89e4eSSatish Balay #undef __FUNCT__
879e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenCreate"
880e5c89e4eSSatish Balay /*@C
881e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
882e5c89e4eSSatish Balay 
883e5c89e4eSSatish Balay    Not Collective
884e5c89e4eSSatish Balay 
885e5c89e4eSSatish Balay    Input Parameters:
886e5c89e4eSSatish Balay +  string - the string to look in
887e5c89e4eSSatish Balay -  token - the character to look for
888e5c89e4eSSatish Balay 
889e5c89e4eSSatish Balay    Output Parameter:
890e5c89e4eSSatish Balay .  a - pointer to token
891e5c89e4eSSatish Balay 
892e5c89e4eSSatish Balay    Notes:
893e5c89e4eSSatish Balay 
894e5c89e4eSSatish Balay      This version is different from the system version in that
895e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
896e5c89e4eSSatish Balay 
8976f013253SBarry Smith     Not for use in Fortran
8986f013253SBarry Smith 
899e5c89e4eSSatish Balay    Level: intermediate
900e5c89e4eSSatish Balay 
901e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
902e5c89e4eSSatish Balay @*/
9037087cfbeSBarry Smith PetscErrorCode  PetscTokenCreate(const char a[],const char b,PetscToken *t)
904e5c89e4eSSatish Balay {
905e5c89e4eSSatish Balay   PetscErrorCode ierr;
906e5c89e4eSSatish Balay 
907e5c89e4eSSatish Balay   PetscFunctionBegin;
9081d1a0024SBarry Smith   ierr = PetscNew(struct _p_PetscToken,t);CHKERRQ(ierr);
909e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
910a297a907SKarl Rupp 
911e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
912e5c89e4eSSatish Balay   (*t)->token   = b;
913e5c89e4eSSatish Balay   PetscFunctionReturn(0);
914e5c89e4eSSatish Balay }
915e5c89e4eSSatish Balay 
916e5c89e4eSSatish Balay #undef __FUNCT__
917e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenDestroy"
918e5c89e4eSSatish Balay /*@C
919e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
920e5c89e4eSSatish Balay 
921e5c89e4eSSatish Balay    Not Collective
922e5c89e4eSSatish Balay 
923e5c89e4eSSatish Balay    Input Parameters:
924e5c89e4eSSatish Balay .  a - pointer to token
925e5c89e4eSSatish Balay 
926e5c89e4eSSatish Balay    Level: intermediate
927e5c89e4eSSatish Balay 
9286f013253SBarry Smith    Notes:     Not for use in Fortran
9296f013253SBarry Smith 
930e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
931e5c89e4eSSatish Balay @*/
9328c74ee41SBarry Smith PetscErrorCode  PetscTokenDestroy(PetscToken *a)
933e5c89e4eSSatish Balay {
934e5c89e4eSSatish Balay   PetscErrorCode ierr;
935e5c89e4eSSatish Balay 
936e5c89e4eSSatish Balay   PetscFunctionBegin;
9378c74ee41SBarry Smith   if (!*a) PetscFunctionReturn(0);
9388c74ee41SBarry Smith   ierr = PetscFree((*a)->array);CHKERRQ(ierr);
9398c74ee41SBarry Smith   ierr = PetscFree(*a);CHKERRQ(ierr);
940e5c89e4eSSatish Balay   PetscFunctionReturn(0);
941e5c89e4eSSatish Balay }
942e5c89e4eSSatish Balay 
943e5c89e4eSSatish Balay 
944e5c89e4eSSatish Balay #undef __FUNCT__
945e5c89e4eSSatish Balay #define __FUNCT__ "PetscGetPetscDir"
946e5c89e4eSSatish Balay /*@C
947e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
948e5c89e4eSSatish Balay 
949e5c89e4eSSatish Balay    Not Collective
950e5c89e4eSSatish Balay 
951e5c89e4eSSatish Balay    Output Parameter:
952e5c89e4eSSatish Balay .  dir - the directory
953e5c89e4eSSatish Balay 
954e5c89e4eSSatish Balay    Level: developer
955e5c89e4eSSatish Balay 
9566f013253SBarry Smith    Notes: Not for use in Fortran
9576f013253SBarry Smith 
958e5c89e4eSSatish Balay @*/
9597087cfbeSBarry Smith PetscErrorCode  PetscGetPetscDir(const char *dir[])
960e5c89e4eSSatish Balay {
961e5c89e4eSSatish Balay   PetscFunctionBegin;
962e5c89e4eSSatish Balay   *dir = PETSC_DIR;
963e5c89e4eSSatish Balay   PetscFunctionReturn(0);
964e5c89e4eSSatish Balay }
965e5c89e4eSSatish Balay 
966e5c89e4eSSatish Balay #undef __FUNCT__
967e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrreplace"
968e5c89e4eSSatish Balay /*@C
969e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
970e5c89e4eSSatish Balay 
971e5c89e4eSSatish Balay    Not Collective
972e5c89e4eSSatish Balay 
973e5c89e4eSSatish Balay    Input Parameters:
974e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
97571573d7dSBarry Smith .   aa - the string to look in
976d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
977e5c89e4eSSatish Balay -   len - the length of b
978e5c89e4eSSatish Balay 
979e5c89e4eSSatish Balay    Notes:
980e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
981d5649816SBarry Smith       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
982e5c89e4eSSatish Balay       as well as any environmental variables.
983e5c89e4eSSatish Balay 
9846f013253SBarry Smith       PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
985acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
986acc6cc86SBarry Smith 
9876f013253SBarry Smith       Not for use in Fortran
9886f013253SBarry Smith 
989e5c89e4eSSatish Balay    Level: intermediate
990e5c89e4eSSatish Balay 
991e5c89e4eSSatish Balay @*/
9927087cfbeSBarry Smith PetscErrorCode  PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
993e5c89e4eSSatish Balay {
994e5c89e4eSSatish Balay   PetscErrorCode ierr;
995e5c89e4eSSatish Balay   int            i = 0;
996e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
99771573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
998d5649816SBarry Smith   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0};
999d5649816SBarry Smith   const char     *r[] = {0,0,0,0,0,0,0,0,0};
1000ace3abfcSBarry Smith   PetscBool      flag;
1001e5c89e4eSSatish Balay 
1002e5c89e4eSSatish Balay   PetscFunctionBegin;
1003e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
100471573d7dSBarry Smith   if (aa == b) {
100522982a5fSBarry Smith     ierr = PetscStrallocpy(aa,(char**)&a);CHKERRQ(ierr);
100671573d7dSBarry Smith   }
1007e5c89e4eSSatish Balay   ierr = PetscMalloc(len*sizeof(char*),&work);CHKERRQ(ierr);
1008e5c89e4eSSatish Balay 
1009e5c89e4eSSatish Balay   /* get values for replaced variables */
1010487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr);
1011487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr);
1012487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr);
1013487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[3]);CHKERRQ(ierr);
1014487e5849SBarry Smith   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[4]);CHKERRQ(ierr);
1015e5c89e4eSSatish Balay   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[5]);CHKERRQ(ierr);
1016487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[6]);CHKERRQ(ierr);
1017d5649816SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[7]);CHKERRQ(ierr);
1018487e5849SBarry Smith   ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr);
1019487e5849SBarry Smith   ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1020487e5849SBarry Smith   ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1021487e5849SBarry Smith   ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr);
1022d5649816SBarry Smith   ierr = PetscGetHostName((char*)r[7],256);CHKERRQ(ierr);
1023487e5849SBarry Smith 
1024487e5849SBarry Smith   /* replace that are in environment */
1025487e5849SBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr);
1026487e5849SBarry Smith   if (flag) {
1027487e5849SBarry Smith     ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr);
1028487e5849SBarry Smith   }
1029e5c89e4eSSatish Balay 
1030e5c89e4eSSatish Balay   /* replace the requested strings */
1031e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
1032e5c89e4eSSatish Balay   while (s[i]) {
1033e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
1034e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1035e5c89e4eSSatish Balay     while (par) {
1036e5c89e4eSSatish Balay       *par =  0;
1037e5c89e4eSSatish Balay       par += l;
1038e5c89e4eSSatish Balay 
1039e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
1040e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
1041e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
104217186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
1043e5c89e4eSSatish Balay       ierr = PetscStrcpy(work,b);CHKERRQ(ierr);
1044e5c89e4eSSatish Balay       ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr);
1045e5c89e4eSSatish Balay       ierr = PetscStrcat(work,par);CHKERRQ(ierr);
1046e5c89e4eSSatish Balay       ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr);
1047e5c89e4eSSatish Balay       ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1048e5c89e4eSSatish Balay     }
1049e5c89e4eSSatish Balay     i++;
1050e5c89e4eSSatish Balay   }
1051487e5849SBarry Smith   i = 0;
1052487e5849SBarry Smith   while (r[i]) {
1053e5c89e4eSSatish Balay     tfree = (char*)r[i];
1054e5c89e4eSSatish Balay     ierr  = PetscFree(tfree);CHKERRQ(ierr);
1055487e5849SBarry Smith     i++;
1056e5c89e4eSSatish Balay   }
1057e5c89e4eSSatish Balay 
1058e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
1059e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1060e5c89e4eSSatish Balay   while (par) {
1061e5c89e4eSSatish Balay     *par  = 0;
1062e5c89e4eSSatish Balay     par  += 2;
1063e5c89e4eSSatish Balay     ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
1064e5c89e4eSSatish Balay     ierr  = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
1065e5c89e4eSSatish Balay     *epar = 0;
1066e5c89e4eSSatish Balay     epar += 1;
1067e5c89e4eSSatish Balay     ierr  = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr);
10687ba3a57cSBarry Smith     if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
1069e5c89e4eSSatish Balay     ierr = PetscStrcat(work,env);CHKERRQ(ierr);
1070e5c89e4eSSatish Balay     ierr = PetscStrcat(work,epar);CHKERRQ(ierr);
1071e5c89e4eSSatish Balay     ierr = PetscStrcpy(b,work);CHKERRQ(ierr);
1072e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1073e5c89e4eSSatish Balay   }
1074e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
107571573d7dSBarry Smith   if (aa == b) {
107671573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
107771573d7dSBarry Smith   }
1078e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1079e5c89e4eSSatish Balay }
1080e5c89e4eSSatish Balay 
1081e5c89e4eSSatish Balay 
1082