If a help page for a builtin is showed in response to an error, make sure it fits on screen, or only print the synopsis - this patch also contains a huge number of tweaks to where and when the help pages are printed

darcs-hash:20060526112402-ac50b-88993e45f411b2f1c45b3202c393c5328f1c7429.gz
This commit is contained in:
axel 2006-05-26 21:24:02 +10:00
parent 18a59291ed
commit 17171c3277
7 changed files with 181 additions and 39 deletions

125
builtin.c
View file

@ -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 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 are part of the parser. (They are not parsed as commands, instead
they only slightly alter the parser state) 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 ) void builtin_print_help( wchar_t *cmd, string_buffer_t *b )
{ {
const char *h; const char *h;
@ -189,11 +200,50 @@ void builtin_print_help( wchar_t *cmd, string_buffer_t *b )
if( !h ) if( !h )
return; return;
wchar_t *str = str2wcs( h );
wchar_t *str = str2wcs(builtin_help_get( cmd ));
if( str ) 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 ); sb_append( b, str );
free( str ); free( str );
} }
@ -215,6 +265,10 @@ static int builtin_bind( wchar_t **argv )
L"set-mode", required_argument, 0, 'M' L"set-mode", required_argument, 0, 'M'
} }
, ,
{
L"help", no_argument, 0, 'h'
}
,
{ {
0, 0, 0, 0 0, 0, 0, 0
} }
@ -227,7 +281,7 @@ static int builtin_bind( wchar_t **argv )
int opt = wgetopt_long( argc, int opt = wgetopt_long( argc,
argv, argv,
L"M:", L"M:h",
long_options, long_options,
&opt_index ); &opt_index );
if( opt == -1 ) if( opt == -1 )
@ -250,6 +304,10 @@ static int builtin_bind( wchar_t **argv )
input_set_mode( woptarg ); input_set_mode( woptarg );
break; break;
case 'h':
builtin_print_help( argv[0], sb_out );
return 0;
case '?': case '?':
builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
@ -337,7 +395,7 @@ static int builtin_block( wchar_t **argv )
return 1; return 1;
case 'h': case 'h':
builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_out );
return 0; return 0;
case 'g': case 'g':
@ -478,7 +536,7 @@ static int builtin_builtin( wchar_t **argv )
return 1; return 1;
case 'h': case 'h':
builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_out );
return 0; return 0;
case 'n': case 'n':
@ -701,6 +759,10 @@ static int builtin_functions( wchar_t **argv )
L"all", no_argument, 0, 'a' L"all", no_argument, 0, 'a'
} }
, ,
{
L"help", no_argument, 0, 'h'
}
,
{ {
0, 0, 0, 0 0, 0, 0, 0
} }
@ -713,7 +775,7 @@ static int builtin_functions( wchar_t **argv )
int opt = wgetopt_long( argc, int opt = wgetopt_long( argc,
argv, argv,
L"ed:na", L"ed:nah",
long_options, long_options,
&opt_index ); &opt_index );
if( opt == -1 ) if( opt == -1 )
@ -749,6 +811,10 @@ static int builtin_functions( wchar_t **argv )
show_hidden=1; show_hidden=1;
break; break;
case 'h':
builtin_print_help( argv[0], sb_out );
return 0;
case '?': case '?':
builtin_print_help( argv[0], sb_err ); 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"on-variable", required_argument, 0, 'v'
} }
, ,
{
L"help", no_argument, 0, 'h'
}
,
{ {
0, 0, 0, 0 0, 0, 0, 0
} }
@ -960,7 +1030,7 @@ static int builtin_function( wchar_t **argv )
int opt = wgetopt_long( argc, int opt = wgetopt_long( argc,
argv, argv,
L"bd:s:j:p:v:", L"bd:s:j:p:v:h",
long_options, long_options,
&opt_index ); &opt_index );
if( opt == -1 ) if( opt == -1 )
@ -1114,6 +1184,10 @@ static int builtin_function( wchar_t **argv )
break; break;
} }
case 'h':
builtin_print_help( argv[0], sb_out );
return 0;
case '?': case '?':
builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
res = 1; res = 1;
@ -1160,7 +1234,7 @@ static int builtin_function( wchar_t **argv )
array_list_t names; array_list_t names;
int chars=0; 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: " ); const wchar_t *cfa = _( L"Current functions are: " );
sb_append( sb_err, cfa ); sb_append( sb_err, cfa );
chars += wcslen( cfa ); chars += wcslen( cfa );
@ -1258,7 +1332,7 @@ static int builtin_random( wchar_t **argv )
return 1; return 1;
case 'h': case 'h':
builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_out );
break; break;
case '?': case '?':
@ -1368,6 +1442,10 @@ static int builtin_read( wchar_t **argv )
L"command", required_argument, 0, 'c' L"command", required_argument, 0, 'c'
} }
, ,
{
L"help", no_argument, 0, 'h'
}
,
{ {
0, 0, 0, 0 0, 0, 0, 0
} }
@ -1378,7 +1456,7 @@ static int builtin_read( wchar_t **argv )
int opt = wgetopt_long( argc, int opt = wgetopt_long( argc,
argv, argv,
L"xglUup:c:", L"xglUup:c:h",
long_options, long_options,
&opt_index ); &opt_index );
if( opt == -1 ) if( opt == -1 )
@ -1419,6 +1497,10 @@ static int builtin_read( wchar_t **argv )
commandline = woptarg; commandline = woptarg;
break; break;
case 'h':
builtin_print_help( argv[0], sb_out );
return 0;
case L'?': case L'?':
builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
@ -1695,7 +1777,7 @@ static int builtin_status( wchar_t **argv )
return 1; return 1;
case 'h': case 'h':
builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_out );
return 0; return 0;
case 'j': case 'j':
@ -1849,7 +1931,7 @@ static int builtin_exit( wchar_t **argv )
default: default:
sb_printf( sb_err, sb_printf( sb_err,
_( L"%ls: Too many arguments\n" ), BUILTIN_ERR_TOO_MANY_ARGUMENTS,
argv[0] ); argv[0] );
builtin_print_help( argv[0], sb_err ); 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"last", no_argument, 0, 'l'
} }
, ,
{
L"help", no_argument, 0, 'h'
}
,
{ {
0, 0, 0, 0 0, 0, 0, 0
} }
@ -2422,7 +2508,7 @@ static int builtin_jobs( wchar_t **argv )
int opt = wgetopt_long( argc, int opt = wgetopt_long( argc,
argv, argv,
L"pclg", L"pclgh",
long_options, long_options,
&opt_index ); &opt_index );
if( opt == -1 ) if( opt == -1 )
@ -2440,7 +2526,7 @@ static int builtin_jobs( wchar_t **argv )
sb_append( sb_err, sb_append( sb_err,
parser_current_line() ); parser_current_line() );
// builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
return 1; return 1;
@ -2464,9 +2550,12 @@ static int builtin_jobs( wchar_t **argv )
break; break;
} }
case 'h':
builtin_print_help( argv[0], sb_out );
return 0;
case '?': case '?':
// builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
return 1; return 1;

