/* * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. * * This file is part of Jam - see jam.c for Copyright information. */ /* * variable.c - handle jam multi-element variables * * External routines: * * var_defines() - load a bunch of variable=value settings * var_string() - expand a string with variables in it * var_get() - get value of a user defined symbol * var_set() - set a variable in jam's user defined symbol table * var_swap() - swap a variable's value with the given one * var_done() - free variable tables * * Internal routines: * * var_enter() - make new var symbol table entry, returning var ptr * var_dump() - dump a variable to stdout * * 04/13/94 (seiwald) - added shorthand L0 for null list pointer * 08/23/94 (seiwald) - Support for '+=' (append to variable) * 01/22/95 (seiwald) - split environment variables at blanks or :'s * 05/10/95 (seiwald) - split path variables at SPLITPATH (not :) * 09/11/00 (seiwald) - defunct var_list() removed * 10/22/02 (seiwald) - list_new() now does its own newstr()/copystr() * 11/04/02 (seiwald) - const-ing for string literals */ # include "jam.h" # include "lists.h" # include "parse.h" # include "variable.h" # include "expand.h" # include "hash.h" # include "newstr.h" static struct hash *varhash = 0; /* * VARIABLE - a user defined multi-value variable */ typedef struct _variable VARIABLE ; struct _variable { const char *symbol; LIST *value; } ; static VARIABLE *var_enter( const char *symbol ); static void var_dump( const char *symbol, LIST *value, const char *what ); /* * var_defines() - load a bunch of variable=value settings * * If variable name ends in PATH, split value at :'s. * Otherwise, split at blanks. */ void var_defines( const char **e ) { for( ; *e; e++ ) { const char *val; /* Just say "no": windows defines this in the env, */ /* but we don't want it to override our notion of OS. */ if( !strcmp( *e, "OS=Windows_NT" ) ) continue; # ifdef OS_MAC /* On the mac (MPW), the var=val is actually var\0val */ /* Think different. */ if( ( val = strchr( *e, '=' ) ) || ( val = *e + strlen( *e ) ) ) # else if( val = strchr( *e, '=' ) ) # endif { LIST *l = L0; const char *pp, *p; # ifdef OS_MAC char split = ','; # else char split = ' '; # endif char buf[ MAXSYM ]; /* Split *PATH at :'s, not spaces */ if( val - 4 >= *e ) { if( !strncmp( val - 4, "PATH", 4 ) || !strncmp( val - 4, "Path", 4 ) || !strncmp( val - 4, "path", 4 ) ) split = SPLITPATH; } /* Do the split, excluding empty items: */ for( pp = val + 1; p = strchr( pp, split ); pp = p + 1 ) if( p != pp ) { strncpy( buf, pp, p - pp ); buf[ p - pp ] = '\0'; l = list_new( l, buf, 0 ); } /* Don't add empty item to existing list. */ if( *pp || !l ) l = list_new( l, pp, 0 ); /* Get name */ strncpy( buf, *e, val - *e ); buf[ val - *e ] = '\0'; var_set( buf, l, VAR_SET ); } } } /* * var_string() - expand a string with variables in it * * Copies in to out; doesn't modify targets & sources. */ int var_string( const char *in, char *out, int outsize, LOL *lol ) { char *out0 = out; char *oute = out + outsize - 1; while( *in ) { char *lastword; int dollar = 0; /* Copy white space */ while( isspace( *in ) ) { if( out >= oute ) return -1; *out++ = *in++; } lastword = out; /* Copy non-white space, watching for variables */ while( *in && !isspace( *in ) ) { if( out >= oute ) return -1; if( in[0] == '$' && in[1] == '(' ) dollar++; *out++ = *in++; } /* If a variable encountered, expand it and and embed the */ /* space-separated members of the list in the output. */ if( dollar ) { LIST *l = var_expand( L0, lastword, out, lol, 0 ); out = lastword; while( l ) { int so = strlen( l->string ); if( out + so >= oute ) return -1; strcpy( out, l->string ); out += so; /* Separate with space */ if( l = list_next( l ) ) *out++ = ' '; } list_free( l ); } } if( out >= oute ) return -1; *out++ = '\0'; return out - out0; } /* * var_get() - get value of a user defined symbol * * Returns NULL if symbol unset. */ LIST * var_get( const char *symbol ) { VARIABLE var, *v = &var; v->symbol = symbol; if( varhash && hashcheck( varhash, (HASHDATA **)&v ) ) { if( DEBUG_VARGET ) var_dump( v->symbol, v->value, "get" ); return v->value; } return 0; } /* * var_set() - set a variable in jam's user defined symbol table * * 'flag' controls the relationship between new and old values of * the variable: SET replaces the old with the new; APPEND appends * the new to the old; DEFAULT only uses the new if the variable * was previously unset. * * Copies symbol. Takes ownership of value. */ void var_set( const char *symbol, LIST *value, int flag ) { VARIABLE *v = var_enter( symbol ); if( DEBUG_VARSET ) var_dump( symbol, value, "set" ); switch( flag ) { case VAR_SET: /* Replace value */ list_free( v->value ); v->value = value; break; case VAR_APPEND: /* Append value */ v->value = list_append( v->value, value ); break; case VAR_DEFAULT: /* Set only if unset */ if( !v->value ) v->value = value; else list_free( value ); break; } } /* * var_swap() - swap a variable's value with the given one */ LIST * var_swap( const char *symbol, LIST *value ) { VARIABLE *v = var_enter( symbol ); LIST *oldvalue = v->value; if( DEBUG_VARSET ) var_dump( symbol, value, "set" ); v->value = value; return oldvalue; } /* * var_enter() - make new var symbol table entry, returning var ptr */ static VARIABLE * var_enter( const char *symbol ) { VARIABLE var, *v = &var; if( !varhash ) varhash = hashinit( sizeof( VARIABLE ), "variables" ); v->symbol = symbol; v->value = 0; if( hashenter( varhash, (HASHDATA **)&v ) ) v->symbol = newstr( symbol ); /* never freed */ return v; } /* * var_dump() - dump a variable to stdout */ static void var_dump( const char *symbol, LIST *value, const char *what ) { printf( "%s %s = ", what, symbol ); list_print( value ); printf( "\n" ); } /* * var_done() - free variable tables */ void var_done() { hashdone( varhash ); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#3 | 4619 | Chris Comparini |
Altered implementation of the blank element exclusion code, as per Chris S's suggestion. Presently this excludes all blank words from environment variables. |
||
#2 | 4378 | Chris Comparini |
Omission of trailing blanks on environment variables, from craig_mcpheeters/jam/src/variable.c. Not completely comfortable with this implementation, but here it is.. |
||
#1 | 4331 | Chris Comparini |
Branch of what I hope is _everyone's_ jam branches, if that makes sense. |
||
//guest/perforce_software/jam/src/variable.c | |||||
#7 | 2560 | rmg |
Suppress last blank in variable expansion in actions. I really don't think this could possibly hurt anything. Bug fix documented in RELNOTES. === computer:1666: Change 39567 by seiwald@play-seiwald on 2002/12/27 15:23:10 |
||
#6 | 2493 | rmg |
Rewrite the past: update all jam's source with comments to reflect changes since about 2.3, very early 2001. Whitespace only change. === computer:1666: Change 37660 by seiwald@play-seiwald on 2002/11/06 22:41:35 Note: I regenerated jamgram.c on my linux 7.3 system prior to the submit, since patch was so unhappy trying to lay down the changes from Christopher's change. Presumably this is just due to different yacc/bison/whatever particulars on the system where Christopher made the changes originally. - rmg |
||
#5 | 2491 | rmg |
Some consting in jam to make it more compilable by C++ compilers. No functional change. === computer:1666: Change 37433 by perforce@perforce on 2002/10/30 16:08:51 Recreational const-ing of jam, for compilers that don't allow "string" to be passed as a non-const char *. This included a few places where we were modifying what could possibly have been read-only storage, oddly enough. No functional change. === computer:1666: Change 37602 by seiwald@play-seiwald on 2002/11/04 17:25:40 |
||
#4 | 2489 | rmg |
Jam tinkering: since all calls to list_new() must either newstr() or copystr() the added string, instead just pass a flag and let list_new() do the newstr/copystr. No functional change. === computer:1666: Change 37164 by seiwald@spice on 2002/10/22 01:21:58 |
||
#3 | 1319 | rmg |
Jam 2.3 + Perforce's internal changes. This change is a drop of the Perforce internal Jam changes since the 2.3 public release. The individual changes represented herein are preserved in the //guest/richard_geiger/intjam/ branch. The intent of this drop is to provide a base, from which other contributors' Jam branches may be integrated into. It is not intended to become a packaged release in this state. We will be integrating changes from other users prior to creating the next packaged release. Please refer to the src/RELNOTES file for an overview of the changes present in this integration. - Richard Geiger Open Source Engineer at Perforce |
||
#2 | 486 | Perforce staff |
Jam 2.3. See RELNOTES for a list of changes from 2.2.x. Just about every source file was touched when jam got ANSI-fied. |
||
#1 | 2 | laura | Add Jam/MR 2.2 source |