diff options
Diffstat (limited to 'jam-files/engine/variable.c')
-rw-r--r-- | jam-files/engine/variable.c | 631 |
1 files changed, 0 insertions, 631 deletions
diff --git a/jam-files/engine/variable.c b/jam-files/engine/variable.c deleted file mode 100644 index 795f3458..00000000 --- a/jam-files/engine/variable.c +++ /dev/null @@ -1,631 +0,0 @@ -/* - * Copyright 1993, 2000 Christopher Seiwald. - * - * This file is part of Jam - see jam.c for Copyright information. - */ - -/* This file is ALSO: - * Copyright 2001-2004 David Abrahams. - * Copyright 2005 Reece H. Dunn. - * Copyright 2005 Rene Rivera. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - */ - -#include "jam.h" -#include "lists.h" -#include "parse.h" -#include "variable.h" -#include "expand.h" -#include "hash.h" -#include "filesys.h" -#include "newstr.h" -#include "strings.h" -#include "pathsys.h" -#include <stdlib.h> -#include <stdio.h> - -/* - * 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 -{ - char * symbol; - LIST * value; -}; - -static VARIABLE * var_enter( char * symbol ); -static void var_dump( char * symbol, LIST * value, char * what ); - - -/* - * var_hash_swap() - swap all variable settings with those passed - * - * Used to implement separate settings spaces for modules - */ - -void var_hash_swap( struct hash * * new_vars ) -{ - struct hash * old = varhash; - varhash = *new_vars; - *new_vars = old; -} - - -/* - * var_defines() - load a bunch of variable=value settings - * - * If preprocess is false, take the value verbatim. - * - * Otherwise, if the variable value is enclosed in quotes, strip the - * quotes. - * - * Otherwise, if variable name ends in PATH, split value at :'s. - * - * Otherwise, split the value at blanks. - */ - -void var_defines( char * const * e, int preprocess ) -{ - string buf[1]; - - string_new( buf ); - - for ( ; *e; ++e ) - { - char * val; - -# 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; - char * pp; - char * p; -# ifdef OPT_NO_EXTERNAL_VARIABLE_SPLIT - char split = '\0'; -# else - # ifdef OS_MAC - char split = ','; - # else - char split = ' '; - # endif -# endif - size_t len = strlen( val + 1 ); - - int quoted = ( val[1] == '"' ) && ( val[len] == '"' ) && - ( len > 1 ); - - if ( quoted && preprocess ) - { - string_append_range( buf, val + 2, val + len ); - l = list_new( l, newstr( buf->value ) ); - string_truncate( buf, 0 ); - } - else - { - /* 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; - preprocess && ( ( p = strchr( pp, split ) ) != 0 ); - pp = p + 1 - ) - { - string_append_range( buf, pp, p ); - l = list_new( l, newstr( buf->value ) ); - string_truncate( buf, 0 ); - } - - l = list_new( l, newstr( pp ) ); - } - - /* Get name. */ - string_append_range( buf, *e, val ); - var_set( buf->value, l, VAR_SET ); - string_truncate( buf, 0 ); - } - } - string_free( buf ); -} - - -/* - * var_string() - expand a string with variables in it - * - * Copies in to out; doesn't modify targets & sources. - */ - -int var_string( 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++; - } - #ifdef OPT_AT_FILES - else if ( ( in[ 0 ] == '@' ) && ( in[ 1 ] == '(' ) ) - { - int depth = 1; - char * ine = in + 2; - char * split = 0; - - /* Scan the content of the response file @() section. */ - while ( *ine && ( depth > 0 ) ) - { - switch ( *ine ) - { - case '(': ++depth; break; - case ')': --depth; break; - case ':': - if ( ( depth == 1 ) && ( ine[ 1 ] == 'E' ) && ( ine[ 2 ] == '=' ) ) - split = ine; - break; - } - ++ine; - } - - if ( !split ) - { - /* the @() reference doesn't match the @(foo:E=bar) format. - hence we leave it alone by copying directly to output. */ - int l = 0; - if ( out + 2 >= oute ) return -1; - *( out++ ) = '@'; - *( out++ ) = '('; - l = var_string( in + 2, out, oute - out, lol ); - if ( l < 0 ) return -1; - out += l; - if ( out + 1 >= oute ) return -1; - *( out++ ) = ')'; - } - else if ( depth == 0 ) - { - string file_name_v; - int file_name_l = 0; - const char * file_name_s = 0; - - /* Expand the temporary file name var inline. */ - #if 0 - string_copy( &file_name_v, "$(" ); - string_append_range( &file_name_v, in + 2, split ); - string_push_back( &file_name_v, ')' ); - #else - string_new( &file_name_v ); - string_append_range( &file_name_v, in + 2, split ); - #endif - file_name_l = var_string( file_name_v.value, out, oute - out + 1, lol ); - string_free( &file_name_v ); - if ( file_name_l < 0 ) return -1; - file_name_s = out; - - /* For stdout/stderr we will create a temp file and generate - * a command that outputs the content as needed. - */ - if ( ( strcmp( "STDOUT", out ) == 0 ) || - ( strcmp( "STDERR", out ) == 0 ) ) - { - int err_redir = strcmp( "STDERR", out ) == 0; - out[ 0 ] = '\0'; - file_name_s = path_tmpfile(); - file_name_l = strlen(file_name_s); - #ifdef OS_NT - if ( ( out + 7 + file_name_l + ( err_redir ? 5 : 0 ) ) >= oute ) - return -1; - sprintf( out,"type \"%s\"%s", file_name_s, - err_redir ? " 1>&2" : "" ); - #else - if ( ( out + 6 + file_name_l + ( err_redir ? 5 : 0 ) ) >= oute ) - return -1; - sprintf( out,"cat \"%s\"%s", file_name_s, - err_redir ? " 1>&2" : "" ); - #endif - /* We also make sure that the temp files created by this - * get nuked eventually. - */ - file_remove_atexit( file_name_s ); - } - - /* Expand the file value into the file reference. */ - var_string_to_file( split + 3, ine - split - 4, file_name_s, - lol ); - - /* Continue on with the expansion. */ - out += strlen( out ); - } - - /* And continue with the parsing just past the @() reference. */ - in = ine; - } - #endif - else - { - *out++ = *in++; - } - } - - /* Add zero to 'out' so that 'lastword' is correctly zero-terminated. */ - if ( out >= oute ) - return -1; - /* Do not increment, intentionally. */ - *out = '\0'; - - /* 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; - l = list_next( l ); - if ( l ) *out++ = ' '; - } - - list_free( l ); - } - } - - if ( out >= oute ) - return -1; - - *out++ = '\0'; - - return out - out0; -} - - -void var_string_to_file( const char * in, int insize, const char * out, LOL * lol ) -{ - char const * ine = in + insize; - FILE * out_file = 0; - int out_debug = DEBUG_EXEC ? 1 : 0; - if ( globs.noexec ) - { - /* out_debug = 1; */ - } - else if ( strcmp( out, "STDOUT" ) == 0 ) - { - out_file = stdout; - } - else if ( strcmp( out, "STDERR" ) == 0 ) - { - out_file = stderr; - } - else - { - /* Handle "path to file" filenames. */ - string out_name; - if ( ( out[ 0 ] == '"' ) && ( out[ strlen( out ) - 1 ] == '"' ) ) - { - string_copy( &out_name, out + 1 ); - string_truncate( &out_name, out_name.size - 1 ); - } - else - { - string_copy( &out_name,out ); - } - out_file = fopen( out_name.value, "w" ); - if ( !out_file ) - { - printf( "failed to write output file '%s'!\n", out_name.value ); - exit( EXITBAD ); - } - string_free( &out_name ); - } - - if ( out_debug ) printf( "\nfile %s\n", out ); - - while ( *in && ( in < ine ) ) - { - int dollar = 0; - const char * output_0 = in; - const char * output_1 = in; - - /* Copy white space. */ - while ( ( output_1 < ine ) && isspace( *output_1 ) ) - ++output_1; - - if ( output_0 < output_1 ) - { - if ( out_file ) fwrite( output_0, output_1 - output_0, 1, out_file ); - if ( out_debug ) fwrite( output_0, output_1 - output_0, 1, stdout ); - } - output_0 = output_1; - - /* Copy non-white space, watching for variables. */ - while ( ( output_1 < ine ) && *output_1 && !isspace( *output_1 ) ) - { - if ( ( output_1[ 0 ] == '$' ) && ( output_1[ 1 ] == '(' ) ) - ++dollar; - ++output_1; - } - - /* If a variable encountered, expand it and embed the space-separated - * members of the list in the output. - */ - if ( dollar ) - { - LIST * l = var_expand( L0, (char *)output_0, (char *)output_1, lol, 0 ); - - while ( l ) - { - if ( out_file ) fputs( l->string, out_file ); - if ( out_debug ) puts( l->string ); - l = list_next( l ); - if ( l ) - { - if ( out_file ) fputc( ' ', out_file ); - if ( out_debug ) fputc( ' ', stdout ); - } - } - - list_free( l ); - } - else if ( output_0 < output_1 ) - { - if ( out_file ) - { - const char * output_n = output_0; - while ( output_n < output_1 ) - { - output_n += fwrite( output_n, 1, output_1-output_n, out_file ); - } - } - if ( out_debug ) - { - const char * output_n = output_0; - while ( output_n < output_1 ) - { - output_n += fwrite( output_n, 1, output_1-output_n, stdout ); - } - } - } - - in = output_1; - } - - if ( out_file && ( out_file != stdout ) && ( out_file != stderr ) ) - { - fflush( out_file ); - fclose( out_file ); - } - - if ( out_debug ) fputc( '\n', stdout ); -} - - -/* - * var_get() - get value of a user defined symbol. - * - * Returns NULL if symbol unset. - */ - -LIST * var_get( char * symbol ) -{ - LIST * result = 0; -#ifdef OPT_AT_FILES - /* Some "fixed" variables... */ - if ( strcmp( "TMPDIR", symbol ) == 0 ) - { - result = list_new( L0, newstr( (char *)path_tmpdir() ) ); - } - else if ( strcmp( "TMPNAME", symbol ) == 0 ) - { - result = list_new( L0, newstr( (char *)path_tmpnam() ) ); - } - else if ( strcmp( "TMPFILE", symbol ) == 0 ) - { - result = list_new( L0, newstr( (char *)path_tmpfile() ) ); - } - else if ( strcmp( "STDOUT", symbol ) == 0 ) - { - result = list_new( L0, newstr( "STDOUT" ) ); - } - else if ( strcmp( "STDERR", symbol ) == 0 ) - { - result = list_new( L0, newstr( "STDERR" ) ); - } - else -#endif - { - VARIABLE var; - VARIABLE * v = &var; - - v->symbol = symbol; - - if ( varhash && hashcheck( varhash, (HASHDATA * *)&v ) ) - { - if ( DEBUG_VARGET ) - var_dump( v->symbol, v->value, "get" ); - result = v->value; - } - } - return result; -} - - -/* - * 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( 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( 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( char * symbol ) -{ - VARIABLE var; - VARIABLE * 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( char * symbol, LIST * value, char * what ) -{ - printf( "%s %s = ", what, symbol ); - list_print( value ); - printf( "\n" ); -} - - -/* - * var_done() - free variable tables. - */ - -static void delete_var_( void * xvar, void * data ) -{ - VARIABLE * v = (VARIABLE *)xvar; - freestr( v->symbol ); - list_free( v-> value ); -} - - -void var_done() -{ - hashenumerate( varhash, delete_var_, (void *)0 ); - hashdone( varhash ); -} |