From 84bbf9c2cabe154765e406114b5386bf309aed27 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 5 Dec 2009 20:32:35 -0800 Subject: [PATCH] file-name: Generalize fn_interp_vars(). This more general-purpose version of fn_interp_vars() will be useful in an upcoming commit. --- src/data/file-name.c | 34 +++++++++++++++++++--------------- src/data/file-name.h | 7 ++++--- src/output/output.c | 12 ++++++++++-- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/data/file-name.c b/src/data/file-name.c index 91229595..cf58b6db 100644 --- a/src/data/file-name.c +++ b/src/data/file-name.c @@ -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)); diff --git a/src/data/file-name.h b/src/data/file-name.h index d34bd419..327d716e 100644 --- a/src/data/file-name.h +++ b/src/data/file-name.h @@ -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); diff --git a/src/output/output.c b/src/output/output.c index a556ad81..b97e2de3 100644 --- a/src/output/output.c +++ b/src/output/output.c @@ -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++) -- 2.30.2