View file

@ -62,6 +62,8 @@ enum
*/ */
#define BUILTIN_FOR_ERR_IN _( L"%ls: Second argument must be 'in'\n" ) #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 Stringbuffer used to represent standard output
*/ */

View file

@ -265,6 +265,10 @@ int builtin_commandline( wchar_t **argv )
L"tokenize", no_argument, 0, 'o' L"tokenize", no_argument, 0, 'o'
} }
, ,
{
L"help", no_argument, 0, 'h'
}
,
{ {
0, 0, 0, 0 0, 0, 0, 0
} }
@ -275,7 +279,7 @@ int builtin_commandline( wchar_t **argv )
int opt = wgetopt_long( argc, int opt = wgetopt_long( argc,
argv, argv,
L"aijpctwfor", L"aijpctwforh",
long_options, long_options,
&opt_index ); &opt_index );
if( opt == -1 ) if( opt == -1 )
@ -330,6 +334,10 @@ int builtin_commandline( wchar_t **argv )
tokenize=1; tokenize=1;
break; break;
case 'h':
builtin_print_help( argv[0], sb_out );
return 0;
case L'?': case L'?':
builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
return 1; return 1;

View file

@ -341,6 +341,10 @@ int builtin_complete( wchar_t **argv )
L"do-complete", required_argument, 0, 'C' L"do-complete", required_argument, 0, 'C'
} }
, ,
{
L"help", no_argument, 0, 'h'
}
,
{ {
0, 0, 0, 0 0, 0, 0, 0
} }
@ -351,7 +355,7 @@ int builtin_complete( wchar_t **argv )
int opt = wgetopt_long( argc, int opt = wgetopt_long( argc,
argv, argv,
L"a:c:p:s:l:o:d:frxeun:C:", L"a:c:p:s:l:o:d:frxeun:C:h",
long_options, long_options,
&opt_index ); &opt_index );
if( opt == -1 ) if( opt == -1 )
@ -369,7 +373,7 @@ int builtin_complete( wchar_t **argv )
sb_append( sb_err, sb_append( sb_err,
parser_current_line() ); parser_current_line() );
// builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
res = 1; res = 1;
@ -431,10 +435,14 @@ int builtin_complete( wchar_t **argv )
do_complete = woptarg?woptarg:reader_get_buffer(); do_complete = woptarg?woptarg:reader_get_buffer();
break; break;
case 'h':
builtin_print_help( argv[0], sb_out );
return 0;
case '?': case '?':
sb_append( sb_err, sb_append( sb_err,
parser_current_line() ); parser_current_line() );
// builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
res = 1; res = 1;
break; break;
@ -521,7 +529,7 @@ int builtin_complete( wchar_t **argv )
argv[0] ); argv[0] );
sb_append( sb_err, sb_append( sb_err,
parser_current_line() ); parser_current_line() );
// builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
res = 1; res = 1;
} }

