2 * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
4 * This file is part of Jam - see jam.c for Copyright information.
8 * variable.c - handle jam multi-element variables
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
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
36 # include "variable.h"
41 static struct hash
*varhash
= 0;
44 * VARIABLE - a user defined multi-value variable
47 typedef struct _variable VARIABLE
;
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.
67 var_defines( const char **e
)
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" ) )
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] == ')' )
86 /* On the mac (MPW), the var=val is actually var\0val */
87 /* Think different. */
89 if( ( val
= strchr( *e
, '=' ) ) || ( val
= *e
+ strlen( *e
) ) )
91 if ((val
= strchr(*e
, '=')))
103 /* Split *PATH at :'s, not spaces */
107 if( !strncmp( val
- 4, "PATH", 4 ) ||
108 !strncmp( val
- 4, "Path", 4 ) ||
109 !strncmp( val
- 4, "path", 4 ) )
115 for( pp
= val
+ 1; (p
= strchr(pp
, split
)); pp
= p
+ 1 )
119 if ( len
>= sizeof(buf
) )
122 strncpy( buf
, pp
, len
);
124 l
= list_new( l
, buf
, 0 );
127 l
= list_new( l
, pp
, 0 );
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.
153 char *oute
= out
+ outsize
- 1;
160 /* Copy white space */
162 while( isspace( *in
) )
172 /* Copy non-white space, watching for variables */
174 while( *in
&& !isspace( *in
) )
179 if( in
[0] == '$' && in
[1] == '(' )
185 /* If a variable encountered, expand it and and embed the */
186 /* space-separated members of the list in the output. */
190 LIST
*l
= var_expand( L0
, lastword
, out
, lol
, 0 );
196 int so
= strlen( l
->string
);
198 if( out
+ so
>= oute
)
201 strcpy( out
, l
->string
);
204 /* Separate with space */
206 if ((l
= list_next(l
)))
223 * var_get() - get value of a user defined symbol
225 * Returns NULL if symbol unset.
229 var_get( const char *symbol
)
231 VARIABLE var
, *v
= &var
;
235 if( varhash
&& hashcheck( varhash
, (HASHDATA
**)&v
) )
238 var_dump( v
->symbol
, v
->value
, "get" );
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.
262 VARIABLE
*v
= var_enter( symbol
);
265 var_dump( symbol
, value
, "set" );
271 list_free( v
->value
);
277 v
->value
= list_append( v
->value
, value
);
281 /* Set only if unset */
291 * var_swap() - swap a variable's value with the given one
299 VARIABLE
*v
= var_enter( symbol
);
300 LIST
*oldvalue
= v
->value
;
303 var_dump( symbol
, value
, "set" );
313 * var_enter() - make new var symbol table entry, returning var ptr
317 var_enter( const char *symbol
)
319 VARIABLE var
, *v
= &var
;
322 varhash
= hashinit( sizeof( VARIABLE
), "variables" );
327 if( hashenter( varhash
, (HASHDATA
**)&v
) )
328 v
->symbol
= newstr( symbol
); /* never freed */
334 * var_dump() - dump a variable to stdout
343 printf( "%s %s = ", what
, symbol
);
349 * var_done() - free variable tables