comparison kpathsea/variable.c @ 1268:76a0c05089d4

[project @ 1995-04-20 19:15:51 by jwe] Initial revision
author jwe
date Thu, 20 Apr 1995 19:15:51 +0000
parents
children 611d403c7f3d
comparison
equal deleted inserted replaced
1267:69501f98669d 1268:76a0c05089d4
1 /* variable.c: variable expansion.
2
3 Copyright (C) 1993, 94 Karl Berry.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19 #include <kpathsea/config.h>
20
21 #include <kpathsea/c-ctype.h>
22 #include <kpathsea/cnf.h>
23 #include <kpathsea/fn.h>
24 #include <kpathsea/variable.h>
25
26
27 /* Append the result of value of `var' to EXPANSION, where `var' begins
28 at START and ends at END. If `var' is not set, do not complain. */
29
30 static void
31 expand P3C(fn_type *, expansion, const_string, start, const_string, end)
32 {
33 string value;
34 unsigned len = end - start + 1;
35 string var = xmalloc (len + 1);
36 strncpy (var, start, len);
37 var[len] = 0;
38
39 /* First check the environment variable. */
40 value = getenv (var);
41
42 /* If no envvar, check the config files. */
43 if (!value)
44 value = kpse_cnf_get (var);
45
46 if (value)
47 {
48 value = kpse_var_expand (value);
49 fn_grow (expansion, value, strlen (value));
50 free (value);
51 }
52
53 free (var);
54 }
55
56 /* Can't think of when it would be useful to change these (and the
57 diagnostic messages assume them), but ... */
58 #ifndef IS_VAR_START /* starts all variable references */
59 #define IS_VAR_START(c) ((c) == '$')
60 #endif
61 #ifndef IS_VAR_CHAR /* variable name constituent */
62 #define IS_VAR_CHAR(c) (ISALNUM (c) || (c) == '_')
63 #endif
64 #ifndef IS_VAR_BEGIN_DELIMITER /* start delimited variable name (after $) */
65 #define IS_VAR_BEGIN_DELIMITER(c) ((c) == '{')
66 #endif
67 #ifndef IS_VAR_END_DELIMITER
68 #define IS_VAR_END_DELIMITER(c) ((c) == '}')
69 #endif
70
71
72 /* Maybe we should generalize to allow some or all of the various shell
73 ${...} constructs, especially ${var-value}. */
74
75 string
76 kpse_var_expand P1C(const_string, src)
77 {
78 const_string s;
79 string ret;
80 fn_type expansion;
81 expansion = fn_init ();
82
83 /* Copy everything but variable constructs. */
84 for (s = src; *s; s++)
85 {
86 if (IS_VAR_START (*s))
87 {
88 s++;
89
90 /* Three cases: `$VAR', `${VAR}', `$<anything-else>'. */
91
92 if (IS_VAR_CHAR (*s))
93 { /* $V: collect name constituents, then expand. */
94 const_string var_end = s;
95
96 do
97 var_end++;
98 while (IS_VAR_CHAR (*var_end));
99
100 var_end--; /* had to go one past */
101 expand (&expansion, s, var_end);
102 s = var_end;
103 }
104
105 else if (IS_VAR_BEGIN_DELIMITER (*s))
106 { /* ${: scan ahead for matching delimiter, then expand. */
107 const_string var_end = ++s;
108
109 while (*var_end && !IS_VAR_END_DELIMITER (*var_end))
110 var_end++;
111
112 if (! *var_end)
113 {
114 WARNING1 ("%s: No matching right brace for ${", src);
115 s = var_end - 1; /* will incr to null at top of loop */
116 }
117 else
118 {
119 expand (&expansion, s, var_end - 1);
120 s = var_end; /* will incr past } at top of loop*/
121 }
122 }
123
124
125 else
126 { /* $<something-else>: error. */
127 WARNING2 ("%s: Unrecognized variable construct `$%c'", src, *s);
128 /* Just ignore those chars and keep going. */
129 }
130 }
131 else
132 fn_1grow (&expansion, *s);
133 }
134 fn_1grow (&expansion, 0);
135
136 ret = FN_STRING (expansion);
137 return ret;
138 }
139
140 #ifdef TEST
141
142 static void
143 test_var (string test, string right_answer)
144 {
145 string result = kpse_var_expand (test);
146
147 printf ("expansion of `%s'\t=> %s", test, result);
148 if (!STREQ (result, right_answer))
149 printf (" [should be `%s']", right_answer);
150 putchar ('\n');
151 }
152
153
154 int
155 main ()
156 {
157 test_var ("a", "a");
158 test_var ("$foo", "");
159 test_var ("a$foo", "a");
160 test_var ("$foo a", " a");
161 test_var ("a$foo b", "a b");
162
163 xputenv ("FOO", "foo value");
164 test_var ("a$FOO", "afoo value");
165
166 xputenv ("Dollar", "$");
167 test_var ("$Dollar a", "$ a");
168
169 test_var ("a${FOO}b", "afoo valueb");
170 test_var ("a${}b", "ab");
171
172 test_var ("$$", ""); /* and error */
173 test_var ("a${oops", "a"); /* and error */
174
175 return 0;
176 }
177
178 #endif /* TEST */
179
180
181 /*
182 Local variables:
183 standalone-compile-command: "gcc -g -I. -I.. -DTEST variable.c kpathsea.a"
184 End:
185 */