Index: /trunk/src/kmk/expand.c
===================================================================
--- /trunk/src/kmk/expand.c	(revision 1808)
+++ /trunk/src/kmk/expand.c	(revision 1809)
@@ -228,5 +228,5 @@
   char *o;
   unsigned int line_offset;
-#ifdef KMK
+#ifdef CONFIG_WITH_VALUE_LENGTH
   const char *eos;
 #endif
@@ -248,5 +248,5 @@
     }
 
-#ifdef KMK
+#ifdef CONFIG_WITH_VALUE_LENGTH
   /* Simple first, 50% of the kBuild calls to this function does
      not need any expansion at all. Should be worth a special case. */
@@ -261,5 +261,5 @@
     }
   eos = string + length;
-#endif /* KMK - optimization */
+#endif /* CONFIG_WITH_VALUE_LENGTH */
 
   /* If we want a subset of the string, allocate a temporary buffer for it.
@@ -270,8 +270,8 @@
       memcpy(abuf, string, length);
       abuf[length] = '\0';
-#ifdef KMK
+#ifdef CONFIG_WITH_VALUE_LENGTH
       p1 += abuf - string;
       eos += abuf - string;
-#endif /* KMK - optimization */
+#endif /* CONFIG_WITH_VALUE_LENGTH */
       string = abuf;
     }
@@ -284,7 +284,7 @@
 	 at the next $ or the end of the input.  */
 
-#ifndef KMK
+#ifndef CONFIG_WITH_VALUE_LENGTH
       p1 = strchr (p, '$');
-#endif /* !KMK - optimization  */
+#endif
 
       o = variable_buffer_output (o, p, p1 != 0 ? (unsigned int)(p1 - p) : strlen (p) + 1);
@@ -327,9 +327,9 @@
 	       If so, expand it before expanding the entire reference.  */
 
-#ifndef KMK
+#ifndef CONFIG_WITH_VALUE_LENGTH
 	    end = strchr (beg, closeparen);
-#else  /* KMK - optimization */
+#else
 	    end = memchr (beg, closeparen, eos - beg);
-#endif /* KMK - optimization */
+#endif
 	    if (end == 0)
               /* Unterminated variable reference.  */
@@ -470,7 +470,7 @@
       else
 	++p;
-#ifdef KMK
+#ifdef CONFIG_WITH_VALUE_LENGTH
       p1 = memchr (p, '$', eos - p);
-#endif /* KMK - optimization */
+#endif
     }
 
@@ -481,5 +481,5 @@
   return (variable_buffer + line_offset);
 }
-#ifdef KMK
+#ifdef CONFIG_WITH_VALUE_LENGTH
 
 
@@ -494,5 +494,5 @@
   char *o;
   unsigned int line_offset;
-#ifdef KMK
+#ifdef CONFIG_WITH_VALUE_LENGTH
   const char *eos;
 #endif
@@ -514,5 +514,5 @@
     }
 
-#ifdef KMK
+#ifdef CONFIG_WITH_VALUE_LENGTH
   /* Simple first, 50% of the kBuild calls to this function does
      not need any expansion at all. Should be worth a special case. */
@@ -528,5 +528,5 @@
     }
   eos = string + length;
-#endif /* KMK - optimization */
+#endif /* CONFIG_WITH_VALUE_LENGTH */
 
   /* If we want a subset of the string, allocate a temporary buffer for it.
@@ -537,5 +537,5 @@
       memcpy(abuf, string, length);
       abuf[length] = '\0';
-#ifdef KMK
+#ifdef CONFIG_WITH_VALUE_LENGTH
       p1 += abuf - string;
       eos += abuf - string;
@@ -551,7 +551,7 @@
 	 at the next $ or the end of the input.  */
 
-#ifndef KMK
+#ifndef CONFIG_WITH_VALUE_LENGTH
       p1 = strchr (p, '$');
-#endif /* !KMK */
+#endif
 
       /*o = variable_buffer_output (o, p, p1 != 0 ? (unsigned int)(p1 - p) : strlen (p) + 1); - why +1 ? */
