BSD 4_4_Lite2 release
[unix-history] / usr / src / usr.bin / make / str.c
index 84e95eb..7df8e8d 100644 (file)
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char     sccsid[] = "@(#)str.c  8.4 (Berkeley) 3/21/94";
+static char     sccsid[] = "@(#)str.c  8.6 (Berkeley) 4/28/95";
 #endif /* not lint */
 
 #include "make.h"
 
 #endif /* not lint */
 
 #include "make.h"
 
+static char **argv, *buffer;
+static int argmax, curlen;
+
+/*
+ * str_init --
+ *     Initialize the strings package
+ *
+ */
+void
+str_init()
+{
+    char *p1;
+    argv = (char **)emalloc((argmax = 50) * sizeof(char *));
+    argv[0] = Var_Value(".MAKE", VAR_GLOBAL, &p1);
+}
+
+
+/*
+ * str_end --
+ *     Cleanup the strings package
+ *
+ */
+void
+str_end()
+{
+    if (argv[0]) {
+       free(argv[0]);
+       free((Address) argv);
+    }
+    if (buffer)
+       free(buffer);
+}
+
+
 /*-
  * str_concat --
  *     concatenate the two strings, inserting a space or slash between them,
 /*-
  * str_concat --
  *     concatenate the two strings, inserting a space or slash between them,
@@ -99,29 +133,25 @@ str_concat(s1, s2, flags)
  *     the first word is always the value of the .MAKE variable.
  */
 char **
  *     the first word is always the value of the .MAKE variable.
  */
 char **
-brk_string(str, store_argc)
+brk_string(str, store_argc, expand)
        register char *str;
        int *store_argc;
        register char *str;
        int *store_argc;
+       Boolean expand;
 {
 {
-       static int argmax, curlen;
-       static char **argv, *buf;
        register int argc, ch;
        register char inquote, *p, *start, *t;
        int len;
 
        register int argc, ch;
        register char inquote, *p, *start, *t;
        int len;
 
-       /* save off pmake variable */
-       if (!argv) {
-               argv = (char **)emalloc((argmax = 50) * sizeof(char *));
-               argv[0] = Var_Value(".MAKE", VAR_GLOBAL);
-       }
-
        /* skip leading space chars. */
        for (; *str == ' ' || *str == '\t'; ++str)
                continue;
 
        /* allocate room for a copy of the string */
        /* skip leading space chars. */
        for (; *str == ' ' || *str == '\t'; ++str)
                continue;
 
        /* allocate room for a copy of the string */
-       if ((len = strlen(str) + 1) > curlen)
-               buf = emalloc(curlen = len);
+       if ((len = strlen(str) + 1) > curlen) {
+               if (buffer)
+                   free(buffer);
+               buffer = emalloc(curlen = len);
+       }
 
        /*
         * copy the string; at the same time, parse backslashes,
 
        /*
         * copy the string; at the same time, parse backslashes,
@@ -129,7 +159,7 @@ brk_string(str, store_argc)
         */
        argc = 1;
        inquote = '\0';
         */
        argc = 1;
        inquote = '\0';
-       for (p = str, start = t = buf;; ++p) {
+       for (p = str, start = t = buffer;; ++p) {
                switch(ch = *p) {
                case '"':
                case '\'':
                switch(ch = *p) {
                case '"':
                case '\'':
@@ -138,22 +168,36 @@ brk_string(str, store_argc)
                                        inquote = '\0';
                                else
                                        break;
                                        inquote = '\0';
                                else
                                        break;
-                       else
+                       else {
                                inquote = (char) ch;
                                inquote = (char) ch;
+                               /* Don't miss "" or '' */
+                               if (start == NULL && p[1] == inquote) {
+                                       start = t + 1;
+                                       break;
+                               }
+                       }
+                       if (!expand) {
+                               if (!start)
+                                       start = t;
+                               *t++ = ch;
+                       }
                        continue;
                case ' ':
                case '\t':
                        continue;
                case ' ':
                case '\t':
+               case '\n':
                        if (inquote)
                                break;
                        if (!start)
                                continue;
                        /* FALLTHROUGH */
                        if (inquote)
                                break;
                        if (!start)
                                continue;
                        /* FALLTHROUGH */
-               case '\n':
                case '\0':
                        /*
                         * end of a token -- make sure there's enough argv
                         * space and save off a pointer.
                         */
                case '\0':
                        /*
                         * end of a token -- make sure there's enough argv
                         * space and save off a pointer.
                         */
+                       if (!start)
+                           goto done;
+
                        *t++ = '\0';
                        if (argc == argmax) {
                                argmax *= 2;            /* ramp up fast */
                        *t++ = '\0';
                        if (argc == argmax) {
                                argmax *= 2;            /* ramp up fast */
@@ -167,6 +211,14 @@ brk_string(str, store_argc)
                                goto done;
                        continue;
                case '\\':
                                goto done;
                        continue;
                case '\\':
+                       if (!expand) {
+                               if (!start)
+                                       start = t;
+                               *t++ = '\\';
+                               ch = *++p;
+                               break;
+                       }
+                               
                        switch (ch = *++p) {
                        case '\0':
                        case '\n':
                        switch (ch = *++p) {
                        case '\0':
                        case '\n':