diff --git a/builtin.c b/builtin.c index e5b3b4b10..4c49b734f 100644 --- a/builtin.c +++ b/builtin.c @@ -159,6 +159,15 @@ 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; +} /* Here follows the definition of all builtin commands. The function @@ -170,10 +179,12 @@ void builtin_wperror( const wchar_t *s) are part of the parser. (They are not parsed as commands, instead they only slightly alter the parser state) + If \c b is the buffer representing standard error, and the help + message is about to be printed to an interactive screen, it may be + shortened to fit the screen. + */ - - void builtin_print_help( wchar_t *cmd, string_buffer_t *b ) { const char *h; @@ -189,11 +200,50 @@ void builtin_print_help( wchar_t *cmd, string_buffer_t *b ) if( !h ) return; - - - wchar_t *str = str2wcs(builtin_help_get( cmd )); + wchar_t *str = str2wcs( h ); if( str ) { + + if( is_interactive && !builtin_out_redirect && b==sb_err) + { + /* 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( lines > 2*screen_height/3 ) + { + wchar_t *pos; + + /* Find first empty line */ + for( pos=str; *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 ) + { + *(pos+1)=L'\0'; + } + } + } + } + } + sb_append( b, str ); free( str ); } @@ -215,6 +265,10 @@ static int builtin_bind( wchar_t **argv ) L"set-mode", required_argument, 0, 'M' } , + { + L"help", no_argument, 0, 'h' + } + , { 0, 0, 0, 0 } @@ -227,7 +281,7 @@ static int builtin_bind( wchar_t **argv ) int opt = wgetopt_long( argc, argv, - L"M:", + L"M:h", long_options, &opt_index ); if( opt == -1 ) @@ -250,6 +304,10 @@ static int builtin_bind( wchar_t **argv ) input_set_mode( woptarg ); break; + case 'h': + builtin_print_help( argv[0], sb_out ); + return 0; + case '?': builtin_print_help( argv[0], sb_err ); @@ -337,7 +395,7 @@ static int builtin_block( wchar_t **argv ) return 1; case 'h': - builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_out ); return 0; case 'g': @@ -478,7 +536,7 @@ static int builtin_builtin( wchar_t **argv ) return 1; case 'h': - builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_out ); return 0; case 'n': @@ -701,6 +759,10 @@ static int builtin_functions( wchar_t **argv ) L"all", no_argument, 0, 'a' } , + { + L"help", no_argument, 0, 'h' + } + , { 0, 0, 0, 0 } @@ -713,7 +775,7 @@ static int builtin_functions( wchar_t **argv ) int opt = wgetopt_long( argc, argv, - L"ed:na", + L"ed:nah", long_options, &opt_index ); if( opt == -1 ) @@ -749,6 +811,10 @@ static int builtin_functions( wchar_t **argv ) show_hidden=1; break; + case 'h': + builtin_print_help( argv[0], sb_out ); + return 0; + case '?': builtin_print_help( argv[0], sb_err ); @@ -948,6 +1014,10 @@ static int builtin_function( wchar_t **argv ) L"on-variable", required_argument, 0, 'v' } , + { + L"help", no_argument, 0, 'h' + } + , { 0, 0, 0, 0 } @@ -960,7 +1030,7 @@ static int builtin_function( wchar_t **argv ) int opt = wgetopt_long( argc, argv, - L"bd:s:j:p:v:", + L"bd:s:j:p:v:h", long_options, &opt_index ); if( opt == -1 ) @@ -1114,6 +1184,10 @@ static int builtin_function( wchar_t **argv ) break; } + case 'h': + builtin_print_help( argv[0], sb_out ); + return 0; + case '?': builtin_print_help( argv[0], sb_err ); res = 1; @@ -1160,7 +1234,7 @@ static int builtin_function( wchar_t **argv ) array_list_t names; int chars=0; -// builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_err ); const wchar_t *cfa = _( L"Current functions are: " ); sb_append( sb_err, cfa ); chars += wcslen( cfa ); @@ -1258,7 +1332,7 @@ static int builtin_random( wchar_t **argv ) return 1; case 'h': - builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_out ); break; case '?': @@ -1368,6 +1442,10 @@ static int builtin_read( wchar_t **argv ) L"command", required_argument, 0, 'c' } , + { + L"help", no_argument, 0, 'h' + } + , { 0, 0, 0, 0 } @@ -1378,7 +1456,7 @@ static int builtin_read( wchar_t **argv ) int opt = wgetopt_long( argc, argv, - L"xglUup:c:", + L"xglUup:c:h", long_options, &opt_index ); if( opt == -1 ) @@ -1419,6 +1497,10 @@ static int builtin_read( wchar_t **argv ) commandline = woptarg; break; + case 'h': + builtin_print_help( argv[0], sb_out ); + return 0; + case L'?': builtin_print_help( argv[0], sb_err ); @@ -1695,7 +1777,7 @@ static int builtin_status( wchar_t **argv ) return 1; case 'h': - builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_out ); return 0; case 'j': @@ -1849,7 +1931,7 @@ static int builtin_exit( wchar_t **argv ) default: sb_printf( sb_err, - _( L"%ls: Too many arguments\n" ), + BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0] ); builtin_print_help( argv[0], sb_err ); @@ -2412,6 +2494,10 @@ static int builtin_jobs( wchar_t **argv ) L"last", no_argument, 0, 'l' } , + { + L"help", no_argument, 0, 'h' + } + , { 0, 0, 0, 0 } @@ -2422,7 +2508,7 @@ static int builtin_jobs( wchar_t **argv ) int opt = wgetopt_long( argc, argv, - L"pclg", + L"pclgh", long_options, &opt_index ); if( opt == -1 ) @@ -2440,7 +2526,7 @@ static int builtin_jobs( wchar_t **argv ) sb_append( sb_err, parser_current_line() ); -// builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_err ); return 1; @@ -2464,9 +2550,12 @@ static int builtin_jobs( wchar_t **argv ) break; } + case 'h': + builtin_print_help( argv[0], sb_out ); + return 0; case '?': - // builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_err ); return 1; diff --git a/builtin.h b/builtin.h index f00eecef5..3249f978f 100644 --- a/builtin.h +++ b/builtin.h @@ -62,6 +62,8 @@ enum */ #define BUILTIN_FOR_ERR_IN _( L"%ls: Second argument must be 'in'\n" ) +#define BUILTIN_ERR_TOO_MANY_ARGUMENTS _( L"%ls: Too many arguments\n" ) + /** Stringbuffer used to represent standard output */ diff --git a/builtin_commandline.c b/builtin_commandline.c index 500a27dec..3d0f77e0b 100644 --- a/builtin_commandline.c +++ b/builtin_commandline.c @@ -265,6 +265,10 @@ int builtin_commandline( wchar_t **argv ) L"tokenize", no_argument, 0, 'o' } , + { + L"help", no_argument, 0, 'h' + } + , { 0, 0, 0, 0 } @@ -275,7 +279,7 @@ int builtin_commandline( wchar_t **argv ) int opt = wgetopt_long( argc, argv, - L"aijpctwfor", + L"aijpctwforh", long_options, &opt_index ); if( opt == -1 ) @@ -330,6 +334,10 @@ int builtin_commandline( wchar_t **argv ) tokenize=1; break; + case 'h': + builtin_print_help( argv[0], sb_out ); + return 0; + case L'?': builtin_print_help( argv[0], sb_err ); return 1; diff --git a/builtin_complete.c b/builtin_complete.c index 69b5d8ba9..3e4268c66 100644 --- a/builtin_complete.c +++ b/builtin_complete.c @@ -341,6 +341,10 @@ int builtin_complete( wchar_t **argv ) L"do-complete", required_argument, 0, 'C' } , + { + L"help", no_argument, 0, 'h' + } + , { 0, 0, 0, 0 } @@ -351,7 +355,7 @@ int builtin_complete( wchar_t **argv ) int opt = wgetopt_long( argc, argv, - L"a:c:p:s:l:o:d:frxeun:C:", + L"a:c:p:s:l:o:d:frxeun:C:h", long_options, &opt_index ); if( opt == -1 ) @@ -369,7 +373,7 @@ int builtin_complete( wchar_t **argv ) sb_append( sb_err, parser_current_line() ); -// builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_err ); res = 1; @@ -431,10 +435,14 @@ int builtin_complete( wchar_t **argv ) do_complete = woptarg?woptarg:reader_get_buffer(); break; + case 'h': + builtin_print_help( argv[0], sb_out ); + return 0; + case '?': sb_append( sb_err, parser_current_line() ); - // builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_err ); res = 1; break; @@ -521,7 +529,7 @@ int builtin_complete( wchar_t **argv ) argv[0] ); sb_append( sb_err, parser_current_line() ); - // builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_err ); res = 1; } diff --git a/builtin_set.c b/builtin_set.c index 4a0cbb909..3c64da4bb 100644 --- a/builtin_set.c +++ b/builtin_set.c @@ -373,35 +373,47 @@ int builtin_set( wchar_t **argv ) { { L"export", no_argument, 0, 'x' - }, + } + , { L"global", no_argument, 0, 'g' - }, + } + , { L"local", no_argument, 0, 'l' - }, + } + , { L"erase", no_argument, 0, 'e' - }, + } + , { L"names", no_argument, 0, 'n' - } , + } + , { L"unexport", no_argument, 0, 'u' - } , + } + , { L"universal", no_argument, 0, 'U' - } , + } + , { L"query", no_argument, 0, 'q' - } , + } + , + { + L"help", no_argument, 0, 'h' + } + , { 0, 0, 0, 0 } } ; - const wchar_t *short_options = L"+xglenuUq"; + const wchar_t *short_options = L"+xglenuUqh"; int argc = builtin_count_args(argv); @@ -438,32 +450,47 @@ int builtin_set( wchar_t **argv ) { case 0: break; + case 'e': erase = 1; break; + case 'n': list = 1; break; + case 'x': export = 1; break; + case 'l': local = 1; break; + case 'g': global = 1; break; + case 'u': unexport = 1; break; + case 'U': universal = 1; break; + case 'q': query = 1; break; + + case 'h': + builtin_print_help( argv[0], sb_out ); + return 0; + case '?': + builtin_print_help( argv[0], sb_err ); return 1; + default: break; } @@ -485,7 +512,7 @@ int builtin_set( wchar_t **argv ) argv[0], parser_current_line() ); -// builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_err ); return 1; } @@ -498,7 +525,7 @@ int builtin_set( wchar_t **argv ) argv[0], parser_current_line() ); -// builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_err ); return 1; } @@ -511,7 +538,7 @@ int builtin_set( wchar_t **argv ) BUILTIN_ERR_GLOCAL, argv[0], parser_current_line() ); -// builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_err ); return 1; } @@ -524,7 +551,7 @@ int builtin_set( wchar_t **argv ) BUILTIN_ERR_EXPUNEXP, argv[0], parser_current_line() ); -// builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_err ); return 1; } @@ -564,7 +591,7 @@ int builtin_set( wchar_t **argv ) argv[0], parser_current_line() ); -// builtin_print_help( argv[0], sb_err ); + builtin_print_help( argv[0], sb_err ); retcode = 1; } else diff --git a/builtin_ulimit.c b/builtin_ulimit.c index 80793dac3..d03521939 100644 --- a/builtin_ulimit.c +++ b/builtin_ulimit.c @@ -326,6 +326,10 @@ int builtin_ulimit( wchar_t ** argv ) L"virtual-memory-size", no_argument, 0, 'v' } , + { + L"help", no_argument, 0, 'h' + } + , { 0, 0, 0, 0 } @@ -337,7 +341,7 @@ int builtin_ulimit( wchar_t ** argv ) int opt = wgetopt_long( argc, argv, - L"aHScdflmnptuv", + L"aHScdflmnptuvh", long_options, &opt_index ); if( opt == -1 ) @@ -415,6 +419,10 @@ int builtin_ulimit( wchar_t ** argv ) break; #endif + case L'h': + builtin_print_help( argv[0], sb_out ); + return 0; + case L'?': builtin_print_help( argv[0], sb_err ); return 1; diff --git a/complete.c b/complete.c index 00ed2818d..e3e9a0f7f 100644 --- a/complete.c +++ b/complete.c @@ -2071,7 +2071,7 @@ void complete( const wchar_t *cmd, } } - + free( current_token ); free( current_command ); free( prev_token );