home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* strcons,istrcmp,strvec,vecstr,split 3
- /* SUMMARY
- /* string utility routines
- /* PROJECT
- /* pc-mail
- /* PACKAGE
- /* general stuff
- /* SYNOPSIS
- /* #include "defs.h"
- /*
- /* char *strcons(format,args)
- /* char *format;
- /*
- /* char *split(cpp, sep)
- /* char **cpp;
- /* char *sep;
- /*
- /* int istrncmp(s1,s2,n)
- /* char *s1,s2;
- /* int n;
- /*
- /* int istrcmp(s1,s2)
- /* char *s1,s2;
- /*
- /* char **strvec(string,separ)
- /* char *string;
- /* char *separ;
- /*
- /* freevec(vec)
- /* char **vec;
- /*
- /* char *vecstr(vector,separ)
- /* char **vector;
- /* char *separ;
- /* DESCRIPTION
- /* strcons() produces a formatted string, using printf()-like
- /* arguments. Basically it is an sprintf() that returns a
- /* pointer to the result. memory for the result is taken from
- /* a small memory pool that is recycled upon successive calls.
- /*
- /* split() searches the string pointed to by cpp for the occurrance
- /* of the text token (a string not containing any of the characters
- /* given in the "sep" argument). *cpp is updated if a token is
- /* found; a null pointer is returned otherwise. This function
- /* is an attempt to improve upon the strtok() function, which
- /* can parse only one string at a time. It still modifies its
- /* arguments, however.
- /*
- /* istrcmp() is a case-insensitive version of the strcmp() function.
- /*
- /* istrncmp() is a case-insensitive version of the strncmp() function.
- /*
- /* strvec() breaks a null-terminated string using the separators given
- /* in separ, and returns a null-terminated vector of pointers to the
- /* resulting substrings. Memory for the vector and substrings are
- /* allocated in dynamic memory. The original string is not modified.
- /*
- /* freevec() frees storage allocated by strvec().
- /*
- /* vecstr() takes a null-terminated vector of string pointers
- /* and builds a string from the strings pointed to by the vector
- /* argument, separated by the string in the separ argument.
- /* Memory for the result is allocated in dynamic memory.
- /* FUNCTIONS AND MACROS
- /* strtok(), malloc(), memcpy(), sprintf()
- /* DIAGNOSTICS
- /* strvec(), vecstr() return a null pointer if there was not enough memory
- /* avaliable to hold the result.
- /* BUGS
- /* strcons() does not do smart garbage collection; it just uses
- /* a circular buffer. The present implementation is not portable
- /* to machines that pass arguments via registers.
- /*
- /* strvec() cannot handle strings with more than BUFSIZ words.
- /* strvec() uses strtok(), which may have side effects.
- /* AUTHOR(S)
- /* W.Z. Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Tue Apr 5 20:59:29 MET 1988
- /* LAST MODIFICATION
- /* 90/01/22 13:02:43
- /* VERSION/RELEASE
- /* 2.1
- /*--*/
-
- #include <stdio.h>
- #include <ctype.h>
- #include <varargs.h>
-
- #include "defs.h"
-
- #define NBUF 4
-
- /* strcons - quick-and-dirty string constructor */
-
- /* VARARGS */
-
- char *strcons(va_alist)
- va_dcl
- {
- va_list ap;
- static char strbuf[NBUF][BUFSIZ];
- static int where = 0;
- register char *cp;
- char *fmt;
-
- va_start(ap);
- fmt = va_arg(ap, char *);
- (void) vsprintf(cp = strbuf[where = (where + 1) % NBUF], fmt, ap);
- va_end(ap);
- return (cp);
- }
-
- /* istrcmp - case-insensitive string comparison */
-
- #define LOW(c) (isascii(c)&&isupper(c)?tolower(c):(c))
-
- int istrcmp(s1, s2)
- register char *s1;
- register char *s2;
- {
- while (*s1 && (LOW(*s1) == LOW(*s2)))
- s1++, s2++;
- return (LOW(*s1) - LOW(*s2));
- }
-
- /* istrncmp - case-insensitive string comparison */
-
- #define LOW(c) (isascii(c)&&isupper(c)?tolower(c):(c))
-
- int istrncmp(s1, s2, n)
- register char *s1;
- register char *s2;
- register int n;
- {
- while (n > 0 && *s1 && (LOW(*s1) == LOW(*s2)))
- n--, s1++, s2++;
- return (n > 0 ? LOW(*s1) - LOW(*s2) : 0);
- }
-
- /* strvec - make vector of substring pointers */
-
- char **strvec(str, sep)
- char *str;
- char *sep;
- {
- #ifdef lint
- static
- #endif
- char *tmp[BUFSIZ]; /* scratch substring pointer storage */
- register char **cpp = tmp;
- char *sp; /* ptr to private copy of original */
- register int bytec;
-
- /* make a copy of the original string */
-
- if ((sp = malloc(strlen(str) + 1)) == 0)
- return (0);
- (void) strcpy(sp, str);
-
- /* chop our copy at sequences of one or more separators */
-
- for (*cpp = strtok(sp, sep); *cpp; *++cpp = strtok((char *) 0, sep))
- /* void */ ;
-
- /* now construct the vector of pointers to the substrings */
-
- if ((cpp = (char **) malloc(bytec = (cpp - tmp + 1) * sizeof(*cpp))) == 0)
- return (0);
- return ((char **) memcpy((char *) cpp, (char *) tmp, bytec));
- }
-
- /* freevec - release storage allocated by strvec() */
-
- freevec(vec)
- char **vec;
- {
- free(vec[0]);
- free((char *) vec);
- }
-
- /* vecstr - from null-terminated vector of string pointers to one flat string */
-
- public char *vecstr(vec, sep)
- char **vec;
- char *sep;
- {
- register char **cpp;
- register int len = 0; /* length of final string */
- register char *cp;
- register int flen = strlen(sep); /* filler between substrings */
-
- /* find out how big the resulting string will be */
-
- for (cpp = vec; *cpp; cpp++)
- len += strlen(*cpp) + flen;
-
- /* allocate and initialize the result string */
-
- if ((cp = malloc(len + 1)) == 0)
- return (0);
- *cp = '\0';
-
- /* fill the resulting string */
-
- for (cpp = vec; *cpp; cpp++) {
- (void) strcat(cp, *cpp);
- (void) strcat(cp, sep);
- }
- return (cp);
- }
-
- /* split - return next token in *cpp, update cpp */
-
- public char *split(cpp, sep)
- register char **cpp;
- register char *sep;
- {
- register char *start;
- char *end;
- char *strpbrk();
-
- /*
- * Find the beginning of the first token. If none is found, just return a
- * null value. Otherwise, if there is a separator that follows the token,
- * nullify it and advance *cpp to the first character after the nullified
- * separator. If the token is not followed by a separator advance *cpp to
- * the null byte that follows the token.
- */
-
- start = *cpp + strspn(*cpp, sep);
-
- if (start[0] == 0) {
- return (0); /* no token */
- } else if (end = strpbrk(start, sep)) { /* look for separator */
- *end = '\0'; /* nullify */
- *cpp = end + 1; /* advance beyond end */
- return (start); /* return token */
- } else {
- *cpp = start + strlen(start); /* advance to terminator */
- return (start); /* return token */
- }
- }
-