xref: /petsc/src/sys/utils/str.c (revision 2c9581d29997335d805cf04b9d7ec09e8f4441b2)
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
25d67fe73bSBarry 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 @*/
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   }
62301d30feSBarry 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   }
78301d30feSBarry Smith   (*args)[*argc] = 0;
793c311c98SBarry Smith 
803c311c98SBarry Smith   *argc = 0;
813c311c98SBarry Smith   for (i=0; i<n; i++) {
82d67fe73bSBarry Smith     if (s[i] != sp) break;
833c311c98SBarry Smith   }
843c311c98SBarry Smith   for (;i<n+1; i++) {
85d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
86d67fe73bSBarry Smith     else if (s[i] != sp && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;}
873c311c98SBarry Smith   }
883c311c98SBarry Smith   return 0;
893c311c98SBarry Smith }
903c311c98SBarry Smith 
913c311c98SBarry Smith #undef __FUNCT__
92301d30feSBarry Smith #define __FUNCT__ "PetscStrToArrayDestroy"
93301d30feSBarry Smith /*@C
94301d30feSBarry Smith    PetscStrToArrayDestroy - Frees array created with PetscStrToArray().
95301d30feSBarry Smith 
96301d30feSBarry Smith    Not Collective
97301d30feSBarry Smith 
98301d30feSBarry Smith    Output Parameters:
99301d30feSBarry Smith +  argc - the number of arguments
100301d30feSBarry Smith -  args - the array of arguments
101301d30feSBarry Smith 
102301d30feSBarry Smith    Level: intermediate
103301d30feSBarry Smith 
104301d30feSBarry Smith    Concepts: command line arguments
105301d30feSBarry Smith 
106301d30feSBarry Smith    Notes: This may be called before PetscInitialize() or after PetscFinalize()
107301d30feSBarry Smith 
1086f013253SBarry Smith    Not for use in Fortran
1096f013253SBarry Smith 
110301d30feSBarry Smith .seealso: PetscStrToArray()
111301d30feSBarry Smith 
112301d30feSBarry Smith @*/
1137087cfbeSBarry Smith PetscErrorCode  PetscStrToArrayDestroy(int argc,char **args)
114301d30feSBarry Smith {
115301d30feSBarry Smith   PetscInt i;
116301d30feSBarry Smith 
117301d30feSBarry Smith   for (i=0; i<argc; i++) {
118301d30feSBarry Smith     free(args[i]);
119301d30feSBarry Smith   }
1204996c5bdSBarry Smith   if (args) {
121301d30feSBarry Smith     free(args);
1224996c5bdSBarry Smith   }
123301d30feSBarry Smith   return 0;
124301d30feSBarry Smith }
125301d30feSBarry Smith 
126301d30feSBarry Smith #undef __FUNCT__
127e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrlen"
128e5c89e4eSSatish Balay /*@C
129e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
130e5c89e4eSSatish Balay 
131e5c89e4eSSatish Balay    Not Collective
132e5c89e4eSSatish Balay 
133e5c89e4eSSatish Balay    Input Parameters:
134e5c89e4eSSatish Balay .  s - pointer to string
135e5c89e4eSSatish Balay 
136e5c89e4eSSatish Balay    Output Parameter:
137e5c89e4eSSatish Balay .  len - length in bytes
138e5c89e4eSSatish Balay 
139e5c89e4eSSatish Balay    Level: intermediate
140e5c89e4eSSatish Balay 
141e5c89e4eSSatish Balay    Note:
142e5c89e4eSSatish Balay    This routine is analogous to strlen().
143e5c89e4eSSatish Balay 
144e5c89e4eSSatish Balay    Null string returns a length of zero
145e5c89e4eSSatish Balay 
1466f013253SBarry Smith    Not for use in Fortran
1476f013253SBarry Smith 
148e5c89e4eSSatish Balay   Concepts: string length
149e5c89e4eSSatish Balay 
150e5c89e4eSSatish Balay @*/
1517087cfbeSBarry Smith PetscErrorCode  PetscStrlen(const char s[],size_t *len)
152e5c89e4eSSatish Balay {
153e5c89e4eSSatish Balay   PetscFunctionBegin;
154e5c89e4eSSatish Balay   if (!s) {
155e5c89e4eSSatish Balay     *len = 0;
156e5c89e4eSSatish Balay   } else {
157e5c89e4eSSatish Balay     *len = strlen(s);
158e5c89e4eSSatish Balay   }
159e5c89e4eSSatish Balay   PetscFunctionReturn(0);
160e5c89e4eSSatish Balay }
161e5c89e4eSSatish Balay 
162e5c89e4eSSatish Balay #undef __FUNCT__
163e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrallocpy"
164e5c89e4eSSatish Balay /*@C
165e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
166e5c89e4eSSatish Balay 
167e5c89e4eSSatish Balay    Not Collective
168e5c89e4eSSatish Balay 
169e5c89e4eSSatish Balay    Input Parameters:
170e5c89e4eSSatish Balay .  s - pointer to string
171e5c89e4eSSatish Balay 
172e5c89e4eSSatish Balay    Output Parameter:
173e5c89e4eSSatish Balay .  t - the copied string
174e5c89e4eSSatish Balay 
175e5c89e4eSSatish Balay    Level: intermediate
176e5c89e4eSSatish Balay 
177e5c89e4eSSatish Balay    Note:
178e5c89e4eSSatish Balay       Null string returns a new null string
179e5c89e4eSSatish Balay 
1806f013253SBarry Smith       Not for use in Fortran
1816f013253SBarry Smith 
182e5c89e4eSSatish Balay   Concepts: string copy
183e5c89e4eSSatish Balay 
184e5c89e4eSSatish Balay @*/
1857087cfbeSBarry Smith PetscErrorCode  PetscStrallocpy(const char s[],char *t[])
186e5c89e4eSSatish Balay {
187e5c89e4eSSatish Balay   PetscErrorCode ierr;
188e5c89e4eSSatish Balay   size_t         len;
18971573d7dSBarry Smith   char           *tmp = 0;
190e5c89e4eSSatish Balay 
191e5c89e4eSSatish Balay   PetscFunctionBegin;
192e5c89e4eSSatish Balay   if (s) {
193e5c89e4eSSatish Balay     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
19471573d7dSBarry Smith     ierr = PetscMalloc((1+len)*sizeof(char),&tmp);CHKERRQ(ierr);
19571573d7dSBarry Smith     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
196e5c89e4eSSatish Balay   }
19771573d7dSBarry Smith   *t = tmp;
198e5c89e4eSSatish Balay   PetscFunctionReturn(0);
199e5c89e4eSSatish Balay }
200e5c89e4eSSatish Balay 
201e5c89e4eSSatish Balay #undef __FUNCT__
20247340559SBarry Smith #define __FUNCT__ "PetscStrArrayallocpy"
20347340559SBarry Smith /*@C
20447340559SBarry Smith    PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
20547340559SBarry Smith 
20647340559SBarry Smith    Not Collective
20747340559SBarry Smith 
20847340559SBarry Smith    Input Parameters:
20947340559SBarry Smith .  s - pointer to array of strings (final string is a null)
21047340559SBarry Smith 
21147340559SBarry Smith    Output Parameter:
21247340559SBarry Smith .  t - the copied array string
21347340559SBarry Smith 
21447340559SBarry Smith    Level: intermediate
21547340559SBarry Smith 
21647340559SBarry Smith    Note:
21747340559SBarry Smith       Not for use in Fortran
21847340559SBarry Smith 
21947340559SBarry Smith   Concepts: string copy
22047340559SBarry Smith 
22147340559SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
22247340559SBarry Smith 
22347340559SBarry Smith @*/
22447340559SBarry Smith PetscErrorCode  PetscStrArrayallocpy(const char *const*list,char ***t)
22547340559SBarry Smith {
22647340559SBarry Smith   PetscErrorCode ierr;
22747340559SBarry Smith   PetscInt       i,n = 0;
22847340559SBarry Smith 
22947340559SBarry Smith   PetscFunctionBegin;
23047340559SBarry Smith   while (list[n++]) ;
23147340559SBarry Smith   ierr = PetscMalloc((n+1)*sizeof(char**),t);CHKERRQ(ierr);
23247340559SBarry Smith   for (i=0; i<n; i++) {
23347340559SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
23447340559SBarry Smith   }
23547340559SBarry Smith   (*t)[n] = PETSC_NULL;
23647340559SBarry Smith   PetscFunctionReturn(0);
23747340559SBarry Smith }
23847340559SBarry Smith 
23947340559SBarry Smith #undef __FUNCT__
24047340559SBarry Smith #define __FUNCT__ "PetscStrArrayDestroy"
24147340559SBarry Smith /*@C
24247340559SBarry Smith    PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
24347340559SBarry Smith 
24447340559SBarry Smith    Not Collective
24547340559SBarry Smith 
24647340559SBarry Smith    Output Parameters:
24747340559SBarry Smith .   list - array of strings
24847340559SBarry Smith 
24947340559SBarry Smith    Level: intermediate
25047340559SBarry Smith 
25147340559SBarry Smith    Concepts: command line arguments
25247340559SBarry Smith 
25347340559SBarry Smith    Notes: Not for use in Fortran
25447340559SBarry Smith 
25547340559SBarry Smith .seealso: PetscStrArrayallocpy()
25647340559SBarry Smith 
25747340559SBarry Smith @*/
2586fed8037SJed Brown PetscErrorCode PetscStrArrayDestroy(char ***list)
25947340559SBarry Smith {
26047340559SBarry Smith   PetscInt       n = 0;
26147340559SBarry Smith   PetscErrorCode ierr;
26247340559SBarry Smith 
2636fed8037SJed Brown   PetscFunctionBegin;
2646fed8037SJed Brown   if (!*list) PetscFunctionReturn(0);
2656fed8037SJed Brown   while ((*list)[n]) {
2666fed8037SJed Brown     ierr = PetscFree((*list)[n]);CHKERRQ(ierr);
26747340559SBarry Smith     n++;
26847340559SBarry Smith   }
2696fed8037SJed Brown   ierr = PetscFree(*list);CHKERRQ(ierr);
2706fed8037SJed Brown   PetscFunctionReturn(0);
27147340559SBarry Smith }
27247340559SBarry Smith 
27347340559SBarry Smith #undef __FUNCT__
274e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcpy"
275e5c89e4eSSatish Balay /*@C
276e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
277e5c89e4eSSatish Balay 
278e5c89e4eSSatish Balay    Not Collective
279e5c89e4eSSatish Balay 
280e5c89e4eSSatish Balay    Input Parameters:
281e5c89e4eSSatish Balay .  t - pointer to string
282e5c89e4eSSatish Balay 
283e5c89e4eSSatish Balay    Output Parameter:
284e5c89e4eSSatish Balay .  s - the copied string
285e5c89e4eSSatish Balay 
286e5c89e4eSSatish Balay    Level: intermediate
287e5c89e4eSSatish Balay 
2886f013253SBarry Smith    Notes:
289e5c89e4eSSatish Balay      Null string returns a string starting with zero
290e5c89e4eSSatish Balay 
2916f013253SBarry Smith      Not for use in Fortran
2926f013253SBarry Smith 
293e5c89e4eSSatish Balay   Concepts: string copy
294e5c89e4eSSatish Balay 
295e5c89e4eSSatish Balay .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat()
296e5c89e4eSSatish Balay 
297e5c89e4eSSatish Balay @*/
298acc6cc86SBarry Smith 
2997087cfbeSBarry Smith PetscErrorCode  PetscStrcpy(char s[],const char t[])
300e5c89e4eSSatish Balay {
301e5c89e4eSSatish Balay   PetscFunctionBegin;
30217186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
303e5c89e4eSSatish Balay   if (t) {strcpy(s,t);}
304e5c89e4eSSatish Balay   else if (s) {s[0] = 0;}
305e5c89e4eSSatish Balay   PetscFunctionReturn(0);
306e5c89e4eSSatish Balay }
307e5c89e4eSSatish Balay 
308e5c89e4eSSatish Balay #undef __FUNCT__
309e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncpy"
310e5c89e4eSSatish Balay /*@C
311e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
312e5c89e4eSSatish Balay 
313e5c89e4eSSatish Balay    Not Collective
314e5c89e4eSSatish Balay 
315e5c89e4eSSatish Balay    Input Parameters:
316e5c89e4eSSatish Balay +  t - pointer to string
317e5c89e4eSSatish Balay -  n - the length to copy
318e5c89e4eSSatish Balay 
319e5c89e4eSSatish Balay    Output Parameter:
320e5c89e4eSSatish Balay .  s - the copied string
321e5c89e4eSSatish Balay 
322e5c89e4eSSatish Balay    Level: intermediate
323e5c89e4eSSatish Balay 
324e5c89e4eSSatish Balay    Note:
325e5c89e4eSSatish Balay      Null string returns a string starting with zero
326e5c89e4eSSatish Balay 
327e5c89e4eSSatish Balay   Concepts: string copy
328e5c89e4eSSatish Balay 
329e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat()
330e5c89e4eSSatish Balay 
331e5c89e4eSSatish Balay @*/
3327087cfbeSBarry Smith PetscErrorCode  PetscStrncpy(char s[],const char t[],size_t n)
333e5c89e4eSSatish Balay {
334e5c89e4eSSatish Balay   PetscFunctionBegin;
33517186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
336e5c89e4eSSatish Balay   if (t) {strncpy(s,t,n);}
337e5c89e4eSSatish Balay   else if (s) {s[0] = 0;}
338e5c89e4eSSatish Balay   PetscFunctionReturn(0);
339e5c89e4eSSatish Balay }
340e5c89e4eSSatish Balay 
341e5c89e4eSSatish Balay #undef __FUNCT__
342e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcat"
343e5c89e4eSSatish Balay /*@C
344e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
345e5c89e4eSSatish Balay 
346e5c89e4eSSatish Balay    Not Collective
347e5c89e4eSSatish Balay 
348e5c89e4eSSatish Balay    Input Parameters:
349e5e2177aSMatthew Knepley +  s - string to be added to
350e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
351e5c89e4eSSatish Balay 
352e5c89e4eSSatish Balay    Level: intermediate
353e5c89e4eSSatish Balay 
3546f013253SBarry Smith    Notes: Not for use in Fortran
3556f013253SBarry Smith 
356e5c89e4eSSatish Balay   Concepts: string copy
357e5c89e4eSSatish Balay 
358e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat()
359e5c89e4eSSatish Balay 
360e5c89e4eSSatish Balay @*/
3617087cfbeSBarry Smith PetscErrorCode  PetscStrcat(char s[],const char t[])
362e5c89e4eSSatish Balay {
363e5c89e4eSSatish Balay   PetscFunctionBegin;
3649b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
365e5c89e4eSSatish Balay   strcat(s,t);
366e5c89e4eSSatish Balay   PetscFunctionReturn(0);
367e5c89e4eSSatish Balay }
368e5c89e4eSSatish Balay 
369e5c89e4eSSatish Balay #undef __FUNCT__
370e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncat"
371e5c89e4eSSatish Balay /*@C
372e5c89e4eSSatish Balay    PetscStrncat - Concatenates a string onto a given string, up to a given length
373e5c89e4eSSatish Balay 
374e5c89e4eSSatish Balay    Not Collective
375e5c89e4eSSatish Balay 
376e5c89e4eSSatish Balay    Input Parameters:
377e5c89e4eSSatish Balay +  s - pointer to string to be added to end
378e5c89e4eSSatish Balay .  t - string to be added to
379e5c89e4eSSatish Balay .  n - maximum length to copy
380e5c89e4eSSatish Balay 
381e5c89e4eSSatish Balay    Level: intermediate
382e5c89e4eSSatish Balay 
3836f013253SBarry Smith   Notes:    Not for use in Fortran
3846f013253SBarry Smith 
385e5c89e4eSSatish Balay   Concepts: string copy
386e5c89e4eSSatish Balay 
387e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
388e5c89e4eSSatish Balay 
389e5c89e4eSSatish Balay @*/
3907087cfbeSBarry Smith PetscErrorCode  PetscStrncat(char s[],const char t[],size_t n)
391e5c89e4eSSatish Balay {
392e5c89e4eSSatish Balay   PetscFunctionBegin;
393e5c89e4eSSatish Balay   strncat(s,t,n);
394e5c89e4eSSatish Balay   PetscFunctionReturn(0);
395e5c89e4eSSatish Balay }
396e5c89e4eSSatish Balay 
397e5c89e4eSSatish Balay #undef __FUNCT__
398e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcmp"
399e5c89e4eSSatish Balay /*@C
400e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
401e5c89e4eSSatish Balay 
402e5c89e4eSSatish Balay    Not Collective
403e5c89e4eSSatish Balay 
404e5c89e4eSSatish Balay    Input Parameters:
405e5c89e4eSSatish Balay +  a - pointer to string first string
406e5c89e4eSSatish Balay -  b - pointer to second string
407e5c89e4eSSatish Balay 
408e5c89e4eSSatish Balay    Output Parameter:
4098c74ee41SBarry Smith .  flg - PETSC_TRUE if the two strings are equal
410e5c89e4eSSatish Balay 
411e5c89e4eSSatish Balay    Level: intermediate
412e5c89e4eSSatish Balay 
4136f013253SBarry Smith    Notes:    Not for use in Fortran
4146f013253SBarry Smith 
415e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
416e5c89e4eSSatish Balay 
417e5c89e4eSSatish Balay @*/
4187087cfbeSBarry Smith PetscErrorCode  PetscStrcmp(const char a[],const char b[],PetscBool  *flg)
419e5c89e4eSSatish Balay {
420e5c89e4eSSatish Balay   int c;
421e5c89e4eSSatish Balay 
422e5c89e4eSSatish Balay   PetscFunctionBegin;
423e5c89e4eSSatish Balay   if (!a && !b) {
424e5c89e4eSSatish Balay     *flg = PETSC_TRUE;
425e5c89e4eSSatish Balay   } else if (!a || !b) {
426e5c89e4eSSatish Balay     *flg = PETSC_FALSE;
427e5c89e4eSSatish Balay   } else {
428e5c89e4eSSatish Balay     c = strcmp(a,b);
429e5c89e4eSSatish Balay     if (c) *flg = PETSC_FALSE;
430e5c89e4eSSatish Balay     else   *flg = PETSC_TRUE;
431e5c89e4eSSatish Balay   }
432e5c89e4eSSatish Balay   PetscFunctionReturn(0);
433e5c89e4eSSatish Balay }
434e5c89e4eSSatish Balay 
435e5c89e4eSSatish Balay #undef __FUNCT__
436e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrgrt"
437e5c89e4eSSatish Balay /*@C
438e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
439e5c89e4eSSatish Balay 
440e5c89e4eSSatish Balay    Not Collective
441e5c89e4eSSatish Balay 
442e5c89e4eSSatish Balay    Input Parameters:
443e5c89e4eSSatish Balay +  a - pointer to first string
444e5c89e4eSSatish Balay -  b - pointer to second string
445e5c89e4eSSatish Balay 
446e5c89e4eSSatish Balay    Output Parameter:
447e5c89e4eSSatish Balay .  flg - if the first string is greater
448e5c89e4eSSatish Balay 
449e5c89e4eSSatish Balay    Notes:
450e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
451e5c89e4eSSatish Balay     all others
452e5c89e4eSSatish Balay 
4536f013253SBarry Smith    Not for use in Fortran
4546f013253SBarry Smith 
455e5c89e4eSSatish Balay    Level: intermediate
456e5c89e4eSSatish Balay 
457e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
458e5c89e4eSSatish Balay 
459e5c89e4eSSatish Balay @*/
4607087cfbeSBarry Smith PetscErrorCode  PetscStrgrt(const char a[],const char b[],PetscBool  *t)
461e5c89e4eSSatish Balay {
462e5c89e4eSSatish Balay   int c;
463e5c89e4eSSatish Balay 
464e5c89e4eSSatish Balay   PetscFunctionBegin;
465e5c89e4eSSatish Balay   if (!a && !b) {
466e5c89e4eSSatish Balay     *t = PETSC_FALSE;
467e5c89e4eSSatish Balay   } else if (a && !b) {
468e5c89e4eSSatish Balay     *t = PETSC_TRUE;
469e5c89e4eSSatish Balay   } else if (!a && b) {
470e5c89e4eSSatish Balay     *t = PETSC_FALSE;
471e5c89e4eSSatish Balay   } else {
472e5c89e4eSSatish Balay     c = strcmp(a,b);
473e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
474e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
475e5c89e4eSSatish Balay   }
476e5c89e4eSSatish Balay   PetscFunctionReturn(0);
477e5c89e4eSSatish Balay }
478e5c89e4eSSatish Balay 
479e5c89e4eSSatish Balay #undef __FUNCT__
480e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcasecmp"
481e5c89e4eSSatish Balay /*@C
482e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
483e5c89e4eSSatish Balay      except possibly for case.
484e5c89e4eSSatish Balay 
485e5c89e4eSSatish Balay    Not Collective
486e5c89e4eSSatish Balay 
487e5c89e4eSSatish Balay    Input Parameters:
488e5c89e4eSSatish Balay +  a - pointer to first string
489e5c89e4eSSatish Balay -  b - pointer to second string
490e5c89e4eSSatish Balay 
491e5c89e4eSSatish Balay    Output Parameter:
492e5c89e4eSSatish Balay .  flg - if the two strings are the same
493e5c89e4eSSatish Balay 
494e5c89e4eSSatish Balay    Notes:
495e5c89e4eSSatish Balay     Null arguments are ok
496e5c89e4eSSatish Balay 
4976f013253SBarry Smith    Not for use in Fortran
4986f013253SBarry Smith 
499e5c89e4eSSatish Balay    Level: intermediate
500e5c89e4eSSatish Balay 
501e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
502e5c89e4eSSatish Balay 
503e5c89e4eSSatish Balay @*/
5047087cfbeSBarry Smith PetscErrorCode  PetscStrcasecmp(const char a[],const char b[],PetscBool  *t)
505e5c89e4eSSatish Balay {
506e5c89e4eSSatish Balay   int c;
507e5c89e4eSSatish Balay 
508e5c89e4eSSatish Balay   PetscFunctionBegin;
509e5c89e4eSSatish Balay   if (!a && !b) c = 0;
510e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
51132b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
51232b366c8SSatish Balay   else c = strcasecmp(a,b);
51332b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
514e5c89e4eSSatish Balay   else c = stricmp(a,b);
515e5c89e4eSSatish Balay #else
51632b366c8SSatish Balay   else {
51732b366c8SSatish Balay     char           *aa,*bb;
51832b366c8SSatish Balay     PetscErrorCode ierr;
51932b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
52032b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
52132b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
52232b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
52332b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
524503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
525503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
52632b366c8SSatish Balay     PetscFunctionReturn(0);
52732b366c8SSatish Balay   }
528e5c89e4eSSatish Balay #endif
529e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
530e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
531e5c89e4eSSatish Balay   PetscFunctionReturn(0);
532e5c89e4eSSatish Balay }
533e5c89e4eSSatish Balay 
53432b366c8SSatish Balay 
53532b366c8SSatish Balay 
536e5c89e4eSSatish Balay #undef __FUNCT__
537e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncmp"
538e5c89e4eSSatish Balay /*@C
539e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
540e5c89e4eSSatish Balay 
541e5c89e4eSSatish Balay    Not Collective
542e5c89e4eSSatish Balay 
543e5c89e4eSSatish Balay    Input Parameters:
544e5c89e4eSSatish Balay +  a - pointer to first string
545e5c89e4eSSatish Balay .  b - pointer to second string
546e5c89e4eSSatish Balay -  n - length to compare up to
547e5c89e4eSSatish Balay 
548e5c89e4eSSatish Balay    Output Parameter:
549e5c89e4eSSatish Balay .  t - if the two strings are equal
550e5c89e4eSSatish Balay 
551e5c89e4eSSatish Balay    Level: intermediate
552e5c89e4eSSatish Balay 
5536f013253SBarry Smith    Notes:    Not for use in Fortran
5546f013253SBarry Smith 
555e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
556e5c89e4eSSatish Balay 
557e5c89e4eSSatish Balay @*/
5587087cfbeSBarry Smith PetscErrorCode  PetscStrncmp(const char a[],const char b[],size_t n,PetscBool  *t)
559e5c89e4eSSatish Balay {
560e5c89e4eSSatish Balay   int c;
561e5c89e4eSSatish Balay 
562e5c89e4eSSatish Balay   PetscFunctionBegin;
563e5c89e4eSSatish Balay   c = strncmp(a,b,n);
564e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
565e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
566e5c89e4eSSatish Balay   PetscFunctionReturn(0);
567e5c89e4eSSatish Balay }
568e5c89e4eSSatish Balay 
569e5c89e4eSSatish Balay #undef __FUNCT__
570e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrchr"
571e5c89e4eSSatish Balay /*@C
572e5c89e4eSSatish Balay    PetscStrchr - Locates first occurance of a character in a string
573e5c89e4eSSatish Balay 
574e5c89e4eSSatish Balay    Not Collective
575e5c89e4eSSatish Balay 
576e5c89e4eSSatish Balay    Input Parameters:
577e5c89e4eSSatish Balay +  a - pointer to string
578e5c89e4eSSatish Balay -  b - character
579e5c89e4eSSatish Balay 
580e5c89e4eSSatish Balay    Output Parameter:
581e5c89e4eSSatish Balay .  c - location of occurance, PETSC_NULL if not found
582e5c89e4eSSatish Balay 
583e5c89e4eSSatish Balay    Level: intermediate
584e5c89e4eSSatish Balay 
5856f013253SBarry Smith    Notes:    Not for use in Fortran
5866f013253SBarry Smith 
587e5c89e4eSSatish Balay @*/
5887087cfbeSBarry Smith PetscErrorCode  PetscStrchr(const char a[],char b,char *c[])
589e5c89e4eSSatish Balay {
590e5c89e4eSSatish Balay   PetscFunctionBegin;
591e5c89e4eSSatish Balay   *c = (char *)strchr(a,b);
592e5c89e4eSSatish Balay   PetscFunctionReturn(0);
593e5c89e4eSSatish Balay }
594e5c89e4eSSatish Balay 
595e5c89e4eSSatish Balay #undef __FUNCT__
596e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrrchr"
597e5c89e4eSSatish Balay /*@C
598e5c89e4eSSatish Balay    PetscStrrchr - Locates one location past the last occurance of a character in a string,
599e5c89e4eSSatish Balay       if the character is not found then returns entire string
600e5c89e4eSSatish Balay 
601e5c89e4eSSatish Balay    Not Collective
602e5c89e4eSSatish Balay 
603e5c89e4eSSatish Balay    Input Parameters:
604e5c89e4eSSatish Balay +  a - pointer to string
605e5c89e4eSSatish Balay -  b - character
606e5c89e4eSSatish Balay 
607e5c89e4eSSatish Balay    Output Parameter:
608e5c89e4eSSatish Balay .  tmp - location of occurance, a if not found
609e5c89e4eSSatish Balay 
610e5c89e4eSSatish Balay    Level: intermediate
611e5c89e4eSSatish Balay 
6126f013253SBarry Smith    Notes:    Not for use in Fortran
6136f013253SBarry Smith 
614e5c89e4eSSatish Balay @*/
6157087cfbeSBarry Smith PetscErrorCode  PetscStrrchr(const char a[],char b,char *tmp[])
616e5c89e4eSSatish Balay {
617e5c89e4eSSatish Balay   PetscFunctionBegin;
618e5c89e4eSSatish Balay   *tmp = (char *)strrchr(a,b);
619e5c89e4eSSatish Balay   if (!*tmp) *tmp = (char*)a; else *tmp = *tmp + 1;
620e5c89e4eSSatish Balay   PetscFunctionReturn(0);
621e5c89e4eSSatish Balay }
622e5c89e4eSSatish Balay 
623e5c89e4eSSatish Balay #undef __FUNCT__
624e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrtolower"
625e5c89e4eSSatish Balay /*@C
626e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
627e5c89e4eSSatish Balay 
628e5c89e4eSSatish Balay    Not Collective
629e5c89e4eSSatish Balay 
630e5c89e4eSSatish Balay    Input Parameters:
631e5c89e4eSSatish Balay .  a - pointer to string
632e5c89e4eSSatish Balay 
633e5c89e4eSSatish Balay    Level: intermediate
634e5c89e4eSSatish Balay 
6356f013253SBarry Smith    Notes:    Not for use in Fortran
6366f013253SBarry Smith 
637e5c89e4eSSatish Balay @*/
6387087cfbeSBarry Smith PetscErrorCode  PetscStrtolower(char a[])
639e5c89e4eSSatish Balay {
640e5c89e4eSSatish Balay   PetscFunctionBegin;
641e5c89e4eSSatish Balay   while (*a) {
642e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
643e5c89e4eSSatish Balay     a++;
644e5c89e4eSSatish Balay   }
645e5c89e4eSSatish Balay   PetscFunctionReturn(0);
646e5c89e4eSSatish Balay }
647e5c89e4eSSatish Balay 
6487ba3a57cSBarry Smith #undef __FUNCT__
6497ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswith"
6507ba3a57cSBarry Smith /*@C
6517ba3a57cSBarry Smith    PetscStrendswith - Determines if a string ends with a certain string
6521d1a0024SBarry Smith 
6537ba3a57cSBarry Smith    Not Collective
6547ba3a57cSBarry Smith 
6557ba3a57cSBarry Smith    Input Parameters:
6567ba3a57cSBarry Smith +  a - pointer to string
6577ba3a57cSBarry Smith -  b - string to endwith
6587ba3a57cSBarry Smith 
6597ba3a57cSBarry Smith    Output Parameter:
6607ba3a57cSBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
6617ba3a57cSBarry Smith 
6627ba3a57cSBarry Smith    Notes:     Not for use in Fortran
6637ba3a57cSBarry Smith 
6647ba3a57cSBarry Smith    Level: intermediate
6657ba3a57cSBarry Smith 
6667ba3a57cSBarry Smith @*/
6677ba3a57cSBarry Smith PetscErrorCode  PetscStrendswith(const char a[],const char b[],PetscBool *flg)
6687ba3a57cSBarry Smith {
6697ba3a57cSBarry Smith   char           *test;
6707ba3a57cSBarry Smith   PetscErrorCode ierr;
6717ba3a57cSBarry Smith   size_t         na,nb;
6727ba3a57cSBarry Smith 
6737ba3a57cSBarry Smith   PetscFunctionBegin;
6747ba3a57cSBarry Smith   *flg = PETSC_FALSE;
6757ba3a57cSBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
6767ba3a57cSBarry Smith   if (test) {
6777ba3a57cSBarry Smith     ierr = PetscStrlen(a,&na);CHKERRQ(ierr);
6787ba3a57cSBarry Smith     ierr = PetscStrlen(b,&nb);CHKERRQ(ierr);
6797ba3a57cSBarry Smith     if (a+na-nb == test) *flg = PETSC_TRUE;
6807ba3a57cSBarry Smith   }
6817ba3a57cSBarry Smith   PetscFunctionReturn(0);
6827ba3a57cSBarry Smith }
6837ba3a57cSBarry Smith 
6847ba3a57cSBarry Smith #undef __FUNCT__
685*2c9581d2SBarry Smith #define __FUNCT__ "PetscStrbeginswith"
686*2c9581d2SBarry Smith /*@C
687*2c9581d2SBarry Smith    PetscStrbeginswith - Determines if a string begins with a certain string
688*2c9581d2SBarry Smith 
689*2c9581d2SBarry Smith    Not Collective
690*2c9581d2SBarry Smith 
691*2c9581d2SBarry Smith    Input Parameters:
692*2c9581d2SBarry Smith +  a - pointer to string
693*2c9581d2SBarry Smith -  b - string to beginwith
694*2c9581d2SBarry Smith 
695*2c9581d2SBarry Smith    Output Parameter:
696*2c9581d2SBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
697*2c9581d2SBarry Smith 
698*2c9581d2SBarry Smith    Notes:     Not for use in Fortran
699*2c9581d2SBarry Smith 
700*2c9581d2SBarry Smith    Level: intermediate
701*2c9581d2SBarry Smith 
702*2c9581d2SBarry Smith @*/
703*2c9581d2SBarry Smith PetscErrorCode  PetscStrbeginswith(const char a[],const char b[],PetscBool *flg)
704*2c9581d2SBarry Smith {
705*2c9581d2SBarry Smith   char           *test;
706*2c9581d2SBarry Smith   PetscErrorCode ierr;
707*2c9581d2SBarry Smith 
708*2c9581d2SBarry Smith   PetscFunctionBegin;
709*2c9581d2SBarry Smith   *flg = PETSC_FALSE;
710*2c9581d2SBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
711*2c9581d2SBarry Smith   if (test && (test == a)) {
712*2c9581d2SBarry Smith     *flg = PETSC_TRUE;
713*2c9581d2SBarry Smith   }
714*2c9581d2SBarry Smith   PetscFunctionReturn(0);
715*2c9581d2SBarry Smith }
716*2c9581d2SBarry Smith 
717*2c9581d2SBarry Smith 
718*2c9581d2SBarry Smith #undef __FUNCT__
7197ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswithwhich"
7207ba3a57cSBarry Smith /*@C
7217ba3a57cSBarry Smith    PetscStrendswithwhich - Determines if a string ends with one of several possible strings
7227ba3a57cSBarry Smith 
7237ba3a57cSBarry Smith    Not Collective
7247ba3a57cSBarry Smith 
7257ba3a57cSBarry Smith    Input Parameters:
7267ba3a57cSBarry Smith +  a - pointer to string
7277ba3a57cSBarry Smith -  bs - strings to endwith (last entry must be null)
7287ba3a57cSBarry Smith 
7297ba3a57cSBarry Smith    Output Parameter:
7307ba3a57cSBarry Smith .  cnt - the index of the string it ends with or 1+the last possible index
7317ba3a57cSBarry Smith 
7327ba3a57cSBarry Smith    Notes:     Not for use in Fortran
7337ba3a57cSBarry Smith 
7347ba3a57cSBarry Smith    Level: intermediate
7357ba3a57cSBarry Smith 
7367ba3a57cSBarry Smith @*/
7377ba3a57cSBarry Smith PetscErrorCode  PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt)
7387ba3a57cSBarry Smith {
7397ba3a57cSBarry Smith   PetscBool      flg;
7407ba3a57cSBarry Smith   PetscErrorCode ierr;
7417ba3a57cSBarry Smith 
7427ba3a57cSBarry Smith   PetscFunctionBegin;
7437ba3a57cSBarry Smith   *cnt = 0;
7447ba3a57cSBarry Smith   while (bs[*cnt]) {
7457ba3a57cSBarry Smith     ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr);
7467ba3a57cSBarry Smith     if (flg) PetscFunctionReturn(0);
7477ba3a57cSBarry Smith     *cnt += 1;
7487ba3a57cSBarry Smith   }
7497ba3a57cSBarry Smith   PetscFunctionReturn(0);
7507ba3a57cSBarry Smith }
7517ba3a57cSBarry Smith 
7527ba3a57cSBarry Smith #undef __FUNCT__
7537ba3a57cSBarry Smith #define __FUNCT__ "PetscStrrstr"
7547ba3a57cSBarry Smith /*@C
7557ba3a57cSBarry Smith    PetscStrrstr - Locates last occurance of string in another string
7567ba3a57cSBarry Smith 
7577ba3a57cSBarry Smith    Not Collective
7587ba3a57cSBarry Smith 
7597ba3a57cSBarry Smith    Input Parameters:
7607ba3a57cSBarry Smith +  a - pointer to string
7617ba3a57cSBarry Smith -  b - string to find
7627ba3a57cSBarry Smith 
7637ba3a57cSBarry Smith    Output Parameter:
7647ba3a57cSBarry Smith .  tmp - location of occurance
7657ba3a57cSBarry Smith 
7667ba3a57cSBarry Smith    Notes:     Not for use in Fortran
7677ba3a57cSBarry Smith 
7687ba3a57cSBarry Smith    Level: intermediate
7697ba3a57cSBarry Smith 
7707ba3a57cSBarry Smith @*/
7717ba3a57cSBarry Smith PetscErrorCode  PetscStrrstr(const char a[],const char b[],char *tmp[])
7727ba3a57cSBarry Smith {
7737ba3a57cSBarry Smith   const char *stmp = a, *ltmp = 0;
7747ba3a57cSBarry Smith 
7757ba3a57cSBarry Smith   PetscFunctionBegin;
7767ba3a57cSBarry Smith   while (stmp) {
7777ba3a57cSBarry Smith     stmp = (char *)strstr(stmp,b);
7787ba3a57cSBarry Smith     if (stmp) {ltmp = stmp;stmp++;}
7797ba3a57cSBarry Smith   }
7807ba3a57cSBarry Smith   *tmp = (char *)ltmp;
7817ba3a57cSBarry Smith   PetscFunctionReturn(0);
7827ba3a57cSBarry Smith }
7837ba3a57cSBarry Smith 
7847ba3a57cSBarry Smith #undef __FUNCT__
7857ba3a57cSBarry Smith #define __FUNCT__ "PetscStrstr"
7867ba3a57cSBarry Smith /*@C
7877ba3a57cSBarry Smith    PetscStrstr - Locates first occurance of string in another string
7887ba3a57cSBarry Smith 
7897ba3a57cSBarry Smith    Not Collective
7907ba3a57cSBarry Smith 
7917ba3a57cSBarry Smith    Input Parameters:
792160f4796SJed Brown +  haystack - string to search
793160f4796SJed Brown -  needle - string to find
7947ba3a57cSBarry Smith 
7957ba3a57cSBarry Smith    Output Parameter:
7967ba3a57cSBarry Smith .  tmp - location of occurance, is a PETSC_NULL if the string is not found
7977ba3a57cSBarry Smith 
7987ba3a57cSBarry Smith    Notes: Not for use in Fortran
7997ba3a57cSBarry Smith 
8007ba3a57cSBarry Smith    Level: intermediate
8017ba3a57cSBarry Smith 
8027ba3a57cSBarry Smith @*/
803160f4796SJed Brown PetscErrorCode  PetscStrstr(const char haystack[],const char needle[],char *tmp[])
8047ba3a57cSBarry Smith {
8057ba3a57cSBarry Smith   PetscFunctionBegin;
806160f4796SJed Brown   *tmp = (char *)strstr(haystack,needle);
8077ba3a57cSBarry Smith   PetscFunctionReturn(0);
8087ba3a57cSBarry Smith }
8097ba3a57cSBarry Smith 
8107ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
8111d1a0024SBarry Smith 
812e5c89e4eSSatish Balay #undef __FUNCT__
813e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenFind"
814e5c89e4eSSatish Balay /*@C
815e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
816e5c89e4eSSatish Balay 
817e5c89e4eSSatish Balay    Not Collective
818e5c89e4eSSatish Balay 
819e5c89e4eSSatish Balay    Input Parameters:
820e5c89e4eSSatish Balay .  a - pointer to token
821e5c89e4eSSatish Balay 
822e5c89e4eSSatish Balay    Output Parameter:
823e5c89e4eSSatish Balay .  result - location of occurance, PETSC_NULL if not found
824e5c89e4eSSatish Balay 
825e5c89e4eSSatish Balay    Notes:
826e5c89e4eSSatish Balay 
827e5c89e4eSSatish Balay      This version is different from the system version in that
828e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
829e5c89e4eSSatish Balay 
8304704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
8314704e885SBarry Smith    as a single token.
8324704e885SBarry Smith 
8336f013253SBarry Smith     Not for use in Fortran
8346f013253SBarry Smith 
835e5c89e4eSSatish Balay    Level: intermediate
836e5c89e4eSSatish Balay 
8376f013253SBarry Smith 
838e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
839e5c89e4eSSatish Balay @*/
8407087cfbeSBarry Smith PetscErrorCode  PetscTokenFind(PetscToken a,char *result[])
841e5c89e4eSSatish Balay {
8424704e885SBarry Smith   char *ptr = a->current,token;
843e5c89e4eSSatish Balay 
844e5c89e4eSSatish Balay   PetscFunctionBegin;
845e5c89e4eSSatish Balay   *result = a->current;
8464704e885SBarry Smith   if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);}
8474704e885SBarry Smith   token = a->token;
84890fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
849e5c89e4eSSatish Balay   while (ptr) {
8504704e885SBarry Smith     if (*ptr == token) {
851e5c89e4eSSatish Balay       *ptr++ = 0;
852e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
853e5c89e4eSSatish Balay       a->current = ptr;
854e5c89e4eSSatish Balay       break;
855e5c89e4eSSatish Balay     }
856e5c89e4eSSatish Balay     if (!*ptr) {
857e5c89e4eSSatish Balay       a->current = 0;
858e5c89e4eSSatish Balay       break;
859e5c89e4eSSatish Balay     }
860e5c89e4eSSatish Balay     ptr++;
861e5c89e4eSSatish Balay   }
862e5c89e4eSSatish Balay   PetscFunctionReturn(0);
863e5c89e4eSSatish Balay }
864e5c89e4eSSatish Balay 
865e5c89e4eSSatish Balay #undef __FUNCT__
866e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenCreate"
867e5c89e4eSSatish Balay /*@C
868e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
869e5c89e4eSSatish Balay 
870e5c89e4eSSatish Balay    Not Collective
871e5c89e4eSSatish Balay 
872e5c89e4eSSatish Balay    Input Parameters:
873e5c89e4eSSatish Balay +  string - the string to look in
874e5c89e4eSSatish Balay -  token - the character to look for
875e5c89e4eSSatish Balay 
876e5c89e4eSSatish Balay    Output Parameter:
877e5c89e4eSSatish Balay .  a - pointer to token
878e5c89e4eSSatish Balay 
879e5c89e4eSSatish Balay    Notes:
880e5c89e4eSSatish Balay 
881e5c89e4eSSatish Balay      This version is different from the system version in that
882e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
883e5c89e4eSSatish Balay 
8846f013253SBarry Smith     Not for use in Fortran
8856f013253SBarry Smith 
886e5c89e4eSSatish Balay    Level: intermediate
887e5c89e4eSSatish Balay 
888e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
889e5c89e4eSSatish Balay @*/
8907087cfbeSBarry Smith PetscErrorCode  PetscTokenCreate(const char a[],const char b,PetscToken *t)
891e5c89e4eSSatish Balay {
892e5c89e4eSSatish Balay   PetscErrorCode ierr;
893e5c89e4eSSatish Balay 
894e5c89e4eSSatish Balay   PetscFunctionBegin;
8951d1a0024SBarry Smith   ierr = PetscNew(struct _p_PetscToken,t);CHKERRQ(ierr);
896e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
897e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
898e5c89e4eSSatish Balay   (*t)->token   = b;
899e5c89e4eSSatish Balay   PetscFunctionReturn(0);
900e5c89e4eSSatish Balay }
901e5c89e4eSSatish Balay 
902e5c89e4eSSatish Balay #undef __FUNCT__
903e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenDestroy"
904e5c89e4eSSatish Balay /*@C
905e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
906e5c89e4eSSatish Balay 
907e5c89e4eSSatish Balay    Not Collective
908e5c89e4eSSatish Balay 
909e5c89e4eSSatish Balay    Input Parameters:
910e5c89e4eSSatish Balay .  a - pointer to token
911e5c89e4eSSatish Balay 
912e5c89e4eSSatish Balay    Level: intermediate
913e5c89e4eSSatish Balay 
9146f013253SBarry Smith    Notes:     Not for use in Fortran
9156f013253SBarry Smith 
916e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
917e5c89e4eSSatish Balay @*/
9188c74ee41SBarry Smith PetscErrorCode  PetscTokenDestroy(PetscToken *a)
919e5c89e4eSSatish Balay {
920e5c89e4eSSatish Balay   PetscErrorCode ierr;
921e5c89e4eSSatish Balay 
922e5c89e4eSSatish Balay   PetscFunctionBegin;
9238c74ee41SBarry Smith   if (!*a) PetscFunctionReturn(0);
9248c74ee41SBarry Smith   ierr = PetscFree((*a)->array);CHKERRQ(ierr);
9258c74ee41SBarry Smith   ierr = PetscFree(*a);CHKERRQ(ierr);
926e5c89e4eSSatish Balay   PetscFunctionReturn(0);
927e5c89e4eSSatish Balay }
928e5c89e4eSSatish Balay 
929e5c89e4eSSatish Balay 
930e5c89e4eSSatish Balay #undef __FUNCT__
931e5c89e4eSSatish Balay #define __FUNCT__ "PetscGetPetscDir"
932e5c89e4eSSatish Balay /*@C
933e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
934e5c89e4eSSatish Balay 
935e5c89e4eSSatish Balay    Not Collective
936e5c89e4eSSatish Balay 
937e5c89e4eSSatish Balay    Output Parameter:
938e5c89e4eSSatish Balay .  dir - the directory
939e5c89e4eSSatish Balay 
940e5c89e4eSSatish Balay    Level: developer
941e5c89e4eSSatish Balay 
9426f013253SBarry Smith    Notes: Not for use in Fortran
9436f013253SBarry Smith 
944e5c89e4eSSatish Balay @*/
9457087cfbeSBarry Smith PetscErrorCode  PetscGetPetscDir(const char *dir[])
946e5c89e4eSSatish Balay {
947e5c89e4eSSatish Balay   PetscFunctionBegin;
948e5c89e4eSSatish Balay   *dir = PETSC_DIR;
949e5c89e4eSSatish Balay   PetscFunctionReturn(0);
950e5c89e4eSSatish Balay }
951e5c89e4eSSatish Balay 
952e5c89e4eSSatish Balay #undef __FUNCT__
953e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrreplace"
954e5c89e4eSSatish Balay /*@C
955e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
956e5c89e4eSSatish Balay 
957e5c89e4eSSatish Balay    Not Collective
958e5c89e4eSSatish Balay 
959e5c89e4eSSatish Balay    Input Parameters:
960e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
96171573d7dSBarry Smith .   aa - the string to look in
962d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
963e5c89e4eSSatish Balay -   len - the length of b
964e5c89e4eSSatish Balay 
965e5c89e4eSSatish Balay    Notes:
966e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
967d5649816SBarry Smith       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
968e5c89e4eSSatish Balay       as well as any environmental variables.
969e5c89e4eSSatish Balay 
9706f013253SBarry Smith       PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
971acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
972acc6cc86SBarry Smith 
9736f013253SBarry Smith       Not for use in Fortran
9746f013253SBarry Smith 
975e5c89e4eSSatish Balay    Level: intermediate
976e5c89e4eSSatish Balay 
977e5c89e4eSSatish Balay @*/
9787087cfbeSBarry Smith PetscErrorCode  PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
979e5c89e4eSSatish Balay {
980e5c89e4eSSatish Balay   PetscErrorCode ierr;
981e5c89e4eSSatish Balay   int            i = 0;
982e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
98371573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
984d5649816SBarry Smith   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0};
985d5649816SBarry Smith   const char     *r[] = {0,0,0,0,0,0,0,0,0};
986ace3abfcSBarry Smith   PetscBool      flag;
987e5c89e4eSSatish Balay 
988e5c89e4eSSatish Balay   PetscFunctionBegin;
989e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
99071573d7dSBarry Smith   if (aa == b) {
99122982a5fSBarry Smith     ierr    = PetscStrallocpy(aa,(char **)&a);CHKERRQ(ierr);
99271573d7dSBarry Smith   }
993e5c89e4eSSatish Balay   ierr = PetscMalloc(len*sizeof(char*),&work);CHKERRQ(ierr);
994e5c89e4eSSatish Balay 
995e5c89e4eSSatish Balay   /* get values for replaced variables */
996487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr);
997487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr);
998487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr);
999487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[3]);CHKERRQ(ierr);
1000487e5849SBarry Smith   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[4]);CHKERRQ(ierr);
1001e5c89e4eSSatish Balay   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[5]);CHKERRQ(ierr);
1002487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[6]);CHKERRQ(ierr);
1003d5649816SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[7]);CHKERRQ(ierr);
1004487e5849SBarry Smith   ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr);
1005487e5849SBarry Smith   ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1006487e5849SBarry Smith   ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1007487e5849SBarry Smith   ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr);
1008d5649816SBarry Smith   ierr = PetscGetHostName((char*)r[7],256);CHKERRQ(ierr);
1009487e5849SBarry Smith 
1010487e5849SBarry Smith   /* replace that are in environment */
1011487e5849SBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr);
1012487e5849SBarry Smith   if (flag) {
1013487e5849SBarry Smith     ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr);
1014487e5849SBarry Smith   }
1015e5c89e4eSSatish Balay 
1016e5c89e4eSSatish Balay   /* replace the requested strings */
1017e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
1018e5c89e4eSSatish Balay   while (s[i]) {
1019e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
1020e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1021e5c89e4eSSatish Balay     while (par) {
1022e5c89e4eSSatish Balay       *par  =  0;
1023e5c89e4eSSatish Balay       par  += l;
1024e5c89e4eSSatish Balay 
1025e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
1026e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
1027e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
102817186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
1029e5c89e4eSSatish Balay       ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
1030e5c89e4eSSatish Balay       ierr  = PetscStrcat(work,r[i]);CHKERRQ(ierr);
1031e5c89e4eSSatish Balay       ierr  = PetscStrcat(work,par);CHKERRQ(ierr);
1032e5c89e4eSSatish Balay       ierr  = PetscStrncpy(b,work,len);CHKERRQ(ierr);
1033e5c89e4eSSatish Balay       ierr  = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1034e5c89e4eSSatish Balay     }
1035e5c89e4eSSatish Balay     i++;
1036e5c89e4eSSatish Balay   }
1037487e5849SBarry Smith   i = 0;
1038487e5849SBarry Smith   while (r[i]) {
1039e5c89e4eSSatish Balay     tfree = (char*)r[i];
1040e5c89e4eSSatish Balay     ierr = PetscFree(tfree);CHKERRQ(ierr);
1041487e5849SBarry Smith     i++;
1042e5c89e4eSSatish Balay   }
1043e5c89e4eSSatish Balay 
1044e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
1045e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1046e5c89e4eSSatish Balay   while (par) {
1047e5c89e4eSSatish Balay     *par = 0;
1048e5c89e4eSSatish Balay     par += 2;
1049e5c89e4eSSatish Balay     ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
1050e5c89e4eSSatish Balay     ierr = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
1051e5c89e4eSSatish Balay     *epar = 0;
1052e5c89e4eSSatish Balay     epar += 1;
1053e5c89e4eSSatish Balay     ierr = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr);
10547ba3a57cSBarry Smith     if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
1055e5c89e4eSSatish Balay     ierr = PetscStrcat(work,env);CHKERRQ(ierr);
1056e5c89e4eSSatish Balay     ierr = PetscStrcat(work,epar);CHKERRQ(ierr);
1057e5c89e4eSSatish Balay     ierr = PetscStrcpy(b,work);CHKERRQ(ierr);
1058e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1059e5c89e4eSSatish Balay   }
1060e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
106171573d7dSBarry Smith   if (aa == b) {
106271573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
106371573d7dSBarry Smith   }
1064e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1065e5c89e4eSSatish Balay }
1066e5c89e4eSSatish Balay 
1067e5c89e4eSSatish Balay 
1068