Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/tools/build/jam_src/variable.c @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 7.9 KB
Line 
1/*
2 * Copyright 1993, 2000 Christopher Seiwald.
3 *
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
6
7/*  This file is ALSO:
8 *  Copyright 2001-2004 David Abrahams.
9 *  Distributed under the Boost Software License, Version 1.0.
10 *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
11 */
12
13# include "jam.h"
14# include "lists.h"
15# include "parse.h"
16# include "variable.h"
17# include "expand.h"
18# include "hash.h"
19# include "filesys.h"
20# include "newstr.h"
21# include "strings.h"
22# include <stdlib.h>
23
24/*
25 * variable.c - handle jam multi-element variables
26 *
27 * External routines:
28 *
29 *      var_defines() - load a bunch of variable=value settings
30 *      var_string() - expand a string with variables in it
31 *      var_get() - get value of a user defined symbol
32 *      var_set() - set a variable in jam's user defined symbol table
33 *      var_swap() - swap a variable's value with the given one
34 *      var_done() - free variable tables
35 *
36 * Internal routines:
37 *
38 *      var_enter() - make new var symbol table entry, returning var ptr
39 *      var_dump() - dump a variable to stdout
40 *
41 * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
42 * 08/23/94 (seiwald) - Support for '+=' (append to variable)
43 * 01/22/95 (seiwald) - split environment variables at blanks or :'s
44 * 05/10/95 (seiwald) - split path variables at SPLITPATH (not :)
45 * 09/11/00 (seiwald) - defunct var_list() removed
46 */
47
48static struct hash *varhash = 0;
49
50/*
51 * VARIABLE - a user defined multi-value variable
52 */
53
54typedef struct _variable VARIABLE ;
55
56struct _variable {
57        char    *symbol;
58        LIST    *value;
59} ;
60
61static VARIABLE *var_enter( char *symbol );
62static void var_dump( char *symbol, LIST *value, char *what );
63
64
65
66/*
67 * var_hash_swap() - swap all variable settings with those passed
68 *
69 * Used to implement separate settings spaces for modules
70 */
71void var_hash_swap( struct hash** new_vars )
72{
73    struct hash* old = varhash;
74    varhash = *new_vars;
75    *new_vars = old;
76}
77
78/*
79 * var_defines() - load a bunch of variable=value settings
80 *
81 * If preprocess is false, take the value verbatim.
82 *
83 * Otherwise, if the variable value is enclosed in quotes, strip the
84 * quotes.
85 *
86 * Otherwise, if variable name ends in PATH, split value at :'s.
87 *
88 * Otherwise, split the value at blanks.
89 */
90
91void
92var_defines( char *const* e, int preprocess )
93{
94    string buf[1];
95
96    string_new( buf );
97
98        for( ; *e; e++ )
99        {
100            char *val;
101
102# ifdef OS_MAC
103            /* On the mac (MPW), the var=val is actually var\0val */
104            /* Think different. */
105       
106            if( ( val = strchr( *e, '=' ) ) || ( val = *e + strlen( *e ) ) )
107# else
108            if( val = strchr( *e, '=' ) )
109# endif
110            {
111                LIST *l = L0;
112                char *pp, *p;
113# ifdef OPT_NO_EXTERNAL_VARIABLE_SPLIT
114                char split = '\0';
115# else
116# ifdef OS_MAC
117                char split = ',';
118# else
119                char split = ' ';
120# endif
121# endif
122                size_t len = strlen(val + 1);
123
124                int quoted = val[1] == '"' && val[len] == '"';
125               
126                if ( quoted && preprocess )
127                {
128                    string_append_range( buf, val + 2, val + len );
129                    l = list_new( l, newstr( buf->value ) );
130                    string_truncate( buf, 0 );
131                }
132                else
133                {
134                    /* Split *PATH at :'s, not spaces */
135
136                    if( val - 4 >= *e )
137                    {
138                        if( !strncmp( val - 4, "PATH", 4 ) ||
139                            !strncmp( val - 4, "Path", 4 ) ||
140                            !strncmp( val - 4, "path", 4 ) )
141                            split = SPLITPATH;
142                    }
143
144                    /* Do the split */
145
146                    for(
147                        pp = val + 1;
148                        preprocess && (p = strchr( pp, split )) != 0;
149                        pp = p + 1 )
150                    {
151                        string_append_range( buf, pp, p );
152                        l = list_new( l, newstr( buf->value ) );
153                        string_truncate( buf, 0 );
154                    }
155
156                    l = list_new( l, newstr( pp ) );
157                }
158
159                /* Get name */
160                string_append_range( buf, *e, val );
161                var_set( buf->value, l, VAR_SET );
162                string_truncate( buf, 0 );
163            }
164        }
165        string_free( buf );
166}
167
168/*
169 * var_string() - expand a string with variables in it
170 *
171 * Copies in to out; doesn't modify targets & sources.
172 */
173
174int
175var_string(
176        char    *in,
177        char    *out,
178        int     outsize,
179        LOL     *lol )
180{
181        char    *out0 = out;
182        char    *oute = out + outsize - 1;
183
184        while( *in )
185        {
186            char        *lastword;
187            int         dollar = 0;
188
189            /* Copy white space */
190
191            while( isspace( *in ) )
192            {
193                if( out >= oute )
194                    return -1;
195
196                *out++ = *in++;
197            }
198
199            lastword = out;
200
201            /* Copy non-white space, watching for variables */
202
203            while( *in && !isspace( *in ) )
204            {
205                if( out >= oute )
206                    return -1;
207
208                if( in[0] == '$' && in[1] == '(' )
209                    dollar++;
210
211                *out++ = *in++;
212            }
213
214        /* Add zero to 'out' so that 'lastword' is correctly zero-terminated. */
215        if (out >= oute)
216            return -1;
217        /* Don't increment, intentionally. */
218        *out= '\0';
219           
220            /* If a variable encountered, expand it and and embed the */
221            /* space-separated members of the list in the output. */
222
223            if( dollar )
224            {
225                LIST    *l;
226
227                l = var_expand( L0, lastword, out, lol, 0 );
228
229                out = lastword;
230
231                for( ; l; l = list_next( l ) )
232                {
233                    int so = strlen( l->string );
234
235                    if( out + so >= oute )
236                        return -1;
237
238                    strcpy( out, l->string );
239                    out += so;
240                    *out++ = ' ';
241                }
242
243                list_free( l );
244            }
245        }
246
247        if( out >= oute )
248            return -1;
249
250        *out++ = '\0';
251
252        return out - out0;
253}
254
255/*
256 * var_get() - get value of a user defined symbol
257 *
258 * Returns NULL if symbol unset.
259 */
260
261LIST *
262var_get( char *symbol )
263{
264        VARIABLE var, *v = &var;
265
266        v->symbol = symbol;
267
268        if( varhash && hashcheck( varhash, (HASHDATA **)&v ) )
269        {
270            if( DEBUG_VARGET )
271                var_dump( v->symbol, v->value, "get" );
272            return v->value;
273        }
274   
275        return 0;
276}
277
278/*
279 * var_set() - set a variable in jam's user defined symbol table
280 *
281 * 'flag' controls the relationship between new and old values of
282 * the variable: SET replaces the old with the new; APPEND appends
283 * the new to the old; DEFAULT only uses the new if the variable
284 * was previously unset.
285 *
286 * Copies symbol.  Takes ownership of value.
287 */
288
289void
290var_set(
291        char    *symbol,
292        LIST    *value,
293        int     flag )
294{
295        VARIABLE *v = var_enter( symbol );
296
297        if( DEBUG_VARSET )
298            var_dump( symbol, value, "set" );
299       
300        switch( flag )
301        {
302        case VAR_SET:
303            /* Replace value */
304            list_free( v->value );
305            v->value = value;
306            break;
307
308        case VAR_APPEND:
309            /* Append value */
310            v->value = list_append( v->value, value );
311            break;
312
313        case VAR_DEFAULT:
314            /* Set only if unset */
315            if( !v->value )
316                v->value = value;
317            else
318                list_free( value );
319            break;
320        }
321}
322
323/*
324 * var_swap() - swap a variable's value with the given one
325 */
326
327LIST *
328var_swap(
329        char    *symbol,
330        LIST    *value )
331{
332        VARIABLE *v = var_enter( symbol );
333        LIST     *oldvalue = v->value;
334
335        if( DEBUG_VARSET )
336            var_dump( symbol, value, "set" );
337
338        v->value = value;
339
340        return oldvalue;
341}
342
343
344
345/*
346 * var_enter() - make new var symbol table entry, returning var ptr
347 */
348
349static VARIABLE *
350var_enter( char *symbol )
351{
352        VARIABLE var, *v = &var;
353
354        if( !varhash )
355            varhash = hashinit( sizeof( VARIABLE ), "variables" );
356
357        v->symbol = symbol;
358        v->value = 0;
359
360        if( hashenter( varhash, (HASHDATA **)&v ) )
361            v->symbol = newstr( symbol );       /* never freed */
362
363        return v;
364}
365
366/*
367 * var_dump() - dump a variable to stdout
368 */
369
370static void
371var_dump(
372        char    *symbol,
373        LIST    *value,
374        char    *what )
375{
376        printf( "%s %s = ", what, symbol );
377        list_print( value );
378        printf( "\n" );
379}
380
381/*
382 * var_done() - free variable tables
383 */
384static void delete_var_( void* xvar, void* data )
385{
386    VARIABLE *v = (VARIABLE*)xvar;
387    freestr( v->symbol );
388    list_free( v-> value );
389}
390
391void
392var_done()
393{
394    hashenumerate( varhash, delete_var_, (void*)0 );
395        hashdone( varhash );
396}
Note: See TracBrowser for help on using the repository browser.