@@ -595,9 +595,9 @@
 	       If so, expand it before expanding the entire reference.  */
 
-#ifndef KMK
+#ifndef CONFIG_WITH_VALUE_LENGTH
 	    end = strchr (beg, closeparen);
-#else  /* KMK - optimization */
+#else
 	    end = memchr (beg, closeparen, eos - beg);
-#endif /* KMK - optimization */
+#endif
 	    if (end == 0)
               /* Unterminated variable reference.  */
@@ -738,7 +738,7 @@
       else
 	++p;
-#ifdef KMK
+#ifdef CONFIG_WITH_VALUE_LENGTH
       p1 = memchr (p, '$', eos - p);
-#endif /* KMK - optimization */
+#endif
     }
 
@@ -750,5 +750,5 @@
   return (variable_buffer + line_offset);
 }
-#endif /* KMK - optimization */
+#endif /* CONFIG_WITH_VALUE_LENGTH */
 
 
@@ -904,30 +904,20 @@
 #endif
 
-#ifndef KMK
-# ifdef CONFIG_WITH_VALUE_LENGTH
-  buf = variable_expand_string (buf, v->value, v->value_length);
-# else
+#ifdef CONFIG_WITH_VALUE_LENGTH
+  variable_expand_string_2 (buf, v->value, v->value_length, &buf);
+  return buf;
+#else
   buf = variable_expand_string (buf, v->value, strlen (v->value));
-# endif
   return (buf + strlen (buf));
-#else  /* KMK - optimization */
-# ifdef CONFIG_WITH_VALUE_LENGTH
-  variable_expand_string_2 (buf, v->value, v->value_length, &buf);
-# else
-  variable_expand_string_2 (buf, v->value, strlen (v->value), &buf);
-#  error "huh, this is supposed to be defined"
-# endif
-  assert (*buf == '\0');
-  return buf;
-#endif /* KMK - optimization */
-}
-
-#ifdef CONFIG_WITH_VALUE_LENGTH
-/* Expands the specified string, appending it to the specified variable value. */
+#endif
+}
+
+#ifdef CONFIG_WITH_VALUE_LENGTH
+/* Expands the specified string, appending it to the specified
+   variable value. */
 void
-append_expanded_string_to_variable (struct variable *v, const char *value, int append)
-{
-char *tmp;
-  unsigned int value_len = strlen (value);
+append_expanded_string_to_variable (struct variable *v, const char *value,
+                                    unsigned int value_len, int append)
+{
   char *p = (char *) memchr (value, '$', value_len);
   if (!p)
@@ -955,13 +945,5 @@
           /* Append the assignment value. */
           p = variable_buffer_output (p, value, off_dollar);
-# ifndef KMK
-          p = variable_expand_string (p, value + off_dollar, value_len - off_dollar);
-          p = strchr (p, '\0');
-# else
-          tmp = variable_expand_string_2 (p, value + off_dollar, value_len - off_dollar, &p);
-          assert (*p == '\0');
-          tmp = strchr (tmp, '\0');
-          assert (tmp == p);
-# endif
+          variable_expand_string_2 (p, value + off_dollar, value_len - off_dollar, &p);
         }
       else
@@ -969,13 +951,5 @@
           /* Expand the assignemnt value. */
           p = variable_buffer_output (p, value, off_dollar);
-#ifndef KMK
-          p = variable_expand_string (p, value + off_dollar, value_len - off_dollar);
-          p = strchr (p, '\0');
-#else
-          tmp = variable_expand_string_2 (p, value + off_dollar, value_len - off_dollar, &p);
-          assert (*p == '\0');
-          tmp = strchr (tmp, '\0');
-          assert (tmp == p);
-#endif
+          variable_expand_string_2 (p, value + off_dollar, value_len - off_dollar, &p);
 
           /* Append a space followed by the old value. */
@@ -1046,10 +1020,11 @@
 }
 
