2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-16 01:12:13 +00:00

Implement @(file) syntax in actions.

[SVN r31549]
This commit is contained in:
Rene Rivera
2005-11-03 16:41:05 +00:00
parent baff08aee9
commit 6ff174db28
6 changed files with 434 additions and 26 deletions

View File

@@ -402,6 +402,7 @@ if ! $(debug) || --noassert in $(ARGV)
--defs += OPT_HEADER_CACHE_EXT ;
--defs += OPT_GRAPH_DEBUG_EXT ;
--defs += OPT_SEMAPHORE ;
--defs += OPT_AT_FILES ;
# Bug fixes
--defs += OPT_FIX_TARGET_VARIABLES_EXT ;

View File

@@ -6,6 +6,8 @@
/* 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)
*/
@@ -19,7 +21,9 @@
# 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
@@ -207,6 +211,74 @@ var_string(
if( in[0] == '$' && in[1] == '(' )
dollar++;
#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)
{
printf( "no file specified!\n" );
exit( EXITBAD );
}
if ( depth == 0 )
{
string file_name_v;
int file_name_l = 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 file_name_l;
/* expand the file value into the file reference */
if ( !globs.noexec )
var_string_to_file( split+3, ine-split-4, out, lol );
/* continue on with the expansion */
if ( strcmp( "STDOUT", out ) == 0 || strcmp( "STDERR", out ) == 0 )
out[0] = '\0';
else
out += strlen(out);
}
/* and continue with the parsing just past the @() reference */
in = ine;
}
#endif
*out++ = *in++;
}
@@ -228,7 +300,7 @@ var_string(
out = lastword;
for( ; l; l = list_next( l ) )
while ( l )
{
int so = strlen( l->string );
@@ -237,7 +309,8 @@ var_string(
strcpy( out, l->string );
out += so;
*out++ = ' ';
l = list_next( l );
if ( l ) *out++ = ' ';
}
list_free( l );
@@ -252,6 +325,102 @@ var_string(
return out - out0;
}
void var_string_to_file( const char * in, int insize, const char * out, LOL * lol )
{
const char * ine = in+insize;
FILE * out_file = 0;
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);
}
while( *in && in < ine )
{
int dollar = 0;
const char * output_0 = in;
const char * output_1 = in;
/* Copy white space */
while ( output_1 < ine && *output_1 && isspace( *output_1 ) )
{
++output_1;
}
if ( output_0 < output_1 )
{
fwrite(output_0,output_1-output_0,1,out_file);
}
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] && output_1[1] == '(' )
{
dollar++;
}
++output_1;
}
/* 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( L0, (char*)output_0, (char*)output_1, lol, 0 );
while ( l )
{
fputs( l->string, out_file );
l = list_next( l );
if ( l ) fputc( ' ', out_file );
}
list_free( l );
}
else if ( output_0 < output_1 )
{
fwrite(output_0,output_1-output_0,1,out_file);
}
in = output_1;
}
if ( out_file != stdout && out_file != stderr )
{
fflush( out_file );
fclose( out_file );
}
}
/*
* var_get() - get value of a user defined symbol
*
@@ -261,18 +430,45 @@ var_string(
LIST *
var_get( 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;
}
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 )
{
}
else if ( strcmp( "TMPFILE", symbol ) == 0 )
{
}
#if 0
/* Not really usefull at the moment. */
else if ( strcmp( "STDOUT", symbol ) == 0 )
{
result = list_new( L0, newstr( "STDOUT" ) );
}
else if ( strcmp( "STDERR", symbol ) == 0 )
{
result = list_new( L0, newstr( "STDERR" ) );
}
#endif
else
#endif
{
VARIABLE var, *v = &var;
return 0;
v->symbol = symbol;
if( varhash && hashcheck( varhash, (HASHDATA **)&v ) )
{
if( DEBUG_VARGET )
var_dump( v->symbol, v->value, "get" );
result = v->value;
}
}
return result;
}
/*

View File

@@ -18,6 +18,13 @@ LIST * var_swap( char *symbol, LIST *value );
void var_done();
void var_hash_swap( struct hash** );
/** Expands the "in" expression directly into the "out" file.
The file can be one of: a path, STDOUT, or STDERR to send
the output to a file overwriting previous content, to
the console, or to the error output respectively.
*/
void var_string_to_file( const char * in, int insize, const char * out, LOL * lol );
/*
* Defines for var_set().
*/

