xref: /petsc/src/sys/utils/str.c (revision 40a7e1efb0fdcd482fea27509363e565df09f78a)
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 
47*40a7e1efSBarry Smith   if (!s) n = 0;
48*40a7e1efSBarry Smith   else    n = strlen(s);
493c311c98SBarry Smith   *argc = 0;
503c311c98SBarry Smith   for (i=0; i<n; i++) {
513c311c98SBarry Smith     if (s[i] != ' ') break;
523c311c98SBarry Smith   }
533c311c98SBarry Smith   for (;i<n+1; i++) {
543c311c98SBarry Smith     if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
553c311c98SBarry Smith     else if (s[i] != ' ') {flg = PETSC_FALSE;}
563c311c98SBarry Smith   }
57301d30feSBarry Smith   (*args) = (char **) malloc(((*argc)+1)*sizeof(char**)); if (!*args) return PETSC_ERR_MEM;
5853e6e2c4SHong Zhang   lens    = (int*) malloc((*argc)*sizeof(int)); if (!lens) return PETSC_ERR_MEM;
593c311c98SBarry Smith   for (i=0; i<*argc; i++) lens[i] = 0;
603c311c98SBarry Smith 
613c311c98SBarry Smith   *argc = 0;
623c311c98SBarry Smith   for (i=0; i<n; i++) {
633c311c98SBarry Smith     if (s[i] != ' ') break;
643c311c98SBarry Smith   }
653c311c98SBarry Smith   for (;i<n+1; i++) {
663c311c98SBarry Smith     if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
673c311c98SBarry Smith     else if (s[i] != ' ') {lens[*argc]++;flg = PETSC_FALSE;}
683c311c98SBarry Smith   }
693c311c98SBarry Smith 
703c311c98SBarry Smith   for (i=0; i<*argc; i++) {
71675282fdSHong Zhang     (*args)[i] = (char*) malloc((lens[i]+1)*sizeof(char)); if (!(*args)[i]) return PETSC_ERR_MEM;
723c311c98SBarry Smith   }
73301d30feSBarry Smith   (*args)[*argc] = 0;
743c311c98SBarry Smith 
753c311c98SBarry Smith   *argc = 0;
763c311c98SBarry Smith   for (i=0; i<n; i++) {
773c311c98SBarry Smith     if (s[i] != ' ') break;
783c311c98SBarry Smith   }
793c311c98SBarry Smith   for (;i<n+1; i++) {
803c311c98SBarry Smith     if ((s[i] == ' ' || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
81301d30feSBarry Smith     else if (s[i] != ' ' && s[i] != 0) {(*args)[*argc][cnt++] = s[i]; flg = PETSC_FALSE;}
823c311c98SBarry Smith   }
833c311c98SBarry Smith   return 0;
843c311c98SBarry Smith }
853c311c98SBarry Smith 
863c311c98SBarry Smith #undef __FUNCT__
87301d30feSBarry Smith #define __FUNCT__ "PetscStrToArrayDestroy"
88301d30feSBarry Smith /*@C
89301d30feSBarry Smith    PetscStrToArrayDestroy - Frees array created with PetscStrToArray().
90301d30feSBarry Smith 
91301d30feSBarry Smith    Not Collective
92301d30feSBarry Smith 
93301d30feSBarry Smith    Output Parameters:
94301d30feSBarry Smith +  argc - the number of arguments
95301d30feSBarry Smith -  args - the array of arguments
96301d30feSBarry Smith 
97301d30feSBarry Smith    Level: intermediate
98301d30feSBarry Smith 
99301d30feSBarry Smith    Concepts: command line arguments
100301d30feSBarry Smith 
101301d30feSBarry Smith    Notes: This may be called before PetscInitialize() or after PetscFinalize()
102301d30feSBarry Smith 
1036f013253SBarry Smith    Not for use in Fortran
1046f013253SBarry Smith 
105301d30feSBarry Smith .seealso: PetscStrToArray()
106301d30feSBarry Smith 
107301d30feSBarry Smith @*/
1087087cfbeSBarry Smith PetscErrorCode  PetscStrToArrayDestroy(int argc,char **args)
109301d30feSBarry Smith {
110301d30feSBarry Smith   PetscInt i;
111301d30feSBarry Smith 
112301d30feSBarry Smith   for (i=0; i<argc; i++) {
113301d30feSBarry Smith     free(args[i]);
114301d30feSBarry Smith   }
115301d30feSBarry Smith   free(args);
116301d30feSBarry Smith   return 0;
117301d30feSBarry Smith }
118301d30feSBarry Smith 
119301d30feSBarry Smith #undef __FUNCT__
120e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrlen"
121e5c89e4eSSatish Balay /*@C
122e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
123e5c89e4eSSatish Balay 
124e5c89e4eSSatish Balay    Not Collective
125e5c89e4eSSatish Balay 
126e5c89e4eSSatish Balay    Input Parameters:
127e5c89e4eSSatish Balay .  s - pointer to string
128e5c89e4eSSatish Balay 
129e5c89e4eSSatish Balay    Output Parameter:
130e5c89e4eSSatish Balay .  len - length in bytes
131e5c89e4eSSatish Balay 
132e5c89e4eSSatish Balay    Level: intermediate
133e5c89e4eSSatish Balay 
134e5c89e4eSSatish Balay    Note:
135e5c89e4eSSatish Balay    This routine is analogous to strlen().
136e5c89e4eSSatish Balay 
137e5c89e4eSSatish Balay    Null string returns a length of zero
138e5c89e4eSSatish Balay 
1396f013253SBarry Smith    Not for use in Fortran
1406f013253SBarry Smith 
141e5c89e4eSSatish Balay   Concepts: string length
142e5c89e4eSSatish Balay 
143e5c89e4eSSatish Balay @*/
1447087cfbeSBarry Smith PetscErrorCode  PetscStrlen(const char s[],size_t *len)
145e5c89e4eSSatish Balay {
146e5c89e4eSSatish Balay   PetscFunctionBegin;
147e5c89e4eSSatish Balay   if (!s) {
148e5c89e4eSSatish Balay     *len = 0;
149e5c89e4eSSatish Balay   } else {
150e5c89e4eSSatish Balay     *len = strlen(s);
151e5c89e4eSSatish Balay   }
152e5c89e4eSSatish Balay   PetscFunctionReturn(0);
153e5c89e4eSSatish Balay }
154e5c89e4eSSatish Balay 
155e5c89e4eSSatish Balay #undef __FUNCT__
156e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrallocpy"
157e5c89e4eSSatish Balay /*@C
158e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
159e5c89e4eSSatish Balay 
160e5c89e4eSSatish Balay    Not Collective
161e5c89e4eSSatish Balay 
162e5c89e4eSSatish Balay    Input Parameters:
163e5c89e4eSSatish Balay .  s - pointer to string
164e5c89e4eSSatish Balay 
165e5c89e4eSSatish Balay    Output Parameter:
166e5c89e4eSSatish Balay .  t - the copied string
167e5c89e4eSSatish Balay 
168e5c89e4eSSatish Balay    Level: intermediate
169e5c89e4eSSatish Balay 
170e5c89e4eSSatish Balay    Note:
171e5c89e4eSSatish Balay       Null string returns a new null string
172e5c89e4eSSatish Balay 
1736f013253SBarry Smith       Not for use in Fortran
1746f013253SBarry Smith 
175e5c89e4eSSatish Balay   Concepts: string copy
176e5c89e4eSSatish Balay 
177e5c89e4eSSatish Balay @*/
1787087cfbeSBarry Smith PetscErrorCode  PetscStrallocpy(const char s[],char *t[])
179e5c89e4eSSatish Balay {
180e5c89e4eSSatish Balay   PetscErrorCode ierr;
181e5c89e4eSSatish Balay   size_t         len;
18271573d7dSBarry Smith   char           *tmp = 0;
183e5c89e4eSSatish Balay 
184e5c89e4eSSatish Balay   PetscFunctionBegin;
185e5c89e4eSSatish Balay   if (s) {
186e5c89e4eSSatish Balay     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
18771573d7dSBarry Smith     ierr = PetscMalloc((1+len)*sizeof(char),&tmp);CHKERRQ(ierr);
18871573d7dSBarry Smith     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
189e5c89e4eSSatish Balay   }
19071573d7dSBarry Smith   *t = tmp;
191e5c89e4eSSatish Balay   PetscFunctionReturn(0);
192e5c89e4eSSatish Balay }
193e5c89e4eSSatish Balay 
194e5c89e4eSSatish Balay #undef __FUNCT__
19547340559SBarry Smith #define __FUNCT__ "PetscStrArrayallocpy"
19647340559SBarry Smith /*@C
19747340559SBarry Smith    PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
19847340559SBarry Smith 
19947340559SBarry Smith    Not Collective
20047340559SBarry Smith 
20147340559SBarry Smith    Input Parameters:
20247340559SBarry Smith .  s - pointer to array of strings (final string is a null)
20347340559SBarry Smith 
20447340559SBarry Smith    Output Parameter:
20547340559SBarry Smith .  t - the copied array string
20647340559SBarry Smith 
20747340559SBarry Smith    Level: intermediate
20847340559SBarry Smith 
20947340559SBarry Smith    Note:
21047340559SBarry Smith       Not for use in Fortran
21147340559SBarry Smith 
21247340559SBarry Smith   Concepts: string copy
21347340559SBarry Smith 
21447340559SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
21547340559SBarry Smith 
21647340559SBarry Smith @*/
21747340559SBarry Smith PetscErrorCode  PetscStrArrayallocpy(const char *const*list,char ***t)
21847340559SBarry Smith {
21947340559SBarry Smith   PetscErrorCode ierr;
22047340559SBarry Smith   PetscInt       i,n = 0;
22147340559SBarry Smith 
22247340559SBarry Smith   PetscFunctionBegin;
22347340559SBarry Smith   while (list[n++]) ;
22447340559SBarry Smith   ierr = PetscMalloc((n+1)*sizeof(char**),t);CHKERRQ(ierr);
22547340559SBarry Smith   for (i=0; i<n; i++) {
22647340559SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
22747340559SBarry Smith   }
22847340559SBarry Smith   (*t)[n] = PETSC_NULL;
22947340559SBarry Smith   PetscFunctionReturn(0);
23047340559SBarry Smith }
23147340559SBarry Smith 
23247340559SBarry Smith #undef __FUNCT__
23347340559SBarry Smith #define __FUNCT__ "PetscStrArrayDestroy"
23447340559SBarry Smith /*@C
23547340559SBarry Smith    PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
23647340559SBarry Smith 
23747340559SBarry Smith    Not Collective
23847340559SBarry Smith 
23947340559SBarry Smith    Output Parameters:
24047340559SBarry Smith .   list - array of strings
24147340559SBarry Smith 
24247340559SBarry Smith    Level: intermediate
24347340559SBarry Smith 
24447340559SBarry Smith    Concepts: command line arguments
24547340559SBarry Smith 
24647340559SBarry Smith    Notes: Not for use in Fortran
24747340559SBarry Smith 
24847340559SBarry Smith .seealso: PetscStrArrayallocpy()
24947340559SBarry Smith 
25047340559SBarry Smith @*/
2516fed8037SJed Brown PetscErrorCode PetscStrArrayDestroy(char ***list)
25247340559SBarry Smith {
25347340559SBarry Smith   PetscInt       n = 0;
25447340559SBarry Smith   PetscErrorCode ierr;
25547340559SBarry Smith 
2566fed8037SJed Brown   PetscFunctionBegin;
2576fed8037SJed Brown   if (!*list) PetscFunctionReturn(0);
2586fed8037SJed Brown   while ((*list)[n]) {
2596fed8037SJed Brown     ierr = PetscFree((*list)[n]);CHKERRQ(ierr);
26047340559SBarry Smith     n++;
26147340559SBarry Smith   }
2626fed8037SJed Brown   ierr = PetscFree(*list);CHKERRQ(ierr);
2636fed8037SJed Brown   PetscFunctionReturn(0);
26447340559SBarry Smith }
26547340559SBarry Smith 
26647340559SBarry Smith #undef __FUNCT__
267e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcpy"
268e5c89e4eSSatish Balay /*@C
269e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
270e5c89e4eSSatish Balay 
271e5c89e4eSSatish Balay    Not Collective
272e5c89e4eSSatish Balay 
273e5c89e4eSSatish Balay    Input Parameters:
274e5c89e4eSSatish Balay .  t - pointer to string
275e5c89e4eSSatish Balay 
276e5c89e4eSSatish Balay    Output Parameter:
277e5c89e4eSSatish Balay .  s - the copied string
278e5c89e4eSSatish Balay 
279e5c89e4eSSatish Balay    Level: intermediate
280e5c89e4eSSatish Balay 
2816f013253SBarry Smith    Notes:
282e5c89e4eSSatish Balay      Null string returns a string starting with zero
283e5c89e4eSSatish Balay 
2846f013253SBarry Smith      Not for use in Fortran
2856f013253SBarry Smith 
286e5c89e4eSSatish Balay   Concepts: string copy
287e5c89e4eSSatish Balay 
288e5c89e4eSSatish Balay .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat()
289e5c89e4eSSatish Balay 
290e5c89e4eSSatish Balay @*/
291acc6cc86SBarry Smith 
2927087cfbeSBarry Smith PetscErrorCode  PetscStrcpy(char s[],const char t[])
293e5c89e4eSSatish Balay {
294e5c89e4eSSatish Balay   PetscFunctionBegin;
29517186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
296e5c89e4eSSatish Balay   if (t) {strcpy(s,t);}
297e5c89e4eSSatish Balay   else if (s) {s[0] = 0;}
298e5c89e4eSSatish Balay   PetscFunctionReturn(0);
299e5c89e4eSSatish Balay }
300e5c89e4eSSatish Balay 
301e5c89e4eSSatish Balay #undef __FUNCT__
302e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncpy"
303e5c89e4eSSatish Balay /*@C
304e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
305e5c89e4eSSatish Balay 
306e5c89e4eSSatish Balay    Not Collective
307e5c89e4eSSatish Balay 
308e5c89e4eSSatish Balay    Input Parameters:
309e5c89e4eSSatish Balay +  t - pointer to string
310e5c89e4eSSatish Balay -  n - the length to copy
311e5c89e4eSSatish Balay 
312e5c89e4eSSatish Balay    Output Parameter:
313e5c89e4eSSatish Balay .  s - the copied string
314e5c89e4eSSatish Balay 
315e5c89e4eSSatish Balay    Level: intermediate
316e5c89e4eSSatish Balay 
317e5c89e4eSSatish Balay    Note:
318e5c89e4eSSatish Balay      Null string returns a string starting with zero
319e5c89e4eSSatish Balay 
320e5c89e4eSSatish Balay   Concepts: string copy
321e5c89e4eSSatish Balay 
322e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat()
323e5c89e4eSSatish Balay 
324e5c89e4eSSatish Balay @*/
3257087cfbeSBarry Smith PetscErrorCode  PetscStrncpy(char s[],const char t[],size_t n)
326e5c89e4eSSatish Balay {
327e5c89e4eSSatish Balay   PetscFunctionBegin;
32817186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
329e5c89e4eSSatish Balay   if (t) {strncpy(s,t,n);}
330e5c89e4eSSatish Balay   else if (s) {s[0] = 0;}
331e5c89e4eSSatish Balay   PetscFunctionReturn(0);
332e5c89e4eSSatish Balay }
333e5c89e4eSSatish Balay 
334e5c89e4eSSatish Balay #undef __FUNCT__
335e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcat"
336e5c89e4eSSatish Balay /*@C
337e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
338e5c89e4eSSatish Balay 
339e5c89e4eSSatish Balay    Not Collective
340e5c89e4eSSatish Balay 
341e5c89e4eSSatish Balay    Input Parameters:
342e5e2177aSMatthew Knepley +  s - string to be added to
343e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
344e5c89e4eSSatish Balay 
345e5c89e4eSSatish Balay    Level: intermediate
346e5c89e4eSSatish Balay 
3476f013253SBarry Smith    Notes: Not for use in Fortran
3486f013253SBarry Smith 
349e5c89e4eSSatish Balay   Concepts: string copy
350e5c89e4eSSatish Balay 
351e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat()
352e5c89e4eSSatish Balay 
353e5c89e4eSSatish Balay @*/
3547087cfbeSBarry Smith PetscErrorCode  PetscStrcat(char s[],const char t[])
355e5c89e4eSSatish Balay {
356e5c89e4eSSatish Balay   PetscFunctionBegin;
3579b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
358e5c89e4eSSatish Balay   strcat(s,t);
359e5c89e4eSSatish Balay   PetscFunctionReturn(0);
360e5c89e4eSSatish Balay }
361e5c89e4eSSatish Balay 
362e5c89e4eSSatish Balay #undef __FUNCT__
363e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncat"
364e5c89e4eSSatish Balay /*@C
365e5c89e4eSSatish Balay    PetscStrncat - Concatenates a string onto a given string, up to a given length
366e5c89e4eSSatish Balay 
367e5c89e4eSSatish Balay    Not Collective
368e5c89e4eSSatish Balay 
369e5c89e4eSSatish Balay    Input Parameters:
370e5c89e4eSSatish Balay +  s - pointer to string to be added to end
371e5c89e4eSSatish Balay .  t - string to be added to
372e5c89e4eSSatish Balay .  n - maximum length to copy
373e5c89e4eSSatish Balay 
374e5c89e4eSSatish Balay    Level: intermediate
375e5c89e4eSSatish Balay 
3766f013253SBarry Smith   Notes:    Not for use in Fortran
3776f013253SBarry Smith 
378e5c89e4eSSatish Balay   Concepts: string copy
379e5c89e4eSSatish Balay 
380e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
381e5c89e4eSSatish Balay 
382e5c89e4eSSatish Balay @*/
3837087cfbeSBarry Smith PetscErrorCode  PetscStrncat(char s[],const char t[],size_t n)
384e5c89e4eSSatish Balay {
385e5c89e4eSSatish Balay   PetscFunctionBegin;
386e5c89e4eSSatish Balay   strncat(s,t,n);
387e5c89e4eSSatish Balay   PetscFunctionReturn(0);
388e5c89e4eSSatish Balay }
389e5c89e4eSSatish Balay 
390e5c89e4eSSatish Balay #undef __FUNCT__
391e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcmp"
392e5c89e4eSSatish Balay /*@C
393e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
394e5c89e4eSSatish Balay 
395e5c89e4eSSatish Balay    Not Collective
396e5c89e4eSSatish Balay 
397e5c89e4eSSatish Balay    Input Parameters:
398e5c89e4eSSatish Balay +  a - pointer to string first string
399e5c89e4eSSatish Balay -  b - pointer to second string
400e5c89e4eSSatish Balay 
401e5c89e4eSSatish Balay    Output Parameter:
4028c74ee41SBarry Smith .  flg - PETSC_TRUE if the two strings are equal
403e5c89e4eSSatish Balay 
404e5c89e4eSSatish Balay    Level: intermediate
405e5c89e4eSSatish Balay 
4066f013253SBarry Smith    Notes:    Not for use in Fortran
4076f013253SBarry Smith 
408e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
409e5c89e4eSSatish Balay 
410e5c89e4eSSatish Balay @*/
4117087cfbeSBarry Smith PetscErrorCode  PetscStrcmp(const char a[],const char b[],PetscBool  *flg)
412e5c89e4eSSatish Balay {
413e5c89e4eSSatish Balay   int c;
414e5c89e4eSSatish Balay 
415e5c89e4eSSatish Balay   PetscFunctionBegin;
416e5c89e4eSSatish Balay   if (!a && !b) {
417e5c89e4eSSatish Balay     *flg = PETSC_TRUE;
418e5c89e4eSSatish Balay   } else if (!a || !b) {
419e5c89e4eSSatish Balay     *flg = PETSC_FALSE;
420e5c89e4eSSatish Balay   } else {
421e5c89e4eSSatish Balay     c = strcmp(a,b);
422e5c89e4eSSatish Balay     if (c) *flg = PETSC_FALSE;
423e5c89e4eSSatish Balay     else   *flg = PETSC_TRUE;
424e5c89e4eSSatish Balay   }
425e5c89e4eSSatish Balay   PetscFunctionReturn(0);
426e5c89e4eSSatish Balay }
427e5c89e4eSSatish Balay 
428e5c89e4eSSatish Balay #undef __FUNCT__
429e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrgrt"
430e5c89e4eSSatish Balay /*@C
431e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
432e5c89e4eSSatish Balay 
433e5c89e4eSSatish Balay    Not Collective
434e5c89e4eSSatish Balay 
435e5c89e4eSSatish Balay    Input Parameters:
436e5c89e4eSSatish Balay +  a - pointer to first string
437e5c89e4eSSatish Balay -  b - pointer to second string
438e5c89e4eSSatish Balay 
439e5c89e4eSSatish Balay    Output Parameter:
440e5c89e4eSSatish Balay .  flg - if the first string is greater
441e5c89e4eSSatish Balay 
442e5c89e4eSSatish Balay    Notes:
443e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
444e5c89e4eSSatish Balay     all others
445e5c89e4eSSatish Balay 
4466f013253SBarry Smith    Not for use in Fortran
4476f013253SBarry Smith 
448e5c89e4eSSatish Balay    Level: intermediate
449e5c89e4eSSatish Balay 
450e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
451e5c89e4eSSatish Balay 
452e5c89e4eSSatish Balay @*/
4537087cfbeSBarry Smith PetscErrorCode  PetscStrgrt(const char a[],const char b[],PetscBool  *t)
454e5c89e4eSSatish Balay {
455e5c89e4eSSatish Balay   int c;
456e5c89e4eSSatish Balay 
457e5c89e4eSSatish Balay   PetscFunctionBegin;
458e5c89e4eSSatish Balay   if (!a && !b) {
459e5c89e4eSSatish Balay     *t = PETSC_FALSE;
460e5c89e4eSSatish Balay   } else if (a && !b) {
461e5c89e4eSSatish Balay     *t = PETSC_TRUE;
462e5c89e4eSSatish Balay   } else if (!a && b) {
463e5c89e4eSSatish Balay     *t = PETSC_FALSE;
464e5c89e4eSSatish Balay   } else {
465e5c89e4eSSatish Balay     c = strcmp(a,b);
466e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
467e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
468e5c89e4eSSatish Balay   }
469e5c89e4eSSatish Balay   PetscFunctionReturn(0);
470e5c89e4eSSatish Balay }
471e5c89e4eSSatish Balay 
472e5c89e4eSSatish Balay #undef __FUNCT__
473e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcasecmp"
474e5c89e4eSSatish Balay /*@C
475e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
476e5c89e4eSSatish Balay      except possibly for case.
477e5c89e4eSSatish Balay 
478e5c89e4eSSatish Balay    Not Collective
479e5c89e4eSSatish Balay 
480e5c89e4eSSatish Balay    Input Parameters:
481e5c89e4eSSatish Balay +  a - pointer to first string
482e5c89e4eSSatish Balay -  b - pointer to second string
483e5c89e4eSSatish Balay 
484e5c89e4eSSatish Balay    Output Parameter:
485e5c89e4eSSatish Balay .  flg - if the two strings are the same
486e5c89e4eSSatish Balay 
487e5c89e4eSSatish Balay    Notes:
488e5c89e4eSSatish Balay     Null arguments are ok
489e5c89e4eSSatish Balay 
4906f013253SBarry Smith    Not for use in Fortran
4916f013253SBarry Smith 
492e5c89e4eSSatish Balay    Level: intermediate
493e5c89e4eSSatish Balay 
494e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
495e5c89e4eSSatish Balay 
496e5c89e4eSSatish Balay @*/
4977087cfbeSBarry Smith PetscErrorCode  PetscStrcasecmp(const char a[],const char b[],PetscBool  *t)
498e5c89e4eSSatish Balay {
499e5c89e4eSSatish Balay   int c;
500e5c89e4eSSatish Balay 
501e5c89e4eSSatish Balay   PetscFunctionBegin;
502e5c89e4eSSatish Balay   if (!a && !b) c = 0;
503e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
50432b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
50532b366c8SSatish Balay   else c = strcasecmp(a,b);
50632b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
507e5c89e4eSSatish Balay   else c = stricmp(a,b);
508e5c89e4eSSatish Balay #else
50932b366c8SSatish Balay   else {
51032b366c8SSatish Balay     char           *aa,*bb;
51132b366c8SSatish Balay     PetscErrorCode ierr;
51232b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
51332b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
51432b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
51532b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
51632b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
517503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
518503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
51932b366c8SSatish Balay     PetscFunctionReturn(0);
52032b366c8SSatish Balay   }
521e5c89e4eSSatish Balay #endif
522e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
523e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
524e5c89e4eSSatish Balay   PetscFunctionReturn(0);
525e5c89e4eSSatish Balay }
526e5c89e4eSSatish Balay 
52732b366c8SSatish Balay 
52832b366c8SSatish Balay 
529e5c89e4eSSatish Balay #undef __FUNCT__
530e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncmp"
531e5c89e4eSSatish Balay /*@C
532e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
533e5c89e4eSSatish Balay 
534e5c89e4eSSatish Balay    Not Collective
535e5c89e4eSSatish Balay 
536e5c89e4eSSatish Balay    Input Parameters:
537e5c89e4eSSatish Balay +  a - pointer to first string
538e5c89e4eSSatish Balay .  b - pointer to second string
539e5c89e4eSSatish Balay -  n - length to compare up to
540e5c89e4eSSatish Balay 
541e5c89e4eSSatish Balay    Output Parameter:
542e5c89e4eSSatish Balay .  t - if the two strings are equal
543e5c89e4eSSatish Balay 
544e5c89e4eSSatish Balay    Level: intermediate
545e5c89e4eSSatish Balay 
5466f013253SBarry Smith    Notes:    Not for use in Fortran
5476f013253SBarry Smith 
548e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
549e5c89e4eSSatish Balay 
550e5c89e4eSSatish Balay @*/
5517087cfbeSBarry Smith PetscErrorCode  PetscStrncmp(const char a[],const char b[],size_t n,PetscBool  *t)
552e5c89e4eSSatish Balay {
553e5c89e4eSSatish Balay   int c;
554e5c89e4eSSatish Balay 
555e5c89e4eSSatish Balay   PetscFunctionBegin;
556e5c89e4eSSatish Balay   c = strncmp(a,b,n);
557e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
558e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
559e5c89e4eSSatish Balay   PetscFunctionReturn(0);
560e5c89e4eSSatish Balay }
561e5c89e4eSSatish Balay 
562e5c89e4eSSatish Balay #undef __FUNCT__
563e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrchr"
564e5c89e4eSSatish Balay /*@C
565e5c89e4eSSatish Balay    PetscStrchr - Locates first occurance of a character in a string
566e5c89e4eSSatish Balay 
567e5c89e4eSSatish Balay    Not Collective
568e5c89e4eSSatish Balay 
569e5c89e4eSSatish Balay    Input Parameters:
570e5c89e4eSSatish Balay +  a - pointer to string
571e5c89e4eSSatish Balay -  b - character
572e5c89e4eSSatish Balay 
573e5c89e4eSSatish Balay    Output Parameter:
574e5c89e4eSSatish Balay .  c - location of occurance, PETSC_NULL if not found
575e5c89e4eSSatish Balay 
576e5c89e4eSSatish Balay    Level: intermediate
577e5c89e4eSSatish Balay 
5786f013253SBarry Smith    Notes:    Not for use in Fortran
5796f013253SBarry Smith 
580e5c89e4eSSatish Balay @*/
5817087cfbeSBarry Smith PetscErrorCode  PetscStrchr(const char a[],char b,char *c[])
582e5c89e4eSSatish Balay {
583e5c89e4eSSatish Balay   PetscFunctionBegin;
584e5c89e4eSSatish Balay   *c = (char *)strchr(a,b);
585e5c89e4eSSatish Balay   PetscFunctionReturn(0);
586e5c89e4eSSatish Balay }
587e5c89e4eSSatish Balay 
588e5c89e4eSSatish Balay #undef __FUNCT__
589e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrrchr"
590e5c89e4eSSatish Balay /*@C
591e5c89e4eSSatish Balay    PetscStrrchr - Locates one location past the last occurance of a character in a string,
592e5c89e4eSSatish Balay       if the character is not found then returns entire string
593e5c89e4eSSatish Balay 
594e5c89e4eSSatish Balay    Not Collective
595e5c89e4eSSatish Balay 
596e5c89e4eSSatish Balay    Input Parameters:
597e5c89e4eSSatish Balay +  a - pointer to string
598e5c89e4eSSatish Balay -  b - character
599e5c89e4eSSatish Balay 
600e5c89e4eSSatish Balay    Output Parameter:
601e5c89e4eSSatish Balay .  tmp - location of occurance, a if not found
602e5c89e4eSSatish Balay 
603e5c89e4eSSatish Balay    Level: intermediate
604e5c89e4eSSatish Balay 
6056f013253SBarry Smith    Notes:    Not for use in Fortran
6066f013253SBarry Smith 
607e5c89e4eSSatish Balay @*/
6087087cfbeSBarry Smith PetscErrorCode  PetscStrrchr(const char a[],char b,char *tmp[])
609e5c89e4eSSatish Balay {
610e5c89e4eSSatish Balay   PetscFunctionBegin;
611e5c89e4eSSatish Balay   *tmp = (char *)strrchr(a,b);
612e5c89e4eSSatish Balay   if (!*tmp) *tmp = (char*)a; else *tmp = *tmp + 1;
613e5c89e4eSSatish Balay   PetscFunctionReturn(0);
614e5c89e4eSSatish Balay }
615e5c89e4eSSatish Balay 
616e5c89e4eSSatish Balay #undef __FUNCT__
617e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrtolower"
618e5c89e4eSSatish Balay /*@C
619e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
620e5c89e4eSSatish Balay 
621e5c89e4eSSatish Balay    Not Collective
622e5c89e4eSSatish Balay 
623e5c89e4eSSatish Balay    Input Parameters:
624e5c89e4eSSatish Balay .  a - pointer to string
625e5c89e4eSSatish Balay 
626e5c89e4eSSatish Balay    Level: intermediate
627e5c89e4eSSatish Balay 
6286f013253SBarry Smith    Notes:    Not for use in Fortran
6296f013253SBarry Smith 
630e5c89e4eSSatish Balay @*/
6317087cfbeSBarry Smith PetscErrorCode  PetscStrtolower(char a[])
632e5c89e4eSSatish Balay {
633e5c89e4eSSatish Balay   PetscFunctionBegin;
634e5c89e4eSSatish Balay   while (*a) {
635e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
636e5c89e4eSSatish Balay     a++;
637e5c89e4eSSatish Balay   }
638e5c89e4eSSatish Balay   PetscFunctionReturn(0);
639e5c89e4eSSatish Balay }
640e5c89e4eSSatish Balay 
6417ba3a57cSBarry Smith #undef __FUNCT__
6427ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswith"
6437ba3a57cSBarry Smith /*@C
6447ba3a57cSBarry Smith    PetscStrendswith - Determines if a string ends with a certain string
6451d1a0024SBarry Smith 
6467ba3a57cSBarry Smith    Not Collective
6477ba3a57cSBarry Smith 
6487ba3a57cSBarry Smith    Input Parameters:
6497ba3a57cSBarry Smith +  a - pointer to string
6507ba3a57cSBarry Smith -  b - string to endwith
6517ba3a57cSBarry Smith 
6527ba3a57cSBarry Smith    Output Parameter:
6537ba3a57cSBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
6547ba3a57cSBarry Smith 
6557ba3a57cSBarry Smith    Notes:     Not for use in Fortran
6567ba3a57cSBarry Smith 
6577ba3a57cSBarry Smith    Level: intermediate
6587ba3a57cSBarry Smith 
6597ba3a57cSBarry Smith @*/
6607ba3a57cSBarry Smith PetscErrorCode  PetscStrendswith(const char a[],const char b[],PetscBool *flg)
6617ba3a57cSBarry Smith {
6627ba3a57cSBarry Smith   char           *test;
6637ba3a57cSBarry Smith   PetscErrorCode ierr;
6647ba3a57cSBarry Smith   size_t         na,nb;
6657ba3a57cSBarry Smith 
6667ba3a57cSBarry Smith   PetscFunctionBegin;
6677ba3a57cSBarry Smith   *flg = PETSC_FALSE;
6687ba3a57cSBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
6697ba3a57cSBarry Smith   if (test) {
6707ba3a57cSBarry Smith     ierr = PetscStrlen(a,&na);CHKERRQ(ierr);
6717ba3a57cSBarry Smith     ierr = PetscStrlen(b,&nb);CHKERRQ(ierr);
6727ba3a57cSBarry Smith     if (a+na-nb == test) *flg = PETSC_TRUE;
6737ba3a57cSBarry Smith   }
6747ba3a57cSBarry Smith   PetscFunctionReturn(0);
6757ba3a57cSBarry Smith }
6767ba3a57cSBarry Smith 
6777ba3a57cSBarry Smith #undef __FUNCT__
6787ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswithwhich"
6797ba3a57cSBarry Smith /*@C
6807ba3a57cSBarry Smith    PetscStrendswithwhich - Determines if a string ends with one of several possible strings
6817ba3a57cSBarry Smith 
6827ba3a57cSBarry Smith    Not Collective
6837ba3a57cSBarry Smith 
6847ba3a57cSBarry Smith    Input Parameters:
6857ba3a57cSBarry Smith +  a - pointer to string
6867ba3a57cSBarry Smith -  bs - strings to endwith (last entry must be null)
6877ba3a57cSBarry Smith 
6887ba3a57cSBarry Smith    Output Parameter:
6897ba3a57cSBarry Smith .  cnt - the index of the string it ends with or 1+the last possible index
6907ba3a57cSBarry Smith 
6917ba3a57cSBarry Smith    Notes:     Not for use in Fortran
6927ba3a57cSBarry Smith 
6937ba3a57cSBarry Smith    Level: intermediate
6947ba3a57cSBarry Smith 
6957ba3a57cSBarry Smith @*/
6967ba3a57cSBarry Smith PetscErrorCode  PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt)
6977ba3a57cSBarry Smith {
6987ba3a57cSBarry Smith   PetscBool      flg;
6997ba3a57cSBarry Smith   PetscErrorCode ierr;
7007ba3a57cSBarry Smith 
7017ba3a57cSBarry Smith   PetscFunctionBegin;
7027ba3a57cSBarry Smith   *cnt = 0;
7037ba3a57cSBarry Smith   while (bs[*cnt]) {
7047ba3a57cSBarry Smith     ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr);
7057ba3a57cSBarry Smith     if (flg) PetscFunctionReturn(0);
7067ba3a57cSBarry Smith     *cnt += 1;
7077ba3a57cSBarry Smith   }
7087ba3a57cSBarry Smith   PetscFunctionReturn(0);
7097ba3a57cSBarry Smith }
7107ba3a57cSBarry Smith 
7117ba3a57cSBarry Smith #undef __FUNCT__
7127ba3a57cSBarry Smith #define __FUNCT__ "PetscStrrstr"
7137ba3a57cSBarry Smith /*@C
7147ba3a57cSBarry Smith    PetscStrrstr - Locates last occurance of string in another string
7157ba3a57cSBarry Smith 
7167ba3a57cSBarry Smith    Not Collective
7177ba3a57cSBarry Smith 
7187ba3a57cSBarry Smith    Input Parameters:
7197ba3a57cSBarry Smith +  a - pointer to string
7207ba3a57cSBarry Smith -  b - string to find
7217ba3a57cSBarry Smith 
7227ba3a57cSBarry Smith    Output Parameter:
7237ba3a57cSBarry Smith .  tmp - location of occurance
7247ba3a57cSBarry Smith 
7257ba3a57cSBarry Smith    Notes:     Not for use in Fortran
7267ba3a57cSBarry Smith 
7277ba3a57cSBarry Smith    Level: intermediate
7287ba3a57cSBarry Smith 
7297ba3a57cSBarry Smith @*/
7307ba3a57cSBarry Smith PetscErrorCode  PetscStrrstr(const char a[],const char b[],char *tmp[])
7317ba3a57cSBarry Smith {
7327ba3a57cSBarry Smith   const char *stmp = a, *ltmp = 0;
7337ba3a57cSBarry Smith 
7347ba3a57cSBarry Smith   PetscFunctionBegin;
7357ba3a57cSBarry Smith   while (stmp) {
7367ba3a57cSBarry Smith     stmp = (char *)strstr(stmp,b);
7377ba3a57cSBarry Smith     if (stmp) {ltmp = stmp;stmp++;}
7387ba3a57cSBarry Smith   }
7397ba3a57cSBarry Smith   *tmp = (char *)ltmp;
7407ba3a57cSBarry Smith   PetscFunctionReturn(0);
7417ba3a57cSBarry Smith }
7427ba3a57cSBarry Smith 
7437ba3a57cSBarry Smith #undef __FUNCT__
7447ba3a57cSBarry Smith #define __FUNCT__ "PetscStrstr"
7457ba3a57cSBarry Smith /*@C
7467ba3a57cSBarry Smith    PetscStrstr - Locates first occurance of string in another string
7477ba3a57cSBarry Smith 
7487ba3a57cSBarry Smith    Not Collective
7497ba3a57cSBarry Smith 
7507ba3a57cSBarry Smith    Input Parameters:
751160f4796SJed Brown +  haystack - string to search
752160f4796SJed Brown -  needle - string to find
7537ba3a57cSBarry Smith 
7547ba3a57cSBarry Smith    Output Parameter:
7557ba3a57cSBarry Smith .  tmp - location of occurance, is a PETSC_NULL if the string is not found
7567ba3a57cSBarry Smith 
7577ba3a57cSBarry Smith    Notes: Not for use in Fortran
7587ba3a57cSBarry Smith 
7597ba3a57cSBarry Smith    Level: intermediate
7607ba3a57cSBarry Smith 
7617ba3a57cSBarry Smith @*/
762160f4796SJed Brown PetscErrorCode  PetscStrstr(const char haystack[],const char needle[],char *tmp[])
7637ba3a57cSBarry Smith {
7647ba3a57cSBarry Smith   PetscFunctionBegin;
765160f4796SJed Brown   *tmp = (char *)strstr(haystack,needle);
7667ba3a57cSBarry Smith   PetscFunctionReturn(0);
7677ba3a57cSBarry Smith }
7687ba3a57cSBarry Smith 
7697ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
7701d1a0024SBarry Smith 
771e5c89e4eSSatish Balay #undef __FUNCT__
772e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenFind"
773e5c89e4eSSatish Balay /*@C
774e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
775e5c89e4eSSatish Balay 
776e5c89e4eSSatish Balay    Not Collective
777e5c89e4eSSatish Balay 
778e5c89e4eSSatish Balay    Input Parameters:
779e5c89e4eSSatish Balay .  a - pointer to token
780e5c89e4eSSatish Balay 
781e5c89e4eSSatish Balay    Output Parameter:
782e5c89e4eSSatish Balay .  result - location of occurance, PETSC_NULL if not found
783e5c89e4eSSatish Balay 
784e5c89e4eSSatish Balay    Notes:
785e5c89e4eSSatish Balay 
786e5c89e4eSSatish Balay      This version is different from the system version in that
787e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
788e5c89e4eSSatish Balay 
7894704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
7904704e885SBarry Smith    as a single token.
7914704e885SBarry Smith 
7926f013253SBarry Smith     Not for use in Fortran
7936f013253SBarry Smith 
794e5c89e4eSSatish Balay    Level: intermediate
795e5c89e4eSSatish Balay 
7966f013253SBarry Smith 
797e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
798e5c89e4eSSatish Balay @*/
7997087cfbeSBarry Smith PetscErrorCode  PetscTokenFind(PetscToken a,char *result[])
800e5c89e4eSSatish Balay {
8014704e885SBarry Smith   char *ptr = a->current,token;
802e5c89e4eSSatish Balay 
803e5c89e4eSSatish Balay   PetscFunctionBegin;
804e5c89e4eSSatish Balay   *result = a->current;
8054704e885SBarry Smith   if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);}
8064704e885SBarry Smith   token = a->token;
80790fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
808e5c89e4eSSatish Balay   while (ptr) {
8094704e885SBarry Smith     if (*ptr == token) {
810e5c89e4eSSatish Balay       *ptr++ = 0;
811e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
812e5c89e4eSSatish Balay       a->current = ptr;
813e5c89e4eSSatish Balay       break;
814e5c89e4eSSatish Balay     }
815e5c89e4eSSatish Balay     if (!*ptr) {
816e5c89e4eSSatish Balay       a->current = 0;
817e5c89e4eSSatish Balay       break;
818e5c89e4eSSatish Balay     }
819e5c89e4eSSatish Balay     ptr++;
820e5c89e4eSSatish Balay   }
821e5c89e4eSSatish Balay   PetscFunctionReturn(0);
822e5c89e4eSSatish Balay }
823e5c89e4eSSatish Balay 
824e5c89e4eSSatish Balay #undef __FUNCT__
825e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenCreate"
826e5c89e4eSSatish Balay /*@C
827e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
828e5c89e4eSSatish Balay 
829e5c89e4eSSatish Balay    Not Collective
830e5c89e4eSSatish Balay 
831e5c89e4eSSatish Balay    Input Parameters:
832e5c89e4eSSatish Balay +  string - the string to look in
833e5c89e4eSSatish Balay -  token - the character to look for
834e5c89e4eSSatish Balay 
835e5c89e4eSSatish Balay    Output Parameter:
836e5c89e4eSSatish Balay .  a - pointer to token
837e5c89e4eSSatish Balay 
838e5c89e4eSSatish Balay    Notes:
839e5c89e4eSSatish Balay 
840e5c89e4eSSatish Balay      This version is different from the system version in that
841e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
842e5c89e4eSSatish Balay 
8436f013253SBarry Smith     Not for use in Fortran
8446f013253SBarry Smith 
845e5c89e4eSSatish Balay    Level: intermediate
846e5c89e4eSSatish Balay 
847e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
848e5c89e4eSSatish Balay @*/
8497087cfbeSBarry Smith PetscErrorCode  PetscTokenCreate(const char a[],const char b,PetscToken *t)
850e5c89e4eSSatish Balay {
851e5c89e4eSSatish Balay   PetscErrorCode ierr;
852e5c89e4eSSatish Balay 
853e5c89e4eSSatish Balay   PetscFunctionBegin;
8541d1a0024SBarry Smith   ierr = PetscNew(struct _p_PetscToken,t);CHKERRQ(ierr);
855e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
856e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
857e5c89e4eSSatish Balay   (*t)->token   = b;
858e5c89e4eSSatish Balay   PetscFunctionReturn(0);
859e5c89e4eSSatish Balay }
860e5c89e4eSSatish Balay 
861e5c89e4eSSatish Balay #undef __FUNCT__
862e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenDestroy"
863e5c89e4eSSatish Balay /*@C
864e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
865e5c89e4eSSatish Balay 
866e5c89e4eSSatish Balay    Not Collective
867e5c89e4eSSatish Balay 
868e5c89e4eSSatish Balay    Input Parameters:
869e5c89e4eSSatish Balay .  a - pointer to token
870e5c89e4eSSatish Balay 
871e5c89e4eSSatish Balay    Level: intermediate
872e5c89e4eSSatish Balay 
8736f013253SBarry Smith    Notes:     Not for use in Fortran
8746f013253SBarry Smith 
875e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
876e5c89e4eSSatish Balay @*/
8778c74ee41SBarry Smith PetscErrorCode  PetscTokenDestroy(PetscToken *a)
878e5c89e4eSSatish Balay {
879e5c89e4eSSatish Balay   PetscErrorCode ierr;
880e5c89e4eSSatish Balay 
881e5c89e4eSSatish Balay   PetscFunctionBegin;
8828c74ee41SBarry Smith   if (!*a) PetscFunctionReturn(0);
8838c74ee41SBarry Smith   ierr = PetscFree((*a)->array);CHKERRQ(ierr);
8848c74ee41SBarry Smith   ierr = PetscFree(*a);CHKERRQ(ierr);
885e5c89e4eSSatish Balay   PetscFunctionReturn(0);
886e5c89e4eSSatish Balay }
887e5c89e4eSSatish Balay 
888e5c89e4eSSatish Balay 
889e5c89e4eSSatish Balay #undef __FUNCT__
890e5c89e4eSSatish Balay #define __FUNCT__ "PetscGetPetscDir"
891e5c89e4eSSatish Balay /*@C
892e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
893e5c89e4eSSatish Balay 
894e5c89e4eSSatish Balay    Not Collective
895e5c89e4eSSatish Balay 
896e5c89e4eSSatish Balay    Output Parameter:
897e5c89e4eSSatish Balay .  dir - the directory
898e5c89e4eSSatish Balay 
899e5c89e4eSSatish Balay    Level: developer
900e5c89e4eSSatish Balay 
9016f013253SBarry Smith    Notes: Not for use in Fortran
9026f013253SBarry Smith 
903e5c89e4eSSatish Balay @*/
9047087cfbeSBarry Smith PetscErrorCode  PetscGetPetscDir(const char *dir[])
905e5c89e4eSSatish Balay {
906e5c89e4eSSatish Balay   PetscFunctionBegin;
907e5c89e4eSSatish Balay   *dir = PETSC_DIR;
908e5c89e4eSSatish Balay   PetscFunctionReturn(0);
909e5c89e4eSSatish Balay }
910e5c89e4eSSatish Balay 
911e5c89e4eSSatish Balay #undef __FUNCT__
912e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrreplace"
913e5c89e4eSSatish Balay /*@C
914e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
915e5c89e4eSSatish Balay 
916e5c89e4eSSatish Balay    Not Collective
917e5c89e4eSSatish Balay 
918e5c89e4eSSatish Balay    Input Parameters:
919e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
92071573d7dSBarry Smith .   aa - the string to look in
921d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
922e5c89e4eSSatish Balay -   len - the length of b
923e5c89e4eSSatish Balay 
924e5c89e4eSSatish Balay    Notes:
925e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
926d5649816SBarry Smith       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
927e5c89e4eSSatish Balay       as well as any environmental variables.
928e5c89e4eSSatish Balay 
9296f013253SBarry Smith       PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
930acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
931acc6cc86SBarry Smith 
9326f013253SBarry Smith       Not for use in Fortran
9336f013253SBarry Smith 
934e5c89e4eSSatish Balay    Level: intermediate
935e5c89e4eSSatish Balay 
936e5c89e4eSSatish Balay @*/
9377087cfbeSBarry Smith PetscErrorCode  PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
938e5c89e4eSSatish Balay {
939e5c89e4eSSatish Balay   PetscErrorCode ierr;
940e5c89e4eSSatish Balay   int            i = 0;
941e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
94271573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
943d5649816SBarry Smith   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0};
944d5649816SBarry Smith   const char     *r[] = {0,0,0,0,0,0,0,0,0};
945ace3abfcSBarry Smith   PetscBool      flag;
946e5c89e4eSSatish Balay 
947e5c89e4eSSatish Balay   PetscFunctionBegin;
948e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
94971573d7dSBarry Smith   if (aa == b) {
95022982a5fSBarry Smith     ierr    = PetscStrallocpy(aa,(char **)&a);CHKERRQ(ierr);
95171573d7dSBarry Smith   }
952e5c89e4eSSatish Balay   ierr = PetscMalloc(len*sizeof(char*),&work);CHKERRQ(ierr);
953e5c89e4eSSatish Balay 
954e5c89e4eSSatish Balay   /* get values for replaced variables */
955487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr);
956487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr);
957487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr);
958487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[3]);CHKERRQ(ierr);
959487e5849SBarry Smith   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[4]);CHKERRQ(ierr);
960e5c89e4eSSatish Balay   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[5]);CHKERRQ(ierr);
961487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[6]);CHKERRQ(ierr);
962d5649816SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[7]);CHKERRQ(ierr);
963487e5849SBarry Smith   ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr);
964487e5849SBarry Smith   ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
965487e5849SBarry Smith   ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
966487e5849SBarry Smith   ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr);
967d5649816SBarry Smith   ierr = PetscGetHostName((char*)r[7],256);CHKERRQ(ierr);
968487e5849SBarry Smith 
969487e5849SBarry Smith   /* replace that are in environment */
970487e5849SBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr);
971487e5849SBarry Smith   if (flag) {
972487e5849SBarry Smith     ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr);
973487e5849SBarry Smith   }
974e5c89e4eSSatish Balay 
975e5c89e4eSSatish Balay   /* replace the requested strings */
976e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
977e5c89e4eSSatish Balay   while (s[i]) {
978e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
979e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
980e5c89e4eSSatish Balay     while (par) {
981e5c89e4eSSatish Balay       *par  =  0;
982e5c89e4eSSatish Balay       par  += l;
983e5c89e4eSSatish Balay 
984e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
985e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
986e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
98717186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
988e5c89e4eSSatish Balay       ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
989e5c89e4eSSatish Balay       ierr  = PetscStrcat(work,r[i]);CHKERRQ(ierr);
990e5c89e4eSSatish Balay       ierr  = PetscStrcat(work,par);CHKERRQ(ierr);
991e5c89e4eSSatish Balay       ierr  = PetscStrncpy(b,work,len);CHKERRQ(ierr);
992e5c89e4eSSatish Balay       ierr  = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
993e5c89e4eSSatish Balay     }
994e5c89e4eSSatish Balay     i++;
995e5c89e4eSSatish Balay   }
996487e5849SBarry Smith   i = 0;
997487e5849SBarry Smith   while (r[i]) {
998e5c89e4eSSatish Balay     tfree = (char*)r[i];
999e5c89e4eSSatish Balay     ierr = PetscFree(tfree);CHKERRQ(ierr);
1000487e5849SBarry Smith     i++;
1001e5c89e4eSSatish Balay   }
1002e5c89e4eSSatish Balay 
1003e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
1004e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1005e5c89e4eSSatish Balay   while (par) {
1006e5c89e4eSSatish Balay     *par = 0;
1007e5c89e4eSSatish Balay     par += 2;
1008e5c89e4eSSatish Balay     ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
1009e5c89e4eSSatish Balay     ierr = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
1010e5c89e4eSSatish Balay     *epar = 0;
1011e5c89e4eSSatish Balay     epar += 1;
1012e5c89e4eSSatish Balay     ierr = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr);
10137ba3a57cSBarry Smith     if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
1014e5c89e4eSSatish Balay     ierr = PetscStrcat(work,env);CHKERRQ(ierr);
1015e5c89e4eSSatish Balay     ierr = PetscStrcat(work,epar);CHKERRQ(ierr);
1016e5c89e4eSSatish Balay     ierr = PetscStrcpy(b,work);CHKERRQ(ierr);
1017e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1018e5c89e4eSSatish Balay   }
1019e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
102071573d7dSBarry Smith   if (aa == b) {
102171573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
102271573d7dSBarry Smith   }
1023e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1024e5c89e4eSSatish Balay }
1025e5c89e4eSSatish Balay 
1026e5c89e4eSSatish Balay 
1027