file-name: Generalize fn_interp_vars(). fc11-i386-build49 fc11-x64-build46 lenny-x64-build70
authorBen Pfaff <blp@gnu.org>
Sun, 6 Dec 2009 04:32:35 +0000 (20:32 -0800)
committerBen Pfaff <blp@gnu.org>
Sun, 6 Dec 2009 04:32:35 +0000 (20:32 -0800)
This more general-purpose version of fn_interp_vars() will be useful in an
upcoming commit.

src/data/file-name.c
src/data/file-name.h
src/output/output.c

index 91229595924c7bfe7fe11d1486970ae598950f5c..cf58b6db1a24a27cb0f38b7d8b79417e62be4ef5 100644 (file)
@@ -63,13 +63,13 @@ fn_init (void)
 /* Functions for performing operations on file names. */
 
 
-/* Substitutes $variables in SRC, putting the result in DST,
-   properly handling the case where SRC is a substring of DST.
-   Variables are as defined by GETENV. Supports $var and ${var}
-   syntaxes; $$ substitutes as $. */
+/* Copies from SRC to DST, calling INSERT_VARIABLE to handle each
+   instance of $var or ${var} in SRC.  $$ is replaced by $. */
 void
-fn_interp_vars (struct substring src, const char *(*getenv) (const char *),
-                struct string *dst_)
+fn_interp_vars (struct substring src,
+                void (*insert_variable) (const char *var,
+                                         struct string *dst, void *aux),
+                void *aux, struct string *dst_)
 {
   struct string dst = DS_EMPTY_INITIALIZER;
   int c;
@@ -84,8 +84,7 @@ fn_interp_vars (struct substring src, const char *(*getenv) (const char *),
         else
           {
             struct substring var_name;
-            size_t start;
-            const char *value;
+            char *var;
 
             if (ss_match_char (&src, '('))
               ss_get_until (&src, ')', &var_name);
@@ -95,12 +94,9 @@ fn_interp_vars (struct substring src, const char *(*getenv) (const char *),
               ss_get_chars (&src, MAX (1, ss_span (src, ss_cstr (CC_ALNUM))),
                             &var_name);
 
-            start = ds_length (&dst);
-            ds_put_substring (&dst, var_name);
-            value = getenv (ds_cstr (&dst) + start);
-            ds_truncate (&dst, start);
-
-            ds_put_cstr (&dst, value);
+            var = ss_xstrdup (var_name);
+            insert_variable (var, &dst, aux);
+            free (var);
           }
       }
 
@@ -108,6 +104,14 @@ fn_interp_vars (struct substring src, const char *(*getenv) (const char *),
   ds_destroy (&dst);
 }
 
+static void
+insert_env_var (const char *var, struct string *dst, void *aux UNUSED)
+{
+  const char *value = fn_getenv (var);
+  if (value != NULL)
+    ds_put_cstr (dst, value);
+}
+
 /* Searches for a configuration file with name NAME in the path
    given by PATH, which is environment-interpolated.
    Directories in PATH are delimited by ':'.  Returns the
@@ -126,7 +130,7 @@ fn_search_path (const char *base_name, const char *path_)
 
   /* Interpolate environment variables. */
   ds_init_cstr (&path, path_);
-  fn_interp_vars (ds_ss (&path), fn_getenv, &path);
+  fn_interp_vars (ds_ss (&path), insert_env_var, NULL, &path);
 
   verbose_msg (2, _("searching for \"%s\" in path \"%s\""),
                base_name, ds_cstr (&path));
index d34bd4196fea046db722197aa403db964a423deb..327d716e7f57723da0922a0179779fe9cd15e620 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -28,8 +28,9 @@ extern const char *config_path;
 void fn_init (void);
 
 void fn_interp_vars (struct substring src,
-                     const char *(*getenv) (const char *),
-                     struct string *dst);
+                     void (*insert_variable) (const char *var,
+                                              struct string *dst, void *aux),
+                     void *aux, struct string *dst);
 char *fn_search_path (const char *base_name, const char *path);
 char *fn_dir_name (const char *fn);
 char *fn_extension (const char *fn);
index a556ad81e8e7b1f49584261829459988b83b732b..b97e2de3051349aa78eb87b642ec28610c351623 100644 (file)
@@ -218,6 +218,14 @@ find_defn_value (const char *key)
     return getenv (key);
 }
 
+static void
+insert_defn_value (const char *var, struct string *dst, void *aux UNUSED)
+{
+  const char *value = find_defn_value (var);
+  if (value != NULL)
+    ds_put_cstr (dst, value);
+}
+
 /* Initializes global variables. */
 void
 outp_init (void)
@@ -408,7 +416,7 @@ outp_configure_macro (char *bp)
     ep++;
 
   ds_init_cstr (&d->value, ep);
-  fn_interp_vars (ds_ss (&d->value), find_defn_value, &d->value);
+  fn_interp_vars (ds_ss (&d->value), insert_defn_value, NULL, &d->value);
   d->next = outp_macros;
   d->prev = NULL;
   if (outp_macros)
@@ -758,7 +766,7 @@ outp_configure_driver_line (struct substring line_)
   size_t save_idx;
   size_t i;
 
-  fn_interp_vars (line_, find_defn_value, &line);
+  fn_interp_vars (line_, insert_defn_value, NULL, &line);
 
   save_idx = 0;
   for (i = 0; i < 4; i++)