xref: /petsc/src/sys/utils/str.c (revision 17186662f795a4cab13b7b9cea27a0e065a89ca2)
1e5c89e4eSSatish Balay #define PETSC_DLL
2e5c89e4eSSatish Balay /*
3e5c89e4eSSatish Balay     We define the string operations here. The reason we just do not use
4e5c89e4eSSatish Balay   the standard string routines in the PETSc code is that on some machines
5e5c89e4eSSatish Balay   they are broken or have the wrong prototypes.
6e5c89e4eSSatish Balay 
7e5c89e4eSSatish Balay */
8d382aafbSBarry Smith #include "petscsys.h"                   /*I  "petscsys.h"   I*/
9e5c89e4eSSatish Balay #if defined(PETSC_HAVE_STRING_H)
10e5c89e4eSSatish Balay #include <string.h>
11e5c89e4eSSatish Balay #endif
12e5c89e4eSSatish Balay #if defined(PETSC_HAVE_STRINGS_H)
13e5c89e4eSSatish Balay #include <strings.h>
14e5c89e4eSSatish Balay #endif
15e5c89e4eSSatish Balay 
16e5c89e4eSSatish Balay #undef __FUNCT__
17e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrlen"
18e5c89e4eSSatish Balay /*@C
19e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
20e5c89e4eSSatish Balay 
21e5c89e4eSSatish Balay    Not Collective
22e5c89e4eSSatish Balay 
23e5c89e4eSSatish Balay    Input Parameters:
24e5c89e4eSSatish Balay .  s - pointer to string
25e5c89e4eSSatish Balay 
26e5c89e4eSSatish Balay    Output Parameter:
27e5c89e4eSSatish Balay .  len - length in bytes
28e5c89e4eSSatish Balay 
29e5c89e4eSSatish Balay    Level: intermediate
30e5c89e4eSSatish Balay 
31e5c89e4eSSatish Balay    Note:
32e5c89e4eSSatish Balay    This routine is analogous to strlen().
33e5c89e4eSSatish Balay 
34e5c89e4eSSatish Balay    Null string returns a length of zero
35e5c89e4eSSatish Balay 
36e5c89e4eSSatish Balay   Concepts: string length
37e5c89e4eSSatish Balay 
38e5c89e4eSSatish Balay @*/
39e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrlen(const char s[],size_t *len)
40e5c89e4eSSatish Balay {
41e5c89e4eSSatish Balay   PetscFunctionBegin;
42e5c89e4eSSatish Balay   if (!s) {
43e5c89e4eSSatish Balay     *len = 0;
44e5c89e4eSSatish Balay   } else {
45e5c89e4eSSatish Balay     *len = strlen(s);
46e5c89e4eSSatish Balay   }
47e5c89e4eSSatish Balay   PetscFunctionReturn(0);
48e5c89e4eSSatish Balay }
49e5c89e4eSSatish Balay 
50e5c89e4eSSatish Balay #undef __FUNCT__
51e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrallocpy"
52e5c89e4eSSatish Balay /*@C
53e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
54e5c89e4eSSatish Balay 
55e5c89e4eSSatish Balay    Not Collective
56e5c89e4eSSatish Balay 
57e5c89e4eSSatish Balay    Input Parameters:
58e5c89e4eSSatish Balay .  s - pointer to string
59e5c89e4eSSatish Balay 
60e5c89e4eSSatish Balay    Output Parameter:
61e5c89e4eSSatish Balay .  t - the copied string
62e5c89e4eSSatish Balay 
63e5c89e4eSSatish Balay    Level: intermediate
64e5c89e4eSSatish Balay 
65e5c89e4eSSatish Balay    Note:
66e5c89e4eSSatish Balay       Null string returns a new null string
67e5c89e4eSSatish Balay 
68e5c89e4eSSatish Balay   Concepts: string copy
69e5c89e4eSSatish Balay 
70e5c89e4eSSatish Balay @*/
71e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrallocpy(const char s[],char *t[])
72e5c89e4eSSatish Balay {
73e5c89e4eSSatish Balay   PetscErrorCode ierr;
74e5c89e4eSSatish Balay   size_t         len;
7571573d7dSBarry Smith   char           *tmp = 0;
76e5c89e4eSSatish Balay 
77e5c89e4eSSatish Balay   PetscFunctionBegin;
78e5c89e4eSSatish Balay   if (s) {
79e5c89e4eSSatish Balay     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
8071573d7dSBarry Smith     ierr = PetscMalloc((1+len)*sizeof(char),&tmp);CHKERRQ(ierr);
8171573d7dSBarry Smith     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
82e5c89e4eSSatish Balay   }
8371573d7dSBarry Smith   *t = tmp;
84e5c89e4eSSatish Balay   PetscFunctionReturn(0);
85e5c89e4eSSatish Balay }
86e5c89e4eSSatish Balay 
87e5c89e4eSSatish Balay #undef __FUNCT__
88e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcpy"
89e5c89e4eSSatish Balay /*@C
90e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
91e5c89e4eSSatish Balay 
92e5c89e4eSSatish Balay    Not Collective
93e5c89e4eSSatish Balay 
94e5c89e4eSSatish Balay    Input Parameters:
95e5c89e4eSSatish Balay .  t - pointer to string
96e5c89e4eSSatish Balay 
97e5c89e4eSSatish Balay    Output Parameter:
98e5c89e4eSSatish Balay .  s - the copied string
99e5c89e4eSSatish Balay 
100e5c89e4eSSatish Balay    Level: intermediate
101e5c89e4eSSatish Balay 
102e5c89e4eSSatish Balay    Note:
103e5c89e4eSSatish Balay      Null string returns a string starting with zero
104e5c89e4eSSatish Balay 
105e5c89e4eSSatish Balay   Concepts: string copy
106e5c89e4eSSatish Balay 
107e5c89e4eSSatish Balay .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat()
108e5c89e4eSSatish Balay 
109e5c89e4eSSatish Balay @*/
110acc6cc86SBarry Smith 
111e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrcpy(char s[],const char t[])
112e5c89e4eSSatish Balay {
113e5c89e4eSSatish Balay   PetscFunctionBegin;
114*17186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
115e5c89e4eSSatish Balay   if (t) {strcpy(s,t);}
116e5c89e4eSSatish Balay   else if (s) {s[0] = 0;}
117e5c89e4eSSatish Balay   PetscFunctionReturn(0);
118e5c89e4eSSatish Balay }
119e5c89e4eSSatish Balay 
120e5c89e4eSSatish Balay #undef __FUNCT__
121e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncpy"
122e5c89e4eSSatish Balay /*@C
123e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
124e5c89e4eSSatish Balay 
125e5c89e4eSSatish Balay    Not Collective
126e5c89e4eSSatish Balay 
127e5c89e4eSSatish Balay    Input Parameters:
128e5c89e4eSSatish Balay +  t - pointer to string
129e5c89e4eSSatish Balay -  n - the length to copy
130e5c89e4eSSatish Balay 
131e5c89e4eSSatish Balay    Output Parameter:
132e5c89e4eSSatish Balay .  s - the copied string
133e5c89e4eSSatish Balay 
134e5c89e4eSSatish Balay    Level: intermediate
135e5c89e4eSSatish Balay 
136e5c89e4eSSatish Balay    Note:
137e5c89e4eSSatish Balay      Null string returns a string starting with zero
138e5c89e4eSSatish Balay 
139e5c89e4eSSatish Balay   Concepts: string copy
140e5c89e4eSSatish Balay 
141e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat()
142e5c89e4eSSatish Balay 
143e5c89e4eSSatish Balay @*/
144e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrncpy(char s[],const char t[],size_t n)
145e5c89e4eSSatish Balay {
146e5c89e4eSSatish Balay   PetscFunctionBegin;
147*17186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
148e5c89e4eSSatish Balay   if (t) {strncpy(s,t,n);}
149e5c89e4eSSatish Balay   else if (s) {s[0] = 0;}
150e5c89e4eSSatish Balay   PetscFunctionReturn(0);
151e5c89e4eSSatish Balay }
152e5c89e4eSSatish Balay 
153e5c89e4eSSatish Balay #undef __FUNCT__
154e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcat"
155e5c89e4eSSatish Balay /*@C
156e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
157e5c89e4eSSatish Balay 
158e5c89e4eSSatish Balay    Not Collective
159e5c89e4eSSatish Balay 
160e5c89e4eSSatish Balay    Input Parameters:
161e5e2177aSMatthew Knepley +  s - string to be added to
162e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
163e5c89e4eSSatish Balay 
164e5c89e4eSSatish Balay    Level: intermediate
165e5c89e4eSSatish Balay 
166e5c89e4eSSatish Balay   Concepts: string copy
167e5c89e4eSSatish Balay 
168e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat()
169e5c89e4eSSatish Balay 
170e5c89e4eSSatish Balay @*/
171e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrcat(char s[],const char t[])
172e5c89e4eSSatish Balay {
173e5c89e4eSSatish Balay   PetscFunctionBegin;
1749b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
175e5c89e4eSSatish Balay   strcat(s,t);
176e5c89e4eSSatish Balay   PetscFunctionReturn(0);
177e5c89e4eSSatish Balay }
178e5c89e4eSSatish Balay 
179e5c89e4eSSatish Balay #undef __FUNCT__
180e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncat"
181e5c89e4eSSatish Balay /*@C
182e5c89e4eSSatish Balay    PetscStrncat - Concatenates a string onto a given string, up to a given length
183e5c89e4eSSatish Balay 
184e5c89e4eSSatish Balay    Not Collective
185e5c89e4eSSatish Balay 
186e5c89e4eSSatish Balay    Input Parameters:
187e5c89e4eSSatish Balay +  s - pointer to string to be added to end
188e5c89e4eSSatish Balay .  t - string to be added to
189e5c89e4eSSatish Balay .  n - maximum length to copy
190e5c89e4eSSatish Balay 
191e5c89e4eSSatish Balay    Level: intermediate
192e5c89e4eSSatish Balay 
193e5c89e4eSSatish Balay   Concepts: string copy
194e5c89e4eSSatish Balay 
195e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
196e5c89e4eSSatish Balay 
197e5c89e4eSSatish Balay @*/
198e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrncat(char s[],const char t[],size_t n)
199e5c89e4eSSatish Balay {
200e5c89e4eSSatish Balay   PetscFunctionBegin;
201e5c89e4eSSatish Balay   strncat(s,t,n);
202e5c89e4eSSatish Balay   PetscFunctionReturn(0);
203e5c89e4eSSatish Balay }
204e5c89e4eSSatish Balay 
205e5c89e4eSSatish Balay #undef __FUNCT__
206e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcmp"
207e5c89e4eSSatish Balay /*@C
208e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
209e5c89e4eSSatish Balay 
210e5c89e4eSSatish Balay    Not Collective
211e5c89e4eSSatish Balay 
212e5c89e4eSSatish Balay    Input Parameters:
213e5c89e4eSSatish Balay +  a - pointer to string first string
214e5c89e4eSSatish Balay -  b - pointer to second string
215e5c89e4eSSatish Balay 
216e5c89e4eSSatish Balay    Output Parameter:
217e5c89e4eSSatish Balay .  flg - if the two strings are equal
218e5c89e4eSSatish Balay 
219e5c89e4eSSatish Balay    Level: intermediate
220e5c89e4eSSatish Balay 
221e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
222e5c89e4eSSatish Balay 
223e5c89e4eSSatish Balay @*/
224e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrcmp(const char a[],const char b[],PetscTruth *flg)
225e5c89e4eSSatish Balay {
226e5c89e4eSSatish Balay   int c;
227e5c89e4eSSatish Balay 
228e5c89e4eSSatish Balay   PetscFunctionBegin;
229e5c89e4eSSatish Balay   if (!a && !b) {
230e5c89e4eSSatish Balay     *flg = PETSC_TRUE;
231e5c89e4eSSatish Balay   } else if (!a || !b) {
232e5c89e4eSSatish Balay     *flg = PETSC_FALSE;
233e5c89e4eSSatish Balay   } else {
234e5c89e4eSSatish Balay     c = strcmp(a,b);
235e5c89e4eSSatish Balay     if (c) *flg = PETSC_FALSE;
236e5c89e4eSSatish Balay     else   *flg = PETSC_TRUE;
237e5c89e4eSSatish Balay   }
238e5c89e4eSSatish Balay   PetscFunctionReturn(0);
239e5c89e4eSSatish Balay }
240e5c89e4eSSatish Balay 
241e5c89e4eSSatish Balay #undef __FUNCT__
242e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrgrt"
243e5c89e4eSSatish Balay /*@C
244e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
245e5c89e4eSSatish Balay 
246e5c89e4eSSatish Balay    Not Collective
247e5c89e4eSSatish Balay 
248e5c89e4eSSatish Balay    Input Parameters:
249e5c89e4eSSatish Balay +  a - pointer to first string
250e5c89e4eSSatish Balay -  b - pointer to second string
251e5c89e4eSSatish Balay 
252e5c89e4eSSatish Balay    Output Parameter:
253e5c89e4eSSatish Balay .  flg - if the first string is greater
254e5c89e4eSSatish Balay 
255e5c89e4eSSatish Balay    Notes:
256e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
257e5c89e4eSSatish Balay     all others
258e5c89e4eSSatish Balay 
259e5c89e4eSSatish Balay    Level: intermediate
260e5c89e4eSSatish Balay 
261e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
262e5c89e4eSSatish Balay 
263e5c89e4eSSatish Balay @*/
264e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrgrt(const char a[],const char b[],PetscTruth *t)
265e5c89e4eSSatish Balay {
266e5c89e4eSSatish Balay   int c;
267e5c89e4eSSatish Balay 
268e5c89e4eSSatish Balay   PetscFunctionBegin;
269e5c89e4eSSatish Balay   if (!a && !b) {
270e5c89e4eSSatish Balay     *t = PETSC_FALSE;
271e5c89e4eSSatish Balay   } else if (a && !b) {
272e5c89e4eSSatish Balay     *t = PETSC_TRUE;
273e5c89e4eSSatish Balay   } else if (!a && b) {
274e5c89e4eSSatish Balay     *t = PETSC_FALSE;
275e5c89e4eSSatish Balay   } else {
276e5c89e4eSSatish Balay     c = strcmp(a,b);
277e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
278e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
279e5c89e4eSSatish Balay   }
280e5c89e4eSSatish Balay   PetscFunctionReturn(0);
281e5c89e4eSSatish Balay }
282e5c89e4eSSatish Balay 
283e5c89e4eSSatish Balay #undef __FUNCT__
284e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcasecmp"
285e5c89e4eSSatish Balay /*@C
286e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
287e5c89e4eSSatish Balay      except possibly for case.
288e5c89e4eSSatish Balay 
289e5c89e4eSSatish Balay    Not Collective
290e5c89e4eSSatish Balay 
291e5c89e4eSSatish Balay    Input Parameters:
292e5c89e4eSSatish Balay +  a - pointer to first string
293e5c89e4eSSatish Balay -  b - pointer to second string
294e5c89e4eSSatish Balay 
295e5c89e4eSSatish Balay    Output Parameter:
296e5c89e4eSSatish Balay .  flg - if the two strings are the same
297e5c89e4eSSatish Balay 
298e5c89e4eSSatish Balay    Notes:
299e5c89e4eSSatish Balay     Null arguments are ok
300e5c89e4eSSatish Balay 
301e5c89e4eSSatish Balay    Level: intermediate
302e5c89e4eSSatish Balay 
303e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
304e5c89e4eSSatish Balay 
305e5c89e4eSSatish Balay @*/
306fbb3e65fSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrcasecmp(const char a[],const char b[],PetscTruth *t)
307e5c89e4eSSatish Balay {
308e5c89e4eSSatish Balay   int c;
309e5c89e4eSSatish Balay 
310e5c89e4eSSatish Balay   PetscFunctionBegin;
311e5c89e4eSSatish Balay   if (!a && !b) c = 0;
312e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
31332b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
31432b366c8SSatish Balay   else c = strcasecmp(a,b);
31532b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
316e5c89e4eSSatish Balay   else c = stricmp(a,b);
317e5c89e4eSSatish Balay #else
31832b366c8SSatish Balay   else {
31932b366c8SSatish Balay     char *aa,*bb;
32032b366c8SSatish Balay     PetscErrorCode ierr;
32132b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
32232b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
32332b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
32432b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
32532b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
326503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
327503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
32832b366c8SSatish Balay     PetscFunctionReturn(0);
32932b366c8SSatish Balay   }
330e5c89e4eSSatish Balay #endif
331e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
332e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
333e5c89e4eSSatish Balay   PetscFunctionReturn(0);
334e5c89e4eSSatish Balay }
335e5c89e4eSSatish Balay 
33632b366c8SSatish Balay 
33732b366c8SSatish Balay 
338e5c89e4eSSatish Balay #undef __FUNCT__
339e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncmp"
340e5c89e4eSSatish Balay /*@C
341e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
342e5c89e4eSSatish Balay 
343e5c89e4eSSatish Balay    Not Collective
344e5c89e4eSSatish Balay 
345e5c89e4eSSatish Balay    Input Parameters:
346e5c89e4eSSatish Balay +  a - pointer to first string
347e5c89e4eSSatish Balay .  b - pointer to second string
348e5c89e4eSSatish Balay -  n - length to compare up to
349e5c89e4eSSatish Balay 
350e5c89e4eSSatish Balay    Output Parameter:
351e5c89e4eSSatish Balay .  t - if the two strings are equal
352e5c89e4eSSatish Balay 
353e5c89e4eSSatish Balay    Level: intermediate
354e5c89e4eSSatish Balay 
355e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
356e5c89e4eSSatish Balay 
357e5c89e4eSSatish Balay @*/
358e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrncmp(const char a[],const char b[],size_t n,PetscTruth *t)
359e5c89e4eSSatish Balay {
360e5c89e4eSSatish Balay   int c;
361e5c89e4eSSatish Balay 
362e5c89e4eSSatish Balay   PetscFunctionBegin;
363e5c89e4eSSatish Balay   c = strncmp(a,b,n);
364e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
365e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
366e5c89e4eSSatish Balay   PetscFunctionReturn(0);
367e5c89e4eSSatish Balay }
368e5c89e4eSSatish Balay 
369e5c89e4eSSatish Balay #undef __FUNCT__
370e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrchr"
371e5c89e4eSSatish Balay /*@C
372e5c89e4eSSatish Balay    PetscStrchr - Locates first occurance of a character in a string
373e5c89e4eSSatish Balay 
374e5c89e4eSSatish Balay    Not Collective
375e5c89e4eSSatish Balay 
376e5c89e4eSSatish Balay    Input Parameters:
377e5c89e4eSSatish Balay +  a - pointer to string
378e5c89e4eSSatish Balay -  b - character
379e5c89e4eSSatish Balay 
380e5c89e4eSSatish Balay    Output Parameter:
381e5c89e4eSSatish Balay .  c - location of occurance, PETSC_NULL if not found
382e5c89e4eSSatish Balay 
383e5c89e4eSSatish Balay    Level: intermediate
384e5c89e4eSSatish Balay 
385e5c89e4eSSatish Balay @*/
386e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrchr(const char a[],char b,char *c[])
387e5c89e4eSSatish Balay {
388e5c89e4eSSatish Balay   PetscFunctionBegin;
389e5c89e4eSSatish Balay   *c = (char *)strchr(a,b);
390e5c89e4eSSatish Balay   PetscFunctionReturn(0);
391e5c89e4eSSatish Balay }
392e5c89e4eSSatish Balay 
393e5c89e4eSSatish Balay #undef __FUNCT__
394e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrrchr"
395e5c89e4eSSatish Balay /*@C
396e5c89e4eSSatish Balay    PetscStrrchr - Locates one location past the last occurance of a character in a string,
397e5c89e4eSSatish Balay       if the character is not found then returns entire string
398e5c89e4eSSatish Balay 
399e5c89e4eSSatish Balay    Not Collective
400e5c89e4eSSatish Balay 
401e5c89e4eSSatish Balay    Input Parameters:
402e5c89e4eSSatish Balay +  a - pointer to string
403e5c89e4eSSatish Balay -  b - character
404e5c89e4eSSatish Balay 
405e5c89e4eSSatish Balay    Output Parameter:
406e5c89e4eSSatish Balay .  tmp - location of occurance, a if not found
407e5c89e4eSSatish Balay 
408e5c89e4eSSatish Balay    Level: intermediate
409e5c89e4eSSatish Balay 
410e5c89e4eSSatish Balay @*/
411e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrrchr(const char a[],char b,char *tmp[])
412e5c89e4eSSatish Balay {
413e5c89e4eSSatish Balay   PetscFunctionBegin;
414e5c89e4eSSatish Balay   *tmp = (char *)strrchr(a,b);
415e5c89e4eSSatish Balay   if (!*tmp) *tmp = (char*)a; else *tmp = *tmp + 1;
416e5c89e4eSSatish Balay   PetscFunctionReturn(0);
417e5c89e4eSSatish Balay }
418e5c89e4eSSatish Balay 
419e5c89e4eSSatish Balay #undef __FUNCT__
420e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrtolower"
421e5c89e4eSSatish Balay /*@C
422e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
423e5c89e4eSSatish Balay 
424e5c89e4eSSatish Balay    Not Collective
425e5c89e4eSSatish Balay 
426e5c89e4eSSatish Balay    Input Parameters:
427e5c89e4eSSatish Balay .  a - pointer to string
428e5c89e4eSSatish Balay 
429e5c89e4eSSatish Balay    Level: intermediate
430e5c89e4eSSatish Balay 
431e5c89e4eSSatish Balay @*/
432e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrtolower(char a[])
433e5c89e4eSSatish Balay {
434e5c89e4eSSatish Balay   PetscFunctionBegin;
435e5c89e4eSSatish Balay   while (*a) {
436e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
437e5c89e4eSSatish Balay     a++;
438e5c89e4eSSatish Balay   }
439e5c89e4eSSatish Balay   PetscFunctionReturn(0);
440e5c89e4eSSatish Balay }
441e5c89e4eSSatish Balay 
4421d1a0024SBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
4431d1a0024SBarry Smith 
4441d1a0024SBarry Smith 
445e5c89e4eSSatish Balay #undef __FUNCT__
446e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenFind"
447e5c89e4eSSatish Balay /*@C
448e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
449e5c89e4eSSatish Balay 
450e5c89e4eSSatish Balay    Not Collective
451e5c89e4eSSatish Balay 
452e5c89e4eSSatish Balay    Input Parameters:
453e5c89e4eSSatish Balay .  a - pointer to token
454e5c89e4eSSatish Balay 
455e5c89e4eSSatish Balay    Output Parameter:
456e5c89e4eSSatish Balay .  result - location of occurance, PETSC_NULL if not found
457e5c89e4eSSatish Balay 
458e5c89e4eSSatish Balay    Notes:
459e5c89e4eSSatish Balay 
460e5c89e4eSSatish Balay      This version is different from the system version in that
461e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
462e5c89e4eSSatish Balay 
4634704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
4644704e885SBarry Smith    as a single token.
4654704e885SBarry Smith 
466e5c89e4eSSatish Balay    Level: intermediate
467e5c89e4eSSatish Balay 
468e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
469e5c89e4eSSatish Balay @*/
4701d1a0024SBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscTokenFind(PetscToken a,char *result[])
471e5c89e4eSSatish Balay {
4724704e885SBarry Smith   char *ptr = a->current,token;
473e5c89e4eSSatish Balay 
474e5c89e4eSSatish Balay   PetscFunctionBegin;
475e5c89e4eSSatish Balay   *result = a->current;
4764704e885SBarry Smith   if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);}
4774704e885SBarry Smith   token = a->token;
47890fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
479e5c89e4eSSatish Balay   while (ptr) {
4804704e885SBarry Smith     if (*ptr == token) {
481e5c89e4eSSatish Balay       *ptr++ = 0;
482e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
483e5c89e4eSSatish Balay       a->current = ptr;
484e5c89e4eSSatish Balay       break;
485e5c89e4eSSatish Balay     }
486e5c89e4eSSatish Balay     if (!*ptr) {
487e5c89e4eSSatish Balay       a->current = 0;
488e5c89e4eSSatish Balay       break;
489e5c89e4eSSatish Balay     }
490e5c89e4eSSatish Balay     ptr++;
491e5c89e4eSSatish Balay   }
492e5c89e4eSSatish Balay   PetscFunctionReturn(0);
493e5c89e4eSSatish Balay }
494e5c89e4eSSatish Balay 
495e5c89e4eSSatish Balay #undef __FUNCT__
496e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenCreate"
497e5c89e4eSSatish Balay /*@C
498e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
499e5c89e4eSSatish Balay 
500e5c89e4eSSatish Balay    Not Collective
501e5c89e4eSSatish Balay 
502e5c89e4eSSatish Balay    Input Parameters:
503e5c89e4eSSatish Balay +  string - the string to look in
504e5c89e4eSSatish Balay -  token - the character to look for
505e5c89e4eSSatish Balay 
506e5c89e4eSSatish Balay    Output Parameter:
507e5c89e4eSSatish Balay .  a - pointer to token
508e5c89e4eSSatish Balay 
509e5c89e4eSSatish Balay    Notes:
510e5c89e4eSSatish Balay 
511e5c89e4eSSatish Balay      This version is different from the system version in that
512e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
513e5c89e4eSSatish Balay 
514e5c89e4eSSatish Balay    Level: intermediate
515e5c89e4eSSatish Balay 
516e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
517e5c89e4eSSatish Balay @*/
5181d1a0024SBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscTokenCreate(const char a[],const char b,PetscToken *t)
519e5c89e4eSSatish Balay {
520e5c89e4eSSatish Balay   PetscErrorCode ierr;
521e5c89e4eSSatish Balay 
522e5c89e4eSSatish Balay   PetscFunctionBegin;
5231d1a0024SBarry Smith   ierr = PetscNew(struct _p_PetscToken,t);CHKERRQ(ierr);
524e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
525e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
526e5c89e4eSSatish Balay   (*t)->token   = b;
527e5c89e4eSSatish Balay   PetscFunctionReturn(0);
528e5c89e4eSSatish Balay }
529e5c89e4eSSatish Balay 
530e5c89e4eSSatish Balay #undef __FUNCT__
531e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenDestroy"
532e5c89e4eSSatish Balay /*@C
533e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
534e5c89e4eSSatish Balay 
535e5c89e4eSSatish Balay    Not Collective
536e5c89e4eSSatish Balay 
537e5c89e4eSSatish Balay    Input Parameters:
538e5c89e4eSSatish Balay .  a - pointer to token
539e5c89e4eSSatish Balay 
540e5c89e4eSSatish Balay    Level: intermediate
541e5c89e4eSSatish Balay 
542e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
543e5c89e4eSSatish Balay @*/
5441d1a0024SBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscTokenDestroy(PetscToken a)
545e5c89e4eSSatish Balay {
546e5c89e4eSSatish Balay   PetscErrorCode ierr;
547e5c89e4eSSatish Balay 
548e5c89e4eSSatish Balay   PetscFunctionBegin;
549e5c89e4eSSatish Balay   ierr = PetscFree(a->array);CHKERRQ(ierr);
550e5c89e4eSSatish Balay   ierr = PetscFree(a);CHKERRQ(ierr);
551e5c89e4eSSatish Balay   PetscFunctionReturn(0);
552e5c89e4eSSatish Balay }
553e5c89e4eSSatish Balay 
554e5c89e4eSSatish Balay #undef __FUNCT__
555e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrrstr"
556e5c89e4eSSatish Balay /*@C
557e5c89e4eSSatish Balay    PetscStrrstr - Locates last occurance of string in another string
558e5c89e4eSSatish Balay 
559e5c89e4eSSatish Balay    Not Collective
560e5c89e4eSSatish Balay 
561e5c89e4eSSatish Balay    Input Parameters:
562e5c89e4eSSatish Balay +  a - pointer to string
563e5c89e4eSSatish Balay -  b - string to find
564e5c89e4eSSatish Balay 
565e5c89e4eSSatish Balay    Output Parameter:
566e5c89e4eSSatish Balay .  tmp - location of occurance
567e5c89e4eSSatish Balay 
568e5c89e4eSSatish Balay    Level: intermediate
569e5c89e4eSSatish Balay 
570e5c89e4eSSatish Balay @*/
571e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrrstr(const char a[],const char b[],char *tmp[])
572e5c89e4eSSatish Balay {
573e5c89e4eSSatish Balay   const char *stmp = a, *ltmp = 0;
574e5c89e4eSSatish Balay 
575e5c89e4eSSatish Balay   PetscFunctionBegin;
576e5c89e4eSSatish Balay   while (stmp) {
577e5c89e4eSSatish Balay     stmp = (char *)strstr(stmp,b);
578e5c89e4eSSatish Balay     if (stmp) {ltmp = stmp;stmp++;}
579e5c89e4eSSatish Balay   }
580e5c89e4eSSatish Balay   *tmp = (char *)ltmp;
581e5c89e4eSSatish Balay   PetscFunctionReturn(0);
582e5c89e4eSSatish Balay }
583e5c89e4eSSatish Balay 
584e5c89e4eSSatish Balay #undef __FUNCT__
585e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrstr"
586e5c89e4eSSatish Balay /*@C
587e5c89e4eSSatish Balay    PetscStrstr - Locates first occurance of string in another string
588e5c89e4eSSatish Balay 
589e5c89e4eSSatish Balay    Not Collective
590e5c89e4eSSatish Balay 
591e5c89e4eSSatish Balay    Input Parameters:
592e5c89e4eSSatish Balay +  a - pointer to string
593e5c89e4eSSatish Balay -  b - string to find
594e5c89e4eSSatish Balay 
595e5c89e4eSSatish Balay    Output Parameter:
596e5c89e4eSSatish Balay .  tmp - location of occurance
597e5c89e4eSSatish Balay 
598e5c89e4eSSatish Balay    Level: intermediate
599e5c89e4eSSatish Balay 
600e5c89e4eSSatish Balay @*/
601e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscStrstr(const char a[],const char b[],char *tmp[])
602e5c89e4eSSatish Balay {
603e5c89e4eSSatish Balay   PetscFunctionBegin;
604e5c89e4eSSatish Balay   *tmp = (char *)strstr(a,b);
605e5c89e4eSSatish Balay   PetscFunctionReturn(0);
606e5c89e4eSSatish Balay }
607e5c89e4eSSatish Balay 
608e5c89e4eSSatish Balay #undef __FUNCT__
609e5c89e4eSSatish Balay #define __FUNCT__ "PetscGetPetscDir"
610e5c89e4eSSatish Balay /*@C
611e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
612e5c89e4eSSatish Balay 
613e5c89e4eSSatish Balay    Not Collective
614e5c89e4eSSatish Balay 
615e5c89e4eSSatish Balay    Output Parameter:
616e5c89e4eSSatish Balay .  dir - the directory
617e5c89e4eSSatish Balay 
618e5c89e4eSSatish Balay    Level: developer
619e5c89e4eSSatish Balay 
620e5c89e4eSSatish Balay @*/
621e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscGetPetscDir(const char *dir[])
622e5c89e4eSSatish Balay {
623e5c89e4eSSatish Balay   PetscFunctionBegin;
624e5c89e4eSSatish Balay   *dir = PETSC_DIR;
625e5c89e4eSSatish Balay   PetscFunctionReturn(0);
626e5c89e4eSSatish Balay }
627e5c89e4eSSatish Balay 
628e5c89e4eSSatish Balay #undef __FUNCT__
629e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrreplace"
630e5c89e4eSSatish Balay /*@C
631e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
632e5c89e4eSSatish Balay 
633e5c89e4eSSatish Balay    Not Collective
634e5c89e4eSSatish Balay 
635e5c89e4eSSatish Balay    Input Parameters:
636e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
63771573d7dSBarry Smith .   aa - the string to look in
638d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
639e5c89e4eSSatish Balay -   len - the length of b
640e5c89e4eSSatish Balay 
641e5c89e4eSSatish Balay    Notes:
642e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
643e5c89e4eSSatish Balay       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME} with appropriate values
644e5c89e4eSSatish Balay       as well as any environmental variables.
645e5c89e4eSSatish Balay 
646acc6cc86SBarry Smith       Note: PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
647acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
648acc6cc86SBarry Smith 
649e5c89e4eSSatish Balay    Level: intermediate
650e5c89e4eSSatish Balay 
651e5c89e4eSSatish Balay @*/
65271573d7dSBarry Smith PetscErrorCode PETSC_DLLEXPORT PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
653e5c89e4eSSatish Balay {
654e5c89e4eSSatish Balay   PetscErrorCode ierr;
655e5c89e4eSSatish Balay   int            i = 0;
656e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
65771573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
658e5c89e4eSSatish Balay   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}",0};
659487e5849SBarry Smith   const char     *r[] = {0,0,0,0,0,0,0,0};
660e5c89e4eSSatish Balay   PetscTruth     flag;
661e5c89e4eSSatish Balay 
662e5c89e4eSSatish Balay   PetscFunctionBegin;
663e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
66471573d7dSBarry Smith   if (aa == b) {
66522982a5fSBarry Smith     ierr    = PetscStrallocpy(aa,(char **)&a);CHKERRQ(ierr);
66671573d7dSBarry Smith   }
667e5c89e4eSSatish Balay   ierr = PetscMalloc(len*sizeof(char*),&work);CHKERRQ(ierr);
668e5c89e4eSSatish Balay 
669e5c89e4eSSatish Balay   /* get values for replaced variables */
670487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr);
671487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr);
672487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr);
673487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[3]);CHKERRQ(ierr);
674487e5849SBarry Smith   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[4]);CHKERRQ(ierr);
675e5c89e4eSSatish Balay   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[5]);CHKERRQ(ierr);
676487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[6]);CHKERRQ(ierr);
677487e5849SBarry Smith   ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr);
678487e5849SBarry Smith   ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
679487e5849SBarry Smith   ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
680487e5849SBarry Smith   ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr);
681487e5849SBarry Smith 
682487e5849SBarry Smith   /* replace that are in environment */
683487e5849SBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr);
684487e5849SBarry Smith   if (flag) {
685487e5849SBarry Smith     ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr);
686487e5849SBarry Smith   }
687e5c89e4eSSatish Balay 
688e5c89e4eSSatish Balay   /* replace the requested strings */
689e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
690e5c89e4eSSatish Balay   while (s[i]) {
691e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
692e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
693e5c89e4eSSatish Balay     while (par) {
694e5c89e4eSSatish Balay       *par  =  0;
695e5c89e4eSSatish Balay       par  += l;
696e5c89e4eSSatish Balay 
697e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
698e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
699e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
700*17186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
701e5c89e4eSSatish Balay       ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
702e5c89e4eSSatish Balay       ierr  = PetscStrcat(work,r[i]);CHKERRQ(ierr);
703e5c89e4eSSatish Balay       ierr  = PetscStrcat(work,par);CHKERRQ(ierr);
704e5c89e4eSSatish Balay       ierr  = PetscStrncpy(b,work,len);CHKERRQ(ierr);
705e5c89e4eSSatish Balay       ierr  = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
706e5c89e4eSSatish Balay     }
707e5c89e4eSSatish Balay     i++;
708e5c89e4eSSatish Balay   }
709487e5849SBarry Smith   i = 0;
710487e5849SBarry Smith   while (r[i]) {
711e5c89e4eSSatish Balay     tfree = (char*)r[i];
712e5c89e4eSSatish Balay     ierr = PetscFree(tfree);CHKERRQ(ierr);
713487e5849SBarry Smith     i++;
714e5c89e4eSSatish Balay   }
715e5c89e4eSSatish Balay 
716e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
717e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
718e5c89e4eSSatish Balay   while (par) {
719e5c89e4eSSatish Balay     *par = 0;
720e5c89e4eSSatish Balay     par += 2;
721e5c89e4eSSatish Balay     ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
722e5c89e4eSSatish Balay     ierr = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
723e5c89e4eSSatish Balay     *epar = 0;
724e5c89e4eSSatish Balay     epar += 1;
725e5c89e4eSSatish Balay     ierr = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr);
726e5c89e4eSSatish Balay     if (!flag) {
727e32f2f54SBarry Smith       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
728e5c89e4eSSatish Balay     }
729e5c89e4eSSatish Balay     ierr = PetscStrcat(work,env);CHKERRQ(ierr);
730e5c89e4eSSatish Balay     ierr = PetscStrcat(work,epar);CHKERRQ(ierr);
731e5c89e4eSSatish Balay     ierr = PetscStrcpy(b,work);CHKERRQ(ierr);
732e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
733e5c89e4eSSatish Balay   }
734e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
73571573d7dSBarry Smith   if (aa == b) {
73671573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
73771573d7dSBarry Smith   }
738e5c89e4eSSatish Balay   PetscFunctionReturn(0);
739e5c89e4eSSatish Balay }
740e5c89e4eSSatish Balay 
741e5c89e4eSSatish Balay 
742