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:
@@ -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]
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
46
historic/jam/test/builtin_shell.jam
Normal file
46
historic/jam/test/builtin_shell.jam
Normal 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) ;
|
||||
11
historic/jam/test/test.bat
Normal file
11
historic/jam/test/test.bat
Normal 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
|
||||
9
historic/jam/test/test.sh
Normal file
9
historic/jam/test/test.sh
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user