[vlc-devel] vlc --help is useless on windows
Brian Robb
vascy at hotmail.com
Sun Sep 4 03:19:56 CEST 2005
The command: vlc --help is useless on windows, because vlc spawns a dos
window
and prints the help info into it, leaving all but the last bit of help
visible.
(You can't scroll up on windows...)
You can't redirect it like: "vlc --help > help.txt" so you're stuck.
Solution: print the help info to a text file...
Here's what I did:
In libvlc.c I changed the Help function to (Line 2046, libvlc.c):
static void Help( vlc_t *p_this, char const *psz_help_name )
{
FILE* output = NULL;
#ifdef WIN32
ShowConsole();
#endif
#ifdef WIN32
output = fopen("vlc-help.txt", "wt+"); // wt+ rather than wb+ to convert \n
into \r\n
#endif
if (output == NULL) {
output = stderr;
}
if( psz_help_name && !strcmp( psz_help_name, "help" ) )
{
fprintf( output, VLC_USAGE, p_this->psz_object_name );
Usage( p_this, output, "help" );
Usage( p_this, output, "main" );
}
else if( psz_help_name && !strcmp( psz_help_name, "longhelp" ) )
{
fprintf( stdout, VLC_USAGE, p_this->psz_object_name );
Usage( p_this, output, NULL );
}
else if( psz_help_name )
{
Usage( p_this, output, psz_help_name );
}
#ifdef WIN32
if (output != NULL && (output != stderr && output != stdout)) {
fprintf (stderr, "Created vlc-help.txt...\n");
fclose(output);
}
output = NULL;
#endif
#ifdef WIN32 /* Pause the console because it's destroyed when we exit
*/
PauseConsole();
#endif
}
Note: If you comment out the line:
output = fopen("vlc-help.txt", "wt+"); // wt+ rather than wb+ to convert \n
into \r\n
It'll revert to the previous way of doing things.
-------------------------------------------------
Then change the prototype for Usage to (Line 100, libvlc.c):
static void Usage ( vlc_t *, FILE* output, char const
*psz_module_name );
I then changed the Usage function to (Line 2096, libvlc.c):
( Note I've just added a parameter FILE* output
and changed fprintf (stderr, ...); to fprintf(output, ...); )
static void Usage( vlc_t *p_this, FILE* output, char const *psz_module_name
)
{
#define FORMAT_STRING " %s --%s%s%s%s%s%s%s "
/* short option ------' | | | | | | |
* option name ------------' | | | | | |
* <bra -------------------------' | | | | |
* option type or "" --------------' | | | |
* ket> -----------------------------' | | |
* padding spaces ---------------------' | |
* comment -------------------------------' |
* comment suffix --------------------------'
*
* The purpose of having bra and ket is that we might i18n them as well.
*/
#define LINE_START 8
#define PADDING_SPACES 25
vlc_list_t *p_list;
module_t *p_parser;
module_config_t *p_item;
char psz_spaces_text[PADDING_SPACES+LINE_START+1];
char psz_spaces_longtext[LINE_START+3];
char psz_format[sizeof(FORMAT_STRING)];
char psz_buffer[10000];
char psz_short[4];
int i_index;
int i_width = ConsoleWidth() - (PADDING_SPACES+LINE_START+1);
vlc_bool_t b_advanced = config_GetInt( p_this, "advanced" );
vlc_bool_t b_description;
memset( psz_spaces_text, ' ', PADDING_SPACES+LINE_START );
psz_spaces_text[PADDING_SPACES+LINE_START] = '\0';
memset( psz_spaces_longtext, ' ', LINE_START+2 );
psz_spaces_longtext[LINE_START+2] = '\0';
strcpy( psz_format, FORMAT_STRING );
/* List all modules */
p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
/* Enumerate the config for each module */
for( i_index = 0; i_index < p_list->i_count; i_index++ )
{
vlc_bool_t b_help_module;
p_parser = (module_t *)p_list->p_values[i_index].p_object ;
if( psz_module_name && strcmp( psz_module_name,
p_parser->psz_object_name ) )
{
continue;
}
/* Ignore modules without config options */
if( !p_parser->i_config_items )
{
continue;
}
/* Ignore modules with only advanced config options if requested */
if( !b_advanced )
{
for( p_item = p_parser->p_config;
p_item->i_type != CONFIG_HINT_END;
p_item++ )
{
if( (p_item->i_type & CONFIG_ITEM) &&
!p_item->b_advanced ) break;
}
if( p_item->i_type == CONFIG_HINT_END ) continue;
}
/* Print name of module */
if( strcmp( "main", p_parser->psz_object_name ) )
fprintf( output, "\n %s\n", p_parser->psz_longname );
b_help_module = !strcmp( "help", p_parser->psz_object_name );
/* Print module options */
for( p_item = p_parser->p_config;
p_item->i_type != CONFIG_HINT_END;
p_item++ )
{
char *psz_text, *psz_spaces = psz_spaces_text;
char *psz_bra = NULL, *psz_type = NULL, *psz_ket = NULL;
char *psz_suf = "", *psz_prefix = NULL;
signed int i;
/* Skip deprecated options */
if( p_item->psz_current )
{
continue;
}
/* Skip advanced options if requested */
if( p_item->b_advanced && !b_advanced )
{
continue;
}
switch( p_item->i_type )
{
case CONFIG_HINT_CATEGORY:
case CONFIG_HINT_USAGE:
if( !strcmp( "main", p_parser->psz_object_name ) )
fprintf( output, "\n %s\n", p_item->psz_text );
break;
case CONFIG_ITEM_STRING:
case CONFIG_ITEM_FILE:
case CONFIG_ITEM_DIRECTORY:
case CONFIG_ITEM_MODULE: /* We could also have "=<" here */
case CONFIG_ITEM_MODULE_CAT:
case CONFIG_ITEM_MODULE_LIST:
case CONFIG_ITEM_MODULE_LIST_CAT:
psz_bra = " <"; psz_type = _("string"); psz_ket = ">";
if( p_item->ppsz_list )
{
psz_bra = " {";
psz_type = psz_buffer;
psz_type[0] = '\0';
for( i = 0; p_item->ppsz_list[i]; i++ )
{
if( i ) strcat( psz_type, "," );
strcat( psz_type, p_item->ppsz_list[i] );
}
psz_ket = "}";
}
break;
case CONFIG_ITEM_INTEGER:
case CONFIG_ITEM_KEY: /* FIXME: do something a bit more clever
*/
psz_bra = " <"; psz_type = _("integer"); psz_ket = ">";
if( p_item->i_list )
{
psz_bra = " {";
psz_type = psz_buffer;
psz_type[0] = '\0';
for( i = 0; p_item->ppsz_list_text[i]; i++ )
{
if( i ) strcat( psz_type, ", " );
sprintf( psz_type + strlen(psz_type), "%i (%s)",
p_item->pi_list[i],
p_item->ppsz_list_text[i] );
}
psz_ket = "}";
}
break;
case CONFIG_ITEM_FLOAT:
psz_bra = " <"; psz_type = _("float"); psz_ket = ">";
break;
case CONFIG_ITEM_BOOL:
psz_bra = ""; psz_type = ""; psz_ket = "";
if( !b_help_module )
{
psz_suf = p_item->i_value ? _(" (default enabled)") :
_(" (default disabled)");
}
break;
}
if( !psz_type )
{
continue;
}
/* Add short option if any */
if( p_item->i_short )
{
sprintf( psz_short, "-%c,", p_item->i_short );
}
else
{
strcpy( psz_short, " " );
}
i = PADDING_SPACES - strlen( p_item->psz_name )
- strlen( psz_bra ) - strlen( psz_type )
- strlen( psz_ket ) - 1;
if( p_item->i_type == CONFIG_ITEM_BOOL && !b_help_module )
{
psz_prefix = ", --no-";
i -= strlen( p_item->psz_name ) + strlen( psz_prefix );
}
if( i < 0 )
{
psz_spaces[0] = '\n';
i = 0;
}
else
{
psz_spaces[i] = '\0';
}
if( p_item->i_type == CONFIG_ITEM_BOOL && !b_help_module )
{
fprintf( output, psz_format, psz_short, p_item->psz_name,
psz_prefix, p_item->psz_name, psz_bra, psz_type,
psz_ket, psz_spaces );
}
else
{
fprintf( output, psz_format, psz_short, p_item->psz_name,
"", "", psz_bra, psz_type, psz_ket, psz_spaces );
}
psz_spaces[i] = ' ';
/* We wrap the rest of the output */
sprintf( psz_buffer, "%s%s", p_item->psz_text, psz_suf );
b_description = config_GetInt( p_this, "help-verbose" );
description:
psz_text = psz_buffer;
while( *psz_text )
{
char *psz_parser, *psz_word;
size_t i_end = strlen( psz_text );
/* If the remaining text fits in a line, print it. */
if( i_end <= (size_t)i_width )
{
fprintf( output, "%s\n", psz_text );
break;
}
/* Otherwise, eat as many words as possible */
psz_parser = psz_text;
do
{
psz_word = psz_parser;
psz_parser = strchr( psz_word, ' ' );
/* If no space was found, we reached the end of the text
* block; otherwise, we skip the space we just found. */
psz_parser = psz_parser ? psz_parser + 1
: psz_text + i_end;
} while( psz_parser - psz_text <= i_width );
/* We cut a word in one of these cases:
* - it's the only word in the line and it's too long.
* - we used less than 80% of the width and the word we are
* going to wrap is longer than 40% of the width, and
even
* if the word would have fit in the next line. */
if( psz_word == psz_text
|| ( psz_word - psz_text < 80 * i_width / 100
&& psz_parser - psz_word > 40 * i_width / 100 ) )
{
char c = psz_text[i_width];
psz_text[i_width] = '\0';
fprintf( output, "%s\n%s", psz_text, psz_spaces );
psz_text += i_width;
psz_text[0] = c;
}
else
{
psz_word[-1] = '\0';
fprintf( output, "%s\n%s", psz_text, psz_spaces );
psz_text = psz_word;
}
}
if( b_description && p_item->psz_longtext )
{
sprintf( psz_buffer, "%s%s", p_item->psz_longtext, psz_suf
);
b_description = VLC_FALSE;
psz_spaces = psz_spaces_longtext;
fprintf( output, "%s", psz_spaces );
goto description;
}
}
}
/* Release the module list */
vlc_list_release( p_list );
}
I've put:
#ifdef WIN32
output = fopen("vlc-help.txt", "wt+"); // wt+ rather than wb+ to convert \n
into \r\n
#endif
In #ifdef WIN32, the unix version of that line would be:
#ifndef WIN32
output = fopen("vlc-help.txt", "wb+");
#endif
(This fixes vlc --longhelp too.)
:)
--
This is the vlc-devel mailing-list, see http://www.videolan.org/vlc/
To unsubscribe, please read http://developers.videolan.org/lists.html
More information about the vlc-devel
mailing list