View file

@ -373,35 +373,47 @@ int builtin_set( wchar_t **argv )
{ {
{ {
L"export", no_argument, 0, 'x' L"export", no_argument, 0, 'x'
}, }
,
{ {
L"global", no_argument, 0, 'g' L"global", no_argument, 0, 'g'
}, }
,
{ {
L"local", no_argument, 0, 'l' L"local", no_argument, 0, 'l'
}, }
,
{ {
L"erase", no_argument, 0, 'e' L"erase", no_argument, 0, 'e'
}, }
,
{ {
L"names", no_argument, 0, 'n' L"names", no_argument, 0, 'n'
} , }
,
{ {
L"unexport", no_argument, 0, 'u' L"unexport", no_argument, 0, 'u'
} , }
,
{ {
L"universal", no_argument, 0, 'U' L"universal", no_argument, 0, 'U'
} , }
,
{ {
L"query", no_argument, 0, 'q' L"query", no_argument, 0, 'q'
} , }
,
{
L"help", no_argument, 0, 'h'
}
,
{ {
0, 0, 0, 0 0, 0, 0, 0
} }
} }
; ;
const wchar_t *short_options = L"+xglenuUq"; const wchar_t *short_options = L"+xglenuUqh";
int argc = builtin_count_args(argv); int argc = builtin_count_args(argv);
@ -438,32 +450,47 @@ int builtin_set( wchar_t **argv )
{ {
case 0: case 0:
break; break;
case 'e': case 'e':
erase = 1; erase = 1;
break; break;
case 'n': case 'n':
list = 1; list = 1;
break; break;
case 'x': case 'x':
export = 1; export = 1;
break; break;
case 'l': case 'l':
local = 1; local = 1;
break; break;
case 'g': case 'g':
global = 1; global = 1;
break; break;
case 'u': case 'u':
unexport = 1; unexport = 1;
break; break;
case 'U': case 'U':
universal = 1; universal = 1;
break; break;
case 'q': case 'q':
query = 1; query = 1;
break; break;
case 'h':
builtin_print_help( argv[0], sb_out );
return 0;
case '?': case '?':
builtin_print_help( argv[0], sb_err );
return 1; return 1;
default: default:
break; break;
} }
@ -485,7 +512,7 @@ int builtin_set( wchar_t **argv )
argv[0], argv[0],
parser_current_line() ); parser_current_line() );
// builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
return 1; return 1;
} }
@ -498,7 +525,7 @@ int builtin_set( wchar_t **argv )
argv[0], argv[0],
parser_current_line() ); parser_current_line() );
// builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
return 1; return 1;
} }
@ -511,7 +538,7 @@ int builtin_set( wchar_t **argv )
BUILTIN_ERR_GLOCAL, BUILTIN_ERR_GLOCAL,
argv[0], argv[0],
parser_current_line() ); parser_current_line() );
// builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
return 1; return 1;
} }
@ -524,7 +551,7 @@ int builtin_set( wchar_t **argv )
BUILTIN_ERR_EXPUNEXP, BUILTIN_ERR_EXPUNEXP,
argv[0], argv[0],
parser_current_line() ); parser_current_line() );
// builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
return 1; return 1;
} }
@ -564,7 +591,7 @@ int builtin_set( wchar_t **argv )
argv[0], argv[0],
parser_current_line() ); parser_current_line() );
// builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
retcode = 1; retcode = 1;
} }
else else

View file

@ -326,6 +326,10 @@ int builtin_ulimit( wchar_t ** argv )
L"virtual-memory-size", no_argument, 0, 'v' L"virtual-memory-size", no_argument, 0, 'v'
} }
, ,
{
L"help", no_argument, 0, 'h'
}
,
{ {
0, 0, 0, 0 0, 0, 0, 0
} }
@ -337,7 +341,7 @@ int builtin_ulimit( wchar_t ** argv )
int opt = wgetopt_long( argc, int opt = wgetopt_long( argc,
argv, argv,
L"aHScdflmnptuv", L"aHScdflmnptuvh",
long_options, long_options,
&opt_index ); &opt_index );
if( opt == -1 ) if( opt == -1 )
@ -415,6 +419,10 @@ int builtin_ulimit( wchar_t ** argv )
break; break;
#endif #endif
case L'h':
builtin_print_help( argv[0], sb_out );
return 0;
case L'?': case L'?':
builtin_print_help( argv[0], sb_err ); builtin_print_help( argv[0], sb_err );
return 1; return 1;