xref: /petsc/src/sys/utils/str.c (revision 573b0fb4b27458e353e9b121e629dc5c63cf6459)
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 
10e5c89e4eSSatish Balay #undef __FUNCT__
113c311c98SBarry Smith #define __FUNCT__ "PetscStrToArray"
123c311c98SBarry Smith /*@C
13d67fe73bSBarry Smith    PetscStrToArray - Seperates a string by a charactor (for example ' ' or '\n') and creates an array of strings
143c311c98SBarry Smith 
153c311c98SBarry Smith    Not Collective
163c311c98SBarry Smith 
173c311c98SBarry Smith    Input Parameters:
18d67fe73bSBarry Smith +  s - pointer to string
19a2ea699eSBarry Smith -  sp - separator charactor
203c311c98SBarry Smith 
213c311c98SBarry Smith    Output Parameter:
223c311c98SBarry Smith +   argc - the number of entries in the array
233c311c98SBarry Smith -   args - an array of the entries with a null at the end
243c311c98SBarry Smith 
253c311c98SBarry Smith    Level: intermediate
263c311c98SBarry Smith 
27301d30feSBarry Smith    Notes: this may be called before PetscInitialize() or after PetscFinalize()
283c311c98SBarry Smith 
296f013253SBarry Smith    Not for use in Fortran
306f013253SBarry Smith 
31b4cd4cebSBarry Smith    Developer Notes: Using raw malloc() and does not call error handlers since this may be used before PETSc is initialized. Used
32b4cd4cebSBarry Smith      to generate argc, args arguments passed to MPI_Init()
33301d30feSBarry Smith 
34b4cd4cebSBarry Smith .seealso: PetscStrToArrayDestroy(), PetscToken, PetscTokenCreate()
353c311c98SBarry Smith 
363c311c98SBarry Smith @*/
37d67fe73bSBarry Smith PetscErrorCode  PetscStrToArray(const char s[],char sp,int *argc,char ***args)
383c311c98SBarry Smith {
393c311c98SBarry Smith   int       i,n,*lens,cnt = 0;
40ace3abfcSBarry Smith   PetscBool flg = PETSC_FALSE;
413c311c98SBarry Smith 
4240a7e1efSBarry Smith   if (!s) n = 0;
4340a7e1efSBarry Smith   else    n = strlen(s);
443c311c98SBarry Smith   *argc = 0;
454996c5bdSBarry Smith   if (!n) {
464996c5bdSBarry Smith     *args = 0;
474996c5bdSBarry Smith     return(0);
484996c5bdSBarry Smith   }
493c311c98SBarry Smith   for (i=0; i<n; i++) {
50d67fe73bSBarry Smith     if (s[i] != sp) break;
513c311c98SBarry Smith   }
523c311c98SBarry Smith   for (;i<n+1; i++) {
53d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
54d67fe73bSBarry Smith     else if (s[i] != sp) {flg = PETSC_FALSE;}
553c311c98SBarry Smith   }
56a2ea699eSBarry 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++) {
62d67fe73bSBarry Smith     if (s[i] != sp) break;
633c311c98SBarry Smith   }
643c311c98SBarry Smith   for (;i<n+1; i++) {
65d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*argc)++;}
66d67fe73bSBarry Smith     else if (s[i] != sp) {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   }
72a2ea699eSBarry Smith   free(lens);
73301d30feSBarry Smith   (*args)[*argc] = 0;
743c311c98SBarry Smith 
753c311c98SBarry Smith   *argc = 0;
763c311c98SBarry Smith   for (i=0; i<n; i++) {
77d67fe73bSBarry Smith     if (s[i] != sp) break;
783c311c98SBarry Smith   }
793c311c98SBarry Smith   for (;i<n+1; i++) {
80d67fe73bSBarry Smith     if ((s[i] == sp || s[i] == 0) && !flg) {flg = PETSC_TRUE; (*args)[*argc][cnt++] = 0; (*argc)++; cnt = 0;}
81d67fe73bSBarry Smith     else if (s[i] != sp && 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 
112a297a907SKarl Rupp   for (i=0; i<argc; i++) free(args[i]);
113a297a907SKarl Rupp   if (args) free(args);
114301d30feSBarry Smith   return 0;
115301d30feSBarry Smith }
116301d30feSBarry Smith 
117301d30feSBarry Smith #undef __FUNCT__
118e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrlen"
119e5c89e4eSSatish Balay /*@C
120e5c89e4eSSatish Balay    PetscStrlen - Gets length of a string
121e5c89e4eSSatish Balay 
122e5c89e4eSSatish Balay    Not Collective
123e5c89e4eSSatish Balay 
124e5c89e4eSSatish Balay    Input Parameters:
125e5c89e4eSSatish Balay .  s - pointer to string
126e5c89e4eSSatish Balay 
127e5c89e4eSSatish Balay    Output Parameter:
128e5c89e4eSSatish Balay .  len - length in bytes
129e5c89e4eSSatish Balay 
130e5c89e4eSSatish Balay    Level: intermediate
131e5c89e4eSSatish Balay 
132e5c89e4eSSatish Balay    Note:
133e5c89e4eSSatish Balay    This routine is analogous to strlen().
134e5c89e4eSSatish Balay 
135e5c89e4eSSatish Balay    Null string returns a length of zero
136e5c89e4eSSatish Balay 
1376f013253SBarry Smith    Not for use in Fortran
1386f013253SBarry Smith 
139e5c89e4eSSatish Balay   Concepts: string length
140e5c89e4eSSatish Balay 
141e5c89e4eSSatish Balay @*/
1427087cfbeSBarry Smith PetscErrorCode  PetscStrlen(const char s[],size_t *len)
143e5c89e4eSSatish Balay {
144e5c89e4eSSatish Balay   PetscFunctionBegin;
145a297a907SKarl Rupp   if (!s) *len = 0;
146a297a907SKarl Rupp   else    *len = strlen(s);
147e5c89e4eSSatish Balay   PetscFunctionReturn(0);
148e5c89e4eSSatish Balay }
149e5c89e4eSSatish Balay 
150e5c89e4eSSatish Balay #undef __FUNCT__
151e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrallocpy"
152e5c89e4eSSatish Balay /*@C
153e5c89e4eSSatish Balay    PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
154e5c89e4eSSatish Balay 
155e5c89e4eSSatish Balay    Not Collective
156e5c89e4eSSatish Balay 
157e5c89e4eSSatish Balay    Input Parameters:
158e5c89e4eSSatish Balay .  s - pointer to string
159e5c89e4eSSatish Balay 
160e5c89e4eSSatish Balay    Output Parameter:
161e5c89e4eSSatish Balay .  t - the copied string
162e5c89e4eSSatish Balay 
163e5c89e4eSSatish Balay    Level: intermediate
164e5c89e4eSSatish Balay 
165e5c89e4eSSatish Balay    Note:
166e5c89e4eSSatish Balay       Null string returns a new null string
167e5c89e4eSSatish Balay 
1686f013253SBarry Smith       Not for use in Fortran
1696f013253SBarry Smith 
170e5c89e4eSSatish Balay   Concepts: string copy
171e5c89e4eSSatish Balay 
172e5c89e4eSSatish Balay @*/
1737087cfbeSBarry Smith PetscErrorCode  PetscStrallocpy(const char s[],char *t[])
174e5c89e4eSSatish Balay {
175e5c89e4eSSatish Balay   PetscErrorCode ierr;
176e5c89e4eSSatish Balay   size_t         len;
17771573d7dSBarry Smith   char           *tmp = 0;
178e5c89e4eSSatish Balay 
179e5c89e4eSSatish Balay   PetscFunctionBegin;
180e5c89e4eSSatish Balay   if (s) {
181e5c89e4eSSatish Balay     ierr = PetscStrlen(s,&len);CHKERRQ(ierr);
18271573d7dSBarry Smith     ierr = PetscMalloc((1+len)*sizeof(char),&tmp);CHKERRQ(ierr);
18371573d7dSBarry Smith     ierr = PetscStrcpy(tmp,s);CHKERRQ(ierr);
184e5c89e4eSSatish Balay   }
18571573d7dSBarry Smith   *t = tmp;
186e5c89e4eSSatish Balay   PetscFunctionReturn(0);
187e5c89e4eSSatish Balay }
188e5c89e4eSSatish Balay 
189e5c89e4eSSatish Balay #undef __FUNCT__
19047340559SBarry Smith #define __FUNCT__ "PetscStrArrayallocpy"
19147340559SBarry Smith /*@C
19247340559SBarry Smith    PetscStrArrayallocpy - Allocates space to hold a copy of an array of strings then copies the strings
19347340559SBarry Smith 
19447340559SBarry Smith    Not Collective
19547340559SBarry Smith 
19647340559SBarry Smith    Input Parameters:
19747340559SBarry Smith .  s - pointer to array of strings (final string is a null)
19847340559SBarry Smith 
19947340559SBarry Smith    Output Parameter:
20047340559SBarry Smith .  t - the copied array string
20147340559SBarry Smith 
20247340559SBarry Smith    Level: intermediate
20347340559SBarry Smith 
20447340559SBarry Smith    Note:
20547340559SBarry Smith       Not for use in Fortran
20647340559SBarry Smith 
20747340559SBarry Smith   Concepts: string copy
20847340559SBarry Smith 
20947340559SBarry Smith .seealso: PetscStrallocpy() PetscStrArrayDestroy()
21047340559SBarry Smith 
21147340559SBarry Smith @*/
21247340559SBarry Smith PetscErrorCode  PetscStrArrayallocpy(const char *const *list,char ***t)
21347340559SBarry Smith {
21447340559SBarry Smith   PetscErrorCode ierr;
21547340559SBarry Smith   PetscInt       i,n = 0;
21647340559SBarry Smith 
21747340559SBarry Smith   PetscFunctionBegin;
21847340559SBarry Smith   while (list[n++]) ;
21947340559SBarry Smith   ierr = PetscMalloc((n+1)*sizeof(char**),t);CHKERRQ(ierr);
22047340559SBarry Smith   for (i=0; i<n; i++) {
22147340559SBarry Smith     ierr = PetscStrallocpy(list[i],(*t)+i);CHKERRQ(ierr);
22247340559SBarry Smith   }
2230298fd71SBarry Smith   (*t)[n] = NULL;
22447340559SBarry Smith   PetscFunctionReturn(0);
22547340559SBarry Smith }
22647340559SBarry Smith 
22747340559SBarry Smith #undef __FUNCT__
22847340559SBarry Smith #define __FUNCT__ "PetscStrArrayDestroy"
22947340559SBarry Smith /*@C
23047340559SBarry Smith    PetscStrArrayDestroy - Frees array of strings created with PetscStrArrayallocpy().
23147340559SBarry Smith 
23247340559SBarry Smith    Not Collective
23347340559SBarry Smith 
23447340559SBarry Smith    Output Parameters:
23547340559SBarry Smith .   list - array of strings
23647340559SBarry Smith 
23747340559SBarry Smith    Level: intermediate
23847340559SBarry Smith 
23947340559SBarry Smith    Concepts: command line arguments
24047340559SBarry Smith 
24147340559SBarry Smith    Notes: Not for use in Fortran
24247340559SBarry Smith 
24347340559SBarry Smith .seealso: PetscStrArrayallocpy()
24447340559SBarry Smith 
24547340559SBarry Smith @*/
2466fed8037SJed Brown PetscErrorCode PetscStrArrayDestroy(char ***list)
24747340559SBarry Smith {
24847340559SBarry Smith   PetscInt       n = 0;
24947340559SBarry Smith   PetscErrorCode ierr;
25047340559SBarry Smith 
2516fed8037SJed Brown   PetscFunctionBegin;
2526fed8037SJed Brown   if (!*list) PetscFunctionReturn(0);
2536fed8037SJed Brown   while ((*list)[n]) {
2546fed8037SJed Brown     ierr = PetscFree((*list)[n]);CHKERRQ(ierr);
25547340559SBarry Smith     n++;
25647340559SBarry Smith   }
2576fed8037SJed Brown   ierr = PetscFree(*list);CHKERRQ(ierr);
2586fed8037SJed Brown   PetscFunctionReturn(0);
25947340559SBarry Smith }
26047340559SBarry Smith 
26147340559SBarry Smith #undef __FUNCT__
262e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcpy"
263e5c89e4eSSatish Balay /*@C
264e5c89e4eSSatish Balay    PetscStrcpy - Copies a string
265e5c89e4eSSatish Balay 
266e5c89e4eSSatish Balay    Not Collective
267e5c89e4eSSatish Balay 
268e5c89e4eSSatish Balay    Input Parameters:
269e5c89e4eSSatish Balay .  t - pointer to string
270e5c89e4eSSatish Balay 
271e5c89e4eSSatish Balay    Output Parameter:
272e5c89e4eSSatish Balay .  s - the copied string
273e5c89e4eSSatish Balay 
274e5c89e4eSSatish Balay    Level: intermediate
275e5c89e4eSSatish Balay 
2766f013253SBarry Smith    Notes:
277e5c89e4eSSatish Balay      Null string returns a string starting with zero
278e5c89e4eSSatish Balay 
2796f013253SBarry Smith      Not for use in Fortran
2806f013253SBarry Smith 
281e5c89e4eSSatish Balay   Concepts: string copy
282e5c89e4eSSatish Balay 
283e5c89e4eSSatish Balay .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat()
284e5c89e4eSSatish Balay 
285e5c89e4eSSatish Balay @*/
286acc6cc86SBarry Smith 
2877087cfbeSBarry Smith PetscErrorCode  PetscStrcpy(char s[],const char t[])
288e5c89e4eSSatish Balay {
289e5c89e4eSSatish Balay   PetscFunctionBegin;
29017186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
291a297a907SKarl Rupp   if (t) strcpy(s,t);
292a297a907SKarl Rupp   else if (s) s[0] = 0;
293e5c89e4eSSatish Balay   PetscFunctionReturn(0);
294e5c89e4eSSatish Balay }
295e5c89e4eSSatish Balay 
296e5c89e4eSSatish Balay #undef __FUNCT__
297e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncpy"
298e5c89e4eSSatish Balay /*@C
299e5c89e4eSSatish Balay    PetscStrncpy - Copies a string up to a certain length
300e5c89e4eSSatish Balay 
301e5c89e4eSSatish Balay    Not Collective
302e5c89e4eSSatish Balay 
303e5c89e4eSSatish Balay    Input Parameters:
304e5c89e4eSSatish Balay +  t - pointer to string
305e5c89e4eSSatish Balay -  n - the length to copy
306e5c89e4eSSatish Balay 
307e5c89e4eSSatish Balay    Output Parameter:
308e5c89e4eSSatish Balay .  s - the copied string
309e5c89e4eSSatish Balay 
310e5c89e4eSSatish Balay    Level: intermediate
311e5c89e4eSSatish Balay 
312e5c89e4eSSatish Balay    Note:
313e5c89e4eSSatish Balay      Null string returns a string starting with zero
314e5c89e4eSSatish Balay 
315e5c89e4eSSatish Balay   Concepts: string copy
316e5c89e4eSSatish Balay 
317e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat()
318e5c89e4eSSatish Balay 
319e5c89e4eSSatish Balay @*/
3207087cfbeSBarry Smith PetscErrorCode  PetscStrncpy(char s[],const char t[],size_t n)
321e5c89e4eSSatish Balay {
322e5c89e4eSSatish Balay   PetscFunctionBegin;
32317186662SBarry Smith   if (t && !s) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to copy string into null pointer");
324a297a907SKarl Rupp   if (t) strncpy(s,t,n);
325a297a907SKarl Rupp   else if (s) s[0] = 0;
326e5c89e4eSSatish Balay   PetscFunctionReturn(0);
327e5c89e4eSSatish Balay }
328e5c89e4eSSatish Balay 
329e5c89e4eSSatish Balay #undef __FUNCT__
330e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcat"
331e5c89e4eSSatish Balay /*@C
332e5c89e4eSSatish Balay    PetscStrcat - Concatenates a string onto a given string
333e5c89e4eSSatish Balay 
334e5c89e4eSSatish Balay    Not Collective
335e5c89e4eSSatish Balay 
336e5c89e4eSSatish Balay    Input Parameters:
337e5e2177aSMatthew Knepley +  s - string to be added to
338e5e2177aSMatthew Knepley -  t - pointer to string to be added to end
339e5c89e4eSSatish Balay 
340e5c89e4eSSatish Balay    Level: intermediate
341e5c89e4eSSatish Balay 
3426f013253SBarry Smith    Notes: Not for use in Fortran
3436f013253SBarry Smith 
344e5c89e4eSSatish Balay   Concepts: string copy
345e5c89e4eSSatish Balay 
346e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat()
347e5c89e4eSSatish Balay 
348e5c89e4eSSatish Balay @*/
3497087cfbeSBarry Smith PetscErrorCode  PetscStrcat(char s[],const char t[])
350e5c89e4eSSatish Balay {
351e5c89e4eSSatish Balay   PetscFunctionBegin;
3529b754dc9SBarry Smith   if (!t) PetscFunctionReturn(0);
353e5c89e4eSSatish Balay   strcat(s,t);
354e5c89e4eSSatish Balay   PetscFunctionReturn(0);
355e5c89e4eSSatish Balay }
356e5c89e4eSSatish Balay 
357e5c89e4eSSatish Balay #undef __FUNCT__
358e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncat"
359e5c89e4eSSatish Balay /*@C
360e5c89e4eSSatish Balay    PetscStrncat - Concatenates a string onto a given string, up to a given length
361e5c89e4eSSatish Balay 
362e5c89e4eSSatish Balay    Not Collective
363e5c89e4eSSatish Balay 
364e5c89e4eSSatish Balay    Input Parameters:
365e5c89e4eSSatish Balay +  s - pointer to string to be added to end
366e5c89e4eSSatish Balay .  t - string to be added to
367e5c89e4eSSatish Balay .  n - maximum length to copy
368e5c89e4eSSatish Balay 
369e5c89e4eSSatish Balay    Level: intermediate
370e5c89e4eSSatish Balay 
3716f013253SBarry Smith   Notes:    Not for use in Fortran
3726f013253SBarry Smith 
373e5c89e4eSSatish Balay   Concepts: string copy
374e5c89e4eSSatish Balay 
375e5c89e4eSSatish Balay .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
376e5c89e4eSSatish Balay 
377e5c89e4eSSatish Balay @*/
3787087cfbeSBarry Smith PetscErrorCode  PetscStrncat(char s[],const char t[],size_t n)
379e5c89e4eSSatish Balay {
380e5c89e4eSSatish Balay   PetscFunctionBegin;
381e5c89e4eSSatish Balay   strncat(s,t,n);
382e5c89e4eSSatish Balay   PetscFunctionReturn(0);
383e5c89e4eSSatish Balay }
384e5c89e4eSSatish Balay 
385e5c89e4eSSatish Balay #undef __FUNCT__
386*573b0fb4SBarry Smith #define __FUNCT__ "PetscStrcmpNoError"
387*573b0fb4SBarry Smith /*
388*573b0fb4SBarry Smith    Only to be used with PetscCheck__FUNCT__()!
389*573b0fb4SBarry Smith 
390*573b0fb4SBarry Smith    Will be removed once we eliminate the __FUNCT__ paradigm
391*573b0fb4SBarry Smith */
392*573b0fb4SBarry Smith void  PetscStrcmpNoError(const char a[],const char b[],PetscBool  *flg)
393*573b0fb4SBarry Smith {
394*573b0fb4SBarry Smith   int c;
395*573b0fb4SBarry Smith 
396*573b0fb4SBarry Smith   if (!a && !b)      *flg = PETSC_TRUE;
397*573b0fb4SBarry Smith   else if (!a || !b) *flg = PETSC_FALSE;
398*573b0fb4SBarry Smith   else {
399*573b0fb4SBarry Smith     c = strcmp(a,b);
400*573b0fb4SBarry Smith     if (c) *flg = PETSC_FALSE;
401*573b0fb4SBarry Smith     else   *flg = PETSC_TRUE;
402*573b0fb4SBarry Smith   }
403*573b0fb4SBarry Smith }
404*573b0fb4SBarry Smith 
405*573b0fb4SBarry Smith #undef __FUNCT__
406e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcmp"
407e5c89e4eSSatish Balay /*@C
408e5c89e4eSSatish Balay    PetscStrcmp - Compares two strings,
409e5c89e4eSSatish Balay 
410e5c89e4eSSatish Balay    Not Collective
411e5c89e4eSSatish Balay 
412e5c89e4eSSatish Balay    Input Parameters:
413e5c89e4eSSatish Balay +  a - pointer to string first string
414e5c89e4eSSatish Balay -  b - pointer to second string
415e5c89e4eSSatish Balay 
416e5c89e4eSSatish Balay    Output Parameter:
4178c74ee41SBarry Smith .  flg - PETSC_TRUE if the two strings are equal
418e5c89e4eSSatish Balay 
419e5c89e4eSSatish Balay    Level: intermediate
420e5c89e4eSSatish Balay 
4216f013253SBarry Smith    Notes:    Not for use in Fortran
4226f013253SBarry Smith 
423e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
424e5c89e4eSSatish Balay 
425e5c89e4eSSatish Balay @*/
4267087cfbeSBarry Smith PetscErrorCode  PetscStrcmp(const char a[],const char b[],PetscBool  *flg)
427e5c89e4eSSatish Balay {
428e5c89e4eSSatish Balay   int c;
429e5c89e4eSSatish Balay 
430e5c89e4eSSatish Balay   PetscFunctionBegin;
431a297a907SKarl Rupp   if (!a && !b)      *flg = PETSC_TRUE;
432a297a907SKarl Rupp   else if (!a || !b) *flg = PETSC_FALSE;
433a297a907SKarl Rupp   else {
434e5c89e4eSSatish Balay     c = strcmp(a,b);
435e5c89e4eSSatish Balay     if (c) *flg = PETSC_FALSE;
436e5c89e4eSSatish Balay     else   *flg = PETSC_TRUE;
437e5c89e4eSSatish Balay   }
438e5c89e4eSSatish Balay   PetscFunctionReturn(0);
439e5c89e4eSSatish Balay }
440e5c89e4eSSatish Balay 
441e5c89e4eSSatish Balay #undef __FUNCT__
442e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrgrt"
443e5c89e4eSSatish Balay /*@C
444e5c89e4eSSatish Balay    PetscStrgrt - If first string is greater than the second
445e5c89e4eSSatish Balay 
446e5c89e4eSSatish Balay    Not Collective
447e5c89e4eSSatish Balay 
448e5c89e4eSSatish Balay    Input Parameters:
449e5c89e4eSSatish Balay +  a - pointer to first string
450e5c89e4eSSatish Balay -  b - pointer to second string
451e5c89e4eSSatish Balay 
452e5c89e4eSSatish Balay    Output Parameter:
453e5c89e4eSSatish Balay .  flg - if the first string is greater
454e5c89e4eSSatish Balay 
455e5c89e4eSSatish Balay    Notes:
456e5c89e4eSSatish Balay     Null arguments are ok, a null string is considered smaller than
457e5c89e4eSSatish Balay     all others
458e5c89e4eSSatish Balay 
4596f013253SBarry Smith    Not for use in Fortran
4606f013253SBarry Smith 
461e5c89e4eSSatish Balay    Level: intermediate
462e5c89e4eSSatish Balay 
463e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
464e5c89e4eSSatish Balay 
465e5c89e4eSSatish Balay @*/
4667087cfbeSBarry Smith PetscErrorCode  PetscStrgrt(const char a[],const char b[],PetscBool  *t)
467e5c89e4eSSatish Balay {
468e5c89e4eSSatish Balay   int c;
469e5c89e4eSSatish Balay 
470e5c89e4eSSatish Balay   PetscFunctionBegin;
471a297a907SKarl Rupp   if (!a && !b) *t = PETSC_FALSE;
472a297a907SKarl Rupp   else if (a && !b) *t = PETSC_TRUE;
473a297a907SKarl Rupp   else if (!a && b) *t = PETSC_FALSE;
474a297a907SKarl Rupp   else {
475e5c89e4eSSatish Balay     c = strcmp(a,b);
476e5c89e4eSSatish Balay     if (c > 0) *t = PETSC_TRUE;
477e5c89e4eSSatish Balay     else       *t = PETSC_FALSE;
478e5c89e4eSSatish Balay   }
479e5c89e4eSSatish Balay   PetscFunctionReturn(0);
480e5c89e4eSSatish Balay }
481e5c89e4eSSatish Balay 
482e5c89e4eSSatish Balay #undef __FUNCT__
483e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrcasecmp"
484e5c89e4eSSatish Balay /*@C
485e5c89e4eSSatish Balay    PetscStrcasecmp - Returns true if the two strings are the same
486e5c89e4eSSatish Balay      except possibly for case.
487e5c89e4eSSatish Balay 
488e5c89e4eSSatish Balay    Not Collective
489e5c89e4eSSatish Balay 
490e5c89e4eSSatish Balay    Input Parameters:
491e5c89e4eSSatish Balay +  a - pointer to first string
492e5c89e4eSSatish Balay -  b - pointer to second string
493e5c89e4eSSatish Balay 
494e5c89e4eSSatish Balay    Output Parameter:
495e5c89e4eSSatish Balay .  flg - if the two strings are the same
496e5c89e4eSSatish Balay 
497e5c89e4eSSatish Balay    Notes:
498e5c89e4eSSatish Balay     Null arguments are ok
499e5c89e4eSSatish Balay 
5006f013253SBarry Smith    Not for use in Fortran
5016f013253SBarry Smith 
502e5c89e4eSSatish Balay    Level: intermediate
503e5c89e4eSSatish Balay 
504e5c89e4eSSatish Balay .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
505e5c89e4eSSatish Balay 
506e5c89e4eSSatish Balay @*/
5077087cfbeSBarry Smith PetscErrorCode  PetscStrcasecmp(const char a[],const char b[],PetscBool  *t)
508e5c89e4eSSatish Balay {
509e5c89e4eSSatish Balay   int c;
510e5c89e4eSSatish Balay 
511e5c89e4eSSatish Balay   PetscFunctionBegin;
512e5c89e4eSSatish Balay   if (!a && !b) c = 0;
513e5c89e4eSSatish Balay   else if (!a || !b) c = 1;
51432b366c8SSatish Balay #if defined(PETSC_HAVE_STRCASECMP)
51532b366c8SSatish Balay   else c = strcasecmp(a,b);
51632b366c8SSatish Balay #elif defined(PETSC_HAVE_STRICMP)
517e5c89e4eSSatish Balay   else c = stricmp(a,b);
518e5c89e4eSSatish Balay #else
51932b366c8SSatish Balay   else {
52032b366c8SSatish Balay     char           *aa,*bb;
52132b366c8SSatish Balay     PetscErrorCode ierr;
52232b366c8SSatish Balay     ierr = PetscStrallocpy(a,&aa);CHKERRQ(ierr);
52332b366c8SSatish Balay     ierr = PetscStrallocpy(b,&bb);CHKERRQ(ierr);
52432b366c8SSatish Balay     ierr = PetscStrtolower(aa);CHKERRQ(ierr);
52532b366c8SSatish Balay     ierr = PetscStrtolower(bb);CHKERRQ(ierr);
52632b366c8SSatish Balay     ierr = PetscStrcmp(aa,bb,t);CHKERRQ(ierr);
527503cfb0cSBarry Smith     ierr = PetscFree(aa);CHKERRQ(ierr);
528503cfb0cSBarry Smith     ierr = PetscFree(bb);CHKERRQ(ierr);
52932b366c8SSatish Balay     PetscFunctionReturn(0);
53032b366c8SSatish Balay   }
531e5c89e4eSSatish Balay #endif
532e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
533e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
534e5c89e4eSSatish Balay   PetscFunctionReturn(0);
535e5c89e4eSSatish Balay }
536e5c89e4eSSatish Balay 
53732b366c8SSatish Balay 
53832b366c8SSatish Balay 
539e5c89e4eSSatish Balay #undef __FUNCT__
540e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrncmp"
541e5c89e4eSSatish Balay /*@C
542e5c89e4eSSatish Balay    PetscStrncmp - Compares two strings, up to a certain length
543e5c89e4eSSatish Balay 
544e5c89e4eSSatish Balay    Not Collective
545e5c89e4eSSatish Balay 
546e5c89e4eSSatish Balay    Input Parameters:
547e5c89e4eSSatish Balay +  a - pointer to first string
548e5c89e4eSSatish Balay .  b - pointer to second string
549e5c89e4eSSatish Balay -  n - length to compare up to
550e5c89e4eSSatish Balay 
551e5c89e4eSSatish Balay    Output Parameter:
552e5c89e4eSSatish Balay .  t - if the two strings are equal
553e5c89e4eSSatish Balay 
554e5c89e4eSSatish Balay    Level: intermediate
555e5c89e4eSSatish Balay 
5566f013253SBarry Smith    Notes:    Not for use in Fortran
5576f013253SBarry Smith 
558e5c89e4eSSatish Balay .seealso: PetscStrgrt(), PetscStrcmp(), PetscStrcasecmp()
559e5c89e4eSSatish Balay 
560e5c89e4eSSatish Balay @*/
5617087cfbeSBarry Smith PetscErrorCode  PetscStrncmp(const char a[],const char b[],size_t n,PetscBool  *t)
562e5c89e4eSSatish Balay {
563e5c89e4eSSatish Balay   int c;
564e5c89e4eSSatish Balay 
565e5c89e4eSSatish Balay   PetscFunctionBegin;
566e5c89e4eSSatish Balay   c = strncmp(a,b,n);
567e5c89e4eSSatish Balay   if (!c) *t = PETSC_TRUE;
568e5c89e4eSSatish Balay   else    *t = PETSC_FALSE;
569e5c89e4eSSatish Balay   PetscFunctionReturn(0);
570e5c89e4eSSatish Balay }
571e5c89e4eSSatish Balay 
572e5c89e4eSSatish Balay #undef __FUNCT__
573e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrchr"
574e5c89e4eSSatish Balay /*@C
575e5c89e4eSSatish Balay    PetscStrchr - Locates first occurance of a character in a string
576e5c89e4eSSatish Balay 
577e5c89e4eSSatish Balay    Not Collective
578e5c89e4eSSatish Balay 
579e5c89e4eSSatish Balay    Input Parameters:
580e5c89e4eSSatish Balay +  a - pointer to string
581e5c89e4eSSatish Balay -  b - character
582e5c89e4eSSatish Balay 
583e5c89e4eSSatish Balay    Output Parameter:
5840298fd71SBarry Smith .  c - location of occurance, NULL if not found
585e5c89e4eSSatish Balay 
586e5c89e4eSSatish Balay    Level: intermediate
587e5c89e4eSSatish Balay 
5886f013253SBarry Smith    Notes:    Not for use in Fortran
5896f013253SBarry Smith 
590e5c89e4eSSatish Balay @*/
5917087cfbeSBarry Smith PetscErrorCode  PetscStrchr(const char a[],char b,char *c[])
592e5c89e4eSSatish Balay {
593e5c89e4eSSatish Balay   PetscFunctionBegin;
594e5c89e4eSSatish Balay   *c = (char*)strchr(a,b);
595e5c89e4eSSatish Balay   PetscFunctionReturn(0);
596e5c89e4eSSatish Balay }
597e5c89e4eSSatish Balay 
598e5c89e4eSSatish Balay #undef __FUNCT__
599e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrrchr"
600e5c89e4eSSatish Balay /*@C
601e5c89e4eSSatish Balay    PetscStrrchr - Locates one location past the last occurance of a character in a string,
602e5c89e4eSSatish Balay       if the character is not found then returns entire string
603e5c89e4eSSatish Balay 
604e5c89e4eSSatish Balay    Not Collective
605e5c89e4eSSatish Balay 
606e5c89e4eSSatish Balay    Input Parameters:
607e5c89e4eSSatish Balay +  a - pointer to string
608e5c89e4eSSatish Balay -  b - character
609e5c89e4eSSatish Balay 
610e5c89e4eSSatish Balay    Output Parameter:
611e5c89e4eSSatish Balay .  tmp - location of occurance, a if not found
612e5c89e4eSSatish Balay 
613e5c89e4eSSatish Balay    Level: intermediate
614e5c89e4eSSatish Balay 
6156f013253SBarry Smith    Notes:    Not for use in Fortran
6166f013253SBarry Smith 
617e5c89e4eSSatish Balay @*/
6187087cfbeSBarry Smith PetscErrorCode  PetscStrrchr(const char a[],char b,char *tmp[])
619e5c89e4eSSatish Balay {
620e5c89e4eSSatish Balay   PetscFunctionBegin;
621e5c89e4eSSatish Balay   *tmp = (char*)strrchr(a,b);
622a297a907SKarl Rupp   if (!*tmp) *tmp = (char*)a;
623a297a907SKarl Rupp   else *tmp = *tmp + 1;
624e5c89e4eSSatish Balay   PetscFunctionReturn(0);
625e5c89e4eSSatish Balay }
626e5c89e4eSSatish Balay 
627e5c89e4eSSatish Balay #undef __FUNCT__
628e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrtolower"
629e5c89e4eSSatish Balay /*@C
630e5c89e4eSSatish Balay    PetscStrtolower - Converts string to lower case
631e5c89e4eSSatish Balay 
632e5c89e4eSSatish Balay    Not Collective
633e5c89e4eSSatish Balay 
634e5c89e4eSSatish Balay    Input Parameters:
635e5c89e4eSSatish Balay .  a - pointer to string
636e5c89e4eSSatish Balay 
637e5c89e4eSSatish Balay    Level: intermediate
638e5c89e4eSSatish Balay 
6396f013253SBarry Smith    Notes:    Not for use in Fortran
6406f013253SBarry Smith 
641e5c89e4eSSatish Balay @*/
6427087cfbeSBarry Smith PetscErrorCode  PetscStrtolower(char a[])
643e5c89e4eSSatish Balay {
644e5c89e4eSSatish Balay   PetscFunctionBegin;
645e5c89e4eSSatish Balay   while (*a) {
646e5c89e4eSSatish Balay     if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
647e5c89e4eSSatish Balay     a++;
648e5c89e4eSSatish Balay   }
649e5c89e4eSSatish Balay   PetscFunctionReturn(0);
650e5c89e4eSSatish Balay }
651e5c89e4eSSatish Balay 
6527ba3a57cSBarry Smith #undef __FUNCT__
6532f234a98SBarry Smith #define __FUNCT__ "PetscStrtoupper"
6542f234a98SBarry Smith /*@C
6552f234a98SBarry Smith    PetscStrtolower - Converts string to upper case
6562f234a98SBarry Smith 
6572f234a98SBarry Smith    Not Collective
6582f234a98SBarry Smith 
6592f234a98SBarry Smith    Input Parameters:
6602f234a98SBarry Smith .  a - pointer to string
6612f234a98SBarry Smith 
6622f234a98SBarry Smith    Level: intermediate
6632f234a98SBarry Smith 
6642f234a98SBarry Smith    Notes:    Not for use in Fortran
6652f234a98SBarry Smith 
6662f234a98SBarry Smith @*/
6672f234a98SBarry Smith PetscErrorCode  PetscStrtoupper(char a[])
6682f234a98SBarry Smith {
6692f234a98SBarry Smith   PetscFunctionBegin;
6702f234a98SBarry Smith   while (*a) {
6712f234a98SBarry Smith     if (*a >= 'a' && *a <= 'z') *a += 'A' - 'a';
6722f234a98SBarry Smith     a++;
6732f234a98SBarry Smith   }
6742f234a98SBarry Smith   PetscFunctionReturn(0);
6752f234a98SBarry Smith }
6762f234a98SBarry Smith 
6772f234a98SBarry Smith #undef __FUNCT__
6787ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswith"
6797ba3a57cSBarry Smith /*@C
6807ba3a57cSBarry Smith    PetscStrendswith - Determines if a string ends with a certain string
6811d1a0024SBarry Smith 
6827ba3a57cSBarry Smith    Not Collective
6837ba3a57cSBarry Smith 
6847ba3a57cSBarry Smith    Input Parameters:
6857ba3a57cSBarry Smith +  a - pointer to string
6867ba3a57cSBarry Smith -  b - string to endwith
6877ba3a57cSBarry Smith 
6887ba3a57cSBarry Smith    Output Parameter:
6897ba3a57cSBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
6907ba3a57cSBarry Smith 
6917ba3a57cSBarry Smith    Notes:     Not for use in Fortran
6927ba3a57cSBarry Smith 
6937ba3a57cSBarry Smith    Level: intermediate
6947ba3a57cSBarry Smith 
6957ba3a57cSBarry Smith @*/
6967ba3a57cSBarry Smith PetscErrorCode  PetscStrendswith(const char a[],const char b[],PetscBool *flg)
6977ba3a57cSBarry Smith {
6987ba3a57cSBarry Smith   char           *test;
6997ba3a57cSBarry Smith   PetscErrorCode ierr;
7007ba3a57cSBarry Smith   size_t         na,nb;
7017ba3a57cSBarry Smith 
7027ba3a57cSBarry Smith   PetscFunctionBegin;
7037ba3a57cSBarry Smith   *flg = PETSC_FALSE;
7047ba3a57cSBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
7057ba3a57cSBarry Smith   if (test) {
7067ba3a57cSBarry Smith     ierr = PetscStrlen(a,&na);CHKERRQ(ierr);
7077ba3a57cSBarry Smith     ierr = PetscStrlen(b,&nb);CHKERRQ(ierr);
7087ba3a57cSBarry Smith     if (a+na-nb == test) *flg = PETSC_TRUE;
7097ba3a57cSBarry Smith   }
7107ba3a57cSBarry Smith   PetscFunctionReturn(0);
7117ba3a57cSBarry Smith }
7127ba3a57cSBarry Smith 
7137ba3a57cSBarry Smith #undef __FUNCT__
7142c9581d2SBarry Smith #define __FUNCT__ "PetscStrbeginswith"
7152c9581d2SBarry Smith /*@C
7162c9581d2SBarry Smith    PetscStrbeginswith - Determines if a string begins with a certain string
7172c9581d2SBarry Smith 
7182c9581d2SBarry Smith    Not Collective
7192c9581d2SBarry Smith 
7202c9581d2SBarry Smith    Input Parameters:
7212c9581d2SBarry Smith +  a - pointer to string
7222c9581d2SBarry Smith -  b - string to beginwith
7232c9581d2SBarry Smith 
7242c9581d2SBarry Smith    Output Parameter:
7252c9581d2SBarry Smith .  flg - PETSC_TRUE or PETSC_FALSE
7262c9581d2SBarry Smith 
7272c9581d2SBarry Smith    Notes:     Not for use in Fortran
7282c9581d2SBarry Smith 
7292c9581d2SBarry Smith    Level: intermediate
7302c9581d2SBarry Smith 
7312c9581d2SBarry Smith @*/
7322c9581d2SBarry Smith PetscErrorCode  PetscStrbeginswith(const char a[],const char b[],PetscBool *flg)
7332c9581d2SBarry Smith {
7342c9581d2SBarry Smith   char           *test;
7352c9581d2SBarry Smith   PetscErrorCode ierr;
7362c9581d2SBarry Smith 
7372c9581d2SBarry Smith   PetscFunctionBegin;
7382c9581d2SBarry Smith   *flg = PETSC_FALSE;
7392c9581d2SBarry Smith   ierr = PetscStrrstr(a,b,&test);CHKERRQ(ierr);
740a297a907SKarl Rupp   if (test && (test == a)) *flg = PETSC_TRUE;
7412c9581d2SBarry Smith   PetscFunctionReturn(0);
7422c9581d2SBarry Smith }
7432c9581d2SBarry Smith 
7442c9581d2SBarry Smith 
7452c9581d2SBarry Smith #undef __FUNCT__
7467ba3a57cSBarry Smith #define __FUNCT__ "PetscStrendswithwhich"
7477ba3a57cSBarry Smith /*@C
7487ba3a57cSBarry Smith    PetscStrendswithwhich - Determines if a string ends with one of several possible strings
7497ba3a57cSBarry Smith 
7507ba3a57cSBarry Smith    Not Collective
7517ba3a57cSBarry Smith 
7527ba3a57cSBarry Smith    Input Parameters:
7537ba3a57cSBarry Smith +  a - pointer to string
7547ba3a57cSBarry Smith -  bs - strings to endwith (last entry must be null)
7557ba3a57cSBarry Smith 
7567ba3a57cSBarry Smith    Output Parameter:
7577ba3a57cSBarry Smith .  cnt - the index of the string it ends with or 1+the last possible index
7587ba3a57cSBarry Smith 
7597ba3a57cSBarry Smith    Notes:     Not for use in Fortran
7607ba3a57cSBarry Smith 
7617ba3a57cSBarry Smith    Level: intermediate
7627ba3a57cSBarry Smith 
7637ba3a57cSBarry Smith @*/
7647ba3a57cSBarry Smith PetscErrorCode  PetscStrendswithwhich(const char a[],const char *const *bs,PetscInt *cnt)
7657ba3a57cSBarry Smith {
7667ba3a57cSBarry Smith   PetscBool      flg;
7677ba3a57cSBarry Smith   PetscErrorCode ierr;
7687ba3a57cSBarry Smith 
7697ba3a57cSBarry Smith   PetscFunctionBegin;
7707ba3a57cSBarry Smith   *cnt = 0;
7717ba3a57cSBarry Smith   while (bs[*cnt]) {
7727ba3a57cSBarry Smith     ierr = PetscStrendswith(a,bs[*cnt],&flg);CHKERRQ(ierr);
7737ba3a57cSBarry Smith     if (flg) PetscFunctionReturn(0);
7747ba3a57cSBarry Smith     *cnt += 1;
7757ba3a57cSBarry Smith   }
7767ba3a57cSBarry Smith   PetscFunctionReturn(0);
7777ba3a57cSBarry Smith }
7787ba3a57cSBarry Smith 
7797ba3a57cSBarry Smith #undef __FUNCT__
7807ba3a57cSBarry Smith #define __FUNCT__ "PetscStrrstr"
7817ba3a57cSBarry Smith /*@C
7827ba3a57cSBarry Smith    PetscStrrstr - Locates last occurance of string in another string
7837ba3a57cSBarry Smith 
7847ba3a57cSBarry Smith    Not Collective
7857ba3a57cSBarry Smith 
7867ba3a57cSBarry Smith    Input Parameters:
7877ba3a57cSBarry Smith +  a - pointer to string
7887ba3a57cSBarry Smith -  b - string to find
7897ba3a57cSBarry Smith 
7907ba3a57cSBarry Smith    Output Parameter:
7917ba3a57cSBarry Smith .  tmp - location of occurance
7927ba3a57cSBarry Smith 
7937ba3a57cSBarry Smith    Notes:     Not for use in Fortran
7947ba3a57cSBarry Smith 
7957ba3a57cSBarry Smith    Level: intermediate
7967ba3a57cSBarry Smith 
7977ba3a57cSBarry Smith @*/
7987ba3a57cSBarry Smith PetscErrorCode  PetscStrrstr(const char a[],const char b[],char *tmp[])
7997ba3a57cSBarry Smith {
8007ba3a57cSBarry Smith   const char *stmp = a, *ltmp = 0;
8017ba3a57cSBarry Smith 
8027ba3a57cSBarry Smith   PetscFunctionBegin;
8037ba3a57cSBarry Smith   while (stmp) {
8047ba3a57cSBarry Smith     stmp = (char*)strstr(stmp,b);
8057ba3a57cSBarry Smith     if (stmp) {ltmp = stmp;stmp++;}
8067ba3a57cSBarry Smith   }
8077ba3a57cSBarry Smith   *tmp = (char*)ltmp;
8087ba3a57cSBarry Smith   PetscFunctionReturn(0);
8097ba3a57cSBarry Smith }
8107ba3a57cSBarry Smith 
8117ba3a57cSBarry Smith #undef __FUNCT__
8127ba3a57cSBarry Smith #define __FUNCT__ "PetscStrstr"
8137ba3a57cSBarry Smith /*@C
8147ba3a57cSBarry Smith    PetscStrstr - Locates first occurance of string in another string
8157ba3a57cSBarry Smith 
8167ba3a57cSBarry Smith    Not Collective
8177ba3a57cSBarry Smith 
8187ba3a57cSBarry Smith    Input Parameters:
819160f4796SJed Brown +  haystack - string to search
820160f4796SJed Brown -  needle - string to find
8217ba3a57cSBarry Smith 
8227ba3a57cSBarry Smith    Output Parameter:
8230298fd71SBarry Smith .  tmp - location of occurance, is a NULL if the string is not found
8247ba3a57cSBarry Smith 
8257ba3a57cSBarry Smith    Notes: Not for use in Fortran
8267ba3a57cSBarry Smith 
8277ba3a57cSBarry Smith    Level: intermediate
8287ba3a57cSBarry Smith 
8297ba3a57cSBarry Smith @*/
830160f4796SJed Brown PetscErrorCode  PetscStrstr(const char haystack[],const char needle[],char *tmp[])
8317ba3a57cSBarry Smith {
8327ba3a57cSBarry Smith   PetscFunctionBegin;
833160f4796SJed Brown   *tmp = (char*)strstr(haystack,needle);
8347ba3a57cSBarry Smith   PetscFunctionReturn(0);
8357ba3a57cSBarry Smith }
8367ba3a57cSBarry Smith 
8377ba3a57cSBarry Smith struct _p_PetscToken {char token;char *array;char *current;};
8381d1a0024SBarry Smith 
839e5c89e4eSSatish Balay #undef __FUNCT__
840e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenFind"
841e5c89e4eSSatish Balay /*@C
842e5c89e4eSSatish Balay    PetscTokenFind - Locates next "token" in a string
843e5c89e4eSSatish Balay 
844e5c89e4eSSatish Balay    Not Collective
845e5c89e4eSSatish Balay 
846e5c89e4eSSatish Balay    Input Parameters:
847e5c89e4eSSatish Balay .  a - pointer to token
848e5c89e4eSSatish Balay 
849e5c89e4eSSatish Balay    Output Parameter:
8500298fd71SBarry Smith .  result - location of occurance, NULL if not found
851e5c89e4eSSatish Balay 
852e5c89e4eSSatish Balay    Notes:
853e5c89e4eSSatish Balay 
854e5c89e4eSSatish Balay      This version is different from the system version in that
855e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
856e5c89e4eSSatish Balay 
8574704e885SBarry Smith      This version also treats all characters etc. inside a double quote "
8584704e885SBarry Smith    as a single token.
8594704e885SBarry Smith 
8606f013253SBarry Smith     Not for use in Fortran
8616f013253SBarry Smith 
862e5c89e4eSSatish Balay    Level: intermediate
863e5c89e4eSSatish Balay 
8646f013253SBarry Smith 
865e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenDestroy()
866e5c89e4eSSatish Balay @*/
8677087cfbeSBarry Smith PetscErrorCode  PetscTokenFind(PetscToken a,char *result[])
868e5c89e4eSSatish Balay {
8694704e885SBarry Smith   char *ptr = a->current,token;
870e5c89e4eSSatish Balay 
871e5c89e4eSSatish Balay   PetscFunctionBegin;
872e5c89e4eSSatish Balay   *result = a->current;
8734704e885SBarry Smith   if (ptr && !*ptr) {*result = 0;PetscFunctionReturn(0);}
8744704e885SBarry Smith   token = a->token;
87590fdf44cSMatthew Knepley   if (ptr && (*ptr == '"')) {token = '"';(*result)++;ptr++;}
876e5c89e4eSSatish Balay   while (ptr) {
8774704e885SBarry Smith     if (*ptr == token) {
878e5c89e4eSSatish Balay       *ptr++ = 0;
879e5c89e4eSSatish Balay       while (*ptr == a->token) ptr++;
880e5c89e4eSSatish Balay       a->current = ptr;
881e5c89e4eSSatish Balay       break;
882e5c89e4eSSatish Balay     }
883e5c89e4eSSatish Balay     if (!*ptr) {
884e5c89e4eSSatish Balay       a->current = 0;
885e5c89e4eSSatish Balay       break;
886e5c89e4eSSatish Balay     }
887e5c89e4eSSatish Balay     ptr++;
888e5c89e4eSSatish Balay   }
889e5c89e4eSSatish Balay   PetscFunctionReturn(0);
890e5c89e4eSSatish Balay }
891e5c89e4eSSatish Balay 
892e5c89e4eSSatish Balay #undef __FUNCT__
893e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenCreate"
894e5c89e4eSSatish Balay /*@C
895e5c89e4eSSatish Balay    PetscTokenCreate - Creates a PetscToken used to find tokens in a string
896e5c89e4eSSatish Balay 
897e5c89e4eSSatish Balay    Not Collective
898e5c89e4eSSatish Balay 
899e5c89e4eSSatish Balay    Input Parameters:
900e5c89e4eSSatish Balay +  string - the string to look in
901e5c89e4eSSatish Balay -  token - the character to look for
902e5c89e4eSSatish Balay 
903e5c89e4eSSatish Balay    Output Parameter:
904e5c89e4eSSatish Balay .  a - pointer to token
905e5c89e4eSSatish Balay 
906e5c89e4eSSatish Balay    Notes:
907e5c89e4eSSatish Balay 
908e5c89e4eSSatish Balay      This version is different from the system version in that
909e5c89e4eSSatish Balay   it allows you to pass a read-only string into the function.
910e5c89e4eSSatish Balay 
9116f013253SBarry Smith     Not for use in Fortran
9126f013253SBarry Smith 
913e5c89e4eSSatish Balay    Level: intermediate
914e5c89e4eSSatish Balay 
915e5c89e4eSSatish Balay .seealso: PetscTokenFind(), PetscTokenDestroy()
916e5c89e4eSSatish Balay @*/
9177087cfbeSBarry Smith PetscErrorCode  PetscTokenCreate(const char a[],const char b,PetscToken *t)
918e5c89e4eSSatish Balay {
919e5c89e4eSSatish Balay   PetscErrorCode ierr;
920e5c89e4eSSatish Balay 
921e5c89e4eSSatish Balay   PetscFunctionBegin;
9221d1a0024SBarry Smith   ierr = PetscNew(struct _p_PetscToken,t);CHKERRQ(ierr);
923e5c89e4eSSatish Balay   ierr = PetscStrallocpy(a,&(*t)->array);CHKERRQ(ierr);
924a297a907SKarl Rupp 
925e5c89e4eSSatish Balay   (*t)->current = (*t)->array;
926e5c89e4eSSatish Balay   (*t)->token   = b;
927e5c89e4eSSatish Balay   PetscFunctionReturn(0);
928e5c89e4eSSatish Balay }
929e5c89e4eSSatish Balay 
930e5c89e4eSSatish Balay #undef __FUNCT__
931e5c89e4eSSatish Balay #define __FUNCT__ "PetscTokenDestroy"
932e5c89e4eSSatish Balay /*@C
933e5c89e4eSSatish Balay    PetscTokenDestroy - Destroys a PetscToken
934e5c89e4eSSatish Balay 
935e5c89e4eSSatish Balay    Not Collective
936e5c89e4eSSatish Balay 
937e5c89e4eSSatish Balay    Input Parameters:
938e5c89e4eSSatish Balay .  a - pointer to token
939e5c89e4eSSatish Balay 
940e5c89e4eSSatish Balay    Level: intermediate
941e5c89e4eSSatish Balay 
9426f013253SBarry Smith    Notes:     Not for use in Fortran
9436f013253SBarry Smith 
944e5c89e4eSSatish Balay .seealso: PetscTokenCreate(), PetscTokenFind()
945e5c89e4eSSatish Balay @*/
9468c74ee41SBarry Smith PetscErrorCode  PetscTokenDestroy(PetscToken *a)
947e5c89e4eSSatish Balay {
948e5c89e4eSSatish Balay   PetscErrorCode ierr;
949e5c89e4eSSatish Balay 
950e5c89e4eSSatish Balay   PetscFunctionBegin;
9518c74ee41SBarry Smith   if (!*a) PetscFunctionReturn(0);
9528c74ee41SBarry Smith   ierr = PetscFree((*a)->array);CHKERRQ(ierr);
9538c74ee41SBarry Smith   ierr = PetscFree(*a);CHKERRQ(ierr);
954e5c89e4eSSatish Balay   PetscFunctionReturn(0);
955e5c89e4eSSatish Balay }
956e5c89e4eSSatish Balay 
957e5c89e4eSSatish Balay 
958e5c89e4eSSatish Balay #undef __FUNCT__
959e5c89e4eSSatish Balay #define __FUNCT__ "PetscGetPetscDir"
960e5c89e4eSSatish Balay /*@C
961e5c89e4eSSatish Balay    PetscGetPetscDir - Gets the directory PETSc is installed in
962e5c89e4eSSatish Balay 
963e5c89e4eSSatish Balay    Not Collective
964e5c89e4eSSatish Balay 
965e5c89e4eSSatish Balay    Output Parameter:
966e5c89e4eSSatish Balay .  dir - the directory
967e5c89e4eSSatish Balay 
968e5c89e4eSSatish Balay    Level: developer
969e5c89e4eSSatish Balay 
9706f013253SBarry Smith    Notes: Not for use in Fortran
9716f013253SBarry Smith 
972e5c89e4eSSatish Balay @*/
9737087cfbeSBarry Smith PetscErrorCode  PetscGetPetscDir(const char *dir[])
974e5c89e4eSSatish Balay {
975e5c89e4eSSatish Balay   PetscFunctionBegin;
976e5c89e4eSSatish Balay   *dir = PETSC_DIR;
977e5c89e4eSSatish Balay   PetscFunctionReturn(0);
978e5c89e4eSSatish Balay }
979e5c89e4eSSatish Balay 
980e5c89e4eSSatish Balay #undef __FUNCT__
981e5c89e4eSSatish Balay #define __FUNCT__ "PetscStrreplace"
982e5c89e4eSSatish Balay /*@C
983e5c89e4eSSatish Balay    PetscStrreplace - Replaces substrings in string with other substrings
984e5c89e4eSSatish Balay 
985e5c89e4eSSatish Balay    Not Collective
986e5c89e4eSSatish Balay 
987e5c89e4eSSatish Balay    Input Parameters:
988e5c89e4eSSatish Balay +   comm - MPI_Comm of processors that are processing the string
98971573d7dSBarry Smith .   aa - the string to look in
990d8ccf1fbSBarry Smith .   b - the resulting copy of a with replaced strings (b can be the same as a)
991e5c89e4eSSatish Balay -   len - the length of b
992e5c89e4eSSatish Balay 
993e5c89e4eSSatish Balay    Notes:
994e5c89e4eSSatish Balay       Replaces   ${PETSC_ARCH},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
995d5649816SBarry Smith       ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME}, ${HOSTNAME} with appropriate values
996e5c89e4eSSatish Balay       as well as any environmental variables.
997e5c89e4eSSatish Balay 
9986f013253SBarry Smith       PETSC_LIB_DIR uses the environmental variable if it exists. PETSC_ARCH and PETSC_DIR use what
999acc6cc86SBarry Smith       PETSc was built with and do not use environmental variables.
1000acc6cc86SBarry Smith 
10016f013253SBarry Smith       Not for use in Fortran
10026f013253SBarry Smith 
1003e5c89e4eSSatish Balay    Level: intermediate
1004e5c89e4eSSatish Balay 
1005e5c89e4eSSatish Balay @*/
10067087cfbeSBarry Smith PetscErrorCode  PetscStrreplace(MPI_Comm comm,const char aa[],char b[],size_t len)
1007e5c89e4eSSatish Balay {
1008e5c89e4eSSatish Balay   PetscErrorCode ierr;
1009e5c89e4eSSatish Balay   int            i = 0;
1010e5c89e4eSSatish Balay   size_t         l,l1,l2,l3;
101171573d7dSBarry Smith   char           *work,*par,*epar,env[1024],*tfree,*a = (char*)aa;
1012d5649816SBarry Smith   const char     *s[] = {"${PETSC_ARCH}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}","${HOSTNAME}",0};
1013d5649816SBarry Smith   const char     *r[] = {0,0,0,0,0,0,0,0,0};
1014ace3abfcSBarry Smith   PetscBool      flag;
1015e5c89e4eSSatish Balay 
1016e5c89e4eSSatish Balay   PetscFunctionBegin;
1017e32f2f54SBarry Smith   if (!a || !b) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"a and b strings must be nonnull");
101871573d7dSBarry Smith   if (aa == b) {
101922982a5fSBarry Smith     ierr = PetscStrallocpy(aa,(char**)&a);CHKERRQ(ierr);
102071573d7dSBarry Smith   }
1021e5c89e4eSSatish Balay   ierr = PetscMalloc(len*sizeof(char*),&work);CHKERRQ(ierr);
1022e5c89e4eSSatish Balay 
1023e5c89e4eSSatish Balay   /* get values for replaced variables */
1024487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_ARCH,(char**)&r[0]);CHKERRQ(ierr);
1025487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_DIR,(char**)&r[1]);CHKERRQ(ierr);
1026487e5849SBarry Smith   ierr = PetscStrallocpy(PETSC_LIB_DIR,(char**)&r[2]);CHKERRQ(ierr);
1027487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[3]);CHKERRQ(ierr);
1028487e5849SBarry Smith   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[4]);CHKERRQ(ierr);
1029e5c89e4eSSatish Balay   ierr = PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[5]);CHKERRQ(ierr);
1030487e5849SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[6]);CHKERRQ(ierr);
1031d5649816SBarry Smith   ierr = PetscMalloc(256*sizeof(char),&r[7]);CHKERRQ(ierr);
1032487e5849SBarry Smith   ierr = PetscGetDisplay((char*)r[3],256);CHKERRQ(ierr);
1033487e5849SBarry Smith   ierr = PetscGetHomeDirectory((char*)r[4],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1034487e5849SBarry Smith   ierr = PetscGetWorkingDirectory((char*)r[5],PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
1035487e5849SBarry Smith   ierr = PetscGetUserName((char*)r[6],256);CHKERRQ(ierr);
1036d5649816SBarry Smith   ierr = PetscGetHostName((char*)r[7],256);CHKERRQ(ierr);
1037487e5849SBarry Smith 
1038487e5849SBarry Smith   /* replace that are in environment */
1039487e5849SBarry Smith   ierr = PetscOptionsGetenv(comm,"PETSC_LIB_DIR",env,1024,&flag);CHKERRQ(ierr);
1040487e5849SBarry Smith   if (flag) {
1041487e5849SBarry Smith     ierr = PetscStrallocpy(env,(char**)&r[2]);CHKERRQ(ierr);
1042487e5849SBarry Smith   }
1043e5c89e4eSSatish Balay 
1044e5c89e4eSSatish Balay   /* replace the requested strings */
1045e5c89e4eSSatish Balay   ierr = PetscStrncpy(b,a,len);CHKERRQ(ierr);
1046e5c89e4eSSatish Balay   while (s[i]) {
1047e5c89e4eSSatish Balay     ierr = PetscStrlen(s[i],&l);CHKERRQ(ierr);
1048e5c89e4eSSatish Balay     ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1049e5c89e4eSSatish Balay     while (par) {
1050e5c89e4eSSatish Balay       *par =  0;
1051e5c89e4eSSatish Balay       par += l;
1052e5c89e4eSSatish Balay 
1053e5c89e4eSSatish Balay       ierr = PetscStrlen(b,&l1);CHKERRQ(ierr);
1054e5c89e4eSSatish Balay       ierr = PetscStrlen(r[i],&l2);CHKERRQ(ierr);
1055e5c89e4eSSatish Balay       ierr = PetscStrlen(par,&l3);CHKERRQ(ierr);
105617186662SBarry Smith       if (l1 + l2 + l3 >= len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"b len is not long enough to hold new values");
1057e5c89e4eSSatish Balay       ierr = PetscStrcpy(work,b);CHKERRQ(ierr);
1058e5c89e4eSSatish Balay       ierr = PetscStrcat(work,r[i]);CHKERRQ(ierr);
1059e5c89e4eSSatish Balay       ierr = PetscStrcat(work,par);CHKERRQ(ierr);
1060e5c89e4eSSatish Balay       ierr = PetscStrncpy(b,work,len);CHKERRQ(ierr);
1061e5c89e4eSSatish Balay       ierr = PetscStrstr(b,s[i],&par);CHKERRQ(ierr);
1062e5c89e4eSSatish Balay     }
1063e5c89e4eSSatish Balay     i++;
1064e5c89e4eSSatish Balay   }
1065487e5849SBarry Smith   i = 0;
1066487e5849SBarry Smith   while (r[i]) {
1067e5c89e4eSSatish Balay     tfree = (char*)r[i];
1068e5c89e4eSSatish Balay     ierr  = PetscFree(tfree);CHKERRQ(ierr);
1069487e5849SBarry Smith     i++;
1070e5c89e4eSSatish Balay   }
1071e5c89e4eSSatish Balay 
1072e5c89e4eSSatish Balay   /* look for any other ${xxx} strings to replace from environmental variables */
1073e5c89e4eSSatish Balay   ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1074e5c89e4eSSatish Balay   while (par) {
1075e5c89e4eSSatish Balay     *par  = 0;
1076e5c89e4eSSatish Balay     par  += 2;
1077e5c89e4eSSatish Balay     ierr  = PetscStrcpy(work,b);CHKERRQ(ierr);
1078e5c89e4eSSatish Balay     ierr  = PetscStrstr(par,"}",&epar);CHKERRQ(ierr);
1079e5c89e4eSSatish Balay     *epar = 0;
1080e5c89e4eSSatish Balay     epar += 1;
1081e5c89e4eSSatish Balay     ierr  = PetscOptionsGetenv(comm,par,env,256,&flag);CHKERRQ(ierr);
10827ba3a57cSBarry Smith     if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Substitution string ${%s} not found as environmental variable",par);
1083e5c89e4eSSatish Balay     ierr = PetscStrcat(work,env);CHKERRQ(ierr);
1084e5c89e4eSSatish Balay     ierr = PetscStrcat(work,epar);CHKERRQ(ierr);
1085e5c89e4eSSatish Balay     ierr = PetscStrcpy(b,work);CHKERRQ(ierr);
1086e5c89e4eSSatish Balay     ierr = PetscStrstr(b,"${",&par);CHKERRQ(ierr);
1087e5c89e4eSSatish Balay   }
1088e5c89e4eSSatish Balay   ierr = PetscFree(work);CHKERRQ(ierr);
108971573d7dSBarry Smith   if (aa == b) {
109071573d7dSBarry Smith     ierr = PetscFree(a);CHKERRQ(ierr);
109171573d7dSBarry Smith   }
1092e5c89e4eSSatish Balay   PetscFunctionReturn(0);
1093e5c89e4eSSatish Balay }
1094e5c89e4eSSatish Balay 
1095e5c89e4eSSatish Balay 
1096