home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
octave-1.1.1p1-src.tgz
/
tar.out
/
fsf
/
octave
/
kpathsea
/
variable.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-28
|
5KB
|
175 lines
/* variable.c: variable expansion.
Copyright (C) 1993 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/fn.h>
#include <kpathsea/variable.h>
/* Append the result of `getenv (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;
value = getenv (var);
if (value)
fn_grow (expansion, value, strlen (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. See comments at `kpse_make_specs' in
`tex-make.c', for example. */
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 -posix -g -I. -I.. -DTEST variable.c kpathsea.a"
End:
*/