Actual source code: str.c
1: /*$Id: str.c,v 1.51 2001/04/05 21:06:52 balay Exp $*/
2: /*
3: We define the string operations here. The reason we just do not use
4: the standard string routines in the PETSc code is that on some machines
5: they are broken or have the wrong prototypes.
7: */
8: #include petsc.h
9: #include petscsys.h
10: #if defined(PETSC_HAVE_STRING_H)
11: #include <string.h>
12: #endif
13: #if defined(PETSC_HAVE_STRINGS_H)
14: #include <strings.h>
15: #endif
16: #include "petscfix.h"
18: /*@C
19: PetscStrlen - Gets length of a string
21: Not Collective
23: Input Parameters:
24: . s - pointer to string
26: Output Parameter:
27: . len - length in bytes
29: Level: intermediate
31: Note:
32: This routine is analogous to strlen().
34: Null string returns a length of zero
36: Concepts: string length
37:
38: @*/
39: int PetscStrlen(const char s[],int *len)
40: {
42: if (!s) {
43: *len = 0;
44: } else {
45: *len = strlen(s);
46: }
47: return(0);
48: }
50: /*@C
51: PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
53: Not Collective
55: Input Parameters:
56: . s - pointer to string
58: Output Parameter:
59: . t - the copied string
61: Level: intermediate
63: Note:
64: Null string returns a new null string
66: Concepts: string copy
67:
68: @*/
69: int PetscStrallocpy(const char s[],char **t)
70: {
71: int ierr,len;
74: if (s) {
75: PetscStrlen(s,&len);
76: PetscMalloc((1+len)*sizeof(char),t);
77: PetscStrcpy(*t,s);
78: } else {
79: *t = 0;
80: }
81: return(0);
82: }
84: /*@C
85: PetscStrcpy - Copies a string
87: Not Collective
89: Input Parameters:
90: . s - pointer to string
92: Output Parameter:
93: . t - the copied string
95: Level: intermediate
97: Note:
98: Null string returns a string starting with zero
100: Concepts: string copy
101:
102: .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat()
104: @*/
105: int PetscStrcpy(char s[],const char t[])
106: {
108: if (t && !s) {
109: SETERRQ(1,"Trying to copy string into null pointer");
110: }
111: if (t) {strcpy(s,t);}
112: else {s[0] = 0;}
113: return(0);
114: }
116: /*@C
117: PetscStrncpy - Copies a string up to a certain length
119: Not Collective
121: Input Parameters:
122: + s - pointer to string
123: - n - the length to copy
125: Output Parameter:
126: . t - the copied string
128: Level: intermediate
130: Note:
131: Null string returns a string starting with zero
133: Concepts: string copy
135: .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat()
136:
137: @*/
138: int PetscStrncpy(char s[],const char t[],int n)
139: {
141: strncpy(s,t,n);
142: return(0);
143: }
145: /*@C
146: PetscStrcat - Concatenates a string onto a given string
148: Not Collective
150: Input Parameters:
151: + s - pointer to string to be added to end
152: - t - string to be added to
154: Level: intermediate
156: Concepts: string copy
158: .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat()
159:
160: @*/
161: int PetscStrcat(char s[],const char t[])
162: {
164: strcat(s,t);
165: return(0);
166: }
168: /*@C
169: PetscStrncat - Concatenates a string onto a given string, up to a given length
171: Not Collective
173: Input Parameters:
174: + s - pointer to string to be added to end
175: . t - string to be added to
176: . n - maximum length to copy
178: Level: intermediate
180: Concepts: string copy
182: .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
183:
184: @*/
185: int PetscStrncat(char s[],const char t[],int n)
186: {
188: strncat(s,t,n);
189: return(0);
190: }
192: /*@C
193: PetscStrcmp - Compares two strings,
195: Not Collective
197: Input Parameters:
198: + a - pointer to string first string
199: - b - pointer to second string
201: Output Parameter:
202: . flg - if the two strings are equal
204: Level: intermediate
206: .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
208: @*/
209: int PetscStrcmp(const char a[],const char b[],PetscTruth *flg)
210: {
211: int c;
214: if (!a && !b) {
215: *flg = PETSC_TRUE;
216: } else if (!a || !b) {
217: *flg = PETSC_FALSE;
218: } else {
219: c = strcmp(a,b);
220: if (c) *flg = PETSC_FALSE;
221: else *flg = PETSC_TRUE;
222: }
223: return(0);
224: }
226: /*@C
227: PetscStrgrt - If first string is greater than the second
229: Not Collective
231: Input Parameters:
232: + a - pointer to string first string
233: - b - pointer to second string
235: Output Parameter:
236: . flg - if the first string is greater
238: Notes:
239: Null arguments are ok, a null string is considered smaller than
240: all others
242: Level: intermediate
244: .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
246: @*/
247: int PetscStrgrt(const char a[],const char b[],PetscTruth *t)
248: {
249: int c;
252: if (!a && !b) {
253: *t = PETSC_FALSE;
254: } else if (a && !b) {
255: *t = PETSC_TRUE;
256: } else if (!a && b) {
257: *t = PETSC_FALSE;
258: } else {
259: c = strcmp(a,b);
260: if (c > 0) *t = PETSC_TRUE;
261: else *t = PETSC_FALSE;
262: }
263: return(0);
264: }
266: /*@C
267: PetscStrcasecmp - Returns true if the two strings are the same
268: except possibly for case.
270: Not Collective
272: Input Parameters:
273: + a - pointer to string first string
274: - b - pointer to second string
276: Output Parameter:
277: . flg - if the two strings are the same
279: Notes:
280: Null arguments are ok
282: Level: intermediate
284: .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
286: @*/
287: int PetscStrcasecmp(const char a[],const char b[],PetscTruth *t)
288: {
289: int c;
292: if (!a && !b) c = 0;
293: else if (!a || !b) c = 1;
294: #if defined (PARCH_win32)
295: else c = stricmp(a,b);
296: #else
297: else c = strcasecmp(a,b);
298: #endif
299: if (!c) *t = PETSC_TRUE;
300: else *t = PETSC_FALSE;
301: return(0);
302: }
304: /*@C
305: PetscStrcmp - Compares two strings, up to a certain length
307: Not Collective
309: Input Parameters:
310: + a - pointer to string first string
311: . b - pointer to second string
312: - n - length to compare up to
314: Output Parameter:
315: . t - if the two strings are equal
317: Level: intermediate
319: .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
321: @*/
322: int PetscStrncmp(const char a[],const char b[],int n,PetscTruth *t)
323: {
324: int c;
327: c = strncmp(a,b,n);
328: if (!c) *t = PETSC_TRUE;
329: else *t = PETSC_FALSE;
330: return(0);
331: }
333: /*@C
334: PetscStrchr - Locates first occurance of a character in a string
336: Not Collective
338: Input Parameters:
339: + a - pointer to string first string
340: - b - character
342: Output Parameter:
343: . c - location of occurance, PETSC_NULL if not found
345: Level: intermediate
347: @*/
348: int PetscStrchr(const char a[],char b,char **c)
349: {
351: *c = (char *)strchr(a,b);
352: return(0);
353: }
355: /*@C
356: PetscStrrchr - Locates one location past the last occurance of a character in a string,
357: if the character is not found then returns entire string
359: Not Collective
361: Input Parameters:
362: + a - pointer to string first string
363: - b - character
365: Output Parameter:
366: . tmp - location of occurance, a if not found
368: Level: intermediate
370: @*/
371: int PetscStrrchr(const char a[],char b,char **tmp)
372: {
374: *tmp = (char *)strrchr(a,b);
375: if (!*tmp) *tmp = (char*)a; else *tmp = *tmp + 1;
376: return(0);
377: }
379: /*@C
380: PetscStrtolower - Converts string to lower case
382: Not Collective
384: Input Parameters:
385: . a - pointer to string
387: Level: intermediate
389: @*/
390: int PetscStrtolower(char a[])
391: {
393: while (*a) {
394: if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
395: a++;
396: }
397: return(0);
398: }
400: /*@C
401: PetscTokenFind - Locates next "token" in a string
403: Not Collective
405: Input Parameters:
406: . a - pointer to token
408: Output Parameter:
409: . result - location of occurance, a if not found
411: Notes:
413: This version is different from the system version in that
414: it allows you to pass a read-only string into the function.
416: Level: intermediate
418: .seealso: PetscTokenCreate(), PetscTokenDestroy()
419: @*/
420: int PetscTokenFind(PetscToken *a,char **result)
421: {
422: char *ptr = a->current;
425: *result = a->current;
426: if (ptr && *ptr == 0) *result = 0;
427: while (ptr) {
428: if (*ptr == a->token) {
429: *ptr++ = 0;
430: while (*ptr == a->token) ptr++;
431: a->current = ptr;
432: break;
433: }
434: if (*ptr == 0) {
435: a->current = 0;
436: break;
437: }
438: ptr++;
439: }
440: return(0);
441: }
443: /*@C
444: PetscTokenCreate - Creates a PetscToken used to find tokens in a string
446: Not Collective
448: Input Parameters:
449: + string - the string to look in
450: - token - the character to look for
452: Output Parameter:
453: . a - pointer to token
455: Notes:
457: This version is different from the system version in that
458: it allows you to pass a read-only string into the function.
460: Level: intermediate
462: .seealso: PetscTokenFind(), PetscTokenDestroy()
463: @*/
464: int PetscTokenCreate(const char a[],const char b,PetscToken **t)
465: {
466: int ierr,len;
469: PetscNew(PetscToken,t);
470: PetscStrlen(a,&len);
471: PetscStrallocpy(a,&(*t)->array);
472: (*t)->current = (*t)->array;
473: (*t)->token = b;
474: return(0);
475: }
477: /*@C
478: PetscTokenDestroy - Destroys a PetscToken
480: Not Collective
482: Input Parameters:
483: . a - pointer to token
485: Level: intermediate
487: .seealso: PetscTokenCreate(), PetscTokenFind()
488: @*/
489: int PetscTokenDestroy(PetscToken *a)
490: {
494: PetscFree(a->array);
495: PetscFree(a);
496: return(0);
497: }
499: /*@C
500: PetscStrstr - Locates first occurance of string in another string
502: Not Collective
504: Input Parameters:
505: + a - pointer to string
506: - b - string to find
508: Output Parameter:
509: . tmp - location of occurance
511: Level: intermediate
513: @*/
514: int PetscStrstr(const char a[],const char b[],char **tmp)
515: {
517: *tmp = (char *)strstr(a,b);
518: return(0);
519: }
521: /*@C
522: PetscGetPetscDir - Gets the directory PETSc is installed in
524: Not Collective
526: Output Parameter:
527: . dir - the directory
529: Level: developer
531: @*/
532: int PetscGetPetscDir(char **dir)
533: {
535: *dir = PETSC_DIR;
536: return(0);
537: }
539: /*@C
540: PetscStrreplace - Replaces substrings in string with other substrings
542: Not Collective
544: Input Parameters:
545: + comm - MPI_Comm of processors that are processing the string
546: . a - the string to look in
547: . b - the resulting copy of a with replaced strings
548: - len - the length of b
550: Notes:
551: Replaces ${PETSC_ARCH},${BOPT},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
552: ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME} with appropriate values
553: as well as any environmental variables.
554:
555: Level: intermediate
557: @*/
558: int PetscStrreplace(MPI_Comm comm,const char a[],char *b,int len)
559: {
560: int ierr,i = 0,l,l1,l2,l3;
561: char *work,*par,*epar,env[256];
562: char *s[] = {"${PETSC_ARCH}","${BOPT}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}",0};
563: char *r[] = {PETSC_ARCH,PETSC_BOPT,PETSC_DIR,PETSC_LIB_DIR,0,0,0,0,0};
564: PetscTruth flag;
567: if (len <= 0) SETERRQ(1,"Length of b must be greater than 0");
568: if (!a || !b) SETERRQ(1,"a and b strings must be nonnull");
569: PetscMalloc(len*sizeof(char*),&work);
571: /* get values for replaced variables */
572: PetscMalloc(256*sizeof(char),&r[4]);
573: PetscMalloc(256*sizeof(char),&r[5]);
574: PetscMalloc(256*sizeof(char),&r[6]);
575: PetscMalloc(256*sizeof(char),&r[7]);
576: PetscGetDisplay(r[4],256);
577: PetscGetHomeDirectory(r[5],256);
578: PetscGetWorkingDirectory(r[6],256);
579: PetscGetUserName(r[7],256);
581: /* replace the requested strings */
582: PetscStrncpy(b,a,len);
583: while (s[i]) {
584: PetscStrlen(s[i],&l);
585: PetscStrstr(b,s[i],&par);
586: while (par) {
587: *par = 0;
588: par += l;
590: PetscStrlen(b,&l1);
591: PetscStrlen(r[i],&l2);
592: PetscStrlen(par,&l3);
593: if (l1 + l2 + l3 >= len) {
594: SETERRQ(1,"b len is not long enough to hold new values");
595: }
596: ierr = PetscStrcpy(work,b);
597: ierr = PetscStrcat(work,r[i]);
598: ierr = PetscStrcat(work,par);
599: ierr = PetscStrncpy(b,work,len);
600: ierr = PetscStrstr(b,s[i],&par);
601: }
602: i++;
603: }
604: PetscFree(r[4]);
605: PetscFree(r[5]);
606: PetscFree(r[6]);
607: PetscFree(r[7]);
609: /* look for any other ${xxx} strings to replace from environmental variables */
610: PetscStrstr(b,"${",&par);
611: while (par) {
612: *par = 0;
613: par += 2;
614: ierr = PetscStrcpy(work,b);
615: PetscStrstr(par,"}",&epar);
616: *epar = 0;
617: epar += 1;
618: PetscOptionsGetenv(comm,par,env,256,&flag);
619: if (!flag) {
620: SETERRQ1(1,"Substitution string ${%s} not found as environmental variable",par);
621: }
622: PetscStrcat(work,env);
623: PetscStrcat(work,epar);
624: PetscStrcpy(b,work);
625: PetscStrstr(b,"${",&par);
626: }
627: PetscFree(work);
629: return(0);
630: }