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

* Add "exit-status" and "no-output" options to SHELL builtin.

* Add optional exit result value to EXIT builtin.


[SVN r32534]
This commit is contained in:
Rene Rivera
2006-02-03 23:18:34 +00:00
parent b938340596
commit 315dcc4163
6 changed files with 196 additions and 35 deletions

View File

@@ -698,10 +698,10 @@ ECHO /args/ ;
Blurts out the message /args/ to stdout.
[pre
EXIT /args/ ;
rule EXIT ( /message/ * : /result-value/ ? )
]
Blurts out the message args to stdout and then exits with a failure status.
Blurts out the /message/ to stdout and then exits with a failure status if no /result-value/ is given, otherwise it exits with the given /result-value/.
"=Echo=", "=echo=", "=Exit=", and "=exit=" are accepted as aliases for =ECHO= and =EXIT=, since it is hard to tell that these are built-in rules and not part of the language, like "=include=".
@@ -768,7 +768,14 @@ local PSDK-location =
rule SHELL ( /command/ : * )
]
=SHELL= executes /command/, and then returns the standard output of /command/. =SHELL= only works on platforms with a =popen()= function in the C library. On platforms without a working =popen()= function, =SHELL= is implemented as a no-op. =SHELL= works on Unix, MacOS X, and most Windows compilers. =SHELL= is a no-op on Metrowerks compilers under Windows.
=SHELL= executes /command/, and then returns the standard output of /command/. =SHELL= only works on platforms with a =popen()= function in the C library. On platforms without a working =popen()= function, =SHELL= is implemented as a no-op. =SHELL= works on Unix, MacOS X, and most Windows compilers. =SHELL= is a no-op on Metrowerks compilers under Windows. There is a variable set of allowed options as additional arguments:
[variablelist
[[=exit-status=] [In addition to the output the result status of the executed command is returned as a second element of the result.]]
[[=no-output=] [Don't capture the output of the command. Instead an empty ("") string value is returned in place of the output.]]
]
Because the Perforce/Jambase defines a =Shell= rule which hides the builtin =COMMAND= can be used as an alias for =SHELL=.
[endsect]

View File

@@ -98,10 +98,14 @@ load_builtins()
bind_builtin( "ECHO" ,
builtin_echo, 0, 0 ) ) );
duplicate_rule( "exit" ,
duplicate_rule( "Exit" ,
bind_builtin( "EXIT" ,
builtin_exit, 0, 0 ) ) );
{
char * args[] = { "message", "*", ":", "result-value", "?", 0 };
duplicate_rule( "exit" ,
duplicate_rule( "Exit" ,
bind_builtin( "EXIT" ,
builtin_exit, 0, args ) ) );
}
{
char * args[] = { "directories", "*", ":", "patterns", "*", ":", "case-insensitive", "?", 0 };
@@ -327,7 +331,7 @@ load_builtins()
# endif
{
char * args[] = { "command", 0 };
char * args[] = { "command", ":", "*", 0 };
bind_builtin( "SHELL",
builtin_shell, 0, args );
bind_builtin( "COMMAND",
@@ -496,13 +500,20 @@ builtin_echo(
LIST *
builtin_exit(
PARSE *parse,
FRAME *frame )
PARSE *parse,
FRAME *frame )
{
list_print( lol_get( frame->args, 0 ) );
printf( "\n" );
exit( EXITBAD ); /* yeech */
return L0;
list_print( lol_get( frame->args, 0 ) );
printf( "\n" );
if ( lol_get( frame->args, 1 ) )
{
exit ( atoi( lol_get( frame->args, 1 )->string ) );
}
else
{
exit( EXITBAD ); /* yeech */
}
return L0;
}
/*
@@ -1663,31 +1674,64 @@ bjam_import_rule(PyObject* self, PyObject* args)
LIST *builtin_shell( PARSE *parse, FRAME *frame )
{
LIST* arg = lol_get( frame->args, 0 );
LIST* result = 0;
LIST* command = lol_get( frame->args, 0 );
LIST* result = 0;
string s;
int ret;
char buffer[1024];
FILE *p = NULL;
int exit_status = -1;
int exit_status_opt = 0;
int no_output_opt = 0;
/* Process the variable args options. */
{
int a = 1;
LIST * arg = lol_get( frame->args, a );
while ( arg )
{
if ( strcmp("exit-status", arg->string) == 0 )
{
exit_status_opt = 1;
}
else if ( strcmp("no-output", arg->string) == 0 )
{
no_output_opt = 1;
}
arg = lol_get( frame->args, ++a );
}
}
string_new( &s );
fflush(NULL);
p = popen(arg->string, "r");
p = popen(command->string, "r");
if ( p == NULL )
return L0;
while ( (ret = fread(buffer, sizeof(char), sizeof(buffer)-1, p)) > 0 )
{
buffer[ret] = 0;
string_append( &s, buffer );
if ( ! no_output_opt )
{
string_append( &s, buffer );
}
}
pclose(p);
exit_status = pclose(p);
/* The command output is returned first. */
result = list_new( L0, newstr(s.value) );
string_free(&s);
/* The command exit result next. */
if ( exit_status_opt )
{
sprintf (buffer, "%d", exit_status);
result = list_new( result, newstr( buffer ) );
}
return result;
}

View File

@@ -0,0 +1,46 @@
#~ Copyright 2006 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)
ECHO --- Testing SHELL builtin... ;
local result = 0 ;
local rule error ( message * )
{
local b = [ BACKTRACE ] ;
ECHO "$(b[9]):$(b[10]): error:" $(message) ;
}
local rule assert ( expected + : test ? : obtained + )
{
test ?= "(==)" ;
local r = 0 ;
if $(test) = "(==)" && $(expected) != $(obtained)
{
error [FAILED] '$(expected)' $(test) '$(obtained)' ;
r = 1 ;
}
else if $(test) = "(!=)" && $(expected) = $(obtained)
{
error [FAILED] '$(expected)' $(test) '$(obtained)' ;
r = 1 ;
}
result = [ CALC $(result) + $(r) ] ;
}
#~ ---------------------------------------------------------------------
local c = "date" ;
if $(NT) { c = "PATH" ; }
assert "" : (!=) : [ SHELL $(c) ] ;
assert "" : (==) : [ SHELL $(c) : no-output ] ;
assert "" 0 : (!=) : [ SHELL $(c) : exit-status ] ;
assert "" 0 : (==) : [ SHELL $(c) : no-output : exit-status ] ;
assert "" : (!=) : [ COMMAND $(c) ] ;
assert "" : (==) : [ COMMAND $(c) : no-output ] ;
assert "" 0 : (!=) : [ COMMAND $(c) : exit-status ] ;
assert "" 0 : (==) : [ COMMAND $(c) : no-output : exit-status ] ;
#~ ---------------------------------------------------------------------
EXIT --- Complete : $(result) ;

View File

@@ -0,0 +1,11 @@
@ECHO OFF
REM ~ Copyright 2006 Rene Rivera.
REM ~ Distributed under the Boost Software License, Version 1.0.
REM ~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
set BJAM=..\..\build\jam_src\bin.ntx86\bjam
@ECHO ON
%BJAM% -f builtin_shell.jam

View File

@@ -0,0 +1,9 @@
#!/bin/sh
#~ Copyright 2002-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)
BJAM=`ls -1 ../../build/jam_src/bin.*/bjam`
${BJAM} -f builtin_shell.jam

View File

@@ -98,10 +98,14 @@ load_builtins()
bind_builtin( "ECHO" ,
builtin_echo, 0, 0 ) ) );
duplicate_rule( "exit" ,
duplicate_rule( "Exit" ,
bind_builtin( "EXIT" ,
builtin_exit, 0, 0 ) ) );
{
char * args[] = { "message", "*", ":", "result-value", "?", 0 };
duplicate_rule( "exit" ,
duplicate_rule( "Exit" ,
bind_builtin( "EXIT" ,
builtin_exit, 0, args ) ) );
}
{
char * args[] = { "directories", "*", ":", "patterns", "*", ":", "case-insensitive", "?", 0 };
@@ -327,7 +331,7 @@ load_builtins()
# endif
{
char * args[] = { "command", 0 };
char * args[] = { "command", ":", "*", 0 };
bind_builtin( "SHELL",
builtin_shell, 0, args );
bind_builtin( "COMMAND",
@@ -496,13 +500,20 @@ builtin_echo(
LIST *
builtin_exit(
PARSE *parse,
FRAME *frame )
PARSE *parse,
FRAME *frame )
{
list_print( lol_get( frame->args, 0 ) );
printf( "\n" );
exit( EXITBAD ); /* yeech */
return L0;
list_print( lol_get( frame->args, 0 ) );
printf( "\n" );
if ( lol_get( frame->args, 1 ) )
{
exit ( atoi( lol_get( frame->args, 1 )->string ) );
}
else
{
exit( EXITBAD ); /* yeech */
}
return L0;
}
/*
@@ -1663,31 +1674,64 @@ bjam_import_rule(PyObject* self, PyObject* args)
LIST *builtin_shell( PARSE *parse, FRAME *frame )
{
LIST* arg = lol_get( frame->args, 0 );
LIST* result = 0;
LIST* command = lol_get( frame->args, 0 );
LIST* result = 0;
string s;
int ret;
char buffer[1024];
FILE *p = NULL;
int exit_status = -1;
int exit_status_opt = 0;
int no_output_opt = 0;
/* Process the variable args options. */
{
int a = 1;
LIST * arg = lol_get( frame->args, a );
while ( arg )
{
if ( strcmp("exit-status", arg->string) == 0 )
{
exit_status_opt = 1;
}
else if ( strcmp("no-output", arg->string) == 0 )
{
no_output_opt = 1;
}
arg = lol_get( frame->args, ++a );
}
}
string_new( &s );
fflush(NULL);
p = popen(arg->string, "r");
p = popen(command->string, "r");
if ( p == NULL )
return L0;
while ( (ret = fread(buffer, sizeof(char), sizeof(buffer)-1, p)) > 0 )
{
buffer[ret] = 0;
string_append( &s, buffer );
if ( ! no_output_opt )
{
string_append( &s, buffer );
}
}
pclose(p);
exit_status = pclose(p);
/* The command output is returned first. */
result = list_new( L0, newstr(s.value) );
string_free(&s);
/* The command exit result next. */
if ( exit_status_opt )
{
sprintf (buffer, "%d", exit_status);
result = list_new( result, newstr( buffer ) );
}
return result;
}