-#ifdef KMK /* possible optimization... */
-/* The special, and most comment case, of
-   allocated_variable_expand_for_file. */
+#ifdef CONFIG_WITH_VALUE_LENGTH
+/* Handle the most common case in allocated_variable_expand_for_file
+   specially and provide some additional string lenght features. */
 
 char *
-allocated_variable_expand_2 (const char *line, long length, unsigned int *value_len)
+allocated_variable_expand_2 (const char *line, unsigned int length,
+                             unsigned int *value_len)
 {
   char *value;
@@ -1059,15 +1034,11 @@
   variable_buffer = 0;
 
-#if 0 /* for profiling */
-  if (length < 0)
-    length = strlen (line);
-#endif
-
   if (!value_len)
-    value = variable_expand_string (NULL, line, length);
+    value = variable_expand_string (NULL, line, length != ~0U ? length : -1);
   else
     {
       char *eol;
-      value = variable_expand_string_2 (NULL, line, length, &eol);
+      value = variable_expand_string_2 (NULL, line,
+                                        length != ~0U ? length : -1, &eol);
       *value_len = eol - value;
     }
@@ -1078,6 +1049,6 @@
   return value;
 }
-
-#endif
+#endif /* CONFIG_WITH_VALUE_LENGTH */
+
 /* Install a new variable_buffer context, returning the current one for
    safe-keeping.  */
Index: /trunk/src/kmk/function.c
===================================================================
--- /trunk/src/kmk/function.c	(revision 1808)
+++ /trunk/src/kmk/function.c	(revision 1809)
@@ -931,7 +931,7 @@
   char *list = expand_argument (argv[1], NULL);
   const char *body = argv[2];
-#ifdef KMK
+#ifdef CONFIG_WITH_VALUE_LENGTH
   long body_len = strlen (body);
-#endif /* KMK - optimization */
+#endif
 
   int doneany = 0;
@@ -947,8 +947,16 @@
   while ((p = find_next_token (&list_iterator, &len)) != 0)
     {
-#ifndef KMK
+#ifndef CONFIG_WITH_VALUE_LENGTH
       char *result = 0;
-#endif /* KMK - optimization */
-#ifdef CONFIG_WITH_VALUE_LENGTH
+
+      free (var->value);
+      var->value = savestring (p, len);
+      result = allocated_variable_expand (body);
+
+      o = variable_buffer_output (o, result, strlen (result));
+      o = variable_buffer_output (o, " ", 1);
+      doneany = 1;
+      free (result);
+#else  /* CONFIG_WITH_VALUE_LENGTH */
       if (len >= (unsigned int)var->value_alloc_len)
         {
@@ -960,21 +968,9 @@
       var->value[len] = '\0';
       var->value_length = len;
-#else
-      free (var->value);
-      var->value = savestring (p, len);
-#endif
-
-#ifndef KMK
-      result = allocated_variable_expand (body);
-
-      o = variable_buffer_output (o, result, strlen (result));
-      o = variable_buffer_output (o, " ", 1);
-      doneany = 1;
-      free (result);
-#else  /* KMK - optimization */
+
       variable_expand_string_2 (o, body, body_len, &o);
       o = variable_buffer_output (o, " ", 1);
       doneany = 1;
-#endif /* KMK - optimization */
+#endif /* CONFIG_WITH_VALUE_LENGTH */
     }
 
@@ -4314,13 +4310,13 @@
 
       v->exp_count = EXP_COUNT_MAX;
-#ifndef KMK
+#ifndef CONFIG_WITH_VALUE_LENGTH
       o = variable_expand_string (o, body, flen+3);
       v->exp_count = 0;
 
       o += strlen (o);
-#else  /* KMK - optimization */
+#else  /* CONFIG_WITH_VALUE_LENGTH */
       variable_expand_string_2 (o, body, flen+3, &o);
       v->exp_count = 0;
-#endif /* KMK - optimization */
+#endif /* CONFIG_WITH_VALUE_LENGTH */
 #ifdef CONFIG_WITH_EVALPLUS
     }
