Index: /trunk/src/kmk/main.c
===================================================================
--- /trunk/src/kmk/main.c	(revision 1810)
+++ /trunk/src/kmk/main.c	(revision 1811)
@@ -2805,5 +2805,9 @@
     /* Ignore plain `-' for compatibility.  */
     return;
+#ifndef CONFIG_WITH_VALUE_LENGTH
   v = try_variable_definition (0, arg, o_command, 0);
+#else
+  v = try_variable_definition (0, arg, NULL, o_command, 0);
+#endif
   if (v != 0)
     {
Index: /trunk/src/kmk/make.h
===================================================================
--- /trunk/src/kmk/make.h	(revision 1810)
+++ /trunk/src/kmk/make.h	(revision 1811)
@@ -386,5 +386,9 @@
 char *next_token (const char *);
 char *end_of_token (const char *);
+#ifndef CONFIG_WITH_VALUE_LENGTH
 void collapse_continuations (char *);
+#else
+char *collapse_continuations (char *, unsigned int);
+#endif
 #ifdef CONFIG_WITH_OPTIMIZATION_HACKS /* memchr is usually compiler intrinsic, thus faster. */
 # define lindex(s, limit, c) ((char *)memchr((s), (c), (limit) - (s)))
Index: /trunk/src/kmk/misc.c
===================================================================
--- /trunk/src/kmk/misc.c	(revision 1810)
+++ /trunk/src/kmk/misc.c	(revision 1811)
@@ -20,4 +20,7 @@
 #include "dep.h"
 #include "debug.h"
+#ifdef CONFIG_WITH_VALUE_LENGTH
+# include <assert.h>
+#endif
 
 /* All bcopy calls in this file can be replaced by memcpy and save a tick or two. */
@@ -83,6 +86,11 @@
    This is done by copying the text at LINE into itself.  */
 
+#ifndef CONFIG_WITH_VALUE_LENGTH
 void
 collapse_continuations (char *line)
+#else
+char *
+collapse_continuations (char *line, unsigned int linelen)
+#endif
 {
   register char *in, *out, *p;
@@ -90,7 +98,14 @@
   register unsigned int bs_write;
 
+#ifndef CONFIG_WITH_VALUE_LENGTH
   in = strchr (line, '\n');
   if (in == 0)
     return;
+#else
+  assert (strlen (line) == linelen);
+  in = memchr (line, '\n', linelen);
+  if (in == 0)
+      return line + linelen;
+#endif
 
   out = in;
@@ -158,4 +173,8 @@
 
   *out = '\0';
+#ifdef CONFIG_WITH_VALUE_LENGTH
+  assert (strchr (line, '\0') == out);
+  return out;
+#endif
 }
 
Index: /trunk/src/kmk/read.c
===================================================================
--- /trunk/src/kmk/read.c	(revision 1810)
+++ /trunk/src/kmk/read.c	(revision 1811)
@@ -54,4 +54,7 @@
     char *bufnext;      /* Start of the next line in the buffer.  */
     char *bufstart;     /* Start of the entire buffer.  */
+#ifdef CONFIG_WITH_VALUE_LENGTH
+    char *eol;          /* End of the current line in the buffer. */
+#endif
     unsigned int size;  /* Malloc'd size of buffer. */
     FILE *fp;           /* File, or NULL if this is an internal buffer.  */
@@ -149,5 +152,9 @@
 static enum make_word_type get_next_mword (char *buffer, char *delim,
                                            char **startp, unsigned int *length);
+#ifndef CONFIG_WITH_VALUE_LENGTH
 static void remove_comments (char *line);
+#else
+static char *remove_comments (char *line, char *eol);
+#endif
 static char *find_char_unquote (char *string, int stop1, int stop2,
                                 int blank, int ignorevars);
@@ -430,4 +437,7 @@
   ebuf.size = 200;
   ebuf.buffer = ebuf.bufnext = ebuf.bufstart = xmalloc (ebuf.size);
+#ifdef CONFIG_WITH_VALUE_LENGTH
+  ebuf.eol = NULL;
+#endif
 
   curfile = reading_file;
@@ -464,4 +474,7 @@
   ebuf.buffer = ebuf.bufnext = ebuf.bufstart = buffer;
   ebuf.fp = NULL;
+#ifdef CONFIG_WITH_VALUE_LENGTH
+  ebuf.eol = ebuf.buffer + ebuf.size;
+#endif
 
   ebuf.floc = *reading_file;
@@ -546,4 +559,7 @@
     {
       unsigned int linelen;
+#ifdef CONFIG_WITH_VALUE_LENGTH
+      char *eol;
+#endif
       char *line;
       unsigned int wlen;
@@ -564,5 +580,10 @@
         continue;
 
+#ifndef CONFIG_WITH_VALUE_LENGTH
       linelen = strlen (line);
+#else
+      linelen = ebuf->eol - line;
+      assert (strlen (line) == linelen);
+#endif
 
       /* Check for a shell command line first.
@@ -612,8 +633,17 @@
 	  collapsed = xmalloc (collapsed_length);
 	}
+#ifndef CONFIG_WITH_VALUE_LENGTH
       strcpy (collapsed, line);
       /* Collapse continuation lines.  */
       collapse_continuations (collapsed);
       remove_comments (collapsed);
+#else
+      memcpy (collapsed, line, linelen + 1);
+      /* Collapse continuation lines.  */
+      eol = collapse_continuations (collapsed, linelen);
+      assert (strchr (collapsed, '\0') == eol);
+      eol = remove_comments (collapsed, eol);
+      assert (strchr (collapsed, '\0') == eol);
+#endif
 
       /* Compare a word, both length and contents. */
@@ -723,5 +753,9 @@
 	    }
 	  else if (!ignoring
+#ifndef CONFIG_WITH_VALUE_LENGTH
 		   && !try_variable_definition (fstart, p2, o_override, 0))
+#else
+		   && !try_variable_definition (fstart, p2, eol, o_override, 0))
+#endif
 	    error (fstart, _("invalid `override' directive"));
 
