xref: /petsc/src/sys/utils/str.c (revision 6fed8037a6a7895c9373da2f1091ceb99b343b0a)
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
19b4cd4cebSBarry Smith    PetscStrToArray - Seperates a string by its spaces and creates an array of strings
203c311c98SBarry Smith 
213c311c98SBarry Smith    Not Collective
223c311c98SBarry Smith 
233c311c98SBarry Smith    Input Parameters:
243c311c98SBarry Smith .  s - pointer to string
253c311c98SBarry Smith 
263c311c98SBarry Smith    Output Parameter:
273c311c98SBarry Smith +   argc - the number of entries in the array
283c311c98SBarry Smith -   args - an array of the entries with a null at the end
293c311c98SBarry Smith 
303c311c98SBarry Smith    Level: intermediate
313c311c98SBarry Smith 
32301d30feSBarry Smith    Notes: this may be called before PetscInitialize() or after PetscFinalize()
333c311c98SBarry Smith 
346f013253SBarry Smith    Not for use in Fortran
356f013253SBarry Smith 
36b4cd4cebSBarry Smith    Developer Notes: Using raw malloc() and does not call error handlers since this may be used before PETSc is initialized. Used
37b4cd4cebSBarry Smith      to generate argc, args arguments passed to MPI_Init()
38301d30feSBarry Smith 
39b4cd4cebSBarry Smith .seealso: PetscStrToArrayDestroy(), PetscToken, PetscTokenCreate()
403c311c98SBarry Smith 
413c311c98SBarry Smith @*/
427087cfbeSBarry Smith PetscErrorCode  PetscStrToArray(const char s[],int *argc,char ***args)
433c311c98SBarry Smith {
443c311c98SBarry Smith   int        i,n,*lens,cnt = 0;
45ace3abfcSBarry Smith   PetscBool  flg = PETSC_FALSE;
463c311c98SBarry Smith 
473c311c98SBarry Smith   n = strlen(s);
483c311c98SBarry Smith   *argc = 0;
493c311c98SBarry Smith   for (i=0; i<n; i++) {
503c311c98SBarry Smith     if (s[i] != ' ') break;
513c311c98SBarry Smith   }
523c311c98SBarry Smith   for (;i<n+1; i++) {
533c311c98SBarry Smith     if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
543c311c98SBarry Smith     else if (s[i] != ' ') {flg = PETSC_FALSE;}
553c311c98SBarry Smith   }
56301d30feSBarry Smith   (*args) = (char **) malloc(((*argc)+1)*sizeof(char**)); if (!*args) return PETSC_ERR_MEM;
5753e6e2c4SHong Zhang   lens    = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM;
583c311c98SBarry Smith   for (i=0; i<*argc; i++) lens[i] = 0;
593c311c98SBarry Smith 
603c311c98SBarry Smith   *argc = 0;
613c311c98SBarry Smith   for (i=0; i<n; i++) {
623c311c98SBarry Smith     if (s[i] != ' ') break;
633c311c98SBarry Smith   }
643c311c98SBarry Smith   for (;i<n+1; i++) {
653c311c98SBarry Smith     if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
663c311c98SBarry Smith     else if (s[i] != ' ') {lens[*argc]++;flg = PETSC_FALSE;}
673c311c98SBarry Smith   }
683c311c98SBarry Smith 
693c311c98SBarry Smith   for (i=0; i<*argc; i++) {
70675282fdSHong Zhang     (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char)); if (!(*args)[i]) return PETSC_ERR_MEM;
713c311c98SBarry Smith   }
72301d30feSBarry Smith   (*args)[*argc] = 0;
733c311c98SBarry Smith 
743c311c98SBarry Smith   *argc = 0;
753c311c98SBarry Smith   for (i=0; i<n; i++) {
763c311c98SBarry Smith     if (s[i] != ' ') break;
773c311c98SBarry Smith   }
783c311c98SBarry Smith   for (;i<n+1; i++) {
793c311c98SBarry Smith     if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
80301d30feSBarry Smith     else if (s[i] != ' ' && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;}
813c311c98SBarry Smith   }
823c311c98SBarry Smith   return 0;
833c311c98SBarry Smith }
843c311c98SBarry Smith 
853c311c98SBarry Smith #undef __FUNCT__
86301d30feSBarry Smith #define __FUNCT__ "PetscStrToArrayDestroy"
87301d30feSBarry Smith /*@C
88301d30feSBarry Smith    PetscStrToArrayDestroy - Frees array created with PetscStrToArray().
89301d30feSBarry Smith 
90301d30feSBarry Smith    Not Collective
91301d30feSBarry Smith 
92301d30feSBarry Smith    Output Parameters:
93301d30feSBarry Smith +  argc - the number of arguments
94301d30feSBarry Smith -  args - the array of arguments
95301d30feSBarry Smith 
96301d30feSBarry Smith    Level: intermediate
97301d30feSBarry Smith 
98301d30feSBarry Smith    Concepts: command line arguments
99301d30feSBarry Smith 
100301d30feSBarry Smith    Notes: This may be called before PetscInitialize() or after PetscFinalize()
101301d30feSBarry Smith 
1026f013253SBarry Smith    Not for use in Fortran
1036f013253SBarry Smith 
104301d30feSBarry Smith .seealso: PetscStrToArray()
105301d30feSBarry Smith 
106301d30feSBarry Smith @*/
1077087cfbeSBarry Smith PetscErrorCode  PetscStrToArrayDestroy(int argc,char **args)
108301d30feSBarry Smith {
109301d30feSBarry Smith   PetscInt i;
110301d30feSBarry Smith 
111301d30feSBarry Smith   for (i=0; i<argc; i++) {
112301d30feSBarry Smith     free(args[i]);
113301d30feSBarry Smith   }
114301d30feSBarry Smith   free(args);
115301d30feSBarry Smith   return 0;
116301d30feSBarry Smith }
117301d30feSBarry Smith 
118301d30feSBarry Smith #undef __FUNCT__
119e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrlen"
120e5c89e4eSSatish Balay /*@C
121e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
122e5c89e4eSSatish Balay 
123e5c89e4eSSatish Balay    Not Collective
124e5c89e4eSSatish Balay 
125e5c89e4eSSatish Balay    Input Parameters:
126e5c89e4eSSatish Balay .  s - pointer to string
127e5c89e4eSSatish Balay 
128e5c89e4eSSatish Balay    Output Parameter:
129e5c89e4eSSatish Balay .  len - length in bytes
130e5c89e4eSSatish Balay 
131e5c89e4eSSatish Balay    Level: intermediate
132e5c89e4eSSatish Balay 
133e5c89e4eSSatish Balay    Note:
134e5c89e4eSSatish Balay    This routine is analogous to strlen().
135e5c89e4eSSatish Balay 
136e5c89e4eSSatish Balay    Null string returns a length of zero
137e5c89e4eSSatish Balay 
1386f013253SBarry Smith    Not for use in Fortran
1396f013253SBarry Smith 
140e5c89e4eSSatish Balay   Concepts: string length
141e5c89e4eSSatish Balay 
142e5c89e4eSSatish Balay @*/
1437087cfbeSBarry Smith PetscErrorCode  PetscStrlen(const char s[],size_t *len)
144e5c89e4eSSatish Balay {
145e5c89e4eSSatish Balay   PetscFunctionBegin;
146e5c89e4eSSatish Balay   if (!s) {
147e5c89e4eSSatish Balay     *len = 0;
148e5c89e4eSSatish Balay   } else {
149e5c89e4eSSatish Balay     *len = strlen(s);
150e5c89e4eSSatish Balay   }
151e5c89e4eSSatish Balay   PetscFunctionReturn(0);
152e5c89e4eSSatish Balay }
153e5c89e4eSSatish Balay 
154e5c89e4eSSatish Balay #undef __FUNCT__
155e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrallocpy"
156e5c89e4eSSatish Balay /*@C
157e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
158e5c89e4eSSatish Balay 
159e5c89e4eSSatish Balay    Not Collective
160e5c89e4eSSatish Balay 
161e5c89e4eSSatish Balay    Input Parameters:
162e5c89e4eSSatish Balay .  s - pointer to string
163e5c89e4eSSatish Balay 
164e5c89e4eSSatish Balay    Output Parameter:
165e5c89e4eSSatish Balay .  t - the copied string
166e5c89e4eSSatish Balay 
167e5c89e4eSSatish Balay    Level: intermediate
168e5c89e4eSSatish Balay 
169e5c89e4eSSatish Balay    Note:
170e5c89e4eSSatish Balay       Null string returns a new null string
171e5c89e4eSSatish Balay 
1726f013253SBarry Smith       Not for use in Fortran
1736f013253SBarry Smith 
174e5c89e4eSSatish Balay   Concepts: string copy
175e5c89e4eSSatish Balay 
176e5c89e4eSSatish Balay @*/
1777087cfbeSBarry Smith PetscErrorCode  PetscStrallocpy(const char s[],char *t[])
178e5c89e4eSSatish Balay {
179e5c89e4eSSatish Balay   PetscErrorCode ierr;
180e5c89e4eSSatish Balay   size_t         len;
18171573d7dSBarry Smith   char           *tmp = 0;
182e5c89e4eSSatish Balay 
183e5c89e4eSSatish Balay   PetscFunctionBegin;
184e5c89e4eSSatish Balay   if (s) {
185e5c89e4eSSatish Balay     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
18671573d7dSBarry Smith     ierr = PetscMalloc((1+len)*sizeof(char),&tmp);CHKERRQ(ierr);
18771573d7dSBarry Smith     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
188e5c89e4eSSatish Balay   }
18971573d7dSBarry Smith   *t = tmp;
190e5c89e4eSSatish Balay   PetscFunctionReturn(0);
191e5c89e4eSSatish Balay }
192e5c89e4eSSatish Balay 
193e5c89e4eSSatish Balay #undef __FUNCT__
19447340559SBarry Smith #define __FUNCT__ "PetscStrArrayallocpy"
19547340559SBarry Smith /*@C
19647340559SBarry Smith    PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
19747340559SBarry Smith 
19847340559SBarry Smith    Not Collective
19947340559SBarry Smith 
20047340559SBarry Smith    Input Parameters:
20147340559SBarry Smith .  s - pointer to array of strings (final string is a null)
20247340559SBarry Smith 
20347340559SBarry Smith    Output Parameter:
20447340559SBarry Smith .  t - the copied array string
20547340559SBarry Smith 
20647340559SBarry Smith    Level: intermediate
20747340559SBarry Smith 
20847340559SBarry Smith    Note:
20947340559SBarry Smith       Not for use in Fortran
21047340559SBarry Smith 
21147340559SBarry Smith   Concepts: string copy
21247340559SBarry Smith 
21347340559SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
21447340559SBarry Smith 
21547340559SBarry Smith @*/
21647340559SBarry Smith PetscErrorCode  PetscStrArrayallocpy(const char *const*list,char ***t)
21747340559SBarry Smith {
21847340559SBarry Smith   PetscErrorCode ierr;
21947340559SBarry Smith   PetscInt       i,n = 0;
22047340559SBarry Smith 
22147340559SBarry Smith   PetscFunctionBegin;
22247340559SBarry Smith   while (list[n++]) ;
22347340559SBarry Smith   ierr = PetscMalloc((n+1)*sizeof(char**),t);CHKERRQ(ierr);
22447340559SBarry Smith   for (i=0; i<n; i++) {
22547340559SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
22647340559SBarry Smith   }
22747340559SBarry Smith   (*t)[n] = PETSC_NULL;
22847340559SBarry Smith   PetscFunctionReturn(0);
22947340559SBarry Smith }
23047340559SBarry Smith 
23147340559SBarry Smith #undef __FUNCT__
23247340559SBarry Smith #define __FUNCT__ "PetscStrArrayDestroy"
23347340559SBarry Smith /*@C
23447340559SBarry Smith    PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
23547340559SBarry Smith 
23647340559SBarry Smith    Not Collective
23747340559SBarry Smith 
23847340559SBarry Smith    Output Parameters:
23947340559SBarry Smith .   list - array of strings
24047340559SBarry Smith 
24147340559SBarry Smith    Level: intermediate
24247340559SBarry Smith 
24347340559SBarry Smith    Concepts: command line arguments
24447340559SBarry Smith 
24547340559SBarry Smith    Notes: Not for use in Fortran
24647340559SBarry Smith 
24747340559SBarry Smith .seealso: PetscStrArrayallocpy()
24847340559SBarry Smith 
24947340559SBarry Smith @*/
250*6fed8037SJed Brown PetscErrorCode PetscStrArrayDestroy(char ***list)
25147340559SBarry Smith {
25247340559SBarry Smith   PetscInt       n = 0;
25347340559SBarry Smith   PetscErrorCode ierr;
25447340559SBarry Smith 
255*6fed8037SJed Brown   PetscFunctionBegin;
256*6fed8037SJed Brown   if (!*list) PetscFunctionReturn(0);
257*6fed8037SJed Brown   while ((*list)[n]) {
258*6fed8037SJed Brown     ierr = PetscFree((*list)[n]);CHKERRQ(ierr);
25947340559SBarry Smith     n++;
26047340559SBarry Smith   }
261*6fed8037SJed Brown   ierr = PetscFree(*list);CHKERRQ(ierr);
262*6fed8037SJed Brown   PetscFunctionReturn(0);
26347340559SBarry Smith }
26447340559SBarry Smith 
26547340559SBarry Smith #undef __FUNCT__
266e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcpy"
267e5c89e4eSSatish Balay /*@C
268e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
269e5c89e4eSSatish Balay 
270e5c89e4eSSatish Balay    Not Collective
271e5c89e4eSSatish Balay 
272e5c89e4eSSatish Balay    Input Parameters:
273e5c89e4eSSatish Balay .  t - pointer to string
274e5c89e4eSSatish Balay 
275e5c89e4eSSatish Balay    Output Parameter:
276e5c89e4eSSatish Balay .  s - the copied string
277e5c89e4eSSatish Balay 
278e5c89e4eSSatish Balay    Level: intermediate
279e5c89e4eSSatish Balay 
2806f013253SBarry Smith    Notes:
281e5c89e4eSSatish Balay      Null string returns a string starting with zero
282e5c89e4eSSatish Balay 
2836f013253SBarry Smith      Not for use in Fortran
2846f013253SBarry Smith 
285e5c89e4eSSatish Balay   Concepts: string copy
286e5c89e4eSSatish Balay 
287e5c89e4eSSatish Balay .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat()
288e5c89e4eSSatish Balay 
289e5c89e4eSSatish Balay @*/
290acc6cc86SBarry Smith 
2917087cfbeSBarry Smith PetscErrorCode  PetscStrcpy(char s[],const char t[])
292e5c89e4eSSatish Balay {
293e5c89e4eSSatish Balay   PetscFunctionBegin;
29417186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
295e5c89e4eSSatish Balay   if (t) {strcpy(s,t);}
296e5c89e4eSSatish Balay   else if (s) {s[0] = 0;}
297e5c89e4eSSatish Balay   PetscFunctionReturn(0);
298e5c89e4eSSatish Balay }
299e5c89e4eSSatish Balay 
300e5c89e4eSSatish Balay #undef __FUNCT__
301e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncpy"
302e5c89e4eSSatish Balay /*@C
303e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
304e5c89e4eSSatish Balay 
305e5c89e4eSSatish Balay    Not Collective
306e5c89e4eSSatish Balay 
307e5c89e4eSSatish Balay    Input Parameters:
308e5c89e4eSSatish Balay +  t - pointer to string
309e5c89e4eSSatish Balay -  n - the length to copy
310e5c89e4eSSatish Balay 
311e5c89e4eSSatish Balay    Output Parameter:
312e5c89e4eSSatish Balay .  s - the copied string
313e5c89e4eSSatish Balay 
314e5c89e4eSSatish Balay    Level: intermediate
315e5c89e4eSSatish Balay 
316e5c89e4eSSatish Balay    Note:
317e5c89e4eSSatish Balay      Null string returns a string starting with zero
318e5c89e4eSSatish Balay 
319e5c89e4eSSatish Balay   Concepts: string copy
320e5c89e4eSSatish Balay 
321e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat()
322e5c89e4eSSatish Balay 
323e5c89e4eSSatish Balay @*/
3247087cfbeSBarry Smith PetscErrorCode  PetscStrncpy(char s[],const char t[],size_t n)
325e5c89e4eSSatish Balay {
326e5c89e4eSSatish Balay   PetscFunctionBegin;
32717186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
328e5c89e4eSSatish Balay   if (t) {strncpy(s,t,n);}
329e5c89e4eSSatish Balay   else if (s) {s[0] = 0;}
330e5c89e4eSSatish Balay   PetscFunctionReturn(0);
331e5c89e4eSSatish Balay }
332e5c89e4eSSatish Balay 
333e5c89e4eSSatish Balay #undef __FUNCT__
334e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcat"
335e5c89e4eSSatish Balay /*@C
336e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
337e5c89e4eSSatish Balay 
338e5c89e4eSSatish Balay    Not Collective
339e5c89e4eSSatish Balay 
340e5c89e4eSSatish Balay    Input Parameters:
341e5e2177aSMatthew Knepley +  s - string to be added to
342e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
343e5c89e4eSSatish Balay 
344e5c89e4eSSatish Balay    Level: intermediate
345e5c89e4eSSatish Balay 
3466f013253SBarry Smith    Notes: Not for use in Fortran
3476f013253SBarry Smith 
348e5c89e4eSSatish Balay   Concepts: string copy
349e5c89e4eSSatish Balay 
350e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat()
351e5c89e4eSSatish Balay 
352e5c89e4eSSatish Balay @*/
3537087cfbeSBarry Smith PetscErrorCode  PetscStrcat(char s[],const char t[])
354e5c89e4eSSatish Balay {
355e5c89e4eSSatish Balay   PetscFunctionBegin;
3569b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
357e5c89e4eSSatish Balay   strcat(s,t);
358e5c89e4eSSatish Balay   PetscFunctionReturn(0);
359e5c89e4eSSatish Balay }
360e5c89e4eSSatish Balay 
361e5c89e4eSSatish Balay #undef __FUNCT__
362e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncat"
363e5c89e4eSSatish Balay /*@C
364e5c89e4eSSatish Balay    PetscStrncat - Concatenates a string onto a given string, up to a given length
365e5c89e4eSSatish Balay 
366e5c89e4eSSatish Balay    Not Collective
367e5c89e4eSSatish Balay 
368e5c89e4eSSatish Balay    Input Parameters:
369e5c89e4eSSatish Balay +  s - pointer to string to be added to end
370e5c89e4eSSatish Balay .  t - string to be added to
371e5c89e4eSSatish Balay .  n - maximum length to copy
372e5c89e4eSSatish Balay 
373e5c89e4eSSatish Balay    Level: intermediate
374e5c89e4eSSatish Balay 
3756f013253SBarry Smith   Notes:    Not for use in Fortran
3766f013253SBarry Smith 
377e5c89e4eSSatish Balay   Concepts: string copy
378e5c89e4eSSatish Balay 
379e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
380e5c89e4eSSatish Balay 
381e5c89e4eSSatish Balay @*/
3827087cfbeSBarry Smith PetscErrorCode  PetscStrncat(char s[],const char t[],size_t n)
383e5c89e4eSSatish Balay {
384e5c89e4eSSatish Balay   PetscFunctionBegin;
385e5c89e4eSSatish Balay   strncat(s,t,n);
386e5c89e4eSSatish Balay   PetscFunctionReturn(0);
387e5c89e4eSSatish Balay }
388e5c89e4eSSatish Balay 
389e5c89e4eSSatish Balay #undef __FUNCT__
390e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcmp"
391e5c89e4eSSatish Balay /*@C
392e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
393e5c89e4eSSatish Balay 
394e5c89e4eSSatish Balay    Not Collective
395e5c89e4eSSatish Balay 
396e5c89e4eSSatish Balay    Input Parameters:
397e5c89e4eSSatish Balay +  a - pointer to string first string
398e5c89e4eSSatish Balay -  b - pointer to second string
399e5c89e4eSSatish Balay 
400e5c89e4eSSatish Balay    Output Parameter:
4018c74ee41SBarry Smith .  flg - PETSC_TRUE if the two strings are equal
402e5c89e4eSSatish Balay 
403e5c89e4eSSatish Balay    Level: intermediate
404e5c89e4eSSatish Balay 
4056f013253SBarry Smith    Notes:    Not for use in Fortran
4066f013253SBarry Smith 
407e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
408e5c89e4eSSatish Balay 
409e5c89e4eSSatish Balay @*/
4107087cfbeSBarry Smith PetscErrorCode  PetscStrcmp(const char a[],const char b[],PetscBool  *flg)
411e5c89e4eSSatish Balay {
412e5c89e4eSSatish Balay   int c;
413e5c89e4eSSatish Balay 
414e5c89e4eSSatish Balay   PetscFunctionBegin;
415e5c89e4eSSatish Balay   if (!a && !b) {
416e5c89e4eSSatish Balay     *flg = PETSC_TRUE;
417e5c89e4eSSatish Balay   } else if (!a || !b) {
418e5c89e4eSSatish Balay     *flg = PETSC_FALSE;
419e5c89e4eSSatish Balay   } 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;
457e5c89e4eSSatish Balay   if (!a && !b) {
458e5c89e4eSSatish Balay     *t = PETSC_FALSE;
459e5c89e4eSSatish Balay   } else if (a && !b) {
460e5c89e4eSSatish Balay     *t = PETSC_TRUE;
461e5c89e4eSSatish Balay   } else if (!a && b) {
462e5c89e4eSSatish Balay     *t = PETSC_FALSE;
463e5c89e4eSSatish Balay   } else {
464e5c89e4eSSatish Balay     c = strcmp(a,b);
465e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
466e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
467e5c89e4eSSatish Balay   }
468e5c89e4eSSatish Balay   PetscFunctionReturn(0);
469e5c89e4eSSatish Balay }
470e5c89e4eSSatish Balay 
471e5c89e4eSSatish Balay #undef __FUNCT__
472e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcasecmp"
473e5c89e4eSSatish Balay /*@C
474e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
475e5c89e4eSSatish Balay      except possibly for case.
476e5c89e4eSSatish Balay 
477e5c89e4eSSatish Balay    Not Collective
478e5c89e4eSSatish Balay 
479e5c89e4eSSatish Balay    Input Parameters:
480e5c89e4eSSatish Balay +  a - pointer to first string
481e5c89e4eSSatish Balay -  b - pointer to second string
482e5c89e4eSSatish Balay 
483e5c89e4eSSatish Balay    Output Parameter:
484e5c89e4eSSatish Balay .  flg - if the two strings are the same
485e5c89e4eSSatish Balay 
486e5c89e4eSSatish Balay    Notes:
487e5c89e4eSSatish Balay     Null arguments are ok
488e5c89e4eSSatish Balay 
4896f013253SBarry Smith    Not for use in Fortran
4906f013253SBarry Smith 
491e5c89e4eSSatish Balay    Level: intermediate
492e5c89e4eSSatish Balay 
493e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
494e5c89e4eSSatish Balay 
495e5c89e4eSSatish Balay @*/
4967087cfbeSBarry Smith PetscErrorCode  PetscStrcasecmp(const char a[],const char b[],PetscBool  *t)
497e5c89e4eSSatish Balay {
498e5c89e4eSSatish Balay   int c;
499e5c89e4eSSatish Balay 
500e5c89e4eSSatish Balay   PetscFunctionBegin;
501e5c89e4eSSatish Balay   if (!a && !b) c = 0;
502e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
50332b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
50432b366c8SSatish Balay   else c = strcasecmp(a,b);
50532b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
506e5c89e4eSSatish Balay   else c = stricmp(a,b);
507e5c89e4eSSatish Balay #else
50832b366c8SSatish Balay   else {
50932b366c8SSatish Balay     char           *aa,*bb;
51032b366c8SSatish Balay     PetscErrorCode ierr;
51132b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
51232b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
51332b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
51432b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
51532b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
516503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
517503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
51832b366c8SSatish Balay     PetscFunctionReturn(0);
51932b366c8SSatish Balay   }
520e5c89e4eSSatish Balay #endif
521e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
522e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
523e5c89e4eSSatish Balay   PetscFunctionReturn(0);
524e5c89e4eSSatish Balay }
525e5c89e4eSSatish Balay 
52632b366c8SSatish Balay 
52732b366c8SSatish Balay 
528e5c89e4eSSatish Balay #undef __FUNCT__
529e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncmp"
530e5c89e4eSSatish Balay /*@C
531e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
532e5c89e4eSSatish Balay 
533e5c89e4eSSatish Balay    Not Collective
534e5c89e4eSSatish Balay 
535e5c89e4eSSatish Balay    Input Parameters:
536e5c89e4eSSatish Balay +  a - pointer to first string
537e5c89e4eSSatish Balay .  b - pointer to second string
538e5c89e4eSSatish Balay -  n - length to compare up to
539e5c89e4eSSatish Balay 
540e5c89e4eSSatish Balay    Output Parameter:
541e5c89e4eSSatish Balay .  t - if the two strings are equal
542e5c89e4eSSatish Balay 
543e5c89e4eSSatish Balay    Level: intermediate
544e5c89e4eSSatish Balay 
5456f013253SBarry Smith    Notes:    Not for use in Fortran
5466f013253SBarry Smith 
547e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
548e5c89e4eSSatish Balay 
549e5c89e4eSSatish Balay @*/
5507087cfbeSBarry Smith PetscErrorCode  PetscStrncmp(const char a[],const char b[],size_t n,PetscBool  *t)
551e5c89e4eSSatish Balay {
552e5c89e4eSSatish Balay   int c;
553e5c89e4eSSatish Balay 
554e5c89e4eSSatish Balay   PetscFunctionBegin;
555e5c89e4eSSatish Balay   c = strncmp(a,b,n);
556e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
557e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
558e5c89e4eSSatish Balay   PetscFunctionReturn(0);
559e5c89e4eSSatish Balay }
560e5c89e4eSSatish Balay 
561e5c89e4eSSatish Balay #undef __FUNCT__
562e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrchr"
563e5c89e4eSSatish Balay /*@C
564e5c89e4eSSatish Balay    PetscStrchr - Locates first occurance of a character in a string
565e5c89e4eSSatish Balay 
566e5c89e4eSSatish Balay    Not Collective
567e5c89e4eSSatish Balay 
568e5c89e4eSSatish Balay    Input Parameters:
569e5c89e4eSSatish Balay +  a - pointer to string
570e5c89e4eSSatish Balay -  b - character
571e5c89e4eSSatish Balay 
572e5c89e4eSSatish Balay    Output Parameter:
573e5c89e4eSSatish Balay .  c - location of occurance, PETSC_NULL if not found
574e5c89e4eSSatish Balay 
575e5c89e4eSSatish Balay    Level: intermediate
576e5c89e4eSSatish Balay 
5776f013253SBarry Smith    Notes:    Not for use in Fortran
5786f013253SBarry Smith 
579e5c89e4eSSatish Balay @*/
5807087cfbeSBarry Smith PetscErrorCode  PetscStrchr(const char a[],char b,char *c[])
581e5c89e4eSSatish Balay {
582e5c89e4eSSatish Balay   PetscFunctionBegin;
583e5c89e4eSSatish Balay   *c = (char *)strchr(a,b);
584e5c89e4eSSatish Balay   PetscFunctionReturn(0);
585e5c89e4eSSatish Balay }
586e5c89e4eSSatish Balay 
587e5c89e4eSSatish Balay #undef __FUNCT__
588e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrrchr"
589e5c89e4eSSatish Balay /*@C
590e5c89e4eSSatish Balay    PetscStrrchr - Locates one location past the last occurance of a character in a string,
591e5c89e4eSSatish Balay       if the character is not found then returns entire string
592e5c89e4eSSatish Balay 
593e5c89e4eSSatish Balay    Not Collective
594e5c89e4eSSatish Balay 
595e5c89e4eSSatish Balay    Input Parameters:
596e5c89e4eSSatish Balay +  a - pointer to string
597e5c89e4eSSatish Balay -  b - character
598e5c89e4eSSatish Balay 
599e5c89e4eSSatish Balay    Output Parameter:
600e5c89e4eSSatish Balay .  tmp - location of occurance, a if not found
601e5c89e4eSSatish Balay 
602e5c89e4eSSatish Balay    Level: intermediate
603e5c89e4eSSatish Balay 
6046f013253SBarry Smith    Notes:    Not for use in Fortran
6056f013253SBarry Smith 
606e5c89e4eSSatish Balay @*/
6077087cfbeSBarry Smith PetscErrorCode  PetscStrrchr(const char a[],char b,char *tmp[])
608e5c89e4eSSatish Balay {
609e5c89e4eSSatish Balay   PetscFunctionBegin;
610e5c89e4eSSatish Balay   *tmp = (char *)strrchr(a,b);
611e5c89e4eSSatish Balay   if (!*tmp) *tmp = (char*)a; else *tmp = *tmp + 1;
612e5c89e4eSSatish Balay   PetscFunctionReturn(0);
613e5c89e4eSSatish Balay }
614e5c89e4eSSatish Balay 
615e5c89e4eSSatish Balay #undef __FUNCT__
616e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrtolower"
617e5c89e4eSSatish Balay /*@C
618e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
619e5c89e4eSSatish Balay 
620e5c89e4eSSatish Balay    Not Collective
621e5c89e4eSSatish Balay 
622e5c89e4eSSatish Balay    Input Parameters:
623e5c89e4eSSatish Balay .  a - pointer to string
624e5c89e4eSSatish Balay 
625e5c89e4eSSatish Balay    Level: intermediate
626e5c89e4eSSatish Balay 
6276f013253SBarry Smith    Notes:    Not for use in Fortran
6286f013253SBarry Smith 
629e5c89e4eSSatish Balay @*/
6307087cfbeSBarry Smith PetscErrorCode  PetscStrtolower(char a[])
631e5c89e4eSSatish Balay {
632e5c89e4eSSatish Balay   PetscFunctionBegin;
633e5c89e4eSSatish Balay   while (*a) {
634e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
635e5c89e4eSSatish Balay     a++;
636e5c89e4eSSatish Balay   }
637e5c89e4eSSatish Balay   PetscFunctionReturn(0);
638e5c89e4eSSatish Balay }
639e5c89e4eSSatish Balay 
6407ba3a57cSBarry Smith #undef __FUNCT__
6417ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswith"
6427ba3a57cSBarry Smith /*@C
6437ba3a57cSBarry Smith    PetscStrendswith - Determines if a string ends with a certain string
6441d1a0024SBarry Smith 
6457ba3a57cSBarry Smith    Not Collective
6467ba3a57cSBarry Smith 
6477ba3a57cSBarry Smith    Input Parameters:
6487ba3a57cSBarry Smith +  a - pointer to string
6497ba3a57cSBarry Smith -  b - string to endwith
6507ba3a57cSBarry Smith 
6517ba3a57cSBarry Smith    Output Parameter:
6527ba3a57cSBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
6537ba3a57cSBarry Smith 
6547ba3a57cSBarry Smith    Notes:     Not for use in Fortran
6557ba3a57cSBarry Smith 
6567ba3a57cSBarry Smith    Level: intermediate
6577ba3a57cSBarry Smith 
6587ba3a57cSBarry Smith @*/
6597ba3a57cSBarry Smith PetscErrorCode  PetscStrendswith(const char a[],const char b[],PetscBool *flg)
6607ba3a57cSBarry Smith {
6617ba3a57cSBarry Smith   char           *test;
6627ba3a57cSBarry Smith   PetscErrorCode ierr;
6637ba3a57cSBarry Smith   size_t         na,nb;
6647ba3a57cSBarry Smith 
6657ba3a57cSBarry Smith   PetscFunctionBegin;
6667ba3a57cSBarry Smith   *flg = PETSC_FALSE;
6677ba3a57cSBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
6687ba3a57cSBarry Smith   if (test) {
6697ba3a57cSBarry Smith     ierr = PetscStrlen(a,&na);CHKERRQ(ierr);
6707ba3a57cSBarry Smith     ierr = PetscStrlen(b,&nb);CHKERRQ(ierr);
6717ba3a57cSBarry Smith     if (a+na-nb == test) *flg = PETSC_TRUE;
6727ba3a57cSBarry Smith   }
6737ba3a57cSBarry Smith   PetscFunctionReturn(0);
6747ba3a57cSBarry Smith }
6757ba3a57cSBarry Smith 
6767ba3a57cSBarry Smith #undef __FUNCT__
6777ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswithwhich"
6787ba3a57cSBarry Smith /*@C
6797ba3a57cSBarry Smith    PetscStrendswithwhich - Determines if a string ends with one of several possible strings
6807ba3a57cSBarry Smith 
6817ba3a57cSBarry Smith    Not Collective
6827ba3a57cSBarry Smith 
6837ba3a57cSBarry Smith    Input Parameters:
6847ba3a57cSBarry Smith +  a - pointer to string
6857ba3a57cSBarry Smith -  bs - strings to endwith (last entry must be null)
6867ba3a57cSBarry Smith 
6877ba3a57cSBarry Smith    Output Parameter:
6887ba3a57cSBarry Smith .  cnt - the index of the string it ends with or 1+the last possible index
6897ba3a57cSBarry Smith 
6907ba3a57cSBarry Smith    Notes:     Not for use in Fortran
6917ba3a57cSBarry Smith 
6927ba3a57cSBarry Smith    Level: intermediate
6937ba3a57cSBarry Smith 
6947ba3a57cSBarry Smith @*/
6957ba3a57cSBarry Smith PetscErrorCode  PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt)
6967ba3a57cSBarry Smith {
6977ba3a57cSBarry Smith   PetscBool      flg;
6987ba3a57cSBarry Smith   PetscErrorCode ierr;
6997ba3a57cSBarry Smith 
7007ba3a57cSBarry Smith   PetscFunctionBegin;
7017ba3a57cSBarry Smith   *cnt = 0;
7027ba3a57cSBarry Smith   while (bs[*cnt]) {
7037ba3a57cSBarry Smith     ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr);
7047ba3a57cSBarry Smith     if (flg) PetscFunctionReturn(0);
7057ba3a57cSBarry Smith     *cnt += 1;
7067ba3a57cSBarry Smith   }
7077ba3a57cSBarry Smith   PetscFunctionReturn(0);
7087ba3a57cSBarry Smith }
7097ba3a57cSBarry Smith 
7107ba3a57cSBarry Smith #undef __FUNCT__
7117ba3a57cSBarry Smith #define __FUNCT__ "PetscStrrstr"
7127ba3a57cSBarry Smith /*@C
7137ba3a57cSBarry Smith    PetscStrrstr - Locates last occurance of string in another string
7147ba3a57cSBarry Smith 
7157ba3a57cSBarry Smith    Not Collective
7167ba3a57cSBarry Smith 
7177ba3a57cSBarry Smith    Input Parameters:
7187ba3a57cSBarry Smith +  a - pointer to string
7197ba3a57cSBarry Smith -  b - string to find
7207ba3a57cSBarry Smith 
7217ba3a57cSBarry Smith    Output Parameter:
7227ba3a57cSBarry Smith .  tmp - location of occurance
7237ba3a57cSBarry Smith 
7247ba3a57cSBarry Smith    Notes:     Not for use in Fortran
7257ba3a57cSBarry Smith 
7267ba3a57cSBarry Smith    Level: intermediate
7277ba3a57cSBarry Smith 
7287ba3a57cSBarry Smith @*/
7297ba3a57cSBarry Smith PetscErrorCode  PetscStrrstr(const char a[],const char b[],char *tmp[])
7307ba3a57cSBarry Smith {
7317ba3a57cSBarry Smith   const char *stmp = a, *ltmp = 0;
7327ba3a57cSBarry Smith 
7337ba3a57cSBarry Smith   PetscFunctionBegin;
7347ba3a57cSBarry Smith   while (stmp) {
7357ba3a57cSBarry Smith     stmp = (char *)strstr(stmp,b);
7367ba3a57cSBarry Smith     if (stmp) {ltmp = stmp;stmp++;}
7377ba3a57cSBarry Smith   }
7387ba3a57cSBarry Smith   *tmp = (char *)ltmp;
7397ba3a57cSBarry Smith   PetscFunctionReturn(0);
7407ba3a57cSBarry Smith }
7417ba3a57cSBarry Smith 
7427ba3a57cSBarry Smith #undef __FUNCT__
7437ba3a57cSBarry Smith #define __FUNCT__ "PetscStrstr"
7447ba3a57cSBarry Smith /*@C
7457ba3a57cSBarry Smith    PetscStrstr - Locates first occurance of string in another string
7467ba3a57cSBarry Smith 
7477ba3a57cSBarry Smith    Not Collective
7487ba3a57cSBarry Smith 
7497ba3a57cSBarry Smith    Input Parameters:
750160f4796SJed Brown +  haystack - string to search
751160f4796SJed Brown -  needle - string to find
7527ba3a57cSBarry Smith 
7537ba3a57cSBarry Smith    Output Parameter:
7547ba3a57cSBarry Smith .  tmp - location of occurance, is a PETSC_NULL if the string is not found
7557ba3a57cSBarry Smith 
7567ba3a57cSBarry Smith    Notes: Not for use in Fortran
7577ba3a57cSBarry Smith 
7587ba3a57cSBarry Smith    Level: intermediate
7597ba3a57cSBarry Smith 
7607ba3a57cSBarry Smith @*/
761160f4796SJed Brown PetscErrorCode  PetscStrstr(const char haystack[],const char needle[],char *tmp[])
7627ba3a57cSBarry Smith {
7637ba3a57cSBarry Smith   PetscFunctionBegin;
764160f4796SJed Brown   *tmp = (char *)strstr(haystack,needle);
7657ba3a57cSBarry Smith   PetscFunctionReturn(0);
7667ba3a57cSBarry Smith }
7677ba3a57cSBarry Smith 
7687ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
7691d1a0024SBarry Smith 
770e5c89e4eSSatish Balay #undef __FUNCT__
771e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenFind"
772e5c89e4eSSatish Balay /*@C
773e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
774e5c89e4eSSatish Balay 
775e5c89e4eSSatish Balay    Not Collective
776e5c89e4eSSatish Balay 
777e5c89e4eSSatish Balay    Input Parameters:
778e5c89e4eSSatish Balay .  a - pointer to token
779e5c89e4eSSatish Balay 
780e5c89e4eSSatish Balay    Output Parameter:
781e5c89e4eSSatish Balay .  result - location of occurance, PETSC_NULL if not found
782e5c89e4eSSatish Balay 
783e5c89e4eSSatish Balay    Notes:
784e5c89e4eSSatish Balay 
785e5c89e4eSSatish Balay      This version is different from the system version in that
786e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
787e5c89e4eSSatish Balay 
7884704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
7894704e885SBarry Smith    as a single token.
7904704e885SBarry Smith 
7916f013253SBarry Smith     Not for use in Fortran
7926f013253SBarry Smith 
793e5c89e4eSSatish Balay    Level: intermediate
794e5c89e4eSSatish Balay 
7956f013253SBarry Smith 
796e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
797e5c89e4eSSatish Balay @*/
7987087cfbeSBarry Smith PetscErrorCode  PetscTokenFind(PetscToken a,char *result[])
799e5c89e4eSSatish Balay {
8004704e885SBarry Smith   char *ptr = a->current,token;
801e5c89e4eSSatish Balay 
802e5c89e4eSSatish Balay   PetscFunctionBegin;
803e5c89e4eSSatish Balay   *result = a->current;
8044704e885SBarry Smith   if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);}
8054704e885SBarry Smith   token = a->token;
80690fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
807e5c89e4eSSatish Balay   while (ptr) {
8084704e885SBarry Smith     if (*ptr == token) {
809e5c89e4eSSatish Balay       *ptr++ = 0;
810e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
811e5c89e4eSSatish Balay       a->current = ptr;
812e5c89e4eSSatish Balay       break;
813e5c89e4eSSatish Balay     }
814e5c89e4eSSatish Balay     if (!*ptr) {
815e5c89e4eSSatish Balay       a->current = 0;
816e5c89e4eSSatish Balay       break;
817e5c89e4eSSatish Balay     }
818e5c89e4eSSatish Balay     ptr++;
819e5c89e4eSSatish Balay   }
820e5c89e4eSSatish Balay   PetscFunctionReturn(0);
821e5c89e4eSSatish Balay }
822e5c89e4eSSatish Balay 
823e5c89e4eSSatish Balay #undef __FUNCT__
824e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenCreate"
825e5c89e4eSSatish Balay /*@C
826e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
827e5c89e4eSSatish Balay 
828e5c89e4eSSatish Balay    Not Collective
829e5c89e4eSSatish Balay 
830e5c89e4eSSatish Balay    Input Parameters:
831e5c89e4eSSatish Balay +  string - the string to look in
832e5c89e4eSSatish Balay -  token - the character to look for
833e5c89e4eSSatish Balay 
834e5c89e4eSSatish Balay    Output Parameter:
835e5c89e4eSSatish Balay .  a - pointer to token
836e5c89e4eSSatish Balay 
837e5c89e4eSSatish Balay    Notes:
838e5c89e4eSSatish Balay 
839e5c89e4eSSatish Balay      This version is different from the system version in that
840e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
841e5c89e4eSSatish Balay 
8426f013253SBarry Smith     Not for use in Fortran
8436f013253SBarry Smith 
844e5c89e4eSSatish Balay    Level: intermediate
845e5c89e4eSSatish Balay 
846e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
847e5c89e4eSSatish Balay @*/
8487087cfbeSBarry Smith PetscErrorCode  PetscTokenCreate(const char a[],const char b,PetscToken *t)
849e5c89e4eSSatish Balay {
850e5c89e4eSSatish Balay   PetscErrorCode ierr;
851e5c89e4eSSatish Balay 
852e5c89e4eSSatish Balay   PetscFunctionBegin;
8531d1a0024SBarry Smith   ierr = PetscNew(struct _p_PetscToken,t);CHKERRQ(ierr);
854e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
855e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
856e5c89e4eSSatish Balay   (*t)->token   = b;
857e5c89e4eSSatish Balay   PetscFunctionReturn(0);
858e5c89e4eSSatish Balay }
859e5c89e4eSSatish Balay 
860e5c89e4eSSatish Balay #undef __FUNCT__
861e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenDestroy"
862e5c89e4eSSatish Balay /*@C
863e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
864e5c89e4eSSatish Balay 
865e5c89e4eSSatish Balay    Not Collective
866e5c89e4eSSatish Balay 
867e5c89e4eSSatish Balay    Input Parameters:
868e5c89e4eSSatish Balay .  a - pointer to token
869e5c89e4eSSatish Balay 
870e5c89e4eSSatish Balay    Level: intermediate
871e5c89e4eSSatish Balay 
8726f013253SBarry Smith    Notes:     Not for use in Fortran
8736f013253SBarry Smith 
874e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
875e5c89e4eSSatish Balay @*/
8768c74ee41SBarry Smith PetscErrorCode  PetscTokenDestroy(PetscToken *a)
877e5c89e4eSSatish Balay {
878e5c89e4eSSatish Balay   PetscErrorCode ierr;
879e5c89e4eSSatish Balay 
880e5c89e4eSSatish Balay   PetscFunctionBegin;
8818c74ee41SBarry Smith   if (!*a) PetscFunctionReturn(0);
8828c74ee41SBarry Smith   ierr = PetscFree((*a)->array);CHKERRQ(ierr);
8838c74ee41SBarry Smith   ierr = PetscFree(*a);CHKERRQ(ierr);
884e5c89e4eSSatish Balay   PetscFunctionReturn(0);
885e5c89e4eSSatish Balay }
886e5c89e4eSSatish Balay 
887e5c89e4eSSatish Balay 
888e5c89e4eSSatish Balay #undef __FUNCT__
889e5c89e4eSSatish Balay #define __FUNCT__ "PetscGetPetscDir"
890e5c89e4eSSatish Balay /*@C
891e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
892e5c89e4eSSatish Balay 
893e5c89e4eSSatish Balay    Not Collective
894e5c89e4eSSatish Balay 
895e5c89e4eSSatish Balay    Output Parameter:
896e5c89e4eSSatish Balay .  dir - the directory
897e5c89e4eSSatish Balay 
898e5c89e4eSSatish Balay    Level: developer
899e5c89e4eSSatish Balay 
9006f013253SBarry Smith    Notes: Not for use in Fortran
9016f013253SBarry Smith 
902e5c89e4eSSatish Balay @*/
9037087cfbeSBarry Smith PetscErrorCode  PetscGetPetscDir(const char *dir[])
904e5c89e4eSSatish Balay {
905e5c89e4eSSatish Balay   PetscFunctionBegin;
906e5c89e4eSSatish Balay   *dir = PETSC_DIR;
907e5c89e4eSSatish Balay   PetscFunctionReturn(0);
908e5c89e4eSSatish Balay }
909e5c89e4eSSatish Balay 
910e5c89e4eSSatish Balay #undef __FUNCT__
911e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrreplace"
912e5c89e4eSSatish Balay /*@C
913e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
914e5c89e4eSSatish Balay 
915e5c89e4eSSatish Balay    Not Collective
916e5c89e4eSSatish Balay 
917e5c89e4eSSatish Balay    Input Parameters:
918e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
91971573d7dSBarry Smith .   aa - the string to look in
920d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
921e5c89e4eSSatish Balay -   len - the length of b
922e5c89e4eSSatish Balay 
923e5c89e4eSSatish Balay    Notes:
924e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
925d5649816SBarry Smith       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
926e5c89e4eSSatish Balay       as well as any environmental variables.
927e5c89e4eSSatish Balay 
9286f013253SBarry Smith       PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
929acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
930acc6cc86SBarry Smith 
9316f013253SBarry Smith       Not for use in Fortran
9326f013253SBarry Smith 
933e5c89e4eSSatish Balay    Level: intermediate
934e5c89e4eSSatish Balay 
935e5c89e4eSSatish Balay @*/
9367087cfbeSBarry Smith PetscErrorCode  PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
937e5c89e4eSSatish Balay {
938e5c89e4eSSatish Balay   PetscErrorCode ierr;
939e5c89e4eSSatish Balay   int            i = 0;
940e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
94171573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
942d5649816SBarry Smith   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0};
943d5649816SBarry Smith   const char     *r[] = {0,0,0,0,0,0,0,0,0};
944ace3abfcSBarry Smith   PetscBool      flag;
945e5c89e4eSSatish Balay 
946e5c89e4eSSatish Balay   PetscFunctionBegin;
947e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
94871573d7dSBarry Smith   if (aa == b) {
94922982a5fSBarry Smith     ierr    = PetscStrallocpy(aa,(char **)&a);CHKERRQ(ierr);
95071573d7dSBarry Smith   }
951e5c89e4eSSatish Balay   ierr = PetscMalloc(len*sizeof(char*),&work);CHKERRQ(ierr);
952e5c89e4eSSatish Balay 
953e5c89e4eSSatish Balay   /* get values for replaced variables */
954487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr);
955487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr);
956487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr);
957487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[3]);CHKERRQ(ierr);
958487e5849SBarry Smith   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[4]);CHKERRQ(ierr);
959e5c89e4eSSatish Balay   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[5]);CHKERRQ(ierr);
960487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[6]);CHKERRQ(ierr);
961d5649816SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[7]);CHKERRQ(ierr);
962487e5849SBarry Smith   ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr);
963487e5849SBarry Smith   ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
964487e5849SBarry Smith   ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
965487e5849SBarry Smith   ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr);
966d5649816SBarry Smith   ierr = PetscGetHostName((char*)r[7],256);CHKERRQ(ierr);
967487e5849SBarry Smith 
968487e5849SBarry Smith   /* replace that are in environment */
969487e5849SBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr);
970487e5849SBarry Smith   if (flag) {
971487e5849SBarry Smith     ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr);
972487e5849SBarry Smith   }
973e5c89e4eSSatish Balay 
974e5c89e4eSSatish Balay   /* replace the requested strings */
975e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
976e5c89e4eSSatish Balay   while (s[i]) {
977e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
978e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
979e5c89e4eSSatish Balay     while (par) {
980e5c89e4eSSatish Balay       *par  =  0;
981e5c89e4eSSatish Balay       par  += l;
982e5c89e4eSSatish Balay 
983e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
984e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
985e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
98617186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
987e5c89e4eSSatish Balay       ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
988e5c89e4eSSatish Balay       ierr  = PetscStrcat(work,r[i]);CHKERRQ(ierr);
989e5c89e4eSSatish Balay       ierr  = PetscStrcat(work,par);CHKERRQ(ierr);
990e5c89e4eSSatish Balay       ierr  = PetscStrncpy(b,work,len);CHKERRQ(ierr);
991e5c89e4eSSatish Balay       ierr  = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
992e5c89e4eSSatish Balay     }
993e5c89e4eSSatish Balay     i++;
994e5c89e4eSSatish Balay   }
995487e5849SBarry Smith   i = 0;
996487e5849SBarry Smith   while (r[i]) {
997e5c89e4eSSatish Balay     tfree = (char*)r[i];
998e5c89e4eSSatish Balay     ierr = PetscFree(tfree);CHKERRQ(ierr);
999487e5849SBarry Smith     i++;
1000e5c89e4eSSatish Balay   }
1001e5c89e4eSSatish Balay 
1002e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
1003e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1004e5c89e4eSSatish Balay   while (par) {
1005e5c89e4eSSatish Balay     *par = 0;
1006e5c89e4eSSatish Balay     par += 2;
1007e5c89e4eSSatish Balay     ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
1008e5c89e4eSSatish Balay     ierr = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
1009e5c89e4eSSatish Balay     *epar = 0;
1010e5c89e4eSSatish Balay     epar += 1;
1011e5c89e4eSSatish Balay     ierr = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr);
10127ba3a57cSBarry Smith     if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
1013e5c89e4eSSatish Balay     ierr = PetscStrcat(work,env);CHKERRQ(ierr);
1014e5c89e4eSSatish Balay     ierr = PetscStrcat(work,epar);CHKERRQ(ierr);
1015e5c89e4eSSatish Balay     ierr = PetscStrcpy(b,work);CHKERRQ(ierr);
1016e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1017e5c89e4eSSatish Balay   }
1018e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
101971573d7dSBarry Smith   if (aa == b) {
102071573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
102171573d7dSBarry Smith   }
1022e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1023e5c89e4eSSatish Balay }
1024e5c89e4eSSatish Balay 
1025e5c89e4eSSatish Balay 
1026