Index: /trunk/src/kmk/kbuild.c
===================================================================
--- /trunk/src/kmk/kbuild.c	(revision 1808)
+++ /trunk/src/kmk/kbuild.c	(revision 1809)
@@ -1771,5 +1771,6 @@
     if (!s_fNoCompileCmdsDepsDefined)
     {
-        do_variable_definition(NILF, "_DEPFILES_INCLUDED", pDep->value, o_file, f_append, 0 /* !target_var */);
+        do_variable_definition_2(NILF, "_DEPFILES_INCLUDED", pDep->value, pDep->value_length,
+                                 pDep->flavor == f_simple, 0, o_file, f_append, 0 /* !target_var */);
         eval_include_dep(pDep->value, NILF, iVer >= 2 ? incdep_queue : incdep_read_it);
     }
@@ -1801,15 +1802,21 @@
     memcpy(pszDst, "_CMDS_", sizeof("_CMDS_"));
     pVar = kbuild_get_recursive_variable(pszSrcVar);
-    do_variable_definition(NILF, pszDstVar, pVar->value, o_file, f_simple, 0 /* !target_var */);
+    do_variable_definition_2(NILF, pszDstVar, pVar->value, pVar->value_length,
+                             pVar->flavor == f_simple, 0, o_file, f_simple, 0 /* !target_var */);
 
     memcpy(pszSrc, "_OUTPUT", sizeof("_OUTPUT"));
     memcpy(pszDst, "_OUTPUT_", sizeof("_OUTPUT_"));
     pVar = kbuild_get_recursive_variable(pszSrcVar);
-    pOutput = do_variable_definition(NILF, pszDstVar, pVar->value, o_file, f_simple, 0 /* !target_var */);
+    pOutput = do_variable_definition_2(NILF, pszDstVar, pVar->value, pVar->value_length,
+                                       pVar->flavor == f_simple, 0, o_file, f_simple, 0 /* !target_var */);
 
     memcpy(pszSrc, "_OUTPUT_MAYBE", sizeof("_OUTPUT_MAYBE"));
     memcpy(pszDst, "_OUTPUT_MAYBE_", sizeof("_OUTPUT_MAYBE_"));
     pVar = kbuild_query_recursive_variable(pszSrcVar);
-    pOutputMaybe = do_variable_definition(NILF, pszDstVar, pVar ? pVar->value : "", o_file, f_simple, 0 /* !target_var */);
+    if (pVar)
+        pOutputMaybe = do_variable_definition_2(NILF, pszDstVar, pVar->value, pVar->value_length,
+                                                pVar->flavor == f_simple, 0, o_file, f_simple, 0 /* !target_var */);
+    else
+        pOutputMaybe = do_variable_definition_2(NILF, pszDstVar, "", 0, 1, 0, o_file, f_simple, 0 /* !target_var */);
 
     memcpy(pszSrc, "_DEPEND", sizeof("_DEPEND"));
@@ -1822,6 +1829,7 @@
     *psz++ = ' ';
     memcpy(psz, pSource->value, pSource->value_length + 1);
-    do_variable_definition(NILF, pszDstVar, pszVal, o_file, f_simple, 0 /* !target_var */);
-    free(pszVal);
+    do_variable_definition_2(NILF, pszDstVar, pszVal, pVar->value_length + 1 + pDeps->value_length + 1 + pSource->value_length,
+                             pVar->flavor == f_simple && pDeps->flavor == f_simple && pSource->flavor == f_simple,
+                             pszVal, o_file, f_simple, 0 /* !target_var */);
 
     memcpy(pszSrc, "_DEPORD", sizeof("_DEPORD"));
@@ -1834,10 +1842,13 @@
     *psz++ = ' ';
     memcpy(psz, pOrderDeps->value, pOrderDeps->value_length + 1);