@@ -757,5 +791,9 @@
             }
           else if (!ignoring
+# ifndef CONFIG_WITH_VALUE_LENGTH
                    && !try_variable_definition (fstart, p2, o_local, 0))
+# else
+                   && !try_variable_definition (fstart, p2, eol, o_local, 0))
+# endif
             error (fstart, _("invalid `local' directive"));
 
@@ -778,5 +816,9 @@
               struct variable *v;
 
+#ifndef CONFIG_WITH_VALUE_LENGTH
               v = try_variable_definition (fstart, p2, o_file, 0);
+#else
+              v = try_variable_definition (fstart, p2, eol, o_file, 0);
+#endif
               if (v != 0)
                 v->export = v_export;
@@ -789,5 +831,5 @@
                   /* Expand the line so we can use indirect and constructed
                      variable names in an export command.  */
-                  cp = ap = allocated_variable_expand (p2);
+                  cp = ap = allocated_variable_expand (p2); ///// FIXME
 
                   for (p = find_next_token (&cp, &l); p != 0;
@@ -819,5 +861,5 @@
               /* Expand the line so we can use indirect and constructed
                  variable names in an unexport command.  */
-              cp = ap = allocated_variable_expand (p2);
+              cp = ap = allocated_variable_expand (p2); ///// FIXME
 
               for (p = find_next_token (&cp, &l); p != 0;
@@ -862,4 +904,5 @@
 
 #ifdef CONFIG_WITH_INCLUDEDEP
+      assert (strchr (p2, '\0') == eol);
       if (word1eq ("includedep") || word1eq ("includedep-queue") || word1eq ("includedep-flush"))
         {
@@ -874,21 +917,18 @@
           char *free_me = NULL;
           char *name = p2;
-          char *end = strchr (name, '\0');
-          char saved;
-          if (memchr (name, '$', end - name))
+
+          if (memchr (name, '$', eol - name))
             {
               free_me = name = allocated_variable_expand (name);
               while (isspace ((unsigned char)*name))
                 ++name;
-              end = strchr (name, '\0');
+              eol = strchr (name, '\0');
             }
 
-          while (end > name && isspace ((unsigned char)end[-1]))
-            --end;
-
-          saved = *end; /* not sure if this is required... */
-          *end = '\0';
+          while (eol > name && isspace ((unsigned char)eol[-1]))
+            --eol;
+
+          *eol = '\0';
           eval_include_dep (name, fstart, op);
-          *end = saved;
 
           if (free_me)
@@ -909,5 +949,5 @@
 	  int noerror = (p[0] != 'i');
 
-	  p = allocated_variable_expand (p2);
+	  p = allocated_variable_expand (p2); //// FIXME
 
           /* If no filenames, it's a no-op.  */
@@ -956,5 +996,9 @@
 	}
 
+#ifndef CONFIG_WITH_VALUE_LENGTH
       if (try_variable_definition (fstart, p, o_file, 0))
+#else
+      if (try_variable_definition (fstart, p, eol, o_file, 0))
+#endif
 	/* This line has been dealt with.  */
 	goto rule_complete;
@@ -1004,5 +1048,9 @@
         semip = cmdleft;
 
+#ifndef CONFIG_WITH_VALUE_LENGTH
         collapse_continuations (line);
+#else
+        collapse_continuations (line, strlen (line)); /**@todo fix this */
+#endif
 
         /* We can't expand the entire line, since if it's a per-target
@@ -1411,6 +1459,11 @@
    This is done by copying the text at LINE onto itself.  */
 
+#ifndef CONFIG_WITH_VALUE_LENGTH
 static void
 remove_comments (char *line)
+#else
+static char *
+remove_comments (char *line, char *eol)
+#endif
 {
   char *comment;
@@ -1421,4 +1474,11 @@
     /* Cut off the line at the #.  */
     *comment = '\0';
+
+#ifdef CONFIG_WITH_VALUE_LENGTH
+  if (comment)
+    eol = comment;
+  assert (strchr (line, '\0') == eol);
+  return eol;
+#endif
 }
 
@@ -1461,5 +1521,9 @@
       line = ebuf->buffer;
 
+#ifndef CONFIG_WITH_VALUE_LENGTH
       collapse_continuations (line);
+#else
+      ebuf->eol = collapse_continuations (line, ebuf->eol - line);
+#endif
 
       /* If the line doesn't begin with a tab, test to see if it introduces
@@ -1470,5 +1534,10 @@
         {
           p = next_token (line);
+#ifndef CONFIG_WITH_VALUE_LENGTH
           len = strlen (p);
+#else
+          len = ebuf->eol - p;
+          assert (len == strlen (p));
+#endif
 
           /* If this is another 'define', increment the level count.  */
@@ -1483,5 +1552,9 @@
             {
               p += 5;
+#ifndef CONFIG_WITH_VALUE_LENGTH
               remove_comments (p);
+#else
+              ebuf->eol = remove_comments (p, ebuf->eol);
+#endif
               if (*next_token (p) != '\0')
                 error (&ebuf->floc,
@@ -1506,5 +1579,10 @@
 
       /* Otherwise add this line to the variable definition.  */
+#ifndef CONFIG_WITH_VALUE_LENGTH
       len = strlen (line);
+#else
+      len = ebuf->eol - line;
+      assert (len == strlen (line));
+#endif
       if (idx + len + 1 > length)
         {
@@ -1960,5 +2038,9 @@
           /* I don't think this can fail since we already determined it was a
              variable definition.  */
+#ifndef CONFIG_WITH_VALUE_LENGTH
           v = parse_variable_definition (&p->variable, defn);
+#else
+          v = parse_variable_definition (&p->variable, defn, NULL);
+#endif
           assert (v != 0);
 
@@ -1988,5 +2070,9 @@
 
           current_variable_set_list = f->variables;
+#ifndef CONFIG_WITH_VALUE_LENGTH
           v = try_variable_definition (flocp, defn, origin, 1);
+#else
+          v = try_variable_definition (flocp, defn, NULL, origin, 1);
+#endif
           if (!v)
             error (flocp, _("Malformed target-specific variable definition"));
@@ -2836,4 +2922,7 @@
         {
           ebuf->bufnext = ebuf->bufstart + ebuf->size + 1;
+#ifdef CONFIG_WITH_VALUE_LENGTH
+          ebuf->eol = end;
+#endif
           return 0;
         }
@@ -2850,4 +2939,7 @@
   *eol = '\0';
   ebuf->bufnext = eol+1;
+#ifdef CONFIG_WITH_VALUE_LENGTH
+  ebuf->eol = eol;
+#endif
 
   return 0;
@@ -2874,4 +2966,7 @@
   end = p + ebuf->size;
   *p = '\0';
+#ifdef CONFIG_WITH_VALUE_LENGTH
+  ebuf->eol = p;
+#endif
 
   while (fgets (p, end - p, ebuf->fp) != 0)
@@ -2927,4 +3022,7 @@
 	{
 	  p[-1] = '\0';
+#ifdef CONFIG_WITH_VALUE_LENGTH
+          ebuf->eol = p - 1;
+#endif
 	  break;
 	}
@@ -2933,5 +3031,10 @@
          another line.  */
       if (end - p >= 80)
-        continue;
+        {
+#ifdef CONFIG_WITH_VALUE_LENGTH
+          ebuf->eol = p;
+#endif
+          continue;
+        }
 
       /* We need more space at the end of our buffer, so realloc it.
@@ -2945,4 +3048,7 @@
         end = start + ebuf->size;
         *p = '\0';
+#ifdef CONFIG_WITH_VALUE_LENGTH
+        ebuf->eol = p;
+#endif
       }
     }
@@ -3493,2 +3599,3 @@
   return new;
 }
+
Index: /trunk/src/kmk/variable.c
===================================================================
--- /trunk/src/kmk/variable.c	(revision 1810)
+++ /trunk/src/kmk/variable.c	(revision 1811)
@@ -921,8 +921,15 @@
               else
                 {
+#ifndef CONFIG_WITH_VALUE_LENGTH
                   v = do_variable_definition (
                     &p->variable.fileinfo, p->variable.name,
                     p->variable.value, p->variable.origin,
                     p->variable.flavor, 1);
+#else
+                  v = do_variable_definition_2 (
+                    &p->variable.fileinfo, p->variable.name,
+                    p->variable.value, p->variable.value_length, 0, 0,
+                    p->variable.origin, p->variable.flavor, 1);
+#endif
                 }
 
@@ -2030,5 +2037,9 @@
 
 struct variable *
+#ifndef CONFIG_WITH_VALUE_LENGTH
 parse_variable_definition (struct variable *v, char *line)
+#else
+parse_variable_definition (struct variable *v, char *line, char *eos)
+#endif
 {
   register int c;
@@ -2119,5 +2130,7 @@
   v->value = p;
 #ifdef CONFIG_WITH_VALUE_LENGTH
-  v->value_length = v->value_alloc_len = -1;
+  v->value_alloc_len = -1;
+  v->value_length = eos != NULL ? eos - p : -1;
+  assert (eos == NULL || strchr (p, '\0') == eos);
 #endif
 
@@ -2153,6 +2166,11 @@
 
 struct variable *
+#ifndef CONFIG_WITH_VALUE_LENGTH
 try_variable_definition (const struct floc *flocp, char *line,
                          enum variable_origin origin, int target_var)
+#else
+try_variable_definition (const struct floc *flocp, char *line, char *eos,
+                         enum variable_origin origin, int target_var)
+#endif
 {
   struct variable v;
@@ -2164,4 +2182,5 @@
     v.fileinfo.filenm = 0;
 
+#ifndef CONFIG_WITH_VALUE_LENGTH
   if (!parse_variable_definition (&v, line))
     return 0;
@@ -2169,4 +2188,12 @@
   vp = do_variable_definition (flocp, v.name, v.value,
                                origin, v.flavor, target_var);
+#else
+  if (!parse_variable_definition (&v, line, eos))
+    return 0;
+
+  vp = do_variable_definition_2 (flocp, v.name, v.value,
+                                 v.value_length != -1 ? v.value_length : ~0U,
+                                 0, NULL, origin, v.flavor, target_var);
+#endif
 
   free (v.name);
Index: /trunk/src/kmk/variable.h
===================================================================
--- /trunk/src/kmk/variable.h	(revision 1810)
+++ /trunk/src/kmk/variable.h	(revision 1811)
@@ -191,4 +191,8 @@
                                          enum variable_flavor flavor,
                                          int target_var);
+struct variable *parse_variable_definition (struct variable *v, char *line);
+struct variable *try_variable_definition (const struct floc *flocp, char *line,
+                                          enum variable_origin origin,
+                                          int target_var);
 #else  /* CONFIG_WITH_VALUE_LENGTH */
 # define do_variable_definition(flocp, varname, value, origin, flavor, target_var) \
@@ -204,9 +208,11 @@
                                            enum variable_flavor flavor,
                                            int target_var);
-#endif /* CONFIG_WITH_VALUE_LENGTH */
-struct variable *parse_variable_definition (struct variable *v, char *line);
+struct variable *parse_variable_definition (struct variable *v, char *line,
+                                            char *eos);
 struct variable *try_variable_definition (const struct floc *flocp, char *line,
+                                          char *eos,
                                           enum variable_origin origin,
                                           int target_var);
+#endif /* CONFIG_WITH_VALUE_LENGTH */
 void init_hash_global_variable_set (void);
 void hash_init_function_table (void);
