home *** CD-ROM | disk | FTP | other *** search
- /*
- * tstring.c
- *
- * 88-10-01 v1.0 created by greg yachuk, placed in the public domain
- * 88-10-06 v1.1 changed prerequisite list handling
- * 88-11-11 v1.2 fixed some bugs and added environment variables
- * 89-07-12 v1.3 stop appending shell commands, and flush output
- * 89-08-01 v1.4 AB lots of new options and code
- * 89-10-30 v1.5 -f -S -q options, took some changes from v1.4
- * 90-04-18 v1.6 -b -- -W options, emulate <<, non-BSD cleanup
- */
- #include <stdio.h>
- #include <ctype.h>
- #include <malloc.h>
- #include <string.h>
-
- #include "tstring.h"
-
-
- char *talloc(n)
- int n;
- {
- char *s;
-
- s = malloc(n);
- if (s == NULL)
- terror(1, "no free memory");
- return (s);
- }
-
-
- char *trealloc(s, n)
- char *s;
- int n;
- {
- s = realloc(s, n);
- if (s == NULL)
- talloc(n); /* force an error */
- return (s);
- }
-
-
- char *tstrncpy(s, n)
- char *s;
- int n;
- {
- s = strncpy(talloc(n + 1), s, n);
- s[n] = '\0';
- return (s);
- }
-
-
- terror(n, s)
- int n;
- char *s;
- {
- fputs("Make: ", stderr);
- fputs(s, stderr);
- putc('\n', stderr);
- if (n)
- exit(n);
- }
-
-
- /*
- * tstrspan - move to the end of a quoted string, ignoring escaped quotes
- */
- char *tstrspan(str)
- char *str;
- {
- char quote;
-
- if (*str != '\'' && *str != '"')
- return (str + 1);
-
- quote = *str++;
-
- while (*str && *str != quote)
- {
- /* check for escaped quote */
- if (*str == '\\' && str[1] == quote)
- ++str;
- ++str;
- }
-
- return (str);
- }
-
-
- /*
- * tunquote - remove quotes from a string
- */
- char *tunquote(str)
- char *str;
- {
- char *s;
- char *d;
-
- d = s = str;
-
- while (*s)
- {
- while (*s && *s == '"')
- ++s;
-
- while (*s && *s != '"')
- *d++ = *s++;
- }
-
- *d = '\0';
-
- return (str);
- }
-
-
- /*
- * tsplit - split a string into two components, normally a directory
- * path and a filename. If a pointer to a directory is
- * supplied, a string is allocated to contain the directory.
- * The filename is returned as a pointer into the supplied
- * string.
- */
- char *tsplit(s, seps, dp)
- char *s;
- char *seps;
- char **dp;
- {
- char *d; /* directory portion */
- char *f; /* file portion */
-
- d = s;
-
- /* find the final separator */
- while ((f = strpbrk(d, seps)) != NULL)
- d = f + 1;
-
- /* back up to final component */
- f = d;
-
- /* if we are still at the beginning, there was no Directory */
- if (d == s || dp == NULL)
- d = NULL;
- else
- {
- int len;
-
- /*
- * by the time we get here, d points to the final separator
- * char. we can substitute a NULL for this sep-char. Thus,
- * we don't need to add 1 in the following length
- * calculation.
- */
- len = d - s;
-
- d = talloc(len);
- d[--len] = '\0';
- while (--len >= 0)
- d[len] = s[len];
- }
-
- if (dp != NULL)
- *dp = d;
-
- return (f);
- }
-
-
- /*
- * token - take an input string and return a token each call
- * - default token delimiter characters are `isspace()'
- * - separator chars are in addition to `isspace()'
- * - text between quotes (" and ') is a single token
- * - if requested, the separator char is returned
- *
- * called as s = token(string, seps, &schar);
- * or s = token(string, NULL, NULL);
- *
- * followed by s = token(NULL, seps, NULL);
- * or s = token(NULL, NULL, &schar);
- *
- * returns NULL when no more tokens are available
- */
- char *token(s, sep, schar)
- char *s;
- char *sep;
- char *schar;
- {
- static char *olds = NULL;
-
- if (s)
- olds = s; /* we are starting all over again */
-
- if (schar)
- *schar = '\0';
-
- if (!olds || !*olds)
- return (NULL); /* no tokens left */
-
- while (isspace(*olds) || (sep && strchr(sep, *olds)))
- ++olds; /* skip leading spaces and sep's */
-
- if (*olds == NULL)
- return (NULL); /* remainder is all separator's */
-
- s = olds;
-
- while (*olds)
- {
- if (isspace(*olds) || (sep && strchr(sep, *olds)))
- {
- if (schar)
- *schar = *olds;
- *olds++ = '\0'; /* delimit the token */
- return (s);
- }
- else
- if (*olds == '"' || *olds == '\'')
- {
- olds = tstrspan(olds);
- if (*olds != '\0')
- ++olds; /* didn't hit eos, so skip quote */
- }
- else
- ++olds; /* otherwise, pass over char */
- }
-
- olds = NULL;
- return (s); /* return last token */
- }
-
-
- /*
- * tokenize - chop a string up into an array of (char *)'s
- */
- char **tokenize(input)
- char *input;
- {
- char **argv;
- int argc = 0;
- int alen;
-
- alen = 20; /* good initial guess */
- argv = (char **) talloc((alen + 1) * sizeof(char *));
-
- input = token(input, NULL, NULL); /* use default separators */
- while (input)
- {
- if (alen == argc)
- argv = (char **) trealloc((char *) argv,
- (alen <<= 1) * sizeof(char *));
- argv[argc++] = input;
- input = token(NULL, NULL, NULL);
- }
-
- argv[argc] = NULL; /* mark end of array */
-
- return (argv);
- }
-
-
- /*
- * tgets - read input, swallowing escaped newlines as necessary
- */
- char *tgets(fd)
- FILE *fd;
- {
- static char *input = NULL;
- static int inlen = 0;
- char *ep;
- int len;
-
- if (inlen == 0)
- input = talloc(inlen = 162);
-
- input[inlen - 2] = '\n';
- ep = input - 1;
- while ((fgets(input, inlen, fd)) != NULL)
- {
- for (;;)
- {
- while (input[inlen - 2] != '\n' && input[inlen - 2] != '\0')
- {
- len = inlen;
- input = trealloc(input, inlen <<= 1);
- ep = &input[len - 2];
- input[inlen - 2] = '\n';
- fgets(ep + 1, len + 1, fd);
- }
-
- while (*++ep);
- *--ep = '\0';
- do
- {
- --ep;
- } while (ep >= input && isspace(*ep));
-
- if (ep > input && *ep == '\\' && *--ep != '\\')
- fgets(ep + 1, inlen - (ep - input) - 1, fd);
- else
- break;
- }
-
- return (input);
- }
-
- inlen = 0;
- tfree(input);
- input = NULL;
-
- return (NULL);
- }
-