View File

@@ -402,6 +402,7 @@ if ! $(debug) || --noassert in $(ARGV)
--defs += OPT_HEADER_CACHE_EXT ;
--defs += OPT_GRAPH_DEBUG_EXT ;
--defs += OPT_SEMAPHORE ;
--defs += OPT_AT_FILES ;
# Bug fixes
--defs += OPT_FIX_TARGET_VARIABLES_EXT ;

View File

@@ -6,6 +6,8 @@
/* 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)
*/
@@ -19,7 +21,9 @@
# 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
@@ -207,6 +211,74 @@ var_string(
if( in[0] == '$' && in[1] == '(' )
dollar++;
#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)
{
printf( "no file specified!\n" );
exit( EXITBAD );
}
if ( depth == 0 )
{
string file_name_v;
int file_name_l = 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 file_name_l;
/* expand the file value into the file reference */
if ( !globs.noexec )
var_string_to_file( split+3, ine-split-4, out, lol );
/* continue on with the expansion */
if ( strcmp( "STDOUT", out ) == 0 || strcmp( "STDERR", out ) == 0 )
out[0] = '\0';
else
out += strlen(out);
}
/* and continue with the parsing just past the @() reference */
in = ine;
}
#endif
*out++ = *in++;
}
@@ -228,7 +300,7 @@ var_string(
out = lastword;
for( ; l; l = list_next( l ) )
while ( l )
{
int so = strlen( l->string );
@@ -237,7 +309,8 @@ var_string(
strcpy( out, l->string );
out += so;
*out++ = ' ';
l = list_next( l );
if ( l ) *out++ = ' ';
}
list_free( l );
@@ -252,6 +325,102 @@ var_string(
return out - out0;
}
void var_string_to_file( const char * in, int insize, const char * out, LOL * lol )
{
const char * ine = in+insize;
FILE * out_file = 0;
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);
}
while( *in && in < ine )
{
int dollar = 0;
const char * output_0 = in;
const char * output_1 = in;
/* Copy white space */
while ( output_1 < ine && *output_1 && isspace( *output_1 ) )
{
++output_1;
}
if ( output_0 < output_1 )
{
fwrite(output_0,output_1-output_0,1,out_file);
}
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] && output_1[1] == '(' )
{
dollar++;
}
++output_1;
}
/* 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( L0, (char*)output_0, (char*)output_1, lol, 0 );
while ( l )
{
fputs( l->string, out_file );
l = list_next( l );
if ( l ) fputc( ' ', out_file );
}
list_free( l );
}
else if ( output_0 < output_1 )
{
fwrite(output_0,output_1-output_0,1,out_file);
}
in = output_1;
}
if ( out_file != stdout && out_file != stderr )
{
fflush( out_file );
fclose( out_file );
}
}
/*
* var_get() - get value of a user defined symbol
*
@@ -261,18 +430,45 @@ var_string(
LIST *
var_get( 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;
}
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 )
{
}
else if ( strcmp( "TMPFILE", symbol ) == 0 )
{
}
#if 0
/* Not really usefull at the moment. */
else if ( strcmp( "STDOUT", symbol ) == 0 )
{
result = list_new( L0, newstr( "STDOUT" ) );
}
else if ( strcmp( "STDERR", symbol ) == 0 )
{
result = list_new( L0, newstr( "STDERR" ) );
}
#endif
else
#endif
{
VARIABLE var, *v = &var;
return 0;
v->symbol = symbol;
if( varhash && hashcheck( varhash, (HASHDATA **)&v ) )
{
if( DEBUG_VARGET )
var_dump( v->symbol, v->value, "get" );
result = v->value;
}
}
return result;
}
/*

View File

@@ -18,6 +18,13 @@ LIST * var_swap( char *symbol, LIST *value );
void var_done();
void var_hash_swap( struct hash** );
/** Expands the "in" expression directly into the "out" file.
The file can be one of: a path, STDOUT, or STDERR to send
the output to a file overwriting previous content, to
the console, or to the error output respectively.
*/
void var_string_to_file( const char * in, int insize, const char * out, LOL * lol );
/*
* Defines for var_set().
*/