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 first 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: PetscStrtok - Locates next "token" in a string
403: Not Collective
405: Input Parameters:
406: + a - pointer to string
407: - b - token
409: Output Parameter:
410: . result - location of occurance, a if not found
412: Notes:
414: This version is different from the system version in that
415: it allows you to pass a read-only string into the function.
416: A copy is made that is then passed into the system strtok()
417: routine.
419: Limitation:
420: String must be less than or equal 1024 bytes in length, otherwise
421: it will bleed memory.
423: Level: intermediate
425: @*/
426: int PetscStrtok(const char a[],const char b[],char **result)
427: {
428: static char init[1024];
429: char *ptr=0;
430: int ierr,len;
431:
434: if (a) {
435: PetscStrlen(a,&len);
436: if (len > 1023) {
437: PetscMalloc((len+1)*sizeof(char),&ptr);
438: } else {
439: ptr = init;
440: }
441: PetscStrncpy(ptr,a,len+1);
442: }
443: *result = strtok(ptr,b);
444: return(0);
445: }
447: /*@C
448: PetscStrstr - Locates first occurance of string in another string
450: Not Collective
452: Input Parameters:
453: + a - pointer to string
454: - b - string to find
456: Output Parameter:
457: . tmp - location of occurance
459: Level: intermediate
461: @*/
462: int PetscStrstr(const char a[],const char b[],char **tmp)
463: {
465: *tmp = (char *)strstr(a,b);
466: return(0);
467: }
470: /*@C
471: PetscStrreplace - Replaces substrings in string with other substrings
473: Not Collective
475: Input Parameters:
476: + comm - MPI_Comm of processors that are processing the string
477: . a - the string to look in
478: . b - the resulting copy of a with replaced strings
479: - len - the length of b
481: Notes:
482: Replaces ${PETSC_ARCH},${BOPT},${PETSC_DIR},${PETSC_LIB_DIR},${DISPLAY},
483: ${HOMEDIRECTORY},${WORKINGDIRECTORY},${USERNAME} with appropriate values
484: as well as any environmental variables.
485:
486: Level: intermediate
488: @*/
489: int PetscStrreplace(MPI_Comm comm,const char a[],char *b,int len)
490: {
491: int ierr,i = 0,l,l1,l2,l3;
492: char *work,*par,*epar,env[256];
493: char *s[] = {"${PETSC_ARCH}","${BOPT}","${PETSC_DIR}","${PETSC_LIB_DIR}","${DISPLAY}","${HOMEDIRECTORY}","${WORKINGDIRECTORY}","${USERNAME}",0};
494: char *r[] = {PETSC_ARCH,PETSC_BOPT,PETSC_DIR,PETSC_LIB_DIR,0,0,0,0,0};
495: PetscTruth flag;
498: if (len <= 0) SETERRQ(1,"Length of b must be greater than 0");
499: if (!a || !b) SETERRQ(1,"a and b strings must be nonnull");
500: PetscMalloc(len*sizeof(char*),&work);
502: /* get values for replaced variables */
503: PetscMalloc(256*sizeof(char),&r[4]);
504: PetscMalloc(256*sizeof(char),&r[5]);
505: PetscMalloc(256*sizeof(char),&r[6]);
506: PetscMalloc(256*sizeof(char),&r[7]);
507: PetscGetDisplay(r[4],256);
508: PetscGetHomeDirectory(r[5],256);
509: PetscGetWorkingDirectory(r[6],256);
510: PetscGetUserName(r[7],256);
512: /* replace the requested strings */
513: PetscStrncpy(b,a,len);
514: while (s[i]) {
515: PetscStrlen(s[i],&l);
516: PetscStrstr(b,s[i],&par);
517: while (par) {
518: *par = 0;
519: par += l;
521: PetscStrlen(b,&l1);
522: PetscStrlen(r[i],&l2);
523: PetscStrlen(par,&l3);
524: if (l1 + l2 + l3 >= len) {
525: SETERRQ(1,"b len is not long enough to hold new values");
526: }
527: ierr = PetscStrcpy(work,b);
528: ierr = PetscStrcat(work,r[i]);
529: ierr = PetscStrcat(work,par);
530: ierr = PetscStrncpy(b,work,len);
531: ierr = PetscStrstr(b,s[i],&par);
532: }
533: i++;
534: }
535: PetscFree(r[4]);
536: PetscFree(r[5]);
537: PetscFree(r[6]);
538: PetscFree(r[7]);
540: /* look for any other ${xxx} strings to replace from environmental variables */
541: PetscStrstr(b,"${",&par);
542: while (par) {
543: *par = 0;
544: par += 2;
545: ierr = PetscStrcpy(work,b);
546: PetscStrstr(par,"}",&epar);
547: *epar = 0;
548: epar += 1;
549: PetscOptionsGetenv(comm,par,env,256,&flag);
550: if (!flag) {
551: SETERRQ1(1,"Substitution string ${%s} not found as environmental variable",par);
552: }
553: PetscStrcat(work,env);
554: PetscStrcat(work,epar);
555: PetscStrcpy(b,work);
556: PetscStrstr(b,"${",&par);
557: }
558: PetscFree(work);
560: return(0);
561: }