/* * Copyright 1993, 2000 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ #include "Variable.hpp" #include "Expand.hpp" #include "FileSystem.hpp" #include "Hash.hpp" #include "String.hpp" using Jam::List; using Jam::String; /* * 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 */ 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, const 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( char **e ) { for( ; *e; e++ ) { 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 = NULL; 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 */ for( pp = val + 1; p = strchr( pp, split ); pp = p + 1 ) { strncpy( buf, pp, p - pp ); buf[ p - pp ] = '\0'; l = List::list_new( l, String::newstr( buf ) ); } l = List::list_new( l, String::newstr( pp ) ); /* 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, const 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; l = var_expand( NULL, lastword, out, lol, 0 ); out = lastword; for( ; l; l = List::list_next( l ) ) { int so = strlen( l->string ); if( out + so >= oute ) { return -1; } strcpy( out, l->string ); out += so; *out++ = ' '; } List::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::list_free( v->value ); v->value = value; break; case VAR_APPEND: /* Append value */ v->value = List::list_append( v->value, value ); break; case VAR_DEFAULT: /* Set only if unset */ if( !v->value ) { v->value = value; } else { List::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 = String::newstr( (char*)symbol ); /* never freed */ } return v; } /* * var_dump() - dump a variable to stdout */ static void var_dump( const char *symbol, const List *value, const char *what ) { printf( "%s %s = ", what, symbol ); List::list_print( value ); printf( "\n" ); } /* * var_done() - free variable tables */ void var_done() { hashdone( varhash ); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#6 | 1162 | bob_summerwill | Converted LIST into a List class, with all static methods. | ||
#5 | 1153 | bob_summerwill | NewStr has been renamed as String. | ||
#4 | 1146 | bob_summerwill | Moved the NewStr global functions into a static class Jam::String. | ||
#3 | 1138 | bob_summerwill | Removed all extern "C" wrappers, so the program now has C++ linkage throughout, ready for refactoring. | ||
#2 | 1134 | bob_summerwill | Renamed the file system source files. | ||
#1 | 1132 | bob_summerwill | All of the non-generated, non-platform-specific files are now mixed-case C++ source files. | ||
//guest/bob_summerwill/jam/src/variable.c | |||||
#6 | 1130 | bob_summerwill | More .C to .CPP conversions. | ||
#5 | 1127 | bob_summerwill | More file renaming. | ||
#4 | 1126 | bob_summerwill | #include dependencies between headers are now modelled explicitly, with #includes as required in header files, rather than it being a client-code responsibility. | ||
#3 | 1120 | bob_summerwill | A fair-size chunk of char* const-correctness modifications. | ||
#2 | 1118 | bob_summerwill | Various const-correctness fixes. | ||
#1 | 1106 | bob_summerwill | Integrated Jam from "public" to "guest/bob_summerwill". | ||
//guest/perforce_software/jam/src/variable.c | |||||
#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 |