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: #undef __FUNCT__
20: /*@C
21: PetscStrlen - Gets length of a string
23: Not Collective
25: Input Parameters:
26: . s - pointer to string
28: Output Parameter:
29: . len - length in bytes
31: Level: intermediate
33: Note:
34: This routine is analogous to strlen().
36: Null string returns a length of zero
38: Concepts: string length
39:
40: @*/
41: int PetscStrlen(const char s[],int *len)
42: {
44: if (!s) {
45: *len = 0;
46: } else {
47: *len = strlen(s);
48: }
49: return(0);
50: }
52: #undef __FUNCT__
54: /*@C
55: PetscStrallocpy - Allocates space to hold a copy of a string then copies the string
57: Not Collective
59: Input Parameters:
60: . s - pointer to string
62: Output Parameter:
63: . t - the copied string
65: Level: intermediate
67: Note:
68: Null string returns a new null string
70: Concepts: string copy
71:
72: @*/
73: int PetscStrallocpy(const char s[],char **t)
74: {
75: int ierr,len;
78: if (s) {
79: PetscStrlen(s,&len);
80: PetscMalloc((1+len)*sizeof(char),t);
81: PetscStrcpy(*t,s);
82: } else {
83: *t = 0;
84: }
85: return(0);
86: }
88: #undef __FUNCT__
90: /*@C
91: PetscStrcpy - Copies a string
93: Not Collective
95: Input Parameters:
96: . s - pointer to string
98: Output Parameter:
99: . t - the copied string
101: Level: intermediate
103: Note:
104: Null string returns a string starting with zero
106: Concepts: string copy
107:
108: .seealso: PetscStrncpy(), PetscStrcat(), PetscStrncat()
110: @*/
111: int PetscStrcpy(char s[],const char t[])
112: {
114: if (t && !s) {
115: SETERRQ(1,"Trying to copy string into null pointer");
116: }
117: if (t) {strcpy(s,t);}
118: else {s[0] = 0;}
119: return(0);
120: }
122: #undef __FUNCT__
124: /*@C
125: PetscStrncpy - Copies a string up to a certain length
127: Not Collective
129: Input Parameters:
130: + s - pointer to string
131: - n - the length to copy
133: Output Parameter:
134: . t - the copied string
136: Level: intermediate
138: Note:
139: Null string returns a string starting with zero
141: Concepts: string copy
143: .seealso: PetscStrcpy(), PetscStrcat(), PetscStrncat()
144:
145: @*/
146: int PetscStrncpy(char s[],const char t[],int n)
147: {
149: strncpy(s,t,n);
150: return(0);
151: }
153: #undef __FUNCT__
155: /*@C
156: PetscStrcat - Concatenates a string onto a given string
158: Not Collective
160: Input Parameters:
161: + s - pointer to string to be added to end
162: - t - string to be added to
164: Level: intermediate
166: Concepts: string copy
168: .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrncat()
169:
170: @*/
171: int PetscStrcat(char s[],const char t[])
172: {
174: strcat(s,t);
175: return(0);
176: }
178: #undef __FUNCT__
180: /*@C
181: PetscStrncat - Concatenates a string onto a given string, up to a given length
183: Not Collective
185: Input Parameters:
186: + s - pointer to string to be added to end
187: . t - string to be added to
188: . n - maximum length to copy
190: Level: intermediate
192: Concepts: string copy
194: .seealso: PetscStrcpy(), PetscStrncpy(), PetscStrcat()
195:
196: @*/
197: int PetscStrncat(char s[],const char t[],int n)
198: {
200: strncat(s,t,n);
201: return(0);
202: }
204: #undef __FUNCT__
206: /*@C
207: PetscStrcmp - Compares two strings,
209: Not Collective
211: Input Parameters:
212: + a - pointer to string first string
213: - b - pointer to second string
215: Output Parameter:
216: . flg - if the two strings are equal
218: Level: intermediate
220: .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
222: @*/
223: int PetscStrcmp(const char a[],const char b[],PetscTruth *flg)
224: {
225: int c;
228: if (!a && !b) {
229: *flg = PETSC_TRUE;
230: } else if (!a || !b) {
231: *flg = PETSC_FALSE;
232: } else {
233: c = strcmp(a,b);
234: if (c) *flg = PETSC_FALSE;
235: else *flg = PETSC_TRUE;
236: }
237: return(0);
238: }
240: #undef __FUNCT__
242: /*@C
243: PetscStrgrt - If first string is greater than the second
245: Not Collective
247: Input Parameters:
248: + a - pointer to string first string
249: - b - pointer to second string
251: Output Parameter:
252: . flg - if the first string is greater
254: Notes:
255: Null arguments are ok, a null string is considered smaller than
256: all others
258: Level: intermediate
260: .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrcasecmp()
262: @*/
263: int PetscStrgrt(const char a[],const char b[],PetscTruth *t)
264: {
265: int c;
268: if (!a && !b) {
269: *t = PETSC_FALSE;
270: } else if (a && !b) {
271: *t = PETSC_TRUE;
272: } else if (!a && b) {
273: *t = PETSC_FALSE;
274: } else {
275: c = strcmp(a,b);
276: if (c > 0) *t = PETSC_TRUE;
277: else *t = PETSC_FALSE;
278: }
279: return(0);
280: }
282: #undef __FUNCT__
284: /*@C
285: PetscStrcasecmp - Returns true if the two strings are the same
286: except possibly for case.
288: Not Collective
290: Input Parameters:
291: + a - pointer to string first string
292: - b - pointer to second string
294: Output Parameter:
295: . flg - if the two strings are the same
297: Notes:
298: Null arguments are ok
300: Level: intermediate
302: .seealso: PetscStrcmp(), PetscStrncmp(), PetscStrgrt()
304: @*/
305: int PetscStrcasecmp(const char a[],const char b[],PetscTruth *t)
306: {
307: int c;
310: if (!a && !b) c = 0;
311: else if (!a || !b) c = 1;
312: #if defined (PARCH_win32)
313: else c = stricmp(a,b);
314: #else
315: else c = strcasecmp(a,b);
316: #endif
317: if (!c) *t = PETSC_TRUE;
318: else *t = PETSC_FALSE;
319: return(0);
320: }
322: #undef __FUNCT__
324: /*@C
325: PetscStrcmp - Compares two strings, up to a certain length
327: Not Collective
329: Input Parameters:
330: + a - pointer to string first string
331: . b - pointer to second string
332: - n - length to compare up to
334: Output Parameter:
335: . t - if the two strings are equal
337: Level: intermediate
339: .seealso: PetscStrgrt(), PetscStrncmp(), PetscStrcasecmp()
341: @*/
342: int PetscStrncmp(const char a[],const char b[],int n,PetscTruth *t)
343: {
344: int c;
347: c = strncmp(a,b,n);
348: if (!c) *t = PETSC_TRUE;
349: else *t = PETSC_FALSE;
350: return(0);
351: }
353: #undef __FUNCT__
355: /*@C
356: PetscStrchr - Locates first occurance of a character in a string
358: Not Collective
360: Input Parameters:
361: + a - pointer to string first string
362: - b - character
364: Output Parameter:
365: . c - location of occurance, PETSC_NULL if not found
367: Level: intermediate
369: @*/
370: int PetscStrchr(const char a[],char b,char **c)
371: {
373: *c = (char *)strchr(a,b);
374: return(0);
375: }
377: #undef __FUNCT__
379: /*@C
380: PetscStrrchr - Locates one location past the last occurance of a character in a string,
381: if the character is not found then returns entire string
383: Not Collective
385: Input Parameters:
386: + a - pointer to string first string
387: - b - character
389: Output Parameter:
390: . tmp - location of occurance, a if not found
392: Level: intermediate
394: @*/
395: int PetscStrrchr(const char a[],char b,char **tmp)
396: {
398: *tmp = (char *)strrchr(a,b);
399: if (!*tmp) *tmp = (char*)a; else *tmp = *tmp + 1;
400: return(0);
401: }
403: #undef __FUNCT__
405: /*@C
406: PetscStrtolower - Converts string to lower case
408: Not Collective
410: Input Parameters:
411: . a - pointer to string
413: Level: intermediate
415: @*/
416: int PetscStrtolower(char a[])
417: {
419: while (*a) {
420: if (*a >= 'A' && *a <= 'Z') *a += 'a' - 'A';
421: a++;
422: }
423: return(0);
424: }
426: #undef __FUNCT__
428: /*@C
429: PetscTokenFind - Locates next "token" in a string
431: Not Collective
433: Input Parameters:
434: . a - pointer to token
436: Output Parameter:
437: . result - location of occurance, a if not found
439: Notes:
441: This version is different from the system version in that
442: it allows you to pass a read-only string into the function.
444: Level: intermediate
446: .seealso: PetscTokenCreate(), PetscTokenDestroy()
447: @*/
448: int PetscTokenFind(PetscToken *a,char **result)
449: {
450: char *ptr = a->current;
453: *result = a->current;
454: if (ptr && *ptr == 0) *result = 0;
455: while (ptr) {
456: if (*ptr == a->token) {
457: *ptr++ = 0;
458: while (*ptr == a->token) ptr++;
459: a->current = ptr;
460: break;
461: }
462: if (*ptr == 0) {
463: a->current = 0;
464: break;
465: }
466: ptr++;
467: }
468: return(0);
469: }
471: #undef __FUNCT__
473: /*@C
474: PetscTokenCreate - Creates a PetscToken used to find tokens in a string
476: Not Collective
478: Input Parameters:
479: + string - the string to look in
480: - token - the character to look for
482: Output Parameter:
483: . a - pointer to token
485: Notes:
487: This version is different from the system version in that
488: it allows you to pass a read-only string into the function.
490: Level: intermediate
492: .seealso: PetscTokenFind(), PetscTokenDestroy()
493: @*/
494: int PetscTokenCreate(const char a[],const char b,PetscToken **t)
495: {
496: int ierr,len;
499: PetscNew(PetscToken,t);
500: PetscStrlen(a,&len);
501: PetscStrallocpy(a,&(*t)->array);
502: (*t)->current = (*t)->array;
503: (*t)->token = b;
504: return(0);
505: }
507: #undef __FUNCT__
509: /*@C
510: PetscTokenDestroy - Destroys a PetscToken
512: Not Collective
514: Input Parameters:
515: . a - pointer to token
517: Level: intermediate
519: .seealso: PetscTokenCreate(), PetscTokenFind()
520: @*/
521: int PetscTokenDestroy(PetscToken *a)
522: {
526: PetscFree(a->array);
527: PetscFree(a);
528: return(0);
529: }
531: #undef __FUNCT__
533: /*@C
534: PetscStrstr - Locates first occurance of string in another string
536: Not Collective
538: Input Parameters:
539: + a - pointer to string
540: - b - string to find
542: Output Parameter:
543: . tmp - location of occurance
545: Level: intermediate
547: @*/
548: int PetscStrstr(const char a[],const char b[],char **tmp)
549: {
551: *tmp = (char *)strstr(a,b);
552: return(0);
553: }
555: #undef __FUNCT__
557: /*@C
558: PetscGetPetscDir - Gets the directory PETSc is installed in
560: Not Collective
562: Output Parameter:
563: . dir - the directory
565: Level: developer
567: @*/
568: int PetscGetPetscDir(char **dir)
569: {
571: *dir = PETSC_DIR;
572: return(0);
573: }
575: #undef __FUNCT__
577: /*@C
578: PetscStrreplace - Replaces substrings in string with other substrings
580: Not Collective
582: Input Parameters:
583: + comm - MPI_Comm of processors that are processing the string
584: . a - the string to look in
585: . b - the resulting copy of a with replaced strings
586: - len - the length of b
588: Notes:
589: Replaces ${PETSC_ARCH},${BOPT},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
590: ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME} with appropriate values
591: as well as any environmental variables.
592:
593: Level: intermediate
595: @*/
596: int PetscStrreplace(MPI_Comm comm,const char a[],char *b,int len)
597: {
598: int ierr,i = 0,l,l1,l2,l3;
599: char *work,*par,*epar,env[1024];
600: char *s[] = {"${PETSC_ARCH}","${BOPT}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}",0};
601: char *r[] = {PETSC_ARCH,PETSC_BOPT,PETSC_DIR,PETSC_LIB_DIR,0,0,0,0,0};
602: PetscTruth flag;
605: if (len <= 0) SETERRQ(1,"Length of b must be greater than 0");
606: if (!a || !b) SETERRQ(1,"a and b strings must be nonnull");
607: PetscMalloc(len*sizeof(char*),&work);
609: /* get values for replaced variables */
610: PetscMalloc(256*sizeof(char),&r[4]);
611: PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[5]);
612: PetscMalloc(PETSC_MAX_PATH_LEN*sizeof(char),&r[6]);
613: PetscMalloc(256*sizeof(char),&r[7]);
614: PetscGetDisplay(r[4],256);
615: PetscGetHomeDirectory(r[5],PETSC_MAX_PATH_LEN);
616: PetscGetWorkingDirectory(r[6],PETSC_MAX_PATH_LEN);
617: PetscGetUserName(r[7],256);
619: /* replace the requested strings */
620: PetscStrncpy(b,a,len);
621: while (s[i]) {
622: PetscStrlen(s[i],&l);
623: PetscStrstr(b,s[i],&par);
624: while (par) {
625: *par = 0;
626: par += l;
628: PetscStrlen(b,&l1);
629: PetscStrlen(r[i],&l2);
630: PetscStrlen(par,&l3);
631: if (l1 + l2 + l3 >= len) {
632: SETERRQ(1,"b len is not long enough to hold new values");
633: }
634: ierr = PetscStrcpy(work,b);
635: ierr = PetscStrcat(work,r[i]);
636: ierr = PetscStrcat(work,par);
637: ierr = PetscStrncpy(b,work,len);
638: ierr = PetscStrstr(b,s[i],&par);
639: }
640: i++;
641: }
642: PetscFree(r[4]);
643: PetscFree(r[5]);
644: PetscFree(r[6]);
645: PetscFree(r[7]);
647: /* look for any other ${xxx} strings to replace from environmental variables */
648: PetscStrstr(b,"${",&par);
649: while (par) {
650: *par = 0;
651: par += 2;
652: ierr = PetscStrcpy(work,b);
653: PetscStrstr(par,"}",&epar);
654: *epar = 0;
655: epar += 1;
656: PetscOptionsGetenv(comm,par,env,256,&flag);
657: if (!flag) {
658: SETERRQ1(1,"Substitution string ${%s} not found as environmental variable",par);
659: }
660: PetscStrcat(work,env);
661: PetscStrcat(work,epar);
662: PetscStrcpy(b,work);
663: PetscStrstr(b,"${",&par);
664: }
665: PetscFree(work);
667: return(0);
668: }