From 2b7535bb518c909e2a6ce1352df93c5c6bbc084b Mon Sep 17 00:00:00 2001 From: axel Date: Mon, 23 Apr 2007 07:19:47 +1000 Subject: [PATCH] Make the . (source) builtin able to read commands from stdin darcs-hash:20070422211947-ac50b-b8d33d81fcef5e0b7e76a8d2a9f0bcbcf3ac67b7.gz --- builtin.c | 104 ++++++++++++++++++++++++--------------------- doc_src/source.txt | 9 +++- 2 files changed, 63 insertions(+), 50 deletions(-) diff --git a/builtin.c b/builtin.c index 2e84e8ed7..02360d4ee 100644 --- a/builtin.c +++ b/builtin.c @@ -2257,36 +2257,42 @@ static int builtin_source( wchar_t ** argv ) argc = builtin_count_args( argv ); - if( argc < 2 ) - { - sb_printf( sb_err, _( L"%ls: Expected at least one argument, got %d\n" ), argv[0], argc ); - builtin_print_help( argv[0], sb_err ); - return STATUS_BUILTIN_ERROR; - } + wchar_t *fn; + const wchar_t *fn_intern; + - if( wstat(argv[1], &buf) == -1 ) - { - builtin_wperror( L"stat" ); - return STATUS_BUILTIN_ERROR; - } - if( !S_ISREG(buf.st_mode) ) + if( argc < 2 || (wcscmp( argv[1], L"-" ) == 0) ) { - sb_printf( sb_err, _( L"%ls: '%ls' is not a file\n" ), argv[0], argv[1] ); - builtin_print_help( argv[0], sb_err ); - - return STATUS_BUILTIN_ERROR; - } - if( ( fd = wopen( argv[1], O_RDONLY ) ) == -1 ) - { - builtin_wperror( L"open" ); - res = STATUS_BUILTIN_ERROR; + fn = L"-"; + fn_intern = fn; + fd = dup(builtin_stdin); } else { - wchar_t *fn = wrealpath( argv[1], 0 ); - const wchar_t *fn_intern; - + + if( wstat(argv[1], &buf) == -1 ) + { + builtin_wperror( L"stat" ); + return STATUS_BUILTIN_ERROR; + } + + if( !S_ISREG(buf.st_mode) ) + { + sb_printf( sb_err, _( L"%ls: '%ls' is not a file\n" ), argv[0], argv[1] ); + builtin_print_help( argv[0], sb_err ); + + return STATUS_BUILTIN_ERROR; + } + + if( ( fd = wopen( argv[1], O_RDONLY ) ) == -1 ) + { + builtin_wperror( L"open" ); + return STATUS_BUILTIN_ERROR; + } + + fn = wrealpath( argv[1], 0 ); + if( !fn ) { fn_intern = intern( argv[1] ); @@ -2296,32 +2302,34 @@ static int builtin_source( wchar_t ** argv ) fn_intern = intern(fn); free( fn ); } - - parser_push_block( SOURCE ); - reader_push_current_filename( fn_intern ); - current_block->param1.source_dest = fn_intern; - - parse_util_set_argv( argv+2, 0); - - res = reader_read( fd ); - - parser_pop_block(); - if( res ) - { - sb_printf( sb_err, - _( L"%ls: Error while reading file '%ls'\n" ), - argv[0], - argv[1] ); - } - - /* - Do not close fd after calling reader_read. reader_read - automatically closes it before calling eval. - */ - - reader_pop_current_filename(); } + + parser_push_block( SOURCE ); + reader_push_current_filename( fn_intern ); + + current_block->param1.source_dest = fn_intern; + + parse_util_set_argv( (argc>2)?(argv+2):(argv+1), 0); + + res = reader_read( fd ); + + parser_pop_block(); + + if( res ) + { + sb_printf( sb_err, + _( L"%ls: Error while reading file '%ls'\n" ), + argv[0], + argv[1] ); + } + + /* + Do not close fd after calling reader_read. reader_read + automatically closes it before calling eval. + */ + + reader_pop_current_filename(); return res; } diff --git a/doc_src/source.txt b/doc_src/source.txt index 8cbc9c889..54d1e3428 100644 --- a/doc_src/source.txt +++ b/doc_src/source.txt @@ -1,7 +1,7 @@ \section source . - evaluate contents of file. \subsection source-synopsis Synopsis -. FILENAME +. FILENAME [ARGUMENTS...] \subsection source-description Description @@ -9,7 +9,12 @@ Evaluates the commands of the specified file in the current shell. This is different from starting a new process to perform the commands (i.e. fish < FILENAME) since the commands will be evaluated by the current shell, which means that changes in -environment variables, etc., will remain. +environment variables, etc., will remain. If additional arguments are +specified after the file name, they will be inserted into the $argv +variable. + +If no file is specified, or if the file name '-' is used, stdin will +be read. \subsection source-example Example