This is variable.c in view mode; [Download] [Up]
/* variable.c: variable expansion. Copyright (C) 1993, 94 Karl Berry. 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 the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <kpathsea/config.h> #include <kpathsea/c-ctype.h> #include <kpathsea/cnf.h> #include <kpathsea/fn.h> #include <kpathsea/variable.h> /* Append the result of value of `var' to EXPANSION, where `var' begins at START and ends at END. If `var' is not set, do not complain. */ static void expand P3C(fn_type *, expansion, const_string, start, const_string, end) { string value; unsigned len = end - start + 1; string var = xmalloc (len + 1); strncpy (var, start, len); var[len] = 0; /* First check the environment variable. */ value = getenv (var); /* If no envvar, check the config files. */ if (!value) value = kpse_cnf_get (var); if (value) { value = kpse_var_expand (value); fn_grow (expansion, value, strlen (value)); free (value); } free (var); } /* Can't think of when it would be useful to change these (and the diagnostic messages assume them), but ... */ #ifndef IS_VAR_START /* starts all variable references */ #define IS_VAR_START(c) ((c) == '$') #endif #ifndef IS_VAR_CHAR /* variable name constituent */ #define IS_VAR_CHAR(c) (ISALNUM (c) || (c) == '_') #endif #ifndef IS_VAR_BEGIN_DELIMITER /* start delimited variable name (after $) */ #define IS_VAR_BEGIN_DELIMITER(c) ((c) == '{') #endif #ifndef IS_VAR_END_DELIMITER #define IS_VAR_END_DELIMITER(c) ((c) == '}') #endif /* Maybe we should generalize to allow some or all of the various shell ${...} constructs, especially ${var-value}. */ string kpse_var_expand P1C(const_string, src) { const_string s; string ret; fn_type expansion; expansion = fn_init (); /* Copy everything but variable constructs. */ for (s = src; *s; s++) { if (IS_VAR_START (*s)) { s++; /* Three cases: `$VAR', `${VAR}', `$<anything-else>'. */ if (IS_VAR_CHAR (*s)) { /* $V: collect name constituents, then expand. */ const_string var_end = s; do var_end++; while (IS_VAR_CHAR (*var_end)); var_end--; /* had to go one past */ expand (&expansion, s, var_end); s = var_end; } else if (IS_VAR_BEGIN_DELIMITER (*s)) { /* ${: scan ahead for matching delimiter, then expand. */ const_string var_end = ++s; while (*var_end && !IS_VAR_END_DELIMITER (*var_end)) var_end++; if (! *var_end) { WARNING1 ("%s: No matching right brace for ${", src); s = var_end - 1; /* will incr to null at top of loop */ } else { expand (&expansion, s, var_end - 1); s = var_end; /* will incr past } at top of loop*/ } } else { /* $<something-else>: error. */ WARNING2 ("%s: Unrecognized variable construct `$%c'", src, *s); /* Just ignore those chars and keep going. */ } } else fn_1grow (&expansion, *s); } fn_1grow (&expansion, 0); ret = FN_STRING (expansion); return ret; } #ifdef TEST static void test_var (string test, string right_answer) { string result = kpse_var_expand (test); printf ("expansion of `%s'\t=> %s", test, result); if (!STREQ (result, right_answer)) printf (" [should be `%s']", right_answer); putchar ('\n'); } int main () { test_var ("a", "a"); test_var ("$foo", ""); test_var ("a$foo", "a"); test_var ("$foo a", " a"); test_var ("a$foo b", "a b"); xputenv ("FOO", "foo value"); test_var ("a$FOO", "afoo value"); xputenv ("Dollar", "$"); test_var ("$Dollar a", "$ a"); test_var ("a${FOO}b", "afoo valueb"); test_var ("a${}b", "ab"); test_var ("$$", ""); /* and error */ test_var ("a${oops", "a"); /* and error */ return 0; } #endif /* TEST */ /* Local variables: standalone-compile-command: "gcc -g -I. -I.. -DTEST variable.c kpathsea.a" End: */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.