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: }