-    do_variable_definition(NILF, pszDstVar, pszVal, o_file, f_simple, 0 /* !target_var */);
-    free(pszVal);
+    do_variable_definition_2(NILF, pszDstVar, pszVal,
+                             pVar->value_length + 1 + pDirDep->value_length + 1 + pOrderDeps->value_length,
+                             pVar->flavor == f_simple && pDirDep->flavor == f_simple && pOrderDeps->flavor == f_simple,
+                             pszVal, o_file, f_simple, 0 /* !target_var */);
 
     /*
     _OUT_FILES      += $($(target)_$(source)_OUTPUT_) $($(target)_$(source)_OUTPUT_MAYBE_)
     */
+    /** @todo use append? */
     pVar = kbuild_get_variable("_OUT_FILES");
     psz = pszVal = xmalloc(pVar->value_length + 1 + pOutput->value_length + 1 + pOutputMaybe->value_length + 1);
@@ -1847,6 +1858,8 @@
     *psz++ = ' ';
     memcpy(psz, pOutputMaybe->value, pOutputMaybe->value_length + 1);
-    do_variable_definition(NILF, "_OUT_FILES", pszVal, o_file, f_simple, 0 /* !target_var */);
-    free(pszVal);
+    do_variable_definition_2(NILF, "_OUT_FILES", pszVal,
+                             pVar->value_length + 1 + pOutput->value_length + 1 + pOutputMaybe->value_length,
+                             pVar->flavor == f_simple && pOutput->flavor == f_simple && pOutputMaybe->flavor == f_simple,
+                             pszVal, o_file, f_simple, 0 /* !target_var */);
 
     /*
@@ -1854,5 +1867,6 @@
     */
     memcpy(pszDstVar + pTarget->value_length, "_OBJS_", sizeof("_OBJS_"));
-    do_variable_definition(NILF, pszDstVar, pObj->value, o_file, f_append, 0 /* !target_var */);
+    do_variable_definition_2(NILF, pszDstVar, pObj->value, pObj->value_length,
+                             pObj->flavor == f_simple, 0, o_file, f_append, 0 /* !target_var */);
 
     /*
Index: /trunk/src/kmk/main.c
===================================================================
--- /trunk/src/kmk/main.c	(revision 1808)
+++ /trunk/src/kmk/main.c	(revision 1809)
@@ -55,5 +55,5 @@
 #  define INCL_BASE
 #  include <os2.h>
-# endif 
+# endif
 #endif /* KMK*/
 
@@ -375,5 +375,5 @@
     N_("\
   -j [N], --jobs[=N]          Allow N jobs at once; infinite jobs with no arg.\n"),
-#endif 
+#endif
     N_("\
   -k, --keep-going            Keep going when some targets can't be made.\n"),
@@ -1123,5 +1123,5 @@
 /* Determins the number of CPUs that are currently online.
    This is used to setup the default number of job slots. */
