- /* If substitution required, recopy the string and do it. */
- /* Make space in stack frame for the new copy. */
- xnm = alloca (SBYTES (filename) + total + 1);
- x = xnm;
-
- /* Copy the rest of the name through, replacing $ constructs with values. */
- for (p = nm; *p;)
- if (*p != '$')
- *x++ = *p++;
- else
- {
- p++;
- if (p == endp)
- goto badsubst;
- else if (*p == '$')
- {
- *x++ = *p++;
- continue;
- }
- else if (*p == '{')
- {
- o = ++p;
- p = memchr (p, '}', endp - p);
- if (! p)
- goto missingclose;
- s = p++;
- }
- else
- {
- o = p;
- while (p != endp && (c_isalnum (*p) || *p == '_')) p++;
- s = p;
- }
-
- /* Copy out the variable name. */
- target = alloca (s - o + 1);
- memcpy (target, o, s - o);
- target[s - o] = 0;
-
- /* Get variable value. */
- o = egetenv (target);
- if (!o)
- {
- *x++ = '$';
- strcpy (x, target); x+= strlen (target);
- }
- else
- {
- Lisp_Object orig, decoded;
- ptrdiff_t orig_length, decoded_length;
- orig_length = strlen (o);
- orig = make_unibyte_string (o, orig_length);
- decoded = DECODE_FILE (orig);
- decoded_length = SBYTES (decoded);
- memcpy (x, SDATA (decoded), decoded_length);
- x += decoded_length;
-
- /* If environment variable needed decoding, return value
- needs to be multibyte. */
- if (decoded_length != orig_length
- || memcmp (SDATA (decoded), o, orig_length))
- multibyte = 1;
- }
- }
-
- *x = 0;