diff options
Diffstat (limited to 'builtin.cpp')
-rw-r--r-- | builtin.cpp | 5932 |
1 files changed, 2966 insertions, 2966 deletions
diff --git a/builtin.cpp b/builtin.cpp index 21d16402..707d0cd8 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -1,19 +1,19 @@ /** \file builtin.c - Functions for executing builtin functions. + Functions for executing builtin functions. - How to add a new builtin function: + How to add a new builtin function: - 1). Create a function in builtin.c with the following signature: + 1). Create a function in builtin.c with the following signature: - <tt>static int builtin_NAME( parser_t &parser, wchar_t ** args )</tt> + <tt>static int builtin_NAME( parser_t &parser, wchar_t ** args )</tt> - where NAME is the name of the builtin, and args is a zero-terminated list of arguments. + where NAME is the name of the builtin, and args is a zero-terminated list of arguments. - 2). Add a line like { L"NAME", &builtin_NAME, N_(L"Bla bla bla") }, to the builtin_data_t variable. The description is used by the completion system. Note that this array is sorted! + 2). Add a line like { L"NAME", &builtin_NAME, N_(L"Bla bla bla") }, to the builtin_data_t variable. The description is used by the completion system. Note that this array is sorted! - 3). Create a file doc_src/NAME.txt, containing the manual for the builtin in Doxygen-format. Check the other builtin manuals for proper syntax. + 3). Create a file doc_src/NAME.txt, containing the manual for the builtin in Doxygen-format. Check the other builtin manuals for proper syntax. - 4). Use 'darcs add doc_src/NAME.txt' to start tracking changes to the documentation file. + 4). Use 'darcs add doc_src/NAME.txt' to start tracking changes to the documentation file. */ @@ -82,23 +82,23 @@ #define FG_MSG _( L"Send job %d, '%ls' to foreground\n" ) /** - Datastructure to describe a builtin. + Datastructure to describe a builtin. */ struct builtin_data_t { - /** - Name of the builtin - */ - const wchar_t *name; - /** - Function pointer tothe builtin implementation - */ - int (*func)(parser_t &parser, wchar_t **argv); - /** - Description of what the builtin does - */ - const wchar_t *desc; - + /** + Name of the builtin + */ + const wchar_t *name; + /** + Function pointer tothe builtin implementation + */ + int (*func)(parser_t &parser, wchar_t **argv); + /** + Description of what the builtin does + */ + const wchar_t *desc; + bool operator<(const wcstring &) const; bool operator<(const builtin_data_t *) const; }; @@ -162,35 +162,35 @@ static const io_chain_t *real_io; */ static int builtin_count_args( wchar_t **argv ) { - int argc = 1; - while( argv[argc] != 0 ) - { - argc++; - } - return argc; + int argc = 1; + while( argv[argc] != 0 ) + { + argc++; + } + return argc; } -/** - This function works like wperror, but it prints its result into - the sb_err string instead of to stderr. Used by the builtin - commands. +/** + This function works like wperror, but it prints its result into + the sb_err string instead of to stderr. Used by the builtin + commands. */ static void builtin_wperror( const wchar_t *s) { - if( s != 0 ) - { + if( s != 0 ) + { stderr_buffer.append(s); stderr_buffer.append(L": "); - } - char *err = strerror( errno ); - wchar_t *werr = str2wcs( err ); - if( werr ) - { + } + char *err = strerror( errno ); + wchar_t *werr = str2wcs( err ); + if( werr ) + { stderr_buffer.append(werr); stderr_buffer.push_back(L'\n'); - free( werr ); - } + free( werr ); + } } /** @@ -198,12 +198,12 @@ static void builtin_wperror( const wchar_t *s) */ static int count_char( const wchar_t *str, wchar_t c ) { - int res = 0; - for( ; *str; str++ ) - { - res += (*str==c); - } - return res; + int res = 0; + for( ; *str; str++ ) + { + res += (*str==c); + } + return res; } wcstring builtin_help_get( parser_t &parser, const wchar_t *name ) @@ -212,15 +212,15 @@ wcstring builtin_help_get( parser_t &parser, const wchar_t *name ) wcstring out; const wcstring name_esc = escape_string(name, 1); const wcstring cmd = format_string(L"__fish_print_help %ls", name_esc.c_str()); - if( exec_subshell( cmd, lst ) >= 0 ) - { - for( size_t i=0; i<lst.size(); i++ ) - { + if( exec_subshell( cmd, lst ) >= 0 ) + { + for( size_t i=0; i<lst.size(); i++ ) + { out.append(lst.at(i)); out.push_back(L'\n'); - } - } - return out; + } + } + return out; } /** @@ -231,116 +231,116 @@ wcstring builtin_help_get( parser_t &parser, const wchar_t *name ) message is about to be printed to an interactive screen, it may be shortened to fit the screen. - + */ static void builtin_print_help( parser_t &parser, const wchar_t *cmd, wcstring &b ) { - - int is_short = 0; - - if( &b == &stderr_buffer ) - { + + int is_short = 0; + + if( &b == &stderr_buffer ) + { stderr_buffer.append(parser.current_line()); - } - - const wcstring h = builtin_help_get( parser, cmd ); - - if( !h.size()) - return; - - wchar_t *str = wcsdup( h.c_str() ); - if( str ) - { - - if( &b == &stderr_buffer ) - { - - /* - Interactive mode help to screen - only print synopsis if - the rest won't fit - */ - - int screen_height, lines; - - screen_height = common_get_height(); - lines = count_char( str, L'\n' ); - if( !get_is_interactive() || (lines > 2*screen_height/3) ) - { - wchar_t *pos; - int cut=0; - int i; - - is_short = 1; - - /* - First move down 4 lines - */ - - pos = str; - for( i=0; (i<4) && pos && *pos; i++ ) - { - pos = wcschr( pos+1, L'\n' ); - } - - if( pos && *pos ) - { - - /* - Then find the next empty line - */ - for( ; *pos; pos++ ) - { - if( *pos == L'\n' ) - { - wchar_t *pos2; - int is_empty = 1; - - for( pos2 = pos+1; *pos2; pos2++ ) - { - if( *pos2 == L'\n' ) - break; - - if( *pos2 != L'\t' && *pos2 !=L' ' ) - { - is_empty = 0; - break; - } - } - if( is_empty ) - { - /* - And cut it - */ - *(pos2+1)=L'\0'; - cut = 1; - break; - } - } - } - } - - /* - We did not find a good place to cut message to - shorten it - so we make sure we don't print - anything. - */ - if( !cut ) - { - *str = 0; - } - - } - } - + } + + const wcstring h = builtin_help_get( parser, cmd ); + + if( !h.size()) + return; + + wchar_t *str = wcsdup( h.c_str() ); + if( str ) + { + + if( &b == &stderr_buffer ) + { + + /* + Interactive mode help to screen - only print synopsis if + the rest won't fit + */ + + int screen_height, lines; + + screen_height = common_get_height(); + lines = count_char( str, L'\n' ); + if( !get_is_interactive() || (lines > 2*screen_height/3) ) + { + wchar_t *pos; + int cut=0; + int i; + + is_short = 1; + + /* + First move down 4 lines + */ + + pos = str; + for( i=0; (i<4) && pos && *pos; i++ ) + { + pos = wcschr( pos+1, L'\n' ); + } + + if( pos && *pos ) + { + + /* + Then find the next empty line + */ + for( ; *pos; pos++ ) + { + if( *pos == L'\n' ) + { + wchar_t *pos2; + int is_empty = 1; + + for( pos2 = pos+1; *pos2; pos2++ ) + { + if( *pos2 == L'\n' ) + break; + + if( *pos2 != L'\t' && *pos2 !=L' ' ) + { + is_empty = 0; + break; + } + } + if( is_empty ) + { + /* + And cut it + */ + *(pos2+1)=L'\0'; + cut = 1; + break; + } + } + } + } + + /* + We did not find a good place to cut message to + shorten it - so we make sure we don't print + anything. + */ + if( !cut ) + { + *str = 0; + } + + } + } + b.append(str); - if( is_short ) - { + if( is_short ) + { append_format(b, _(L"%ls: Type 'help %ls' for related documentation\n\n"), cmd, cmd); - } - - free( str ); - } + } + + free( str ); + } } /** @@ -349,7 +349,7 @@ static void builtin_print_help( parser_t &parser, const wchar_t *cmd, wcstring & static void builtin_unknown_option( parser_t &parser, const wchar_t *cmd, const wchar_t *opt ) { append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, cmd, opt); - builtin_print_help( parser, cmd, stderr_buffer ); + builtin_print_help( parser, cmd, stderr_buffer ); } /** @@ -358,7 +358,7 @@ static void builtin_unknown_option( parser_t &parser, const wchar_t *cmd, const static void builtin_missing_argument( parser_t &parser, const wchar_t *cmd, const wchar_t *opt ) { append_format(stderr_buffer, BUILTIN_ERR_MISSING, cmd, opt); - builtin_print_help( parser, cmd, stderr_buffer ); + builtin_print_help( parser, cmd, stderr_buffer ); } /* @@ -396,29 +396,29 @@ int builtin_test( parser_t &parser, wchar_t **argv ); */ static void builtin_bind_list() { - size_t i; + size_t i; wcstring_list_t lst; - input_mapping_get_names( lst ); - - for( i=0; i<lst.size(); i++ ) - { - wcstring seq = lst.at(i); - + input_mapping_get_names( lst ); + + for( i=0; i<lst.size(); i++ ) + { + wcstring seq = lst.at(i); + wcstring ecmd; input_mapping_get(seq, ecmd); - ecmd = escape_string(ecmd, 1); - - wcstring tname; - if( input_terminfo_get_name(seq, tname) ) - { - append_format(stdout_buffer, L"bind -k %ls %ls\n", tname.c_str(), ecmd.c_str() ); - } - else - { - const wcstring eseq = escape_string( seq, 1 ); - append_format(stdout_buffer, L"bind %ls %ls\n", eseq.c_str(), ecmd.c_str() ); - } - } + ecmd = escape_string(ecmd, 1); + + wcstring tname; + if( input_terminfo_get_name(seq, tname) ) + { + append_format(stdout_buffer, L"bind -k %ls %ls\n", tname.c_str(), ecmd.c_str() ); + } + else + { + const wcstring eseq = escape_string( seq, 1 ); + append_format(stdout_buffer, L"bind %ls %ls\n", eseq.c_str(), ecmd.c_str() ); + } + } } /** @@ -430,13 +430,13 @@ static void builtin_bind_list() */ static void builtin_bind_key_names( int all ) { - const wcstring_list_t names = input_terminfo_get_names(!all); - for( size_t i=0; i<names.size(); i++ ) - { + const wcstring_list_t names = input_terminfo_get_names(!all); + for( size_t i=0; i<names.size(); i++ ) + { const wcstring &name = names.at(i); - - append_format(stdout_buffer, L"%ls\n", name.c_str() ); - } + + append_format(stdout_buffer, L"%ls\n", name.c_str() ); + } } /** @@ -446,12 +446,12 @@ static void builtin_bind_key_names( int all ) static void builtin_bind_function_names() { wcstring_list_t names = input_function_get_names(); - - for( size_t i=0; i<names.size(); i++ ) - { - const wchar_t *seq = names.at(i).c_str(); - append_format(stdout_buffer, L"%ls\n", seq ); - } + + for( size_t i=0; i<names.size(); i++ ) + { + const wchar_t *seq = names.at(i).c_str(); + append_format(stdout_buffer, L"%ls\n", seq ); + } } /** @@ -460,49 +460,49 @@ static void builtin_bind_function_names() static int builtin_bind_add( wchar_t *seq, wchar_t *cmd, int terminfo ) { - if( terminfo ) - { - const wchar_t *seq2 = input_terminfo_get_sequence( seq ); - if( seq2 ) - { - input_mapping_add( seq2, cmd ); - } - else - { - switch( errno ) - { - - case ENOENT: - { - append_format(stderr_buffer, _(L"%ls: No key with name '%ls' found\n"), L"bind", seq ); - break; - } - - case EILSEQ: - { - append_format(stderr_buffer, _(L"%ls: Key with name '%ls' does not have any mapping\n"), L"bind", seq ); - break; - } - - default: - { - append_format(stderr_buffer, _(L"%ls: Unknown error trying to bind to key named '%ls'\n"), L"bind", seq ); - break; - } - - } - - return 1; - } - - } - else - { - input_mapping_add( seq, cmd ); - } - - return 0; - + if( terminfo ) + { + const wchar_t *seq2 = input_terminfo_get_sequence( seq ); + if( seq2 ) + { + input_mapping_add( seq2, cmd ); + } + else + { + switch( errno ) + { + + case ENOENT: + { + append_format(stderr_buffer, _(L"%ls: No key with name '%ls' found\n"), L"bind", seq ); + break; + } + + case EILSEQ: + { + append_format(stderr_buffer, _(L"%ls: Key with name '%ls' does not have any mapping\n"), L"bind", seq ); + break; + } + + default: + { + append_format(stderr_buffer, _(L"%ls: Unknown error trying to bind to key named '%ls'\n"), L"bind", seq ); + break; + } + + } + + return 1; + } + + } + else + { + input_mapping_add( seq, cmd ); + } + + return 0; + } /** @@ -513,27 +513,27 @@ static int builtin_bind_add( wchar_t *seq, wchar_t *cmd, int terminfo ) */ static void builtin_bind_erase( wchar_t **seq, int all ) { - if( all ) - { - size_t i; - wcstring_list_t lst; - input_mapping_get_names( lst ); - - for( i=0; i<lst.size(); i++ ) - { - input_mapping_erase( lst.at(i).c_str() ); - } - - } - else - { - while( *seq ) - { - input_mapping_erase( *seq++ ); - } - - } - + if( all ) + { + size_t i; + wcstring_list_t lst; + input_mapping_get_names( lst ); + + for( i=0; i<lst.size(); i++ ) + { + input_mapping_erase( lst.at(i).c_str() ); + } + + } + else + { + while( *seq ) + { + input_mapping_erase( *seq++ ); + } + + } + } @@ -543,173 +543,173 @@ static void builtin_bind_erase( wchar_t **seq, int all ) static int builtin_bind( parser_t &parser, wchar_t **argv ) { - enum - { - BIND_INSERT, - BIND_ERASE, - BIND_KEY_NAMES, - BIND_FUNCTION_NAMES - } - ; - - int argc=builtin_count_args( argv ); - int mode = BIND_INSERT; - int res = STATUS_BUILTIN_OK; - int all = 0; - - int use_terminfo = 0; - - woptind=0; - - static const struct woption - long_options[] = - { - { - L"all", no_argument, 0, 'a' - } - , - { - L"erase", no_argument, 0, 'e' - } - , - { - L"function-names", no_argument, 0, 'f' - } - , - { - L"help", no_argument, 0, 'h' - } - , - { - L"key", no_argument, 0, 'k' - } - , - { - L"key-names", no_argument, 0, 'K' - } - , - { - 0, 0, 0, 0 - } - } - ; - - while( 1 ) - { - int opt_index = 0; - int opt = wgetopt_long( argc, - argv, - L"aehkKf", - long_options, - &opt_index ); - - if( opt == -1 ) - break; - - switch( opt ) - { - case 0: - if(long_options[opt_index].flag != 0) - break; - append_format(stderr_buffer, - BUILTIN_ERR_UNKNOWN, - argv[0], - long_options[opt_index].name ); - builtin_print_help( parser, argv[0], stderr_buffer ); - - return STATUS_BUILTIN_ERROR; - - case 'a': - all = 1; - break; - - case 'e': - mode = BIND_ERASE; - break; - - - case 'h': - builtin_print_help( parser, argv[0], stdout_buffer ); - return STATUS_BUILTIN_OK; - - case 'k': - use_terminfo = 1; - break; - - case 'K': - mode = BIND_KEY_NAMES; - break; - - case 'f': - mode = BIND_FUNCTION_NAMES; - break; - - case '?': - builtin_unknown_option( parser, argv[0], argv[woptind-1] ); - return STATUS_BUILTIN_ERROR; - - } - - } - - switch( mode ) - { - - case BIND_ERASE: - { - builtin_bind_erase( &argv[woptind], all); - break; - } - - case BIND_INSERT: - { - switch( argc-woptind ) - { - case 0: - { - builtin_bind_list(); - break; - } - - case 2: - { - builtin_bind_add(argv[woptind], argv[woptind+1], use_terminfo ); - break; - } - - default: - { - res = STATUS_BUILTIN_ERROR; - append_format(stderr_buffer, _(L"%ls: Expected zero or two parameters, got %d"), argv[0], argc-woptind ); - break; - } - } - break; - } - - case BIND_KEY_NAMES: - { - builtin_bind_key_names( all ); - break; - } - - - case BIND_FUNCTION_NAMES: - { - builtin_bind_function_names(); - break; - } - - - default: - { - res = STATUS_BUILTIN_ERROR; - append_format(stderr_buffer, _(L"%ls: Invalid state\n"), argv[0] ); - break; - } - } - - return res; + enum + { + BIND_INSERT, + BIND_ERASE, + BIND_KEY_NAMES, + BIND_FUNCTION_NAMES + } + ; + + int argc=builtin_count_args( argv ); + int mode = BIND_INSERT; + int res = STATUS_BUILTIN_OK; + int all = 0; + + int use_terminfo = 0; + + woptind=0; + + static const struct woption + long_options[] = + { + { + L"all", no_argument, 0, 'a' + } + , + { + L"erase", no_argument, 0, 'e' + } + , + { + L"function-names", no_argument, 0, 'f' + } + , + { + L"help", no_argument, 0, 'h' + } + , + { + L"key", no_argument, 0, 'k' + } + , + { + L"key-names", no_argument, 0, 'K' + } + , + { + 0, 0, 0, 0 + } + } + ; + + while( 1 ) + { + int opt_index = 0; + int opt = wgetopt_long( argc, + argv, + L"aehkKf", + long_options, + &opt_index ); + + if( opt == -1 ) + break; + + switch( opt ) + { + case 0: + if(long_options[opt_index].flag != 0) + break; + append_format(stderr_buffer, + BUILTIN_ERR_UNKNOWN, + argv[0], + long_options[opt_index].name ); + builtin_print_help( parser, argv[0], stderr_buffer ); + + return STATUS_BUILTIN_ERROR; + + case 'a': + all = 1; + break; + + case 'e': + mode = BIND_ERASE; + break; + + + case 'h': + builtin_print_help( parser, argv[0], stdout_buffer ); + return STATUS_BUILTIN_OK; + + case 'k': + use_terminfo = 1; + break; + + case 'K': + mode = BIND_KEY_NAMES; + break; + + case 'f': + mode = BIND_FUNCTION_NAMES; + break; + + case '?': + builtin_unknown_option( parser, argv[0], argv[woptind-1] ); + return STATUS_BUILTIN_ERROR; + + } + + } + + switch( mode ) + { + + case BIND_ERASE: + { + builtin_bind_erase( &argv[woptind], all); + break; + } + + case BIND_INSERT: + { + switch( argc-woptind ) + { + case 0: + { + builtin_bind_list(); + break; + } + + case 2: + { + builtin_bind_add(argv[woptind], argv[woptind+1], use_terminfo ); + break; + } + + default: + { + res = STATUS_BUILTIN_ERROR; + append_format(stderr_buffer, _(L"%ls: Expected zero or two parameters, got %d"), argv[0], argc-woptind ); + break; + } + } + break; + } + + case BIND_KEY_NAMES: + { + builtin_bind_key_names( all ); + break; + } + + + case BIND_FUNCTION_NAMES: + { + builtin_bind_function_names(); + break; + } + + + default: + { + res = STATUS_BUILTIN_ERROR; + append_format(stderr_buffer, _(L"%ls: Invalid state\n"), argv[0] ); + break; + } + } + + return res; } /** @@ -717,147 +717,147 @@ static int builtin_bind( parser_t &parser, wchar_t **argv ) */ static int builtin_block( parser_t &parser, wchar_t **argv ) { - enum - { - UNSET, - GLOBAL, - LOCAL, - } - ; - - int scope=UNSET; - int erase = 0; - int argc=builtin_count_args( argv ); - int type = (1<<EVENT_ANY); - - woptind=0; - - static const struct woption - long_options[] = - { - { - L"erase", no_argument, 0, 'e' - } - , - { - L"local", no_argument, 0, 'l' - } - , - { - L"global", no_argument, 0, 'g' - } - , - { - L"help", no_argument, 0, 'h' - } - , - { - 0, 0, 0, 0 - } - } - ; - - while( 1 ) - { - int opt_index = 0; - - int opt = wgetopt_long( argc, - argv, - L"elgh", - long_options, - &opt_index ); - if( opt == -1 ) - break; - - switch( opt ) - { - case 0: - if(long_options[opt_index].flag != 0) - break; - append_format(stderr_buffer, - BUILTIN_ERR_UNKNOWN, - argv[0], - long_options[opt_index].name ); - builtin_print_help( parser, argv[0], stderr_buffer ); - - return STATUS_BUILTIN_ERROR; - case 'h': - builtin_print_help( parser, argv[0], stdout_buffer ); - return STATUS_BUILTIN_OK; - - case 'g': - scope = GLOBAL; - break; - - case 'l': - scope = LOCAL; - break; - - case 'e': - erase = 1; - break; - - case '?': - builtin_unknown_option( parser, argv[0], argv[woptind-1] ); - return STATUS_BUILTIN_ERROR; - - } - - } - - if( erase ) - { - if( scope != UNSET ) - { - append_format(stderr_buffer, _( L"%ls: Can not specify scope when removing block\n" ), argv[0] ); - return STATUS_BUILTIN_ERROR; - } - + enum + { + UNSET, + GLOBAL, + LOCAL, + } + ; + + int scope=UNSET; + int erase = 0; + int argc=builtin_count_args( argv ); + int type = (1<<EVENT_ANY); + + woptind=0; + + static const struct woption + long_options[] = + { + { + L"erase", no_argument, 0, 'e' + } + , + { + L"local", no_argument, 0, 'l' + } + , + { + L"global", no_argument, 0, 'g' + } + , + { + L"help", no_argument, 0, 'h' + } + , + { + 0, 0, 0, 0 + } + } + ; + + while( 1 ) + { + int opt_index = 0; + + int opt = wgetopt_long( argc, + argv, + L"elgh", + long_options, + &opt_index ); + if( opt == -1 ) + break; + + switch( opt ) + { + case 0: + if(long_options[opt_index].flag != 0) + break; + append_format(stderr_buffer, + BUILTIN_ERR_UNKNOWN, + argv[0], + long_options[opt_index].name ); + builtin_print_help( parser, argv[0], stderr_buffer ); + + return STATUS_BUILTIN_ERROR; + case 'h': + builtin_print_help( parser, argv[0], stdout_buffer ); + return STATUS_BUILTIN_OK; + + case 'g': + scope = GLOBAL; + break; + + case 'l': + scope = LOCAL; + break; + + case 'e': + erase = 1; + break; + + case '?': + builtin_unknown_option( parser, argv[0], argv[woptind-1] ); + return STATUS_BUILTIN_ERROR; + + } + + } + + if( erase ) + { + if( scope != UNSET ) + { + append_format(stderr_buffer, _( L"%ls: Can not specify scope when removing block\n" ), argv[0] ); + return STATUS_BUILTIN_ERROR; + } + if (parser.global_event_blocks.empty()) - { - append_format(stderr_buffer, _( L"%ls: No blocks defined\n" ), argv[0] ); - return STATUS_BUILTIN_ERROR; - } - parser.global_event_blocks.pop_front(); - } - else - { - block_t *block=parser.current_block; + { + append_format(stderr_buffer, _( L"%ls: No blocks defined\n" ), argv[0] ); + return STATUS_BUILTIN_ERROR; + } + parser.global_event_blocks.pop_front(); + } + else + { + block_t *block=parser.current_block; event_blockage_t eb = {}; - eb.typemask = type; - - switch( scope ) - { - case LOCAL: - { - if( !block->outer ) - block=0; - break; - } - case GLOBAL: - { - block=0; - } - case UNSET: - { - while( block && - block->type() != FUNCTION_CALL && - block->type() != FUNCTION_CALL_NO_SHADOW ) - block = block->outer; - } - } - if( block ) - { + eb.typemask = type; + + switch( scope ) + { + case LOCAL: + { + if( !block->outer ) + block=0; + break; + } + case GLOBAL: + { + block=0; + } + case UNSET: + { + while( block && + block->type() != FUNCTION_CALL && + block->type() != FUNCTION_CALL_NO_SHADOW ) + block = block->outer; + } + } + if( block ) + { block->event_blocks.push_front(eb); - } - else - { + } + else + { parser.global_event_blocks.push_front(eb); - } - } + } + } - return STATUS_BUILTIN_OK; + return STATUS_BUILTIN_OK; } @@ -869,83 +869,83 @@ static int builtin_block( parser_t &parser, wchar_t **argv ) */ static int builtin_builtin( parser_t &parser, wchar_t **argv ) { - int argc=builtin_count_args( argv ); - int list=0; - - woptind=0; - - static const struct woption - long_options[] = - { - { - L"names", no_argument, 0, 'n' - } - , - { - L"help", no_argument, 0, 'h' - } - , - { - 0, 0, 0, 0 - } - } - ; - - while( 1 ) - { - int opt_index = 0; - - int opt = wgetopt_long( argc, - argv, - L"nh", - long_options, - &opt_index ); - if( opt == -1 ) - break; - - switch( opt ) - { - case 0: - if(long_options[opt_index].flag != 0) - break; + int argc=builtin_count_args( argv ); + int list=0; + + woptind=0; + + static const struct woption + long_options[] = + { + { + L"names", no_argument, 0, 'n' + } + , + { + L"help", no_argument, 0, 'h' + } + , + { + 0, 0, 0, 0 + } + } + ; + + while( 1 ) + { + int opt_index = 0; + + int opt = wgetopt_long( argc, + argv, + L"nh", + long_options, + &opt_index ); + if( opt == -1 ) + break; + + switch( opt ) + { + case 0: + if(long_options[opt_index].flag != 0) + break; append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], stderr_buffer ); + builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - case 'h': - builtin_print_help( parser, argv[0], stdout_buffer ); - return STATUS_BUILTIN_OK; + return STATUS_BUILTIN_ERROR; + case 'h': + builtin_print_help( parser, argv[0], stdout_buffer ); + return STATUS_BUILTIN_OK; - case 'n': - list=1; - break; + case 'n': + list=1; + break; - case '?': - builtin_unknown_option( parser, argv[0], argv[woptind-1] ); - return STATUS_BUILTIN_ERROR; + case '?': + builtin_unknown_option( parser, argv[0], argv[woptind-1] ); + return STATUS_BUILTIN_ERROR; - } + } - } + } - if( list ) - { + if( list ) + { wcstring_list_t names = builtin_get_names(); sort(names.begin(), names.end()); - - for( size_t i=0; i<names.size(); i++ ) - { - const wchar_t *el = names.at(i).c_str(); - - stdout_buffer.append(el); + + for( size_t i=0; i<names.size(); i++ ) + { + const wchar_t *el = names.at(i).c_str(); + + stdout_buffer.append(el); stdout_buffer.append(L"\n"); - } - } - return STATUS_BUILTIN_OK; + } + } + return STATUS_BUILTIN_OK; } /** @@ -953,68 +953,68 @@ static int builtin_builtin( parser_t &parser, wchar_t **argv ) */ static int builtin_emit( parser_t &parser, wchar_t **argv ) { - int argc=builtin_count_args( argv ); - - woptind=0; - - static const struct woption - long_options[] = - { - { - L"help", no_argument, 0, 'h' - } - , - { - 0, 0, 0, 0 - } - } - ; - - while( 1 ) - { - int opt_index = 0; - - int opt = wgetopt_long( argc, - argv, - L"h", - long_options, - &opt_index ); - if( opt == -1 ) - break; - - switch( opt ) - { - case 0: - if(long_options[opt_index].flag != 0) - break; + int argc=builtin_count_args( argv ); + + woptind=0; + + static const struct woption + long_options[] = + { + { + L"help", no_argument, 0, 'h' + } + , + { + 0, 0, 0, 0 + } + } + ; + + while( 1 ) + { + int opt_index = 0; + + int opt = wgetopt_long( argc, + argv, + L"h", + long_options, + &opt_index ); + if( opt == -1 ) + break; + + switch( opt ) + { + case 0: + if(long_options[opt_index].flag != 0) + break; append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + + case 'h': + builtin_print_help( parser, argv[0], stdout_buffer ); + return STATUS_BUILTIN_OK; + + case '?': + builtin_unknown_option( parser, argv[0], argv[woptind-1] ); + return STATUS_BUILTIN_ERROR; + + } - case 'h': - builtin_print_help( parser, argv[0], stdout_buffer ); - return STATUS_BUILTIN_OK; + } - case '?': - builtin_unknown_option( parser, argv[0], argv[woptind-1] ); - return STATUS_BUILTIN_ERROR; + for (; woptind < argc; woptind++ ) + { + event_fire_generic( argv[woptind] ); + } - } + return STATUS_BUILTIN_OK; - } - for (; woptind < argc; woptind++ ) - { - event_fire_generic( argv[woptind] ); - } - return STATUS_BUILTIN_OK; - - - } @@ -1025,58 +1025,58 @@ static int builtin_emit( parser_t &parser, wchar_t **argv ) */ static int builtin_generic( parser_t &parser, wchar_t **argv ) { - int argc=builtin_count_args( argv ); - woptind=0; - - static const struct woption - long_options[] = - { - { - L"help", no_argument, 0, 'h' - } - , - { - 0, 0, 0, 0 - } - } - ; - - while( 1 ) - { - int opt_index = 0; - - int opt = wgetopt_long( argc, - argv, - L"h", - long_options, - &opt_index ); - if( opt == -1 ) - break; - - switch( opt ) - { - case 0: - if(long_options[opt_index].flag != 0) - break; + int argc=builtin_count_args( argv ); + woptind=0; + + static const struct woption + long_options[] = + { + { + L"help", no_argument, 0, 'h' + } + , + { + 0, 0, 0, 0 + } + } + ; + + while( 1 ) + { + int opt_index = 0; + + int opt = wgetopt_long( argc, + argv, + L"h", + long_options, + &opt_index ); + if( opt == -1 ) + break; + + switch( opt ) + { + case 0: + if(long_options[opt_index].flag != 0) + break; append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; - case 'h': - builtin_print_help( parser, argv[0], stdout_buffer ); - return STATUS_BUILTIN_OK; + case 'h': + builtin_print_help( parser, argv[0], stdout_buffer ); + return STATUS_BUILTIN_OK; - case '?': - builtin_unknown_option( parser, argv[0], argv[woptind-1] ); - return STATUS_BUILTIN_ERROR; + case '?': + builtin_unknown_option( parser, argv[0], argv[woptind-1] ); + return STATUS_BUILTIN_ERROR; - } + } - } - return STATUS_BUILTIN_ERROR; + } + return STATUS_BUILTIN_ERROR; } /** @@ -1086,20 +1086,20 @@ static int builtin_generic( parser_t &parser, wchar_t **argv ) static void functions_def( const wcstring &name, wcstring &out ) { CHECK( ! name.empty(), ); - + wcstring desc, def; function_get_desc(name, &desc); function_get_definition(name, &def); - event_t search(EVENT_ANY); + event_t search(EVENT_ANY); - search.function_name = name; + search.function_name = name; - std::vector<event_t *> ev; - event_get( &search, &ev ); + std::vector<event_t *> ev; + event_get( &search, &ev ); out.append(L"function "); - + /* Typically we prefer to specify the function name first, e.g. "function foo --description bar" But If the function name starts with a -, we'll need to output it after all the options. */ bool defer_function_name = (name.at(0) == L'-'); @@ -1107,82 +1107,82 @@ static void functions_def( const wcstring &name, wcstring &out ) out.append(name); } - if (! desc.empty()) - { + if (! desc.empty()) + { wcstring esc_desc = escape_string(desc, true); - out.append(L" --description "); + out.append(L" --description "); out.append(esc_desc); - } - - if( !function_get_shadows( name ) ) - { - out.append(L" --no-scope-shadowing" ); - } - - for( size_t i=0; i<ev.size(); i++ ) - { - event_t *next = ev.at(i); - switch( next->type ) - { - case EVENT_SIGNAL: - { - append_format( out, L" --on-signal %ls", sig2wcs( next->param1.signal ) ); - break; - } - - case EVENT_VARIABLE: - { - append_format( out, L" --on-variable %ls", next->str_param1.c_str() ); - break; - } - - case EVENT_EXIT: - { - if( next->param1.pid > 0 ) - append_format( out, L" --on-process-exit %d", next->param1.pid ); - else - append_format( out, L" --on-job-exit %d", -next->param1.pid ); - break; - } - - case EVENT_JOB_ID: - { - const job_t *j = job_get( next->param1.job_id ); - if( j ) - append_format( out, L" --on-job-exit %d", j->pgid ); - break; - } - - case EVENT_GENERIC: - { - append_format( out, L" --on-event %ls", next->str_param1.c_str() ); - break; - } - - } - - } - - + } + + if( !function_get_shadows( name ) ) + { + out.append(L" --no-scope-shadowing" ); + } + + for( size_t i=0; i<ev.size(); i++ ) + { + event_t *next = ev.at(i); + switch( next->type ) + { + case EVENT_SIGNAL: + { + append_format( out, L" --on-signal %ls", sig2wcs( next->param1.signal ) ); + break; + } + + case EVENT_VARIABLE: + { + append_format( out, L" --on-variable %ls", next->str_param1.c_str() ); + break; + } + + case EVENT_EXIT: + { + if( next->param1.pid > 0 ) + append_format( out, L" --on-process-exit %d", next->param1.pid ); + else + append_format( out, L" --on-job-exit %d", -next->param1.pid ); + break; + } + + case EVENT_JOB_ID: + { + const job_t *j = job_get( next->param1.job_id ); + if( j ) + append_format( out, L" --on-job-exit %d", j->pgid ); + break; + } + + case EVENT_GENERIC: + { + append_format( out, L" --on-event %ls", next->str_param1.c_str() ); + break; + } + + } + + } + + wcstring_list_t named = function_get_named_arguments( name ); - if( named.size() > 0 ) - { - append_format( out, L" --argument" ); - for( size_t i=0; i < named.size(); i++ ) - { - append_format( out, L" %ls", named.at(i).c_str() ); - } - } + if( named.size() > 0 ) + { + append_format( out, L" --argument" ); + for( size_t i=0; i < named.size(); i++ ) + { + append_format( out, L" %ls", named.at(i).c_str() ); + } + } /* Output the function name if we deferred it */ if ( defer_function_name ){ out.append(L" -- "); out.append(name); } - + /* This forced tab is sort of crummy - not all functions start with a tab */ append_format( out, L"\n\t%ls", def.c_str()); - + /* Append a newline before the 'end', unless there already is one there */ if (! string_suffixes_string(L"\n", def)) { out.push_back(L'\n'); @@ -1196,271 +1196,271 @@ static void functions_def( const wcstring &name, wcstring &out ) */ static int builtin_functions( parser_t &parser, wchar_t **argv ) { - int i; - int erase=0; - wchar_t *desc=0; - - int argc=builtin_count_args( argv ); - int list=0; - int show_hidden=0; - int res = STATUS_BUILTIN_OK; - int query = 0; - int copy = 0; - - woptind=0; - - static const struct woption - long_options[] = - { - { - L"erase", no_argument, 0, 'e' - } - , - { - L"description", required_argument, 0, 'd' - } - , - { - L"names", no_argument, 0, 'n' - } - , - { - L"all", no_argument, 0, 'a' - } - , - { - L"help", no_argument, 0, 'h' - } - , - { - L"query", no_argument, 0, 'q' - } - , - { - L"copy", no_argument, 0, 'c' - } - , - { - 0, 0, 0, 0 - } - } - ; - - while( 1 ) - { - int opt_index = 0; - - int opt = wgetopt_long( argc, - argv, - L"ed:nahqc", - long_options, - &opt_index ); - if( opt == -1 ) - break; - - switch( opt ) - { - case 0: - if(long_options[opt_index].flag != 0) - break; + int i; + int erase=0; + wchar_t *desc=0; + + int argc=builtin_count_args( argv ); + int list=0; + int show_hidden=0; + int res = STATUS_BUILTIN_OK; + int query = 0; + int copy = 0; + + woptind=0; + + static const struct woption + long_options[] = + { + { + L"erase", no_argument, 0, 'e' + } + , + { + L"description", required_argument, 0, 'd' + } + , + { + L"names", no_argument, 0, 'n' + } + , + { + L"all", no_argument, 0, 'a' + } + , + { + L"help", no_argument, 0, 'h' + } + , + { + L"query", no_argument, 0, 'q' + } + , + { + L"copy", no_argument, 0, 'c' + } + , + { + 0, 0, 0, 0 + } + } + ; + + while( 1 ) + { + int opt_index = 0; + + int opt = wgetopt_long( argc, + argv, + L"ed:nahqc", + long_options, + &opt_index ); + if( opt == -1 ) + break; + + switch( opt ) + { + case 0: + if(long_options[opt_index].flag != 0) + break; append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], stderr_buffer ); - - - return STATUS_BUILTIN_ERROR; - - case 'e': - erase=1; - break; - - case 'd': - desc=woptarg; - break; - - case 'n': - list=1; - break; - - case 'a': - show_hidden=1; - break; - - case 'h': - builtin_print_help( parser, argv[0], stdout_buffer ); - return STATUS_BUILTIN_OK; - - case 'q': - query = 1; - break; - - case 'c': - copy = 1; - break; - - case '?': - builtin_unknown_option( parser, argv[0], argv[woptind-1] ); - return STATUS_BUILTIN_ERROR; - - } - - } - - /* - Erase, desc, query, copy and list are mutually exclusive - */ - if( (erase + (!!desc) + list + query + copy) > 1 ) - { - append_format(stderr_buffer, - _( L"%ls: Invalid combination of options\n" ), - argv[0] ); - - builtin_print_help( parser, argv[0], stderr_buffer ); - - return STATUS_BUILTIN_ERROR; - } - - if( erase ) - { - int i; - for( i=woptind; i<argc; i++ ) - function_remove( argv[i] ); - return STATUS_BUILTIN_OK; - } - else if( desc ) - { - wchar_t *func; - - if( argc-woptind != 1 ) - { - append_format(stderr_buffer, - _( L"%ls: Expected exactly one function name\n" ), - argv[0] ); - builtin_print_help( parser, argv[0], stderr_buffer ); - - return STATUS_BUILTIN_ERROR; - } - func = argv[woptind]; - if( !function_exists( func ) ) - { - append_format(stderr_buffer, - _( L"%ls: Function '%ls' does not exist\n" ), - argv[0], - func ); - - builtin_print_help( parser, argv[0], stderr_buffer ); - - return STATUS_BUILTIN_ERROR; - } - - function_set_desc( func, desc ); - - return STATUS_BUILTIN_OK; - } - else if( list || (argc==woptind)) - { - int is_screen = !builtin_out_redirect && isatty(1); + builtin_print_help( parser, argv[0], stderr_buffer ); + + + return STATUS_BUILTIN_ERROR; + + case 'e': + erase=1; + break; + + case 'd': + desc=woptarg; + break; + + case 'n': + list=1; + break; + + case 'a': + show_hidden=1; + break; + + case 'h': + builtin_print_help( parser, argv[0], stdout_buffer ); + return STATUS_BUILTIN_OK; + + case 'q': + query = 1; + break; + + case 'c': + copy = 1; + break; + + case '?': + builtin_unknown_option( parser, argv[0], argv[woptind-1] ); + return STATUS_BUILTIN_ERROR; + + } + + } + + /* + Erase, desc, query, copy and list are mutually exclusive + */ + if( (erase + (!!desc) + list + query + copy) > 1 ) + { + append_format(stderr_buffer, + _( L"%ls: Invalid combination of options\n" ), + argv[0] ); + + builtin_print_help( parser, argv[0], stderr_buffer ); + + return STATUS_BUILTIN_ERROR; + } + + if( erase ) + { + int i; + for( i=woptind; i<argc; i++ ) + function_remove( argv[i] ); + return STATUS_BUILTIN_OK; + } + else if( desc ) + { + wchar_t *func; + + if( argc-woptind != 1 ) + { + append_format(stderr_buffer, + _( L"%ls: Expected exactly one function name\n" ), + argv[0] ); + builtin_print_help( parser, argv[0], stderr_buffer ); + + return STATUS_BUILTIN_ERROR; + } + func = argv[woptind]; + if( !function_exists( func ) ) + { + append_format(stderr_buffer, + _( L"%ls: Function '%ls' does not exist\n" ), + argv[0], + func ); + + builtin_print_help( parser, argv[0], stderr_buffer ); + + return STATUS_BUILTIN_ERROR; + } + + function_set_desc( func, desc ); + + return STATUS_BUILTIN_OK; + } + else if( list || (argc==woptind)) + { + int is_screen = !builtin_out_redirect && isatty(1); size_t i; - wcstring_list_t names = function_get_names( show_hidden ); + wcstring_list_t names = function_get_names( show_hidden ); std::sort(names.begin(), names.end()); - if( is_screen ) - { + if( is_screen ) + { wcstring buff; - for( i=0; i<names.size(); i++ ) - { + for( i=0; i<names.size(); i++ ) + { buff.append(names.at(i)); buff.append(L", "); - } - - write_screen( buff, stdout_buffer ); - } - else - { - for( i=0; i<names.size(); i++ ) - { - stdout_buffer.append(names.at(i).c_str()); + } + + write_screen( buff, stdout_buffer ); + } + else + { + for( i=0; i<names.size(); i++ ) + { + stdout_buffer.append(names.at(i).c_str()); stdout_buffer.append(L"\n"); - } - } - - return STATUS_BUILTIN_OK; - } - else if( copy ) - { - wcstring current_func; - wcstring new_func; - - if( argc-woptind != 2 ) - { - append_format(stderr_buffer, - _( L"%ls: Expected exactly two names (current function name, and new function name)\n" ), - argv[0] ); - builtin_print_help ( parser, argv[0], stderr_buffer ); - - return STATUS_BUILTIN_ERROR; - } - current_func = argv[woptind]; - new_func = argv[woptind+1]; - - if( !function_exists( current_func ) ) - { - append_format(stderr_buffer, - _( L"%ls: Function '%ls' does not exist\n" ), - argv[0], - current_func.c_str() ); - builtin_print_help( parser, argv[0], stderr_buffer ); - - return STATUS_BUILTIN_ERROR; - } - - if( (wcsfuncname( new_func.c_str() ) != 0) || parser_keywords_is_reserved( new_func ) ) - { - append_format(stderr_buffer, - _( L"%ls: Illegal function name '%ls'\n"), - argv[0], - new_func.c_str()); - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - - // keep things simple: don't allow existing names to be copy targets. - if( function_exists( new_func ) ) - { - append_format(stderr_buffer, - _( L"%ls: Function '%ls' already exists. Cannot create copy '%ls'\n" ), - argv[0], - new_func.c_str(), - current_func.c_str() ); - builtin_print_help( parser, argv[0], stderr_buffer ); - - return STATUS_BUILTIN_ERROR; - } - - if( function_copy( current_func, new_func ) ) - return STATUS_BUILTIN_OK; - return STATUS_BUILTIN_ERROR; - } - - for( i=woptind; i<argc; i++ ) - { - if( !function_exists( argv[i] ) ) - res++; - else - { - if( !query ) - { - if( i != woptind) - stdout_buffer.append( L"\n" ); - - functions_def( argv[i], stdout_buffer ); - } - } - } - - return res; + } + } + + return STATUS_BUILTIN_OK; + } + else if( copy ) + { + wcstring current_func; + wcstring new_func; + + if( argc-woptind != 2 ) + { + append_format(stderr_buffer, + _( L"%ls: Expected exactly two names (current function name, and new function name)\n" ), + argv[0] ); + builtin_print_help ( parser, argv[0], stderr_buffer ); + + return STATUS_BUILTIN_ERROR; + } + current_func = argv[woptind]; + new_func = argv[woptind+1]; + + if( !function_exists( current_func ) ) + { + append_format(stderr_buffer, + _( L"%ls: Function '%ls' does not exist\n" ), + argv[0], + current_func.c_str() ); + builtin_print_help( parser, argv[0], stderr_buffer ); + + return STATUS_BUILTIN_ERROR; + } + + if( (wcsfuncname( new_func.c_str() ) != 0) || parser_keywords_is_reserved( new_func ) ) + { + append_format(stderr_buffer, + _( L"%ls: Illegal function name '%ls'\n"), + argv[0], + new_func.c_str()); + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + + // keep things simple: don't allow existing names to be copy targets. + if( function_exists( new_func ) ) + { + append_format(stderr_buffer, + _( L"%ls: Function '%ls' already exists. Cannot create copy '%ls'\n" ), + argv[0], + new_func.c_str(), + current_func.c_str() ); + builtin_print_help( parser, argv[0], stderr_buffer ); + + return STATUS_BUILTIN_ERROR; + } + + if( function_copy( current_func, new_func ) ) + return STATUS_BUILTIN_OK; + return STATUS_BUILTIN_ERROR; + } + + for( i=woptind; i<argc; i++ ) + { + if( !function_exists( argv[i] ) ) + res++; + else + { + if( !query ) + { + if( i != woptind) + stdout_buffer.append( L"\n" ); + + functions_def( argv[i], stdout_buffer ); + } + } + } + + return res; } static unsigned int builtin_echo_digit(wchar_t wc, unsigned int base) @@ -1496,7 +1496,7 @@ static unsigned int builtin_echo_digit(wchar_t wc, unsigned int base) /* Parse a numeric escape sequence in str, returning whether we succeeded. Also return the number of characters consumed and the resulting value. Supported escape sequences: - + \0nnn: octal value, zero to three digits \nnn: octal value, one to three digits \xhh: hex value, one to two digits @@ -1506,7 +1506,7 @@ static bool builtin_echo_parse_numeric_sequence(const wchar_t *str, size_t *cons bool success = false; unsigned char val = 0; //resulting character unsigned int start = 0; //the first character of the numeric part of the sequence - + unsigned int base = 0, max_digits = 0; if (builtin_echo_digit(str[0], 8) != UINT_MAX) { @@ -1522,11 +1522,11 @@ static bool builtin_echo_parse_numeric_sequence(const wchar_t *str, size_t *cons // Hex escape base = 16; max_digits = 2; - + // Skip the x start = 1; } - + if (base != 0) { unsigned int idx; @@ -1536,7 +1536,7 @@ static bool builtin_echo_parse_numeric_sequence(const wchar_t *str, size_t *cons if (digit == UINT_MAX) break; val = val * base + digit; } - + // We succeeded if we consumed at least one digit if (idx > start) { @@ -1558,7 +1558,7 @@ static int builtin_echo( parser_t &parser, wchar_t **argv ) /* Skip first arg */ if (! *argv++) return STATUS_BUILTIN_ERROR; - + /* Process options */ bool print_newline = true, print_spaces = true, interpret_special_chars = false; while (*argv) { @@ -1575,10 +1575,10 @@ static int builtin_echo( parser_t &parser, wchar_t **argv ) } argv++; } - + /* The special character \c can be used to indicate no more output */ bool continue_output = true; - + for (size_t idx = 0; continue_output && argv[idx] != NULL; idx++) { if (print_spaces && idx > 0) @@ -1608,9 +1608,9 @@ static int builtin_echo( parser_t &parser, wchar_t **argv ) case L't': wc = L'\t'; break; case L'v': wc = L'\v'; break; case L'\\': wc = L'\\'; break; - + case L'c': wc = 0; continue_output = false; break; - + default: { /* Octal and hex escape sequences */ @@ -1629,10 +1629,10 @@ static int builtin_echo( parser_t &parser, wchar_t **argv ) break; } } - + /* Skip over characters that were part of this escape sequence (but not the backslash, which will be handled by the loop increment */ j += consumed; - + if (continue_output) stdout_buffer.push_back(wc); } @@ -1646,8 +1646,8 @@ static int builtin_echo( parser_t &parser, wchar_t **argv ) /** The pwd builtin. We don't respect -P to resolve symbolic links because we try to always resolve them. */ static int builtin_pwd( parser_t &parser, wchar_t **argv ) { - wchar_t dir_path[4096]; - wchar_t *res = wgetcwd( dir_path, 4096 ); + wchar_t dir_path[4096]; + wchar_t *res = wgetcwd( dir_path, 4096 ); if (res == NULL) { return STATUS_BUILTIN_ERROR; } else { @@ -1663,348 +1663,348 @@ static int builtin_pwd( parser_t &parser, wchar_t **argv ) */ static int builtin_function( parser_t &parser, wchar_t **argv ) { - int argc = builtin_count_args( argv ); - int res=STATUS_BUILTIN_OK; - wchar_t *desc=0; - std::vector<event_t> events; - + int argc = builtin_count_args( argv ); + int res=STATUS_BUILTIN_OK; + wchar_t *desc=0; + std::vector<event_t> events; + std::auto_ptr<wcstring_list_t> named_arguments(NULL); - wchar_t *name = 0; - bool shadows = true; - - woptind=0; + wchar_t *name = 0; + bool shadows = true; + + woptind=0; function_def_block_t * const fdb = new function_def_block_t(); - parser.push_block( fdb ); - - static const struct woption - long_options[] = - { - { - L"description", required_argument, 0, 'd' - } - , - { - L"on-signal", required_argument, 0, 's' - } - , - { - L"on-job-exit", required_argument, 0, 'j' - } - , - { - L"on-process-exit", required_argument, 0, 'p' - } - , - { - L"on-variable", required_argument, 0, 'v' - } - , - { - L"on-event", required_argument, 0, 'e' - } - , - { - L"help", no_argument, 0, 'h' - } - , - { - L"argument-names", no_argument, 0, 'a' - } - , - { - L"no-scope-shadowing", no_argument, 0, 'S' - } - , - { - 0, 0, 0, 0 - } - } - ; - - while( 1 && (!res ) ) - { - int opt_index = 0; - - int opt = wgetopt_long( argc, - argv, - L"d:s:j:p:v:e:haS", - long_options, - &opt_index ); - if( opt == -1 ) - break; - - switch( opt ) - { - case 0: - if(long_options[opt_index].flag != 0) - break; + parser.push_block( fdb ); + + static const struct woption + long_options[] = + { + { + L"description", required_argument, 0, 'd' + } + , + { + L"on-signal", required_argument, 0, 's' + } + , + { + L"on-job-exit", required_argument, 0, 'j' + } + , + { + L"on-process-exit", required_argument, 0, 'p' + } + , + { + L"on-variable", required_argument, 0, 'v' + } + , + { + L"on-event", required_argument, 0, 'e' + } + , + { + L"help", no_argument, 0, 'h' + } + , + { + L"argument-names", no_argument, 0, 'a' + } + , + { + L"no-scope-shadowing", no_argument, 0, 'S' + } + , + { + 0, 0, 0, 0 + } + } + ; + + while( 1 && (!res ) ) + { + int opt_index = 0; + + int opt = wgetopt_long( argc, + argv, + L"d:s:j:p:v:e:haS", + long_options, + &opt_index ); + if( opt == -1 ) + break; + + switch( opt ) + { + case 0: + if(long_options[opt_index].flag != 0) + break; append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - res = 1; - break; - - case 'd': - desc=woptarg; - break; - - case 's': - { - int sig = wcs2sig( woptarg ); - - if( sig < 0 ) - { - append_format(stderr_buffer, - _( L"%ls: Unknown signal '%ls'\n" ), - argv[0], - woptarg ); - res=1; - break; - } + res = 1; + break; + + case 'd': + desc=woptarg; + break; + + case 's': + { + int sig = wcs2sig( woptarg ); + + if( sig < 0 ) + { + append_format(stderr_buffer, + _( L"%ls: Unknown signal '%ls'\n" ), + argv[0], + woptarg ); + res=1; + break; + } events.push_back(event_t::signal_event(sig)); - break; - } - - case 'v': - { - if( wcsvarname( woptarg ) ) - { - append_format(stderr_buffer, - _( L"%ls: Invalid variable name '%ls'\n" ), - argv[0], - woptarg ); - res=STATUS_BUILTIN_ERROR; - break; - } + break; + } + + case 'v': + { + if( wcsvarname( woptarg ) ) + { + append_format(stderr_buffer, + _( L"%ls: Invalid variable name '%ls'\n" ), + argv[0], + woptarg ); + res=STATUS_BUILTIN_ERROR; + break; + } events.push_back(event_t::variable_event(woptarg)); - break; - } + break; + } - case 'e': - { + case 'e': + { events.push_back(event_t::generic_event(woptarg)); - break; - } - - case 'j': - case 'p': - { - pid_t pid; - wchar_t *end; + break; + } + + case 'j': + case 'p': + { + pid_t pid; + wchar_t *end; event_t e(EVENT_ANY); - - if( ( opt == 'j' ) && - ( wcscasecmp( woptarg, L"caller" ) == 0 ) ) - { - int job_id = -1; - - if( is_subshell ) - { - block_t *b = parser.current_block; - - while( b && (b->type() != SUBST) ) - b = b->outer; - - if( b ) - { - b=b->outer; - } - if( b->job ) - { - job_id = b->job->job_id; - } - } - - if( job_id == -1 ) - { - append_format(stderr_buffer, - _( L"%ls: Cannot find calling job for event handler\n" ), - argv[0] ); - res=1; - } - else - { - e.type = EVENT_JOB_ID; - e.param1.job_id = job_id; - } - - } - else - { - errno = 0; - pid = fish_wcstoi( woptarg, &end, 10 ); - if( errno || !end || *end ) - { - append_format(stderr_buffer, - _( L"%ls: Invalid process id %ls\n" ), - argv[0], - woptarg ); - res=1; - break; - } - - - e.type = EVENT_EXIT; - e.param1.pid = (opt=='j'?-1:1)*abs(pid); - } - if( res ) - { + + if( ( opt == 'j' ) && + ( wcscasecmp( woptarg, L"caller" ) == 0 ) ) + { + int job_id = -1; + + if( is_subshell ) + { + block_t *b = parser.current_block; + + while( b && (b->type() != SUBST) ) + b = b->outer; + + if( b ) + { + b=b->outer; + } + if( b->job ) + { + job_id = b->job->job_id; + } + } + + if( job_id == -1 ) + { + append_format(stderr_buffer, + _( L"%ls: Cannot find calling job for event handler\n" ), + argv[0] ); + res=1; + } + else + { + e.type = EVENT_JOB_ID; + e.param1.job_id = job_id; + } + + } + else + { + errno = 0; + pid = fish_wcstoi( woptarg, &end, 10 ); + if( errno || !end || *end ) + { + append_format(stderr_buffer, + _( L"%ls: Invalid process id %ls\n" ), + argv[0], + woptarg ); + res=1; + break; + } + + + e.type = EVENT_EXIT; + e.param1.pid = (opt=='j'?-1:1)*abs(pid); + } + if( res ) + { /* nothing */ - } - else - { + } + else + { events.push_back(e); - } - break; - } - - case 'a': - if( named_arguments.get() == NULL ) - named_arguments.reset(new wcstring_list_t); - break; - - case 'S': - shadows = 0; - break; - - case 'h': - parser.pop_block(); - parser.push_block( new fake_block_t() ); - builtin_print_help( parser, argv[0], stdout_buffer ); - return STATUS_BUILTIN_OK; - - case '?': - builtin_unknown_option( parser, argv[0], argv[woptind-1] ); - res = 1; - break; - - } - - } - - if( !res ) - { - - if( argc == woptind ) - { - append_format(stderr_buffer, - _( L"%ls: Expected function name\n" ), - argv[0] ); - res=1; - } - else if( wcsfuncname( argv[woptind] ) ) - { - append_format(stderr_buffer, - _( L"%ls: Illegal function name '%ls'\n" ), - argv[0], - argv[woptind] ); - - res=1; - } - else if( parser_keywords_is_reserved(argv[woptind] ) ) - { - - append_format(stderr_buffer, - _( L"%ls: The name '%ls' is reserved,\nand can not be used as a function name\n" ), - argv[0], - argv[woptind] ); - - res=1; - } - else - { - - name = argv[woptind++]; - - if( named_arguments.get() ) - { - while( woptind < argc ) - { - if( wcsvarname( argv[woptind] ) ) - { - append_format(stderr_buffer, - _( L"%ls: Invalid variable name '%ls'\n" ), - argv[0], - argv[woptind] ); - res = STATUS_BUILTIN_ERROR; - break; - } - + } + break; + } + + case 'a': + if( named_arguments.get() == NULL ) + named_arguments.reset(new wcstring_list_t); + break; + + case 'S': + shadows = 0; + break; + + case 'h': + parser.pop_block(); + parser.push_block( new fake_block_t() ); + builtin_print_help( parser, argv[0], stdout_buffer ); + return STATUS_BUILTIN_OK; + + case '?': + builtin_unknown_option( parser, argv[0], argv[woptind-1] ); + res = 1; + break; + + } + + } + + if( !res ) + { + + if( argc == woptind ) + { + append_format(stderr_buffer, + _( L"%ls: Expected function name\n" ), + argv[0] ); + res=1; + } + else if( wcsfuncname( argv[woptind] ) ) + { + append_format(stderr_buffer, + _( L"%ls: Illegal function name '%ls'\n" ), + argv[0], + argv[woptind] ); + + res=1; + } + else if( parser_keywords_is_reserved(argv[woptind] ) ) + { + + append_format(stderr_buffer, + _( L"%ls: The name '%ls' is reserved,\nand can not be used as a function name\n" ), + argv[0], + argv[woptind] ); + + res=1; + } + else + { + + name = argv[woptind++]; + + if( named_arguments.get() ) + { + while( woptind < argc ) + { + if( wcsvarname( argv[woptind] ) ) + { + append_format(stderr_buffer, + _( L"%ls: Invalid variable name '%ls'\n" ), + argv[0], + argv[woptind] ); + res = STATUS_BUILTIN_ERROR; + break; + } + named_arguments->push_back(argv[woptind++]); - } - } - else if( woptind != argc ) - { - append_format(stderr_buffer, - _( L"%ls: Expected one argument, got %d\n" ), - argv[0], - argc ); - res=1; - - } - } - } - - if( res ) - { - size_t i; - size_t chars=0; - - builtin_print_help( parser, argv[0], stderr_buffer ); - const wchar_t *cfa = _( L"Current functions are: " ); - stderr_buffer.append( cfa ); - chars += wcslen( cfa ); + } + } + else if( woptind != argc ) + { + append_format(stderr_buffer, + _( L"%ls: Expected one argument, got %d\n" ), + argv[0], + argc ); + res=1; + + } + } + } + + if( res ) + { + size_t i; + size_t chars=0; + + builtin_print_help( parser, argv[0], stderr_buffer ); + const wchar_t *cfa = _( L"Current functions are: " ); + stderr_buffer.append( cfa ); + chars += wcslen( cfa ); wcstring_list_t names = function_get_names(0); sort(names.begin(), names.end()); - for( i=0; i<names.size(); i++ ) - { - const wchar_t *nxt = names.at(i).c_str(); - size_t l = wcslen( nxt + 2 ); - if( chars+l > common_get_width() ) - { - chars = 0; + for( i=0; i<names.size(); i++ ) + { + const wchar_t *nxt = names.at(i).c_str(); + size_t l = wcslen( nxt + 2 ); + if( chars+l > common_get_width() ) + { + chars = 0; stderr_buffer.push_back(L'\n'); - } + } stderr_buffer.append(nxt); stderr_buffer.append(L" "); - } + } stderr_buffer.push_back(L'\n'); - parser.pop_block(); - parser.push_block( new fake_block_t() ); - } - else - { - function_data_t &d = fdb->function_data; - + parser.pop_block(); + parser.push_block( new fake_block_t() ); + } + else + { + function_data_t &d = fdb->function_data; + d.name = name; if (desc) d.description = desc; - d.events.swap(events); - d.shadows = shadows; + d.events.swap(events); + d.shadows = shadows; if (named_arguments.get()) d.named_arguments.swap(*named_arguments); - - for( size_t i=0; i<d.events.size(); i++ ) - { - event_t &e = d.events.at(i); - e.function_name = d.name; - } - } - - parser.current_block->tok_pos = parser.get_pos(); - parser.current_block->skip = 1; - - return STATUS_BUILTIN_OK; + + for( size_t i=0; i<d.events.size(); i++ ) + { + event_t &e = d.events.at(i); + e.function_name = d.name; + } + } + + parser.current_block->tok_pos = parser.get_pos(); + parser.current_block->skip = 1; + + return STATUS_BUILTIN_OK; } @@ -2013,113 +2013,113 @@ static int builtin_function( parser_t &parser, wchar_t **argv ) */ static int builtin_random( parser_t &parser, wchar_t **argv ) { - static int seeded=0; - static struct drand48_data seed_buffer; - - int argc = builtin_count_args( argv ); - - woptind=0; - - static const struct woption - long_options[] = - { - { - L"help", no_argument, 0, 'h' - } - , - { - 0, 0, 0, 0 - } - } - ; - - while( 1 ) - { - int opt_index = 0; - - int opt = wgetopt_long( argc, - argv, - L"h", - long_options, - &opt_index ); - if( opt == -1 ) - break; - - switch( opt ) - { - case 0: - if(long_options[opt_index].flag != 0) - break; + static int seeded=0; + static struct drand48_data seed_buffer; + + int argc = builtin_count_args( argv ); + + woptind=0; + + static const struct woption + long_options[] = + { + { + L"help", no_argument, 0, 'h' + } + , + { + 0, 0, 0, 0 + } + } + ; + + while( 1 ) + { + int opt_index = 0; + + int opt = wgetopt_long( argc, + argv, + L"h", + long_options, + &opt_index ); + if( opt == -1 ) + break; + + switch( opt ) + { + case 0: + if(long_options[opt_index].flag != 0) + break; append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], stderr_buffer ); - - return STATUS_BUILTIN_ERROR; - - case 'h': - builtin_print_help( parser, argv[0], stdout_buffer ); - break; - - case '?': - builtin_unknown_option( parser, argv[0], argv[woptind-1] ); - return STATUS_BUILTIN_ERROR; - - } - - } - - switch( argc-woptind ) - { - - case 0: - { - long res; - - if( !seeded ) - { - seeded=1; - srand48_r(time(0), &seed_buffer); - } - lrand48_r( &seed_buffer, &res ); - - append_format(stdout_buffer, L"%ld\n", labs(res%32767) ); - break; - } - - case 1: - { - long foo; - wchar_t *end=0; - - errno=0; - foo = wcstol( argv[woptind], &end, 10 ); - if( errno || *end ) - { - append_format(stderr_buffer, - _( L"%ls: Seed value '%ls' is not a valid number\n" ), - argv[0], - argv[woptind] ); - - return STATUS_BUILTIN_ERROR; - } - seeded=1; - srand48_r( foo, &seed_buffer); - break; - } - - default: - { - append_format(stderr_buffer, - _( L"%ls: Expected zero or one argument, got %d\n" ), - argv[0], - argc-woptind ); - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - } - return STATUS_BUILTIN_OK; + builtin_print_help( parser, argv[0], stderr_buffer ); + + return STATUS_BUILTIN_ERROR; + + case 'h': + builtin_print_help( parser, argv[0], stdout_buffer ); + break; + + case '?': + builtin_unknown_option( parser, argv[0], argv[woptind-1] ); + return STATUS_BUILTIN_ERROR; + + } + + } + + switch( argc-woptind ) + { + + case 0: + { + long res; + + if( !seeded ) + { + seeded=1; + srand48_r(time(0), &seed_buffer); + } + lrand48_r( &seed_buffer, &res ); + + append_format(stdout_buffer, L"%ld\n", labs(res%32767) ); + break; + } + + case 1: + { + long foo; + wchar_t *end=0; + + errno=0; + foo = wcstol( argv[woptind], &end, 10 ); + if( errno || *end ) + { + append_format(stderr_buffer, + _( L"%ls: Seed value '%ls' is not a valid number\n" ), + argv[0], + argv[woptind] ); + + return STATUS_BUILTIN_ERROR; + } + seeded=1; + srand48_r( foo, &seed_buffer); + break; + } + + default: + { + append_format(stderr_buffer, + _( L"%ls: Expected zero or one argument, got %d\n" ), + argv[0], + argc-woptind ); + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + } + return STATUS_BUILTIN_OK; } @@ -2128,308 +2128,308 @@ static int builtin_random( parser_t &parser, wchar_t **argv ) */ static int builtin_read( parser_t &parser, wchar_t **argv ) { - wchar_t *buff=0; - int i, argc = builtin_count_args( argv ); - int place = ENV_USER; - wchar_t *nxt; - const wchar_t *prompt = DEFAULT_READ_PROMPT; - const wchar_t *commandline = L""; - int exit_res=STATUS_BUILTIN_OK; - const wchar_t *mode_name = READ_MODE_NAME; - int shell = 0; - - woptind=0; - - while( 1 ) - { - static const struct woption - long_options[] = - { - { - L"export", no_argument, 0, 'x' - } - , - { - L"global", no_argument, 0, 'g' - } - , - { - L"local", no_argument, 0, 'l' - } - , - { - L"universal", no_argument, 0, 'U' - } - , - { - L"unexport", no_argument, 0, 'u' - } - , - { - L"prompt", required_argument, 0, 'p' - } - , - { - L"command", required_argument, 0, 'c' - } - , - { - L"mode-name", required_argument, 0, 'm' - } - , - { - L"shell", no_argument, 0, 's' - } - , - { - L"help", no_argument, 0, 'h' - } - , - { - 0, 0, 0, 0 - } - } - ; - - int opt_index = 0; - - int opt = wgetopt_long( argc, - argv, - L"xglUup:c:hm:s", - long_options, - &opt_index ); - if( opt == -1 ) - break; - - switch( opt ) - { - case 0: - if(long_options[opt_index].flag != 0) - break; + wchar_t *buff=0; + int i, argc = builtin_count_args( argv ); + int place = ENV_USER; + wchar_t *nxt; + const wchar_t *prompt = DEFAULT_READ_PROMPT; + const wchar_t *commandline = L""; + int exit_res=STATUS_BUILTIN_OK; + const wchar_t *mode_name = READ_MODE_NAME; + int shell = 0; + + woptind=0; + + while( 1 ) + { + static const struct woption + long_options[] = + { + { + L"export", no_argument, 0, 'x' + } + , + { + L"global", no_argument, 0, 'g' + } + , + { + L"local", no_argument, 0, 'l' + } + , + { + L"universal", no_argument, 0, 'U' + } + , + { + L"unexport", no_argument, 0, 'u' + } + , + { + L"prompt", required_argument, 0, 'p' + } + , + { + L"command", required_argument, 0, 'c' + } + , + { + L"mode-name", required_argument, 0, 'm' + } + , + { + L"shell", no_argument, 0, 's' + } + , + { + L"help", no_argument, 0, 'h' + } + , + { + 0, 0, 0, 0 + } + } + ; + + int opt_index = 0; + + int opt = wgetopt_long( argc, + argv, + L"xglUup:c:hm:s", + long_options, + &opt_index ); + if( opt == -1 ) + break; + + switch( opt ) + { + case 0: + if(long_options[opt_index].flag != 0) + break; append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], stderr_buffer ); - - return STATUS_BUILTIN_ERROR; - - case L'x': - place |= ENV_EXPORT; - break; - - case L'g': - place |= ENV_GLOBAL; - break; - - case L'l': - place |= ENV_LOCAL; - break; - - case L'U': - place |= ENV_UNIVERSAL; - break; - - case L'u': - place |= ENV_UNEXPORT; - break; - - case L'p': - prompt = woptarg; - break; - - case L'c': - commandline = woptarg; - break; - - case L'm': - mode_name = woptarg; - break; - - case 's': - shell = 1; - break; - - case 'h': - builtin_print_help( parser, argv[0], stdout_buffer ); - return STATUS_BUILTIN_OK; - - case L'?': - builtin_unknown_option( parser, argv[0], argv[woptind-1] ); - return STATUS_BUILTIN_ERROR; - } - - } - - if( ( place & ENV_UNEXPORT ) && ( place & ENV_EXPORT ) ) - { - append_format(stderr_buffer, - BUILTIN_ERR_EXPUNEXP, - argv[0] ); - - - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - - if( (place&ENV_LOCAL?1:0) + (place & ENV_GLOBAL?1:0) + (place & ENV_UNIVERSAL?1:0) > 1) - { - append_format(stderr_buffer, - BUILTIN_ERR_GLOCAL, - argv[0] ); - builtin_print_help( parser, argv[0], stderr_buffer ); - - return STATUS_BUILTIN_ERROR; - } - - /* - Verify all variable names - */ - for( i=woptind; i<argc; i++ ) - { - wchar_t *src; - - if( !wcslen( argv[i] ) ) - { - append_format(stderr_buffer, BUILTIN_ERR_VARNAME_ZERO, argv[0] ); - return STATUS_BUILTIN_ERROR; - } - - for( src=argv[i]; *src; src++ ) - { - if( (!iswalnum(*src)) && (*src != L'_' ) ) - { - append_format(stderr_buffer, BUILTIN_ERR_VARCHAR, argv[0], *src ); - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - } - - } - - /* - The call to reader_readline may change woptind, so we save it away here - */ - i=woptind; - - /* - Check if we should read interactively using \c reader_readline() - */ - if( isatty(0) && builtin_stdin == 0 ) - { - const wchar_t *line; - - reader_push( mode_name ); - reader_set_left_prompt( prompt ); - if( shell ) - { - reader_set_complete_function( &complete ); - reader_set_highlight_function( &highlight_shell ); - reader_set_test_function( &reader_shell_test ); - } - - reader_set_buffer( commandline, wcslen( commandline ) ); - proc_push_interactive( 1 ); - - event_fire_generic(L"fish_prompt"); - line = reader_readline( ); - proc_pop_interactive(); - if( line ) - { - buff = wcsdup( line ); - } - else - { - exit_res = STATUS_BUILTIN_ERROR; - } - reader_pop(); - } - else - { - int eof=0; - - wcstring sb; - - while( 1 ) - { - int finished=0; - - wchar_t res=0; - static mbstate_t state; - memset (&state, '\0', sizeof (state)); - - while( !finished ) - { - char b; - if( read_blocked( builtin_stdin, &b, 1 ) <= 0 ) - { - eof=1; - break; - } - - size_t sz = mbrtowc( &res, &b, 1, &state ); - - switch( sz ) - { - case (size_t)(-1): - memset (&state, '\0', sizeof (state)); - break; - - case (size_t)(-2): - break; - case 0: - eof=1; - finished = 1; - break; - - default: - finished=1; - break; - - } - } - - if( eof ) - break; - - if( res == L'\n' ) - break; - + builtin_print_help( parser, argv[0], stderr_buffer ); + + return STATUS_BUILTIN_ERROR; + + case L'x': + place |= ENV_EXPORT; + break; + + case L'g': + place |= ENV_GLOBAL; + break; + + case L'l': + place |= ENV_LOCAL; + break; + + case L'U': + place |= ENV_UNIVERSAL; + break; + + case L'u': + place |= ENV_UNEXPORT; + break; + + case L'p': + prompt = woptarg; + break; + + case L'c': + commandline = woptarg; + break; + + case L'm': + mode_name = woptarg; + break; + + case 's': + shell = 1; + break; + + case 'h': + builtin_print_help( parser, argv[0], stdout_buffer ); + return STATUS_BUILTIN_OK; + + case L'?': + builtin_unknown_option( parser, argv[0], argv[woptind-1] ); + return STATUS_BUILTIN_ERROR; + } + + } + + if( ( place & ENV_UNEXPORT ) && ( place & ENV_EXPORT ) ) + { + append_format(stderr_buffer, + BUILTIN_ERR_EXPUNEXP, + argv[0] ); + + + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + + if( (place&ENV_LOCAL?1:0) + (place & ENV_GLOBAL?1:0) + (place & ENV_UNIVERSAL?1:0) > 1) + { + append_format(stderr_buffer, + BUILTIN_ERR_GLOCAL, + argv[0] ); + builtin_print_help( parser, argv[0], stderr_buffer ); + + return STATUS_BUILTIN_ERROR; + } + + /* + Verify all variable names + */ + for( i=woptind; i<argc; i++ ) + { + wchar_t *src; + + if( !wcslen( argv[i] ) ) + { + append_format(stderr_buffer, BUILTIN_ERR_VARNAME_ZERO, argv[0] ); + return STATUS_BUILTIN_ERROR; + } + + for( src=argv[i]; *src; src++ ) + { + if( (!iswalnum(*src)) && (*src != L'_' ) ) + { + append_format(stderr_buffer, BUILTIN_ERR_VARCHAR, argv[0], *src ); + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + } + + } + + /* + The call to reader_readline may change woptind, so we save it away here + */ + i=woptind; + + /* + Check if we should read interactively using \c reader_readline() + */ + if( isatty(0) && builtin_stdin == 0 ) + { + const wchar_t *line; + + reader_push( mode_name ); + reader_set_left_prompt( prompt ); + if( shell ) + { + reader_set_complete_function( &complete ); + reader_set_highlight_function( &highlight_shell ); + reader_set_test_function( &reader_shell_test ); + } + + reader_set_buffer( commandline, wcslen( commandline ) ); + proc_push_interactive( 1 ); + + event_fire_generic(L"fish_prompt"); + line = reader_readline( ); + proc_pop_interactive(); + if( line ) + { + buff = wcsdup( line ); + } + else + { + exit_res = STATUS_BUILTIN_ERROR; + } + reader_pop(); + } + else + { + int eof=0; + + wcstring sb; + + while( 1 ) + { + int finished=0; + + wchar_t res=0; + static mbstate_t state; + memset (&state, '\0', sizeof (state)); + + while( !finished ) + { + char b; + if( read_blocked( builtin_stdin, &b, 1 ) <= 0 ) + { + eof=1; + break; + } + + size_t sz = mbrtowc( &res, &b, 1, &state ); + + switch( sz ) + { + case (size_t)(-1): + memset (&state, '\0', sizeof (state)); + break; + + case (size_t)(-2): + break; + case 0: + eof=1; + finished = 1; + break; + + default: + finished=1; + break; + + } + } + + if( eof ) + break; + + if( res == L'\n' ) + break; + sb.push_back(res); - } - - if( sb.size() < 2 && eof ) - { - exit_res = 1; - } - - buff = wcsdup( sb.c_str() ); - } - - if( i != argc && !exit_res ) - { - - wchar_t *state; - - env_var_t ifs = env_get_string( L"IFS" ); - if( ifs.missing() ) - ifs = L""; - - nxt = wcstok( buff, (i<argc-1)?ifs.c_str():L"", &state ); - - while( i<argc ) - { - env_set( argv[i], nxt != 0 ? nxt: L"", place ); - - i++; - if( nxt != 0 ) - nxt = wcstok( 0, (i<argc-1)?ifs.c_str():L"", &state); - } - } - - free( buff ); - - return exit_res; + } + + if( sb.size() < 2 && eof ) + { + exit_res = 1; + } + + buff = wcsdup( sb.c_str() ); + } + + if( i != argc && !exit_res ) + { + + wchar_t *state; + + env_var_t ifs = env_get_string( L"IFS" ); + if( ifs.missing() ) + ifs = L""; + + nxt = wcstok( buff, (i<argc-1)?ifs.c_str():L"", &state ); + + while( i<argc ) + { + env_set( argv[i], nxt != 0 ? nxt: L"", place ); + + i++; + if( nxt != 0 ) + nxt = wcstok( 0, (i<argc-1)?ifs.c_str():L"", &state); + } + } + + free( buff ); + + return exit_res; } /** @@ -2437,243 +2437,243 @@ static int builtin_read( parser_t &parser, wchar_t **argv ) */ static int builtin_status( parser_t &parser, wchar_t **argv ) { - - enum - { - NORMAL, - IS_SUBST, - IS_BLOCK, - IS_INTERACTIVE, - IS_LOGIN, - IS_FULL_JOB_CONTROL, - IS_INTERACTIVE_JOB_CONTROL, - IS_NO_JOB_CONTROL, - STACK_TRACE, - DONE, - CURRENT_FILENAME, - CURRENT_LINE_NUMBER - } - ; - - int mode = NORMAL; - - int argc = builtin_count_args( argv ); - int res=STATUS_BUILTIN_OK; - - woptind=0; - - - const struct woption - long_options[] = - { - { - L"help", no_argument, 0, 'h' - } - , - { - L"is-command-substitution", no_argument, 0, 'c' - } - , - { - L"is-block", no_argument, 0, 'b' - } - , - { - L"is-interactive", no_argument, 0, 'i' - } - , - { - L"is-login", no_argument, 0, 'l' - } - , - { - L"is-full-job-control", no_argument, &mode, IS_FULL_JOB_CONTROL - } - , - { - L"is-interactive-job-control", no_argument, &mode, IS_INTERACTIVE_JOB_CONTROL - } - , - { - L"is-no-job-control", no_argument, &mode, IS_NO_JOB_CONTROL - } - , - { - L"current-filename", no_argument, 0, 'f' - } - , - { - L"current-line-number", no_argument, 0, 'n' - } - , - { - L"job-control", required_argument, 0, 'j' - } - , - { - L"print-stack-trace", no_argument, 0, 't' - } - , - { - 0, 0, 0, 0 - } - } - ; - - while( 1 ) - { - int opt_index = 0; - - int opt = wgetopt_long( argc, - argv, - L":cbilfnhj:t", - long_options, - &opt_index ); - if( opt == -1 ) - break; - - switch( opt ) - { - case 0: - if(long_options[opt_index].flag != 0) - break; + + enum + { + NORMAL, + IS_SUBST, + IS_BLOCK, + IS_INTERACTIVE, + IS_LOGIN, + IS_FULL_JOB_CONTROL, + IS_INTERACTIVE_JOB_CONTROL, + IS_NO_JOB_CONTROL, + STACK_TRACE, + DONE, + CURRENT_FILENAME, + CURRENT_LINE_NUMBER + } + ; + + int mode = NORMAL; + + int argc = builtin_count_args( argv ); + int res=STATUS_BUILTIN_OK; + + woptind=0; + + + const struct woption + long_options[] = + { + { + L"help", no_argument, 0, 'h' + } + , + { + L"is-command-substitution", no_argument, 0, 'c' + } + , + { + L"is-block", no_argument, 0, 'b' + } + , + { + L"is-interactive", no_argument, 0, 'i' + } + , + { + L"is-login", no_argument, 0, 'l' + } + , + { + L"is-full-job-control", no_argument, &mode, IS_FULL_JOB_CONTROL + } + , + { + L"is-interactive-job-control", no_argument, &mode, IS_INTERACTIVE_JOB_CONTROL + } + , + { + L"is-no-job-control", no_argument, &mode, IS_NO_JOB_CONTROL + } + , + { + L"current-filename", no_argument, 0, 'f' + } + , + { + L"current-line-number", no_argument, 0, 'n' + } + , + { + L"job-control", required_argument, 0, 'j' + } + , + { + L"print-stack-trace", no_argument, 0, 't' + } + , + { + 0, 0, 0, 0 + } + } + ; + + while( 1 ) + { + int opt_index = 0; + + int opt = wgetopt_long( argc, + argv, + L":cbilfnhj:t", + long_options, + &opt_index ); + if( opt == -1 ) + break; + + switch( opt ) + { + case 0: + if(long_options[opt_index].flag != 0) + break; append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - - case 'c': - mode = IS_SUBST; - break; - - case 'b': - mode = IS_BLOCK; - break; - - case 'i': - mode = IS_INTERACTIVE; - break; - - case 'l': - mode = IS_LOGIN; - break; - - case 'f': - mode = CURRENT_FILENAME; - break; - - case 'n': - mode = CURRENT_LINE_NUMBER; - break; - - case 'h': - builtin_print_help( parser, argv[0], stdout_buffer ); - return STATUS_BUILTIN_OK; - - case 'j': - if( wcscmp( woptarg, L"full" ) == 0 ) - job_control_mode = JOB_CONTROL_ALL; - else if( wcscmp( woptarg, L"interactive" ) == 0 ) - job_control_mode = JOB_CONTROL_INTERACTIVE; - else if( wcscmp( woptarg, L"none" ) == 0 ) - job_control_mode = JOB_CONTROL_NONE; - else - { - append_format(stderr_buffer, - L"%ls: Invalid job control mode '%ls'\n", - woptarg ); - res = 1; - } - mode = DONE; - break; - - case 't': - mode = STACK_TRACE; - break; - - - case ':': - builtin_missing_argument( parser, argv[0], argv[woptind-1] ); - return STATUS_BUILTIN_ERROR; - - case '?': - builtin_unknown_option( parser, argv[0], argv[woptind-1] ); - return STATUS_BUILTIN_ERROR; - - } - - } - - if( !res ) - { - - switch( mode ) - { - case CURRENT_FILENAME: - { - const wchar_t *fn = parser.current_filename(); - - if( !fn ) - fn = _(L"Standard input"); - - append_format(stdout_buffer, L"%ls\n", fn ); - - break; - } - - case CURRENT_LINE_NUMBER: - { - append_format(stdout_buffer, L"%d\n", parser.get_lineno() ); - break; - } - - case IS_INTERACTIVE: - return !is_interactive_session; - - case IS_SUBST: - return !is_subshell; - - case IS_BLOCK: - return !is_block; - - case IS_LOGIN: - return !is_login; - - case IS_FULL_JOB_CONTROL: - return job_control_mode != JOB_CONTROL_ALL; - - case IS_INTERACTIVE_JOB_CONTROL: - return job_control_mode != JOB_CONTROL_INTERACTIVE; - - case IS_NO_JOB_CONTROL: - return job_control_mode != JOB_CONTROL_NONE; - - case STACK_TRACE: - { - parser.stack_trace( parser.current_block, stdout_buffer ); - break; - } - - case NORMAL: - { - if( is_login ) - append_format(stdout_buffer, _( L"This is a login shell\n" ) ); - else - append_format(stdout_buffer, _( L"This is not a login shell\n" ) ); - - append_format(stdout_buffer, _( L"Job control: %ls\n" ), - job_control_mode==JOB_CONTROL_INTERACTIVE?_( L"Only on interactive jobs" ): - (job_control_mode==JOB_CONTROL_NONE ? _( L"Never" ) : _( L"Always" ) ) ); - - parser.stack_trace( parser.current_block, stdout_buffer ); - break; - } - } - } - - return res; + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + + case 'c': + mode = IS_SUBST; + break; + + case 'b': + mode = IS_BLOCK; + break; + + case 'i': + mode = IS_INTERACTIVE; + break; + + case 'l': + mode = IS_LOGIN; + break; + + case 'f': + mode = CURRENT_FILENAME; + break; + + case 'n': + mode = CURRENT_LINE_NUMBER; + break; + + case 'h': + builtin_print_help( parser, argv[0], stdout_buffer ); + return STATUS_BUILTIN_OK; + + case 'j': + if( wcscmp( woptarg, L"full" ) == 0 ) + job_control_mode = JOB_CONTROL_ALL; + else if( wcscmp( woptarg, L"interactive" ) == 0 ) + job_control_mode = JOB_CONTROL_INTERACTIVE; + else if( wcscmp( woptarg, L"none" ) == 0 ) + job_control_mode = JOB_CONTROL_NONE; + else + { + append_format(stderr_buffer, + L"%ls: Invalid job control mode '%ls'\n", + woptarg ); + res = 1; + } + mode = DONE; + break; + + case 't': + mode = STACK_TRACE; + break; + + + case ':': + builtin_missing_argument( parser, argv[0], argv[woptind-1] ); + return STATUS_BUILTIN_ERROR; + + case '?': + builtin_unknown_option( parser, argv[0], argv[woptind-1] ); + return STATUS_BUILTIN_ERROR; + + } + + } + + if( !res ) + { + + switch( mode ) + { + case CURRENT_FILENAME: + { + const wchar_t *fn = parser.current_filename(); + + if( !fn ) + fn = _(L"Standard input"); + + append_format(stdout_buffer, L"%ls\n", fn ); + + break; + } + + case CURRENT_LINE_NUMBER: + { + append_format(stdout_buffer, L"%d\n", parser.get_lineno() ); + break; + } + + case IS_INTERACTIVE: + return !is_interactive_session; + + case IS_SUBST: + return !is_subshell; + + case IS_BLOCK: + return !is_block; + + case IS_LOGIN: + return !is_login; + + case IS_FULL_JOB_CONTROL: + return job_control_mode != JOB_CONTROL_ALL; + + case IS_INTERACTIVE_JOB_CONTROL: + return job_control_mode != JOB_CONTROL_INTERACTIVE; + + case IS_NO_JOB_CONTROL: + return job_control_mode != JOB_CONTROL_NONE; + + case STACK_TRACE: + { + parser.stack_trace( parser.current_block, stdout_buffer ); + break; + } + + case NORMAL: + { + if( is_login ) + append_format(stdout_buffer, _( L"This is a login shell\n" ) ); + else + append_format(stdout_buffer, _( L"This is not a login shell\n" ) ); + + append_format(stdout_buffer, _( L"Job control: %ls\n" ), + job_control_mode==JOB_CONTROL_INTERACTIVE?_( L"Only on interactive jobs" ): + (job_control_mode==JOB_CONTROL_NONE ? _( L"Never" ) : _( L"Always" ) ) ); + + parser.stack_trace( parser.current_block, stdout_buffer ); + break; + } + } + } + + return res; } @@ -2682,47 +2682,47 @@ static int builtin_status( parser_t &parser, wchar_t **argv ) */ static int builtin_exit( parser_t &parser, wchar_t **argv ) { - int argc = builtin_count_args( argv ); - - long ec=0; - switch( argc ) - { - case 1: - { - ec = proc_get_last_status(); - break; - } - - case 2: - { - wchar_t *end; - errno = 0; - ec = wcstol(argv[1],&end,10); - if( errno || *end != 0) - { - append_format(stderr_buffer, - _( L"%ls: Argument '%ls' must be an integer\n" ), - argv[0], - argv[1] ); - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - break; - } - - default: - { - append_format(stderr_buffer, - BUILTIN_ERR_TOO_MANY_ARGUMENTS, - argv[0] ); - - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - - } - reader_exit( 1, 0 ); - return (int)ec; + int argc = builtin_count_args( argv ); + + long ec=0; + switch( argc ) + { + case 1: + { + ec = proc_get_last_status(); + break; + } + + case 2: + { + wchar_t *end; + errno = 0; + ec = wcstol(argv[1],&end,10); + if( errno || *end != 0) + { + append_format(stderr_buffer, + _( L"%ls: Argument '%ls' must be an integer\n" ), + argv[0], + argv[1] ); + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + break; + } + + default: + { + append_format(stderr_buffer, + BUILTIN_ERR_TOO_MANY_ARGUMENTS, + argv[0] ); + + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + + } + reader_exit( 1, 0 ); + return (int)ec; } /** @@ -2732,23 +2732,23 @@ static int builtin_exit( parser_t &parser, wchar_t **argv ) */ static int builtin_cd( parser_t &parser, wchar_t **argv ) { - env_var_t dir_in; - wcstring dir; - int res=STATUS_BUILTIN_OK; - - - if (argv[1] == NULL) - { - dir_in = env_get_string( L"HOME" ); - if( dir_in.missing_or_empty() ) - { - append_format(stderr_buffer, - _( L"%ls: Could not find home directory\n" ), - argv[0] ); - } - } - else { - dir_in = argv[1]; + env_var_t dir_in; + wcstring dir; + int res=STATUS_BUILTIN_OK; + + + if (argv[1] == NULL) + { + dir_in = env_get_string( L"HOME" ); + if( dir_in.missing_or_empty() ) + { + append_format(stderr_buffer, + _( L"%ls: Could not find home directory\n" ), + argv[0] ); + } + } + else { + dir_in = argv[1]; } bool got_cd_path = false; @@ -2757,84 +2757,84 @@ static int builtin_cd( parser_t &parser, wchar_t **argv ) got_cd_path = path_get_cdpath(dir_in, &dir); } - if( !got_cd_path ) - { - if( errno == ENOTDIR ) - { - append_format(stderr_buffer, - _( L"%ls: '%ls' is not a directory\n" ), - argv[0], - dir_in.c_str() ); - } - else if( errno == ENOENT ) - { - append_format(stderr_buffer, - _( L"%ls: The directory '%ls' does not exist\n" ), - argv[0], - dir_in.c_str() ); - } - else if( errno == EROTTEN ) - { - append_format(stderr_buffer, - _( L"%ls: '%ls' is a rotten symlink\n" ), - argv[0], - dir_in.c_str() ); - - } - else - { - append_format(stderr_buffer, - _( L"%ls: Unknown error trying to locate directory '%ls'\n" ), - argv[0], - dir_in.c_str() ); - - } - - - if( !get_is_interactive() ) - { + if( !got_cd_path ) + { + if( errno == ENOTDIR ) + { + append_format(stderr_buffer, + _( L"%ls: '%ls' is not a directory\n" ), + argv[0], + dir_in.c_str() ); + } + else if( errno == ENOENT ) + { + append_format(stderr_buffer, + _( L"%ls: The directory '%ls' does not exist\n" ), + argv[0], + dir_in.c_str() ); + } + else if( errno == EROTTEN ) + { + append_format(stderr_buffer, + _( L"%ls: '%ls' is a rotten symlink\n" ), + argv[0], + dir_in.c_str() ); + + } + else + { + append_format(stderr_buffer, + _( L"%ls: Unknown error trying to locate directory '%ls'\n" ), + argv[0], + dir_in.c_str() ); + + } + + + if( !get_is_interactive() ) + { stderr_buffer.append(parser.current_line()); - } - - res = 1; - } - else if( wchdir( dir ) != 0 ) - { - struct stat buffer; - int status; - - status = wstat( dir, &buffer ); - if( !status && S_ISDIR(buffer.st_mode)) - { - append_format(stderr_buffer, - _( L"%ls: Permission denied: '%ls'\n" ), - argv[0], - dir.c_str() ); - - } - else - { - - append_format(stderr_buffer, - _( L"%ls: '%ls' is not a directory\n" ), - argv[0], - dir.c_str() ); - } - - if( !get_is_interactive() ) - { + } + + res = 1; + } + else if( wchdir( dir ) != 0 ) + { + struct stat buffer; + int status; + + status = wstat( dir, &buffer ); + if( !status && S_ISDIR(buffer.st_mode)) + { + append_format(stderr_buffer, + _( L"%ls: Permission denied: '%ls'\n" ), + argv[0], + dir.c_str() ); + + } + else + { + + append_format(stderr_buffer, + _( L"%ls: '%ls' is not a directory\n" ), + argv[0], + dir.c_str() ); + } + + if( !get_is_interactive() ) + { stderr_buffer.append(parser.current_line()); - } - - res = 1; - } - else if( !env_set_pwd() ) - { - res=1; - append_format(stderr_buffer, _( L"%ls: Could not set PWD variable\n" ), argv[0] ); - } - - return res; + } + + res = 1; + } + else if( !env_set_pwd() ) + { + res=1; + append_format(stderr_buffer, _( L"%ls: Could not set PWD variable\n" ), argv[0] ); + } + + return res; } /** @@ -2843,10 +2843,10 @@ static int builtin_cd( parser_t &parser, wchar_t **argv ) */ static int builtin_count( parser_t &parser, wchar_t ** argv ) { - int argc; - argc = builtin_count_args( argv ); - append_format(stdout_buffer, L"%d\n", argc-1 ); - return !(argc-1); + int argc; + argc = builtin_count_args( argv ); + append_format(stdout_buffer, L"%d\n", argc-1 ); + return !(argc-1); } /** @@ -2855,96 +2855,96 @@ static int builtin_count( parser_t &parser, wchar_t ** argv ) */ static int builtin_contains( parser_t &parser, wchar_t ** argv ) { - int argc; - argc = builtin_count_args( argv ); - int i; - wchar_t *needle; - int index=0; - - woptind=0; - - const struct woption - long_options[] = - { - { - L"help", no_argument, 0, 'h' - } - , - { - L"index", no_argument, 0, 'i' - } - , - { - 0, 0, 0, 0 - } - } - ; - - while( 1 ) - { - int opt_index = 0; - - int opt = wgetopt_long( argc, - argv, - L"+hi", - long_options, - &opt_index ); - if( opt == -1 ) - break; - - switch( opt ) - { - case 0: + int argc; + argc = builtin_count_args( argv ); + int i; + wchar_t *needle; + int index=0; + + woptind=0; + + const struct woption + long_options[] = + { + { + L"help", no_argument, 0, 'h' + } + , + { + L"index", no_argument, 0, 'i' + } + , + { + 0, 0, 0, 0 + } + } + ; + + while( 1 ) + { + int opt_index = 0; + + int opt = wgetopt_long( argc, + argv, + L"+hi", + long_options, + &opt_index ); + if( opt == -1 ) + break; + + switch( opt ) + { + case 0: assert(opt_index >= 0 && (size_t)opt_index < sizeof long_options / sizeof *long_options); - if(long_options[opt_index].flag != 0) - break; - append_format(stderr_buffer, - BUILTIN_ERR_UNKNOWN, - argv[0], - long_options[opt_index].name ); - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - - - case 'h': - builtin_print_help( parser, argv[0], stdout_buffer ); - return STATUS_BUILTIN_OK; - - - case ':': - builtin_missing_argument( parser, argv[0], argv[woptind-1] ); - return STATUS_BUILTIN_ERROR; - - case '?': - builtin_unknown_option( parser, argv[0], argv[woptind-1] ); - return STATUS_BUILTIN_ERROR; - - case 'i': - index=1; - break; - } - - } - - - - needle = argv[woptind]; - if (!needle) - { - append_format(stderr_buffer, _( L"%ls: Key not specified\n" ), argv[0] ); - } - - - for( i=woptind+1; i<argc; i++ ) - { - - if( !wcscmp( needle, argv[i]) ) - { - if ( index ) append_format(stdout_buffer, L"%d\n", i-woptind ); - return 0; - } - } - return 1; + if(long_options[opt_index].flag != 0) + break; + append_format(stderr_buffer, + BUILTIN_ERR_UNKNOWN, + argv[0], + long_options[opt_index].name ); + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + + + case 'h': + builtin_print_help( parser, argv[0], stdout_buffer ); + return STATUS_BUILTIN_OK; + + + case ':': + builtin_missing_argument( parser, argv[0], argv[woptind-1] ); + return STATUS_BUILTIN_ERROR; + + case '?': + builtin_unknown_option( parser, argv[0], argv[woptind-1] ); + return STATUS_BUILTIN_ERROR; + + case 'i': + index=1; + break; + } + + } + + + + needle = argv[woptind]; + if (!needle) + { + append_format(stderr_buffer, _( L"%ls: Key not specified\n" ), argv[0] ); + } + + + for( i=woptind+1; i<argc; i++ ) + { + + if( !wcscmp( needle, argv[i]) ) + { + if ( index ) append_format(stdout_buffer, L"%d\n", i-woptind ); + return 0; + } + } + return 1; } @@ -2955,92 +2955,92 @@ static int builtin_contains( parser_t &parser, wchar_t ** argv ) static int builtin_source( parser_t &parser, wchar_t ** argv ) { ASSERT_IS_MAIN_THREAD(); - int fd; - int res = STATUS_BUILTIN_OK; - struct stat buf; - int argc; - - argc = builtin_count_args( argv ); - - const wchar_t *fn; - const wchar_t *fn_intern; - - - - if( argc < 2 || (wcscmp( argv[1], L"-" ) == 0) ) - { - fn = L"-"; - fn_intern = fn; - fd = dup(builtin_stdin); - } - else - { - - if( ( fd = wopen_cloexec( argv[1], O_RDONLY ) ) == -1 ) - { - append_format(stderr_buffer, _(L"%ls: Error encountered while sourcing file '%ls':\n"), argv[0], argv[1] ); - builtin_wperror( L"." ); - return STATUS_BUILTIN_ERROR; - } - - if( fstat(fd, &buf) == -1 ) - { - close(fd); - append_format(stderr_buffer, _(L"%ls: Error encountered while sourcing file '%ls':\n"), argv[0], argv[1] ); - builtin_wperror( L"." ); - return STATUS_BUILTIN_ERROR; - } - - if( !S_ISREG(buf.st_mode) ) - { - close(fd); - append_format(stderr_buffer, _( L"%ls: '%ls' is not a file\n" ), argv[0], argv[1] ); - return STATUS_BUILTIN_ERROR; - } - - fn = wrealpath( argv[1], 0 ); - - if( !fn ) - { - fn_intern = intern( argv[1] ); - } - else - { - fn_intern = intern(fn); - free( (void *)fn ); - } - - } - - parser.push_block( new source_block_t(fn_intern) ); - reader_push_current_filename( fn_intern ); - - parse_util_set_argv( (argc>2)?(argv+2):(argv+1), wcstring_list_t()); - - res = reader_read( fd, real_io ? *real_io : io_chain_t() ); - - parser.pop_block(); - - if( res ) - { - append_format(stderr_buffer, - _( L"%ls: Error while reading file '%ls'\n" ), - argv[0], - fn_intern == intern_static(L"-") ? L"<stdin>" : fn_intern ); - } - else - { - res = proc_get_last_status(); - } - - /* - Do not close fd after calling reader_read. reader_read - automatically closes it before calling eval. - */ - - reader_pop_current_filename(); - - return res; + int fd; + int res = STATUS_BUILTIN_OK; + struct stat buf; + int argc; + + argc = builtin_count_args( argv ); + + const wchar_t *fn; + const wchar_t *fn_intern; + + + + if( argc < 2 || (wcscmp( argv[1], L"-" ) == 0) ) + { + fn = L"-"; + fn_intern = fn; + fd = dup(builtin_stdin); + } + else + { + + if( ( fd = wopen_cloexec( argv[1], O_RDONLY ) ) == -1 ) + { + append_format(stderr_buffer, _(L"%ls: Error encountered while sourcing file '%ls':\n"), argv[0], argv[1] ); + builtin_wperror( L"." ); + return STATUS_BUILTIN_ERROR; + } + + if( fstat(fd, &buf) == -1 ) + { + close(fd); + append_format(stderr_buffer, _(L"%ls: Error encountered while sourcing file '%ls':\n"), argv[0], argv[1] ); + builtin_wperror( L"." ); + return STATUS_BUILTIN_ERROR; + } + + if( !S_ISREG(buf.st_mode) ) + { + close(fd); + append_format(stderr_buffer, _( L"%ls: '%ls' is not a file\n" ), argv[0], argv[1] ); + return STATUS_BUILTIN_ERROR; + } + + fn = wrealpath( argv[1], 0 ); + + if( !fn ) + { + fn_intern = intern( argv[1] ); + } + else + { + fn_intern = intern(fn); + free( (void *)fn ); + } + + } + + parser.push_block( new source_block_t(fn_intern) ); + reader_push_current_filename( fn_intern ); + + parse_util_set_argv( (argc>2)?(argv+2):(argv+1), wcstring_list_t()); + + res = reader_read( fd, real_io ? *real_io : io_chain_t() ); + + parser.pop_block(); + + if( res ) + { + append_format(stderr_buffer, + _( L"%ls: Error while reading file '%ls'\n" ), + argv[0], + fn_intern == intern_static(L"-") ? L"<stdin>" : fn_intern ); + } + else + { + res = proc_get_last_status(); + } + + /* + Do not close fd after calling reader_read. reader_read + automatically closes it before calling eval. + */ + + reader_pop_current_filename(); + + return res; } /** @@ -3059,146 +3059,146 @@ static void make_first( job_t *j ) */ static int builtin_fg( parser_t &parser, wchar_t **argv ) { - job_t *j=NULL; - - if( argv[1] == 0 ) - { - /* - Select last constructed job (I.e. first job in the job que) - that is possible to put in the foreground - */ - + job_t *j=NULL; + + if( argv[1] == 0 ) + { + /* + Select last constructed job (I.e. first job in the job que) + that is possible to put in the foreground + */ + job_iterator_t jobs; while ((j = jobs.next())) - { - if( job_get_flag( j, JOB_CONSTRUCTED ) && (!job_is_completed(j)) && - ( (job_is_stopped(j) || (!job_get_flag(j, JOB_FOREGROUND)) ) && job_get_flag( j, JOB_CONTROL) ) ) - { - break; - } - } - if( !j ) - { - append_format(stderr_buffer, - _( L"%ls: There are no suitable jobs\n" ), - argv[0] ); - builtin_print_help( parser, argv[0], stderr_buffer ); - } - } - else if( argv[2] != 0 ) - { - /* - Specifying what more than one job to put to the foreground - is a syntax error, we still try to locate the job argv[1], - since we want to know if this is an ambigous job - specification or if this is an malformed job id - */ - wchar_t *endptr; - int pid; - int found_job = 0; - - errno = 0; - pid = fish_wcstoi( argv[1], &endptr, 10 ); - if( !( *endptr || errno ) ) - { - j = job_get_from_pid( pid ); - if( j ) - found_job = 1; - } - - if( found_job ) - { - append_format(stderr_buffer, - _( L"%ls: Ambiguous job\n" ), - argv[0] ); - } - else - { - append_format(stderr_buffer, - _( L"%ls: '%ls' is not a job\n" ), - argv[0], - argv[1] ); - } - - builtin_print_help( parser, argv[0], stderr_buffer ); - - j=0; - - } - else - { - wchar_t *end; - int pid; - errno = 0; - pid = abs(fish_wcstoi( argv[1], &end, 10 )); - - if( *end || errno ) - { - append_format(stderr_buffer, - BUILTIN_ERR_NOT_NUMBER, - argv[0], - argv[1] ); - builtin_print_help( parser, argv[0], stderr_buffer ); - } - else - { - j = job_get_from_pid( pid ); - if( !j || !job_get_flag( j, JOB_CONSTRUCTED ) || job_is_completed( j )) - { - append_format(stderr_buffer, - _( L"%ls: No suitable job: %d\n" ), - argv[0], - pid ); - builtin_print_help( parser, argv[0], stderr_buffer ); - j=0; - } - else if( !job_get_flag( j, JOB_CONTROL) ) - { - append_format(stderr_buffer, - _( L"%ls: Can't put job %d, '%ls' to foreground because it is not under job control\n" ), - argv[0], - pid, - j->command_wcstr() ); - builtin_print_help( parser, argv[0], stderr_buffer ); - j=0; - } - } - } - - if( j ) - { - if( builtin_err_redirect ) - { - append_format(stderr_buffer, - FG_MSG, - j->job_id, - j->command_wcstr() ); - } - else - { - /* - If we aren't redirecting, send output to real stderr, - since stuff in sb_err won't get printed until the - command finishes. - */ - fwprintf( stderr, - FG_MSG, - j->job_id, - j->command_wcstr() ); - } - - wchar_t *ft = tok_first( j->command_wcstr() ); - if( ft != 0 ) - env_set( L"_", ft, ENV_EXPORT ); - free(ft); - reader_write_title(); - - make_first( j ); - job_set_flag( j, JOB_FOREGROUND, 1 ); - - job_continue( j, job_is_stopped(j) ); - } - return j != 0; + { + if( job_get_flag( j, JOB_CONSTRUCTED ) && (!job_is_completed(j)) && + ( (job_is_stopped(j) || (!job_get_flag(j, JOB_FOREGROUND)) ) && job_get_flag( j, JOB_CONTROL) ) ) + { + break; + } + } + if( !j ) + { + append_format(stderr_buffer, + _( L"%ls: There are no suitable jobs\n" ), + argv[0] ); + builtin_print_help( parser, argv[0], stderr_buffer ); + } + } + else if( argv[2] != 0 ) + { + /* + Specifying what more than one job to put to the foreground + is a syntax error, we still try to locate the job argv[1], + since we want to know if this is an ambigous job + specification or if this is an malformed job id + */ + wchar_t *endptr; + int pid; + int found_job = 0; + + errno = 0; + pid = fish_wcstoi( argv[1], &endptr, 10 ); + if( !( *endptr || errno ) ) + { + j = job_get_from_pid( pid ); + if( j ) + found_job = 1; + } + + if( found_job ) + { + append_format(stderr_buffer, + _( L"%ls: Ambiguous job\n" ), + argv[0] ); + } + else + { + append_format(stderr_buffer, + _( L"%ls: '%ls' is not a job\n" ), + argv[0], + argv[1] ); + } + + builtin_print_help( parser, argv[0], stderr_buffer ); + + j=0; + + } + else + { + wchar_t *end; + int pid; + errno = 0; + pid = abs(fish_wcstoi( argv[1], &end, 10 )); + + if( *end || errno ) + { + append_format(stderr_buffer, + BUILTIN_ERR_NOT_NUMBER, + argv[0], + argv[1] ); + builtin_print_help( parser, argv[0], stderr_buffer ); + } + else + { + j = job_get_from_pid( pid ); + if( !j || !job_get_flag( j, JOB_CONSTRUCTED ) || job_is_completed( j )) + { + append_format(stderr_buffer, + _( L"%ls: No suitable job: %d\n" ), + argv[0], + pid ); + builtin_print_help( parser, argv[0], stderr_buffer ); + j=0; + } + else if( !job_get_flag( j, JOB_CONTROL) ) + { + append_format(stderr_buffer, + _( L"%ls: Can't put job %d, '%ls' to foreground because it is not under job control\n" ), + argv[0], + pid, + j->command_wcstr() ); + builtin_print_help( parser, argv[0], stderr_buffer ); + j=0; + } + } + } + + if( j ) + { + if( builtin_err_redirect ) + { + append_format(stderr_buffer, + FG_MSG, + j->job_id, + j->command_wcstr() ); + } + else + { + /* + If we aren't redirecting, send output to real stderr, + since stuff in sb_err won't get printed until the + command finishes. + */ + fwprintf( stderr, + FG_MSG, + j->job_id, + j->command_wcstr() ); + } + + wchar_t *ft = tok_first( j->command_wcstr() ); + if( ft != 0 ) + env_set( L"_", ft, ENV_EXPORT ); + free(ft); + reader_write_title(); + + make_first( j ); + job_set_flag( j, JOB_FOREGROUND, 1 ); + + job_continue( j, job_is_stopped(j) ); + } + return j != 0; } /** @@ -3206,36 +3206,36 @@ static int builtin_fg( parser_t &parser, wchar_t **argv ) */ static int send_to_bg( parser_t &parser, job_t *j, const wchar_t *name ) { - if( j == 0 ) - { - append_format(stderr_buffer, - _( L"%ls: Unknown job '%ls'\n" ), - L"bg", - name ); - builtin_print_help( parser, L"bg", stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - else if( !job_get_flag( j, JOB_CONTROL ) ) - { - append_format(stderr_buffer, - _( L"%ls: Can't put job %d, '%ls' to background because it is not under job control\n" ), - L"bg", - j->job_id, - j->command_wcstr() ); - builtin_print_help( parser, L"bg", stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - else - { - append_format(stderr_buffer, - _(L"Send job %d '%ls' to background\n"), - j->job_id, - j->command_wcstr() ); - } - make_first( j ); - job_set_flag( j, JOB_FOREGROUND, 0 ); - job_continue( j, job_is_stopped(j) ); - return STATUS_BUILTIN_OK; + if( j == 0 ) + { + append_format(stderr_buffer, + _( L"%ls: Unknown job '%ls'\n" ), + L"bg", + name ); + builtin_print_help( parser, L"bg", stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + else if( !job_get_flag( j, JOB_CONTROL ) ) + { + append_format(stderr_buffer, + _( L"%ls: Can't put job %d, '%ls' to background because it is not under job control\n" ), + L"bg", + j->job_id, + j->command_wcstr() ); + builtin_print_help( parser, L"bg", stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + else + { + append_format(stderr_buffer, + _(L"Send job %d '%ls' to background\n"), + j->job_id, + j->command_wcstr() ); + } + make_first( j ); + job_set_flag( j, JOB_FOREGROUND, 0 ); + job_continue( j, job_is_stopped(j) ); + return STATUS_BUILTIN_OK; } @@ -3244,65 +3244,65 @@ static int send_to_bg( parser_t &parser, job_t *j, const wchar_t *name ) */ static int builtin_bg( parser_t &parser, wchar_t **argv ) { - int res = STATUS_BUILTIN_OK; + int res = STATUS_BUILTIN_OK; - if( argv[1] == 0 ) - { - job_t *j; + if( argv[1] == 0 ) + { + job_t *j; job_iterator_t jobs; while ((j = jobs.next())) { - if( job_is_stopped(j) && job_get_flag( j, JOB_CONTROL ) && (!job_is_completed(j)) ) - { - break; - } - } - - if( !j ) - { - append_format(stderr_buffer, - _( L"%ls: There are no suitable jobs\n" ), - argv[0] ); - res = 1; - } - else - { - res = send_to_bg( parser, j, _(L"(default)" ) ); - } - } - else - { - wchar_t *end; - int i; - int pid; - int err = 0; - - for( i=1; argv[i]; i++ ) - { - errno=0; - pid = fish_wcstoi( argv[i], &end, 10 ); - if( errno || pid < 0 || *end || !job_get_from_pid( pid ) ) - { - append_format(stderr_buffer, - _( L"%ls: '%ls' is not a job\n" ), - argv[0], - argv[i] ); - err = 1; - break; - } - } - - if( !err ) - { - for( i=1; !res && argv[i]; i++ ) - { - pid = fish_wcstoi( argv[i], 0, 10 ); - res |= send_to_bg( parser, job_get_from_pid( pid ), *argv); - } - } - } - - return res; + if( job_is_stopped(j) && job_get_flag( j, JOB_CONTROL ) && (!job_is_completed(j)) ) + { + break; + } + } + + if( !j ) + { + append_format(stderr_buffer, + _( L"%ls: There are no suitable jobs\n" ), + argv[0] ); + res = 1; + } + else + { + res = send_to_bg( parser, j, _(L"(default)" ) ); + } + } + else + { + wchar_t *end; + int i; + int pid; + int err = 0; + + for( i=1; argv[i]; i++ ) + { + errno=0; + pid = fish_wcstoi( argv[i], &end, 10 ); + if( errno || pid < 0 || *end || !job_get_from_pid( pid ) ) + { + append_format(stderr_buffer, + _( L"%ls: '%ls' is not a job\n" ), + argv[0], + argv[i] ); + err = 1; + break; + } + } + + if( !err ) + { + for( i=1; !res && argv[i]; i++ ) + { + pid = fish_wcstoi( argv[i], 0, 10 ); + res |= send_to_bg( parser, job_get_from_pid( pid ), *argv); + } + } + } + + return res; } @@ -3311,65 +3311,65 @@ static int builtin_bg( parser_t &parser, wchar_t **argv ) */ static int builtin_for( parser_t &parser, wchar_t **argv ) { - int argc = builtin_count_args( argv ); - int res=STATUS_BUILTIN_ERROR; - - - if( argc < 3) - { - append_format(stderr_buffer, - BUILTIN_FOR_ERR_COUNT, - argv[0] , - argc ); - builtin_print_help( parser, argv[0], stderr_buffer ); - } - else if ( wcsvarname(argv[1]) ) - { - append_format(stderr_buffer, - BUILTIN_FOR_ERR_NAME, - argv[0], - argv[1] ); - builtin_print_help( parser, argv[0], stderr_buffer ); - } - else if (wcscmp( argv[2], L"in") != 0 ) - { - append_format(stderr_buffer, - BUILTIN_FOR_ERR_IN, - argv[0] ); - builtin_print_help( parser, argv[0], stderr_buffer ); - } - else - { - res=0; - } - - - if( res ) - { - parser.push_block( new fake_block_t() ); - } - else - { + int argc = builtin_count_args( argv ); + int res=STATUS_BUILTIN_ERROR; + + + if( argc < 3) + { + append_format(stderr_buffer, + BUILTIN_FOR_ERR_COUNT, + argv[0] , + argc ); + builtin_print_help( parser, argv[0], stderr_buffer ); + } + else if ( wcsvarname(argv[1]) ) + { + append_format(stderr_buffer, + BUILTIN_FOR_ERR_NAME, + argv[0], + argv[1] ); + builtin_print_help( parser, argv[0], stderr_buffer ); + } + else if (wcscmp( argv[2], L"in") != 0 ) + { + append_format(stderr_buffer, + BUILTIN_FOR_ERR_IN, + argv[0] ); + builtin_print_help( parser, argv[0], stderr_buffer ); + } + else + { + res=0; + } + + + if( res ) + { + parser.push_block( new fake_block_t() ); + } + else + { const wchar_t *for_variable = argv[1]; for_block_t *fb = new for_block_t(for_variable); - parser.push_block( fb ); - fb->tok_pos = parser.get_pos(); + parser.push_block( fb ); + fb->tok_pos = parser.get_pos(); /* Note that we store the sequence of values in opposite order */ wcstring_list_t &for_vars = fb->sequence; - for( int i=argc-1; i>3; i-- ) + for( int i=argc-1; i>3; i-- ) for_vars.push_back(argv[i]); - if( argc > 3 ) - { - env_set( for_variable, argv[3], ENV_LOCAL ); - } - else - { - parser.current_block->skip=1; - } - } - return res; + if( argc > 3 ) + { + env_set( for_variable, argv[3], ENV_LOCAL ); + } + else + { + parser.current_block->skip=1; + } + } + return res; } /** @@ -3377,9 +3377,9 @@ static int builtin_for( parser_t &parser, wchar_t **argv ) */ static int builtin_begin( parser_t &parser, wchar_t **argv ) { - parser.push_block( new scope_block_t(BEGIN) ); - parser.current_block->tok_pos = parser.get_pos(); - return proc_get_last_status(); + parser.push_block( new scope_block_t(BEGIN) ); + parser.current_block->tok_pos = parser.get_pos(); + return proc_get_last_status(); } @@ -3390,93 +3390,93 @@ static int builtin_begin( parser_t &parser, wchar_t **argv ) */ static int builtin_end( parser_t &parser, wchar_t **argv ) { - if( !parser.current_block->outer ) - { - append_format(stderr_buffer, - _( L"%ls: Not inside of block\n" ), - argv[0] ); - - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - else - { - /** - By default, 'end' kills the current block scope. But if we - are rewinding a loop, this should be set to false, so that - variables in the current loop scope won't die between laps. - */ - int kill_block = 1; - - switch( parser.current_block->type() ) - { - case WHILE: - { - /* - If this is a while loop, we rewind the loop unless - it's the last lap, in which case we continue. - */ - if( !( parser.current_block->skip && (parser.current_block->loop_status != LOOP_CONTINUE ))) - { - parser.current_block->loop_status = LOOP_NORMAL; - parser.current_block->skip = 0; - kill_block = 0; - parser.set_pos( parser.current_block->tok_pos); + if( !parser.current_block->outer ) + { + append_format(stderr_buffer, + _( L"%ls: Not inside of block\n" ), + argv[0] ); + + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + else + { + /** + By default, 'end' kills the current block scope. But if we + are rewinding a loop, this should be set to false, so that + variables in the current loop scope won't die between laps. + */ + int kill_block = 1; + + switch( parser.current_block->type() ) + { + case WHILE: + { + /* + If this is a while loop, we rewind the loop unless + it's the last lap, in which case we continue. + */ + if( !( parser.current_block->skip && (parser.current_block->loop_status != LOOP_CONTINUE ))) + { + parser.current_block->loop_status = LOOP_NORMAL; + parser.current_block->skip = 0; + kill_block = 0; + parser.set_pos( parser.current_block->tok_pos); while_block_t *blk = static_cast<while_block_t *>(parser.current_block); blk->status = WHILE_TEST_AGAIN; - } + } - break; - } + break; + } - case IF: - case SUBST: - case BEGIN: + case IF: + case SUBST: + case BEGIN: case SWITCH: case FAKE: - /* - Nothing special happens at the end of these commands. The scope just ends. - */ + /* + Nothing special happens at the end of these commands. The scope just ends. + */ - break; + break; - case FOR: - { - /* - set loop variable to next element, and rewind to the beginning of the block. - */ + case FOR: + { + /* + set loop variable to next element, and rewind to the beginning of the block. + */ for_block_t *fb = static_cast<for_block_t *>(parser.current_block); wcstring_list_t &for_vars = fb->sequence; - if( parser.current_block->loop_status == LOOP_BREAK ) - { + if( parser.current_block->loop_status == LOOP_BREAK ) + { for_vars.clear(); - } + } - if( ! for_vars.empty() ) - { + if( ! for_vars.empty() ) + { const wcstring val = for_vars.back(); for_vars.pop_back(); const wcstring &for_variable = fb->variable; - env_set( for_variable.c_str(), val.c_str(), ENV_LOCAL); - parser.current_block->loop_status = LOOP_NORMAL; - parser.current_block->skip = 0; - - kill_block = 0; - parser.set_pos( parser.current_block->tok_pos ); - } - break; - } - - case FUNCTION_DEF: - { - function_def_block_t *fdb = static_cast<function_def_block_t *>(parser.current_block); - function_data_t &d = fdb->function_data; - + env_set( for_variable.c_str(), val.c_str(), ENV_LOCAL); + parser.current_block->loop_status = LOOP_NORMAL; + parser.current_block->skip = 0; + + kill_block = 0; + parser.set_pos( parser.current_block->tok_pos ); + } + break; + } + + case FUNCTION_DEF: + { + function_def_block_t *fdb = static_cast<function_def_block_t *>(parser.current_block); + function_data_t &d = fdb->function_data; + if (d.name.empty()) { /* Disallow empty function names */ append_format(stderr_buffer, _( L"%ls: No function name given\n" ), argv[0] ); - + /* Return an error via a crummy way. Don't just return here, since we need to pop the block. */ proc_set_last_status(STATUS_BUILTIN_ERROR); } @@ -3491,28 +3491,28 @@ static int builtin_end( parser_t &parser, wchar_t **argv ) wchar_t *def = wcsndup( parser.get_buffer()+parser.current_block->tok_pos, parser.get_job_pos()-parser.current_block->tok_pos ); d.definition = def; - - function_add( d, parser ); + + function_add( d, parser ); free( def ); } - } - break; - + } + break; + default: assert(false); //should never get here break; - } - if( kill_block ) - { - parser.pop_block(); - } - - /* - If everything goes ok, return status of last command to execute. - */ - return proc_get_last_status(); - } + } + if( kill_block ) + { + parser.pop_block(); + } + + /* + If everything goes ok, return status of last command to execute. + */ + return proc_get_last_status(); + } } /** @@ -3531,29 +3531,29 @@ static int builtin_else( parser_t &parser, wchar_t **argv ) block_ok = true; } } - - if( ! block_ok ) - { - append_format(stderr_buffer, - _( L"%ls: Not inside of 'if' block\n" ), - argv[0] ); - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - else - { + + if( ! block_ok ) + { + append_format(stderr_buffer, + _( L"%ls: Not inside of 'if' block\n" ), + argv[0] ); + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + else + { /* Run the else block if the IF expression was false and so were all the ELSEIF expressions (if any) */ bool run_else = ! if_block->any_branch_taken; - if_block->skip = ! run_else; + if_block->skip = ! run_else; if_block->else_evaluated = true; - env_pop(); - env_push(0); - } - - /* - If everything goes ok, return status of last command to execute. - */ - return proc_get_last_status(); + env_pop(); + env_push(0); + } + + /* + If everything goes ok, return status of last command to execute. + */ + return proc_get_last_status(); } /** @@ -3562,49 +3562,49 @@ static int builtin_else( parser_t &parser, wchar_t **argv ) */ static int builtin_break_continue( parser_t &parser, wchar_t **argv ) { - int is_break = (wcscmp(argv[0],L"break")==0); - int argc = builtin_count_args( argv ); - - block_t *b = parser.current_block; - - if( argc != 1 ) - { - append_format(stderr_buffer, - BUILTIN_ERR_UNKNOWN, - argv[0], - argv[1] ); - - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - - - while( (b != 0) && - ( b->type() != WHILE) && - (b->type() != FOR ) ) - { - b = b->outer; - } - - if( b == 0 ) - { - append_format(stderr_buffer, - _( L"%ls: Not inside of loop\n" ), - argv[0] ); - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - - b = parser.current_block; - while( ( b->type() != WHILE) && - (b->type() != FOR ) ) - { - b->skip=1; - b = b->outer; - } - b->skip=1; - b->loop_status = is_break?LOOP_BREAK:LOOP_CONTINUE; - return STATUS_BUILTIN_OK; + int is_break = (wcscmp(argv[0],L"break")==0); + int argc = builtin_count_args( argv ); + + block_t *b = parser.current_block; + + if( argc != 1 ) + { + append_format(stderr_buffer, + BUILTIN_ERR_UNKNOWN, + argv[0], + argv[1] ); + + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + + + while( (b != 0) && + ( b->type() != WHILE) && + (b->type() != FOR ) ) + { + b = b->outer; + } + + if( b == 0 ) + { + append_format(stderr_buffer, + _( L"%ls: Not inside of loop\n" ), + argv[0] ); + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + + b = parser.current_block; + while( ( b->type() != WHILE) && + (b->type() != FOR ) ) + { + b->skip=1; + b = b->outer; + } + b->skip=1; + b->loop_status = is_break?LOOP_BREAK:LOOP_CONTINUE; + return STATUS_BUILTIN_OK; } /** @@ -3614,13 +3614,13 @@ static int builtin_break_continue( parser_t &parser, wchar_t **argv ) static int builtin_breakpoint( parser_t &parser, wchar_t **argv ) { - parser.push_block( new breakpoint_block_t() ); - - reader_read( STDIN_FILENO, real_io ? *real_io : io_chain_t() ); - - parser.pop_block(); - - return proc_get_last_status(); + parser.push_block( new breakpoint_block_t() ); + + reader_read( STDIN_FILENO, real_io ? *real_io : io_chain_t() ); + + parser.pop_block(); + + return proc_get_last_status(); } @@ -3629,67 +3629,67 @@ static int builtin_breakpoint( parser_t &parser, wchar_t **argv ) */ static int builtin_return( parser_t &parser, wchar_t **argv ) { - int argc = builtin_count_args( argv ); - int status = proc_get_last_status(); - - block_t *b = parser.current_block; - - switch( argc ) - { - case 1: - break; - case 2: - { - wchar_t *end; - errno = 0; - status = fish_wcstoi(argv[1],&end,10); - if( errno || *end != 0) - { - append_format(stderr_buffer, - _( L"%ls: Argument '%ls' must be an integer\n" ), - argv[0], - argv[1] ); - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - break; - } - default: - append_format(stderr_buffer, - _( L"%ls: Too many arguments\n" ), - argv[0] ); - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - - - while( (b != 0) && - ( b->type() != FUNCTION_CALL && - b->type() != FUNCTION_CALL_NO_SHADOW) ) - { - b = b->outer; - } - - if( b == 0 ) - { - append_format(stderr_buffer, - _( L"%ls: Not inside of function\n" ), - argv[0] ); - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - - b = parser.current_block; - while( ( b->type() != FUNCTION_CALL && - b->type() != FUNCTION_CALL_NO_SHADOW ) ) - { + int argc = builtin_count_args( argv ); + int status = proc_get_last_status(); + + block_t *b = parser.current_block; + + switch( argc ) + { + case 1: + break; + case 2: + { + wchar_t *end; + errno = 0; + status = fish_wcstoi(argv[1],&end,10); + if( errno || *end != 0) + { + append_format(stderr_buffer, + _( L"%ls: Argument '%ls' must be an integer\n" ), + argv[0], + argv[1] ); + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + break; + } + default: + append_format(stderr_buffer, + _( L"%ls: Too many arguments\n" ), + argv[0] ); + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + + + while( (b != 0) && + ( b->type() != FUNCTION_CALL && + b->type() != FUNCTION_CALL_NO_SHADOW) ) + { + b = b->outer; + } + + if( b == 0 ) + { + append_format(stderr_buffer, + _( L"%ls: Not inside of function\n" ), + argv[0] ); + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + + b = parser.current_block; + while( ( b->type() != FUNCTION_CALL && + b->type() != FUNCTION_CALL_NO_SHADOW ) ) + { b->mark_as_fake(); - b->skip=1; - b = b->outer; - } - b->skip=1; + b->skip=1; + b = b->outer; + } + b->skip=1; - return status; + return status; } /** @@ -3698,28 +3698,28 @@ static int builtin_return( parser_t &parser, wchar_t **argv ) */ static int builtin_switch( parser_t &parser, wchar_t **argv ) { - int res=STATUS_BUILTIN_OK; - int argc = builtin_count_args( argv ); - - if( argc != 2 ) - { - append_format(stderr_buffer, - _( L"%ls: Expected exactly one argument, got %d\n" ), - argv[0], - argc-1 ); - - builtin_print_help( parser, argv[0], stderr_buffer ); - res=1; - parser.push_block( new fake_block_t() ); - } - else - { - parser.push_block( new switch_block_t(argv[1]) ); - parser.current_block->skip=1; + int res=STATUS_BUILTIN_OK; + int argc = builtin_count_args( argv ); + + if( argc != 2 ) + { + append_format(stderr_buffer, + _( L"%ls: Expected exactly one argument, got %d\n" ), + argv[0], + argc-1 ); + + builtin_print_help( parser, argv[0], stderr_buffer ); + res=1; + parser.push_block( new fake_block_t() ); + } + else + { + parser.push_block( new switch_block_t(argv[1]) ); + parser.current_block->skip=1; res = proc_get_last_status(); - } - - return res; + } + + return res; } /** @@ -3728,44 +3728,44 @@ static int builtin_switch( parser_t &parser, wchar_t **argv ) */ static int builtin_case( parser_t &parser, wchar_t **argv ) { - int argc = builtin_count_args( argv ); - int i; - wchar_t *unescaped=0; - - if( parser.current_block->type() != SWITCH ) - { - append_format(stderr_buffer, - _( L"%ls: 'case' command while not in switch block\n" ), - argv[0] ); - builtin_print_help( parser, argv[0], stderr_buffer ); - return STATUS_BUILTIN_ERROR; - } - - parser.current_block->skip = 1; - switch_block_t *sb = static_cast<switch_block_t *>(parser.current_block); - if( sb->switch_taken ) - { - return proc_get_last_status(); - } - + int argc = builtin_count_args( argv ); + int i; + wchar_t *unescaped=0; + + if( parser.current_block->type() != SWITCH ) + { + append_format(stderr_buffer, + _( L"%ls: 'case' command while not in switch block\n" ), + argv[0] ); + builtin_print_help( parser, argv[0], stderr_buffer ); + return STATUS_BUILTIN_ERROR; + } + + parser.current_block->skip = 1; + switch_block_t *sb = static_cast<switch_block_t *>(parser.current_block); + if( sb->switch_taken ) + { + return proc_get_last_status(); + } + const wcstring &switch_value = sb->switch_value; - for( i=1; i<argc; i++ ) - { - int match; - - unescaped = parse_util_unescape_wildcards( argv[i] ); - match = wildcard_match( switch_value, unescaped ); - free( unescaped ); - - if( match ) - { - parser.current_block->skip = 0; - sb->switch_taken = true; - break; - } - } - - return proc_get_last_status(); + for( i=1; i<argc; i++ ) + { + int match; + + unescaped = parse_util_unescape_wildcards( argv[i] ); + match = wildcard_match( switch_value, unescaped ); + free( unescaped ); + + if( match ) + { + parser.current_block->skip = 0; + sb->switch_taken = true; + break; + } + } + + return proc_get_last_status(); } @@ -3776,7 +3776,7 @@ static int builtin_history( parser_t &parser, wchar_t **argv ) { int argc = builtin_count_args(argv); - bool search_history = false; + bool search_history = false; bool delete_item = false; bool search_prefix = false; bool save_history = false; @@ -3798,11 +3798,11 @@ static int builtin_history( parser_t &parser, wchar_t **argv ) int opt_index = 0; woptind = 0; history_t *history = reader_get_history(); - + /* Use the default history if we have none (which happens if invoked non-interactively, e.g. from webconfig.py */ if (! history) history = &history_t::history_with_name(L"fish"); - + while((opt = wgetopt_long_only( argc, argv, L"pdscvl", long_options, &opt_index )) != -1) { switch(opt) @@ -3823,7 +3823,7 @@ static int builtin_history( parser_t &parser, wchar_t **argv ) break; case 'l': clear_history = true; - break; + break; case 'h': builtin_print_help( parser, argv[0], stdout_buffer ); return STATUS_BUILTIN_OK; @@ -3839,7 +3839,7 @@ static int builtin_history( parser_t &parser, wchar_t **argv ) append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], argv[woptind-1]); return STATUS_BUILTIN_ERROR; } - } + } /* Everything after is an argument */ const wcstring_list_t args(argv + woptind, argv + argc); @@ -3869,7 +3869,7 @@ static int builtin_history( parser_t &parser, wchar_t **argv ) while (searcher.go_backwards()) { stdout_buffer.append(searcher.current_string()); - stdout_buffer.append(L"\n"); + stdout_buffer.append(L"\n"); res = STATUS_BUILTIN_OK; } } @@ -3883,7 +3883,7 @@ static int builtin_history( parser_t &parser, wchar_t **argv ) wcstring delete_string = *iter; if (delete_string[0] == '"' && delete_string[delete_string.length() - 1] == '"') delete_string = delete_string.substr(1, delete_string.length() - 2); - + history->remove(delete_string); } return STATUS_BUILTIN_OK; @@ -3919,48 +3919,48 @@ static int builtin_history( parser_t &parser, wchar_t **argv ) */ static const builtin_data_t builtin_datas[]= { - { L".", &builtin_source, N_( L"Evaluate contents of file" ) }, - { L"and", &builtin_generic, N_( L"Execute command if previous command suceeded" ) }, - { L"begin", &builtin_begin, N_( L"Create a block of code" ) }, - { L"bg", &builtin_bg, N_( L"Send job to background" ) }, - { L"bind", &builtin_bind, N_( L"Handle fish key bindings" ) }, - { L"block", &builtin_block, N_( L"Temporarily block delivery of events" ) }, - { L"break", &builtin_break_continue, N_( L"Stop the innermost loop" ) }, - { L"breakpoint", &builtin_breakpoint, N_( L"Temporarily halt execution of a script and launch an interactive debug prompt" ) }, - { L"builtin", &builtin_builtin, N_( L"Run a builtin command instead of a function" ) }, - { L"case", &builtin_case, N_( L"Conditionally execute a block of commands" ) }, - { L"cd", &builtin_cd, N_( L"Change working directory" ) }, - { L"command", &builtin_generic, N_( L"Run a program instead of a function or builtin" ) }, - { L"commandline", &builtin_commandline, N_( L"Set or get the commandline" ) }, - { L"complete", &builtin_complete, N_( L"Edit command specific completions" ) }, - { L"contains", &builtin_contains, N_( L"Search for a specified string in a list" ) }, - { L"continue", &builtin_break_continue, N_( L"Skip the rest of the current lap of the innermost loop" ) }, - { L"count", &builtin_count, N_( L"Count the number of arguments" ) }, - { L"echo", &builtin_echo, N_( L"Print arguments" ) }, - { L"else", &builtin_else, N_( L"Evaluate block if condition is false" ) }, - { L"emit", &builtin_emit, N_( L"Emit an event" ) }, - { L"end", &builtin_end, N_( L"End a block of commands" ) }, - { L"exec", &builtin_generic, N_( L"Run command in current process" ) }, - { L"exit", &builtin_exit, N_( L"Exit the shell" ) }, - { L"fg", &builtin_fg, N_( L"Send job to foreground" ) }, - { L"for", &builtin_for, N_( L"Perform a set of commands multiple times" ) }, - { L"function", &builtin_function, N_( L"Define a new function" ) }, - { L"functions", &builtin_functions, N_( L"List or remove functions" ) }, - { L"history", &builtin_history, N_( L"History of commands executed by user" ) }, - { L"if", &builtin_generic, N_( L"Evaluate block if condition is true" ) }, - { L"jobs", &builtin_jobs, N_( L"Print currently running jobs" ) }, - { L"not", &builtin_generic, N_( L"Negate exit status of job" ) }, - { L"or", &builtin_generic, N_( L"Execute command if previous command failed" ) }, - { L"pwd", &builtin_pwd, N_( L"Print the working directory" ) }, - { L"random", &builtin_random, N_( L"Generate random number" ) }, - { L"read", &builtin_read, N_( L"Read a line of input into variables" ) }, - { L"return", &builtin_return, N_( L"Stop the currently evaluated function" ) }, - { L"set", &builtin_set, N_( L"Handle environment variables" ) }, - { L"status", &builtin_status, N_( L"Return status information about fish" ) }, - { L"switch", &builtin_switch, N_( L"Conditionally execute a block of commands" ) }, - { L"test", &builtin_test, N_( L"Test a condition" ) }, - { L"ulimit", &builtin_ulimit, N_( L"Set or get the shells resource usage limits" ) }, - { L"while", &builtin_generic, N_( L"Perform a command multiple times" ) } + { L".", &builtin_source, N_( L"Evaluate contents of file" ) }, + { L"and", &builtin_generic, N_( L"Execute command if previous command suceeded" ) }, + { L"begin", &builtin_begin, N_( L"Create a block of code" ) }, + { L"bg", &builtin_bg, N_( L"Send job to background" ) }, + { L"bind", &builtin_bind, N_( L"Handle fish key bindings" ) }, + { L"block", &builtin_block, N_( L"Temporarily block delivery of events" ) }, + { L"break", &builtin_break_continue, N_( L"Stop the innermost loop" ) }, + { L"breakpoint", &builtin_breakpoint, N_( L"Temporarily halt execution of a script and launch an interactive debug prompt" ) }, + { L"builtin", &builtin_builtin, N_( L"Run a builtin command instead of a function" ) }, + { L"case", &builtin_case, N_( L"Conditionally execute a block of commands" ) }, + { L"cd", &builtin_cd, N_( L"Change working directory" ) }, + { L"command", &builtin_generic, N_( L"Run a program instead of a function or builtin" ) }, + { L"commandline", &builtin_commandline, N_( L"Set or get the commandline" ) }, + { L"complete", &builtin_complete, N_( L"Edit command specific completions" ) }, + { L"contains", &builtin_contains, N_( L"Search for a specified string in a list" ) }, + { L"continue", &builtin_break_continue, N_( L"Skip the rest of the current lap of the innermost loop" ) }, + { L"count", &builtin_count, N_( L"Count the number of arguments" ) }, + { L"echo", &builtin_echo, N_( L"Print arguments" ) }, + { L"else", &builtin_else, N_( L"Evaluate block if condition is false" ) }, + { L"emit", &builtin_emit, N_( L"Emit an event" ) }, + { L"end", &builtin_end, N_( L"End a block of commands" ) }, + { L"exec", &builtin_generic, N_( L"Run command in current process" ) }, + { L"exit", &builtin_exit, N_( L"Exit the shell" ) }, + { L"fg", &builtin_fg, N_( L"Send job to foreground" ) }, + { L"for", &builtin_for, N_( L"Perform a set of commands multiple times" ) }, + { L"function", &builtin_function, N_( L"Define a new function" ) }, + { L"functions", &builtin_functions, N_( L"List or remove functions" ) }, + { L"history", &builtin_history, N_( L"History of commands executed by user" ) }, + { L"if", &builtin_generic, N_( L"Evaluate block if condition is true" ) }, + { L"jobs", &builtin_jobs, N_( L"Print currently running jobs" ) }, + { L"not", &builtin_generic, N_( L"Negate exit status of job" ) }, + { L"or", &builtin_generic, N_( L"Execute command if previous command failed" ) }, + { L"pwd", &builtin_pwd, N_( L"Print the working directory" ) }, + { L"random", &builtin_random, N_( L"Generate random number" ) }, + { L"read", &builtin_read, N_( L"Read a line of input into variables" ) }, + { L"return", &builtin_return, N_( L"Stop the currently evaluated function" ) }, + { L"set", &builtin_set, N_( L"Handle environment variables" ) }, + { L"status", &builtin_status, N_( L"Return status information about fish" ) }, + { L"switch", &builtin_switch, N_( L"Conditionally execute a block of commands" ) }, + { L"test", &builtin_test, N_( L"Test a condition" ) }, + { L"ulimit", &builtin_ulimit, N_( L"Set or get the shells resource usage limits" ) }, + { L"while", &builtin_generic, N_( L"Perform a command multiple times" ) } }; #define BUILTIN_COUNT (sizeof builtin_datas / sizeof *builtin_datas) @@ -3977,12 +3977,12 @@ static const builtin_data_t *builtin_lookup(const wcstring &name) { void builtin_init() { - - wopterr = 0; - for( size_t i=0; i < BUILTIN_COUNT; i++ ) - { - intern_static( builtin_datas[i].name ); - } + + wopterr = 0; + for( size_t i=0; i < BUILTIN_COUNT; i++ ) + { + intern_static( builtin_datas[i].name ); + } } void builtin_destroy() @@ -3991,7 +3991,7 @@ void builtin_destroy() int builtin_exists( const wcstring &cmd ) { - return !!builtin_lookup(cmd); + return !!builtin_lookup(cmd); } /** @@ -4000,45 +4000,45 @@ int builtin_exists( const wcstring &cmd ) */ static int internal_help( const wchar_t *cmd ) { - CHECK( cmd, 0 ); - return contains( cmd, L"for", L"while", L"function", - L"if", L"end", L"switch", L"case", L"count" ); + CHECK( cmd, 0 ); + return contains( cmd, L"for", L"while", L"function", + L"if", L"end", L"switch", L"case", L"count" ); } int builtin_run( parser_t &parser, const wchar_t * const *argv, const io_chain_t &io ) { - int (*cmd)(parser_t &parser, const wchar_t * const *argv)=0; - real_io = &io; - - CHECK( argv, STATUS_BUILTIN_ERROR ); - CHECK( argv[0], STATUS_BUILTIN_ERROR ); - + int (*cmd)(parser_t &parser, const wchar_t * const *argv)=0; + real_io = &io; + + CHECK( argv, STATUS_BUILTIN_ERROR ); + CHECK( argv[0], STATUS_BUILTIN_ERROR ); + const builtin_data_t *data = builtin_lookup(argv[0]); - cmd = (int (*)(parser_t &parser, const wchar_t * const*))(data ? data->func : NULL); - - if( argv[1] != 0 && !internal_help(argv[0]) ) - { - if( argv[2] == 0 && (parser.is_help( argv[1], 0 ) ) ) - { - builtin_print_help( parser, argv[0], stdout_buffer ); - return STATUS_BUILTIN_OK; - } - } - - if( data != NULL ) - { - int status; - - status = cmd(parser, argv); - return status; - - } - else - { - debug( 0, _( L"Unknown builtin '%ls'" ), argv[0] ); - } - return STATUS_BUILTIN_ERROR; + cmd = (int (*)(parser_t &parser, const wchar_t * const*))(data ? data->func : NULL); + + if( argv[1] != 0 && !internal_help(argv[0]) ) + { + if( argv[2] == 0 && (parser.is_help( argv[1], 0 ) ) ) + { + builtin_print_help( parser, argv[0], stdout_buffer ); + return STATUS_BUILTIN_OK; + } + } + + if( data != NULL ) + { + int status; + + status = cmd(parser, argv); + return status; + + } + else + { + debug( 0, _( L"Unknown builtin '%ls'" ), argv[0] ); + } + return STATUS_BUILTIN_ERROR; } @@ -4053,15 +4053,15 @@ wcstring_list_t builtin_get_names(void) } void builtin_get_names(std::vector<completion_t> &list) { - for (size_t i=0; i < BUILTIN_COUNT; i++) { - list.push_back(completion_t(builtin_datas[i].name)); - } + for (size_t i=0; i < BUILTIN_COUNT; i++) { + list.push_back(completion_t(builtin_datas[i].name)); + } } wcstring builtin_get_desc( const wcstring &name ) { wcstring result; - const builtin_data_t *builtin = builtin_lookup(name); + const builtin_data_t *builtin = builtin_lookup(name); if (builtin) { result = _(builtin->desc); } @@ -4071,12 +4071,12 @@ wcstring builtin_get_desc( const wcstring &name ) void builtin_push_io( parser_t &parser, int in ) { ASSERT_IS_MAIN_THREAD(); - if( builtin_stdin != -1 ) - { + if( builtin_stdin != -1 ) + { struct io_stack_elem_t elem = {builtin_stdin, stdout_buffer, stderr_buffer}; io_stack.push(elem); - } - builtin_stdin = in; + } + builtin_stdin = in; stdout_buffer.clear(); stderr_buffer.clear(); } @@ -4084,20 +4084,20 @@ void builtin_push_io( parser_t &parser, int in ) void builtin_pop_io(parser_t &parser) { ASSERT_IS_MAIN_THREAD(); - builtin_stdin = 0; - if( ! io_stack.empty() ) - { + builtin_stdin = 0; + if( ! io_stack.empty() ) + { struct io_stack_elem_t &elem = io_stack.top(); - stderr_buffer = elem.err; - stdout_buffer = elem.out; - builtin_stdin = elem.in; + stderr_buffer = elem.err; + stdout_buffer = elem.out; + builtin_stdin = elem.in; io_stack.pop(); - } - else - { + } + else + { stdout_buffer.clear(); stderr_buffer.clear(); - builtin_stdin = 0; - } + builtin_stdin = 0; + } } |