Command built-in can parse output into list (no need to Match it now)
[k8jam.git] / variable.c
blob0e6513f5cc739464888f21db7bae38d927e4a52c
1 /*
2 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
7 /*
8 * variable.c - handle jam multi-element variables
10 * External routines:
12 * var_defines() - load a bunch of variable=value settings
13 * var_string() - expand a string with variables in it
14 * var_get() - get value of a user defined symbol
15 * var_set() - set a variable in jam's user defined symbol table
16 * var_swap() - swap a variable's value with the given one
17 * var_done() - free variable tables
19 * Internal routines:
21 * var_enter() - make new var symbol table entry, returning var ptr
22 * var_dump() - dump a variable to stdout
24 * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
25 * 08/23/94 (seiwald) - Support for '+=' (append to variable)
26 * 01/22/95 (seiwald) - split environment variables at blanks or :'s
27 * 05/10/95 (seiwald) - split path variables at SPLITPATH (not :)
28 * 09/11/00 (seiwald) - defunct var_list() removed
29 * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr()
30 * 11/04/02 (seiwald) - const-ing for string literals
33 # include "jam.h"
34 # include "lists.h"
35 # include "parse.h"
36 # include "variable.h"
37 # include "expand.h"
38 # include "hash.h"
39 # include "newstr.h"
41 static struct hash *varhash = 0;
44 * VARIABLE - a user defined multi-value variable
47 typedef struct _variable VARIABLE ;
49 struct _variable {
50 const char *symbol;
51 LIST *value;
52 } ;
54 static VARIABLE *var_enter( const char *symbol );
55 static void var_dump( const char *symbol, LIST *value, const char *what );
60 * var_defines() - load a bunch of variable=value settings
62 * If variable name ends in PATH, split value at :'s.
63 * Otherwise, split at blanks.
66 void
67 var_defines( const char **e )
69 for( ; *e; e++ )
71 const char *val;
73 /* Just say "no": windows defines this in the env, */
74 /* but we don't want it to override our notion of OS. */
76 if( !strcmp( *e, "OS=Windows_NT" ) )
77 continue;
79 /* Just say "no": on Unix, variables can contain function
80 * definitions. their value begins with "()"
82 if( ( val = strchr( *e, '=' ) ) && val[1] == '(' && val[2] == ')' )
83 continue;
85 # ifdef OS_MAC
86 /* On the mac (MPW), the var=val is actually var\0val */
87 /* Think different. */
89 if( ( val = strchr( *e, '=' ) ) || ( val = *e + strlen( *e ) ) )
90 # else
91 if ((val = strchr(*e, '=')))
92 # endif
94 LIST *l = L0;
95 const char *pp, *p;
96 # ifdef OS_MAC
97 char split = ',';
98 # else
99 char split = ' ';
100 # endif
101 char buf[ MAXSYM ];
103 /* Split *PATH at :'s, not spaces */
105 if( val - 4 >= *e )
107 if( !strncmp( val - 4, "PATH", 4 ) ||
108 !strncmp( val - 4, "Path", 4 ) ||
109 !strncmp( val - 4, "path", 4 ) )
110 split = SPLITPATH;
113 /* Do the split */
115 for( pp = val + 1; (p = strchr(pp, split)); pp = p + 1 )
117 int len = p - pp;
119 if ( len >= sizeof(buf) )
120 len = sizeof(buf)-1;
122 strncpy( buf, pp, len );
123 buf[ len ] = '\0';
124 l = list_new( l, buf, 0 );
127 l = list_new( l, pp, 0 );
129 /* Get name */
131 strncpy( buf, *e, val - *e );
132 buf[ val - *e ] = '\0';
134 var_set( buf, l, VAR_SET );
140 * var_string() - expand a string with variables in it
142 * Copies in to out; doesn't modify targets & sources.
146 var_string(
147 const char *in,
148 char *out,
149 int outsize,
150 LOL *lol )
152 char *out0 = out;
153 char *oute = out + outsize - 1;
155 while( *in )
157 char *lastword;
158 int dollar = 0;
160 /* Copy white space */
162 while( isspace( *in ) )
164 if( out >= oute )
165 return -1;
167 *out++ = *in++;
170 lastword = out;
172 /* Copy non-white space, watching for variables */
174 while( *in && !isspace( *in ) )
176 if( out >= oute )
177 return -1;
179 if( in[0] == '$' && in[1] == '(' )
180 dollar++;
182 *out++ = *in++;
185 /* If a variable encountered, expand it and and embed the */
186 /* space-separated members of the list in the output. */
188 if( dollar )
190 LIST *l = var_expand( L0, lastword, out, lol, 0 );
192 out = lastword;
194 while( l )
196 int so = strlen( l->string );
198 if( out + so >= oute )
199 return -1;
201 strcpy( out, l->string );
202 out += so;
204 /* Separate with space */
206 if ((l = list_next(l)))
207 *out++ = ' ';
210 list_free( l );
214 if( out >= oute )
215 return -1;
217 *out++ = '\0';
219 return out - out0;
223 * var_get() - get value of a user defined symbol
225 * Returns NULL if symbol unset.
228 LIST *
229 var_get( const char *symbol )
231 VARIABLE var, *v = &var;
233 v->symbol = symbol;
235 if( varhash && hashcheck( varhash, (HASHDATA **)&v ) )
237 if( DEBUG_VARGET )
238 var_dump( v->symbol, v->value, "get" );
239 return v->value;
242 return 0;
246 * var_set() - set a variable in jam's user defined symbol table
248 * 'flag' controls the relationship between new and old values of
249 * the variable: SET replaces the old with the new; APPEND appends
250 * the new to the old; DEFAULT only uses the new if the variable
251 * was previously unset.
253 * Copies symbol. Takes ownership of value.
256 void
257 var_set(
258 const char *symbol,
259 LIST *value,
260 int flag )
262 VARIABLE *v = var_enter( symbol );
264 if( DEBUG_VARSET )
265 var_dump( symbol, value, "set" );
267 switch( flag )
269 case VAR_SET:
270 /* Replace value */
271 list_free( v->value );
272 v->value = value;
273 break;
275 case VAR_APPEND:
276 /* Append value */
277 v->value = list_append( v->value, value );
278 break;
280 case VAR_DEFAULT:
281 /* Set only if unset */
282 if( !v->value )
283 v->value = value;
284 else
285 list_free( value );
286 break;
291 * var_swap() - swap a variable's value with the given one
294 LIST *
295 var_swap(
296 const char *symbol,
297 LIST *value )
299 VARIABLE *v = var_enter( symbol );
300 LIST *oldvalue = v->value;
302 if( DEBUG_VARSET )
303 var_dump( symbol, value, "set" );
305 v->value = value;
307 return oldvalue;
313 * var_enter() - make new var symbol table entry, returning var ptr
316 static VARIABLE *
317 var_enter( const char *symbol )
319 VARIABLE var, *v = &var;
321 if( !varhash )
322 varhash = hashinit( sizeof( VARIABLE ), "variables" );
324 v->symbol = symbol;
325 v->value = 0;
327 if( hashenter( varhash, (HASHDATA **)&v ) )
328 v->symbol = newstr( symbol ); /* never freed */
330 return v;
334 * var_dump() - dump a variable to stdout
337 static void
338 var_dump(
339 const char *symbol,
340 LIST *value,
341 const char *what )
343 printf( "%s %s = ", what, symbol );
344 list_print( value );
345 printf( "\n" );
349 * var_done() - free variable tables
352 void
353 var_done()
355 hashdone( varhash );