-static int 
+static int
 get_online_cpu_count(void)
 {
@@ -1151,5 +1151,5 @@
     return cpus ? cpus : 1;
 
-# else 
+# else
   /* UNIX like systems, try sysconf and sysctl. */
   int cpus = -1;
@@ -1157,5 +1157,5 @@
   int mib[2];
   size_t sz;
-#  endif 
+#  endif
 
 #  ifdef _SC_NPROCESSORS_ONLN
Index: /trunk/src/kmk/read.c
===================================================================
--- /trunk/src/kmk/read.c	(revision 1808)
+++ /trunk/src/kmk/read.c	(revision 1809)
@@ -418,7 +418,7 @@
     if (!fstat (fileno (ebuf.fp), &st))
       {
-        unsigned int stream_buf_size = 256*1024;
+        int stream_buf_size = 256*1024;
         if (st.st_size < stream_buf_size)
-          stream_buf_size = (st.st_size + 0xfff) & ~0xfffU;
+          stream_buf_size = (st.st_size + 0xfff) & ~0xfff;
         stream_buf = xmalloc (stream_buf_size);
         setvbuf (ebuf.fp, stream_buf, _IOFBF, stream_buf_size);
@@ -2803,5 +2803,5 @@
 {
   char *eol;
-#ifdef KMK
+#ifdef CONFIG_WITH_VALUE_LENGTH
   char *end;
 #endif
@@ -2815,5 +2815,5 @@
 
   eol = ebuf->buffer = ebuf->bufnext;
-#ifdef KMK
+#ifdef CONFIG_WITH_VALUE_LENGTH
   end = ebuf->bufstart + ebuf->size;
 #endif
@@ -2826,5 +2826,5 @@
 
       /* Find the next newline.  At EOS, stop.  */
-#ifndef KMK
+#ifndef CONFIG_WITH_VALUE_LENGTH
       eol = p = strchr (eol , '\n');
 #else
Index: /trunk/src/kmk/variable.c
===================================================================
--- /trunk/src/kmk/variable.c	(revision 1808)
+++ /trunk/src/kmk/variable.c	(revision 1809)
@@ -467,7 +467,8 @@
 struct variable *
 define_variable_in_set (const char *name, unsigned int length,
-                        const char *value, unsigned int value_length, int duplicate_value,
-                        enum variable_origin origin, int recursive,
-                        struct variable_set *set, const struct floc *flocp)
+                        const char *value, unsigned int value_len,
+                        int duplicate_value, enum variable_origin origin,
+                        int recursive, struct variable_set *set,
+                        const struct floc *flocp)
 #else
 struct variable *
@@ -510,8 +511,8 @@
 	{
 #ifdef CONFIG_WITH_VALUE_LENGTH
-          if (value_length == ~0U)
-            value_length = strlen (value);
+          if (value_len == ~0U)
+            value_len = strlen (value);
           else
-            assert (value_length == strlen (value));
+            assert (value_len == strlen (value));
           if (!duplicate_value)
             {
@@ -519,17 +520,17 @@
                 free (v->value);
               v->value = (char *)value;
-              v->value_alloc_len = value_length + 1;
+              v->value_alloc_len = value_len + 1;
             }
           else
             {
-              if ((unsigned int)v->value_alloc_len <= value_length)
+              if ((unsigned int)v->value_alloc_len <= value_len)
                 {
                   free (v->value);
-                  v->value_alloc_len = (value_length + 0x40) & ~0x3f;
+                  v->value_alloc_len = (value_len + 0x40) & ~0x3f;
                   v->value = xmalloc (v->value_alloc_len);
                 }
-              memcpy (v->value, value, value_length + 1);
+              memcpy (v->value, value, value_len + 1);
             }
-          v->value_length = value_length;
+          v->value_length = value_len;
 #else
           if (v->value != 0)
@@ -558,19 +559,19 @@
   hash_insert_at (&set->table, v, var_slot);
 #ifdef CONFIG_WITH_VALUE_LENGTH
-  if (value_length == ~0U)
-    value_length = strlen (value);
+  if (value_len == ~0U)
+    value_len = strlen (value);
   else
-    assert (value_length == strlen (value));
-  v->value_length = value_length;
+    assert (value_len == strlen (value));
+  v->value_length = value_len;
   if (!duplicate_value)
     {
-      v->value_alloc_len = value_length + 1;
+      v->value_alloc_len = value_len + 1;
       v->value = (char *)value;
     }
   else
     {
-      v->value_alloc_len = (value_length + 32) & ~31;
+      v->value_alloc_len = (value_len + 32) & ~31;
       v->value = xmalloc (v->value_alloc_len);
-      memcpy (v->value, value, value_length + 1);
+      memcpy (v->value, value, value_len + 1);
     }
 #else
@@ -1618,5 +1619,5 @@
     {
       v->value_alloc_len *= 2;
-      if (v->value_alloc_len < new_value_len + 1)
+      if ((unsigned)v->value_alloc_len < new_value_len + 1)
           v->value_alloc_len = (new_value_len + 1 + value_len + 0x7f) + ~0x7fU;
       if (append || !v->value_length)
@@ -1655,6 +1656,8 @@
 
 static struct variable *
-do_variable_definition_append (const struct floc *flocp, struct variable *v, const char *value,
-                               enum variable_origin origin, int append)
+do_variable_definition_append (const struct floc *flocp, struct variable *v,
+                               const char *value, unsigned int value_len,
+                               int simple_value, enum variable_origin origin,
+                               int append)
 {
   if (env_overrides && origin == o_env)
@@ -1679,11 +1682,13 @@
   /* The juicy bits, append the specified value to the variable
      This is a heavily exercised code path in kBuild. */
-  if (v->recursive)
-    append_string_to_variable (v, value, strlen (value), append);
+  if (value_len == ~0U)
+    value_len = strlen (value);
+  if (v->recursive || simple_value)
+    append_string_to_variable (v, value, value_len, append);
   else
     /* The previous definition of the variable was simple.
        The new value comes from the old value, which was expanded
        when it was set; and from the expanded new value. */
-    append_expanded_string_to_variable (v, value, append);
+    append_expanded_string_to_variable (v, value, value_len, append);
 
   /* update the variable */
@@ -1697,7 +1702,17 @@
 
 struct variable *
+#ifndef CONFIG_WITH_VALUE_LENGTH
 do_variable_definition (const struct floc *flocp, const char *varname,
                         const char *value, enum variable_origin origin,
                         enum variable_flavor flavor, int target_var)
+#else  /* CONFIG_WITH_VALUE_LENGTH */
+do_variable_definition_2 (const struct floc *flocp,
+                          const char *varname, const char *value,
+                          unsigned int value_len, int simple_value,
+                          char *free_value,
+                          enum variable_origin origin,
+                          enum variable_flavor flavor,
+                          int target_var)
+#endif /* CONFIG_WITH_VALUE_LENGTH */
 {
   const char *p;
@@ -1708,5 +1723,5 @@
   const size_t varname_len = strlen (varname); /* bird */
 #ifdef CONFIG_WITH_VALUE_LENGTH
-  unsigned int value_len = ~0U;
+  assert (value_len == ~0U || value_len == strlen (value));
 #endif
 
@@ -1724,9 +1739,23 @@
 	 variable buffer, and we may still need that if we're looking at a
          target-specific variable.  */
-#if !defined(KMK) || !defined(CONFIG_WITH_VALUE_LENGTH)
+#ifndef CONFIG_WITH_VALUE_LENGTH
       p = alloc_value = allocated_variable_expand (value);
-#else  /* KMK - optimization */
-      p = alloc_value = allocated_variable_expand_2 (value, -1, &value_len);
-#endif /* KMK - optimization */
+#else  /* CONFIG_WITH_VALUE_LENGTH */
+      if (!simple_value)
+        p = alloc_value = allocated_variable_expand_2 (value, value_len, &value_len);
+      else
+      {
+        if (value_len == ~0U)
+          value_len = strlen (value);
+        if (!free_value)
+          p = alloc_value = savestring (value, value_len);
+        else
+          {
+            assert (value == free_value);
+            p = alloc_value = free_value;
+            free_value = 0;
+          }
+      }
+#endif /* CONFIG_WITH_VALUE_LENGTH */
       break;
     case f_conditional:
@@ -1789,9 +1818,14 @@
 #ifdef CONFIG_WITH_VALUE_LENGTH
             v->append = append;
+            v = do_variable_definition_append (flocp, v, value, value_len,
+                                               simple_value, origin,
 # ifdef CONFIG_WITH_PREPEND_ASSIGNMENT
-            return do_variable_definition_append (flocp, v, value, origin, org_flavor == f_append);
+                                               org_flavor == f_append);
 # else
-            return do_variable_definition_append (flocp, v, value, origin, 1);
+                                               1);
 # endif
+            if (free_value)
+               free (free_value);
+            return v;
 #else /* !CONFIG_WITH_VALUE_LENGTH */
 
@@ -1973,4 +2007,7 @@
   if (alloc_value)
     free (alloc_value);
+#else
+  if (free_value)
+    free (free_value);
 #endif
 
@@ -2000,7 +2037,7 @@
   register char *end;
   enum variable_flavor flavor = f_bogus;
-#ifndef KMK
+#ifndef CONFIG_WITH_VALUE_LENGTH
   char *name;
-#endif /* KMK - optimization */
+#endif
 
   while (1)
@@ -2086,18 +2123,12 @@
 
   /* Expand the name, so "$(foo)bar = baz" works.  */
-#ifndef KMK
+#ifndef CONFIG_WITH_VALUE_LENGTH
   name = alloca (end - beg + 1);
   memcpy (name, beg, end - beg);
   name[end - beg] = '\0';
   v->name = allocated_variable_expand (name);
-#else  /* KMK - optimizations */
-  //if (memchr (beg, '$', end - beg)) /* (Mostly for cleaning up the profiler result.) */
-      v->name = allocated_variable_expand_2 (beg, end - beg, NULL);
-  //else
-  //  {
-  //    v->name = memcpy (xmalloc (end - beg + 1), beg, end - beg);
-  //    v->name[end - beg] = '\0';
-  //  }
-#endif /* KMK - optimizations */
+#else  /* CONFIG_WITH_VALUE_LENGTH */
+  v->name = allocated_variable_expand_2 (beg, end - beg, NULL);
+#endif /* CONFIG_WITH_VALUE_LENGTH */
 
   if (v->name[0] == '\0')
Index: /trunk/src/kmk/variable.h
===================================================================
--- /trunk/src/kmk/variable.h	(revision 1808)
+++ /trunk/src/kmk/variable.h	(revision 1809)
@@ -136,15 +136,15 @@
 #endif
 char *allocated_variable_expand_for_file (const char *line, struct file *file);
-#ifndef KMK
+#ifndef CONFIG_WITH_VALUE_LENGTH
 #define	allocated_variable_expand(line) \
   allocated_variable_expand_for_file (line, (struct file *) 0)
-#else  /* KMK */
+#else  /* CONFIG_WITH_VALUE_LENGTH */
 # define allocated_variable_expand(line) \
   allocated_variable_expand_2 (line, -1, NULL)
-char *allocated_variable_expand_2(const char *line, long length, unsigned int *value_len);
-#endif
+char *allocated_variable_expand_2(const char *line, unsigned int length, unsigned int *value_len);
+#endif /* CONFIG_WITH_VALUE_LENGTH */
 char *expand_argument (const char *str, const char *end);
 char *variable_expand_string (char *line, const char *string, long length);
-#ifdef KMK
+#ifdef CONFIG_WITH_VALUE_LENGTH
 char *variable_expand_string_2 (char *line, const char *string, long length, char **eol);
 #endif
@@ -152,5 +152,6 @@
 void restore_variable_buffer (char *buf, unsigned int len);
 #ifdef CONFIG_WITH_VALUE_LENGTH
-extern void append_expanded_string_to_variable (struct variable *v, const char *value, int append);
+void append_expanded_string_to_variable (struct variable *v, const char *value,
+                                         unsigned int value_len, int append);
 #endif
 
@@ -184,4 +185,5 @@
 void merge_variable_set_lists (struct variable_set_list **to_list,
                                struct variable_set_list *from_list);
+#ifndef CONFIG_WITH_VALUE_LENGTH
 struct variable *do_variable_definition (const struct floc *flocp,
                                          const char *name, const char *value,
@@ -189,4 +191,18 @@
                                          enum variable_flavor flavor,
                                          int target_var);
+#else  /* CONFIG_WITH_VALUE_LENGTH */
+# define do_variable_definition(flocp, varname, value, origin, flavor, target_var) \
+    do_variable_definition_2 ((flocp), (varname), (value), ~0U, 0, NULL, \
+                              (origin), (flavor), (target_var))
+
+struct variable *do_variable_definition_2 (const struct floc *flocp,
+                                           const char *varname,
+                                           const char *value,
+                                           unsigned int value_len,
+                                           int simple_value, char *free_value,
+                                           enum variable_origin origin,
+                                           enum variable_flavor flavor,
+                                           int target_var);
+#endif /* CONFIG_WITH_VALUE_LENGTH */
 struct variable *parse_variable_definition (struct variable *v, char *line);
 struct variable *try_variable_definition (const struct floc *flocp, char *line,
