- ds_clear(target);
-
- for (;;)
- {
- switch (*s)
- {
- case '\0':
- goto done ;
-
- case '$':
- s++;
-
- if (*s == '$')
- {
- ds_putc (target, '$');
- s++;
- }
- else
- {
- int stop;
- int start;
- const char *value;
-
- start = ds_length (target);
-
- if (*s == '(')
- {
- stop = ')';
- s++;
- }
- else if (*s == '{')
- {
- stop = '}';
- s++;
- }
- else
- stop = 0;
-
- while (*s && *s != stop
- && (stop || isalpha ((unsigned char) *s)))
- {
- ds_putc (target, *s++);
- }
-
- value = getenv (ds_c_str (target) + start);
- ds_truncate (target, start);
- ds_puts (target, value);
-
- if (stop && *s == stop)
- s++;
- }
- break;
-
- default:
- ds_putc (target, *s++);
- }
- }
-
- done:
- free(input);
- return;
-}
-
-#ifdef unix
-/* Expands csh tilde notation from the path INPUT into a malloc()'d
- returned string. */
-char *
-fn_tilde_expand (const char *input)
-{
- struct string output = DS_INITIALIZER;
- if (input[0] == '~')
- {
- const char *home = NULL;
- const char *remainder = NULL;
- if (input[1] == '/' || input[1] == '\0')
- {
- home = fn_getenv ("HOME");
- remainder = input + 1;
- }
- else
- {
- struct string user_name = DS_INITIALIZER;
- struct passwd *pwd;
-
- ds_assign_buffer (&user_name, input + 1, strcspn (input + 1, "/"));
- pwd = getpwnam (ds_c_str (&user_name));
- if (pwd != NULL && pwd->pw_dir[0] != '\0')
- {
- home = pwd->pw_dir;
- remainder = input + 1 + ds_length (&user_name);
- }
- ds_destroy (&user_name);
- }
-
- if (home != NULL)
- {
- ds_puts (&output, home);
- if (*remainder != '\0')
- ds_puts (&output, remainder);
- }
- }
- if (ds_is_empty (&output))
- ds_puts (&output, input);
- return ds_c_str (&output);
-}
-#else /* !unix */
+/* Searches for a configuration file with name NAME in the directories given in
+ PATH, which is terminated by a null pointer. Returns the full name of the
+ first file found, which the caller is responsible for freeing with free(),
+ or NULL if none is found. */