1 /*****************************************************************************
2 * help.c: command line help
3 *****************************************************************************
4 * Copyright (C) 1998-2011 VLC authors and VideoLAN
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
33 #include <vlc_common.h>
34 #include <vlc_modules.h>
35 #include <vlc_plugin.h>
36 #include <vlc_charset.h>
37 #include "modules/modules.h"
38 #include "config/configuration.h"
42 # include <vlc_charset.h>
43 # define wcwidth(cp) (cp, 1) /* LOL */
47 # include <sys/ioctl.h>
50 #if defined( _WIN32 ) && !VLC_WINSTORE_APP
51 static void ShowConsole (void);
52 static void PauseConsole (void);
54 # define ShowConsole() (void)0
55 # define PauseConsole() (void)0
58 static void Help (vlc_object_t
*, const char *);
59 static void Usage (vlc_object_t
*, const char *);
60 static void Version (void);
61 static void ListModules (vlc_object_t
*, bool);
64 * Returns the console width or a best guess.
66 static unsigned ConsoleWidth(void)
71 if (ioctl(STDOUT_FILENO
, TIOCGWINSZ
, &ws
) == 0)
77 if (ioctl(STDOUT_FILENO
, WIOCGETD
, &uw
) == 0)
78 return uw
.uw_height
/ uw
.uw_vs
;
80 #if defined (_WIN32) && !VLC_WINSTORE_APP
81 CONSOLE_SCREEN_BUFFER_INFO buf
;
83 if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE
), &buf
))
90 * Checks for help command line options such as --help or --version.
91 * If one is found, print the corresponding text.
92 * \return true if a command line options caused some help message to be
93 * printed, false otherwise.
95 bool config_PrintHelp (vlc_object_t
*obj
)
99 /* Check for short help option */
100 if (var_InheritBool (obj
, "help"))
106 /* Check for version option */
107 if (var_InheritBool (obj
, "version"))
113 /* Check for help on modules */
114 str
= var_InheritString (obj
, "module");
122 /* Check for full help option */
123 if (var_InheritBool (obj
, "full-help"))
125 var_Create (obj
, "advanced", VLC_VAR_BOOL
);
126 var_SetBool (obj
, "advanced", true);
127 var_Create (obj
, "help-verbose", VLC_VAR_BOOL
);
128 var_SetBool (obj
, "help-verbose", true);
129 Help (obj
, "full-help");
133 /* Check for long help option */
134 if (var_InheritBool (obj
, "longhelp"))
136 Help (obj
, "longhelp");
140 /* Check for module list option */
141 if (var_InheritBool (obj
, "list"))
143 ListModules (obj
, false );
147 if (var_InheritBool (obj
, "list-verbose"))
149 ListModules (obj
, true);
156 /*****************************************************************************
157 * Help: print program help
158 *****************************************************************************
159 * Print a short inline help. Message interface is initialized at this stage.
160 *****************************************************************************/
161 static inline void print_help_on_full_help( void )
164 puts(_("To get exhaustive help, use '-H'."));
167 static const char vlc_usage
[] = N_(
168 "Usage: %s [options] [stream] ...\n"
169 "You can specify multiple streams on the commandline.\n"
170 "They will be enqueued in the playlist.\n"
171 "The first item specified will be played first.\n"
174 " --option A global option that is set for the duration of the program.\n"
175 " -option A single letter version of a global --option.\n"
176 " :option An option that only applies to the stream directly before it\n"
177 " and that overrides previous settings.\n"
179 "Stream MRL syntax:\n"
180 " [[access][/demux]://]URL[#[title][:chapter][-[title][:chapter]]]\n"
181 " [:option=value ...]\n"
183 " Many of the global --options can also be used as MRL specific :options.\n"
184 " Multiple :option=value pairs can be specified.\n"
187 " file:///path/file Plain media file\n"
188 " http://host[:port]/file HTTP URL\n"
189 " ftp://host[:port]/file FTP URL\n"
190 " mms://host[:port]/file MMS URL\n"
191 " screen:// Screen capture\n"
192 " dvd://[device] DVD device\n"
193 " vcd://[device] VCD device\n"
194 " cdda://[device] Audio CD device\n"
195 " udp://[[<source address>]@[<bind address>][:<bind port>]]\n"
196 " UDP stream sent by a streaming server\n"
197 " vlc://pause:<seconds> Pause the playlist for a certain time\n"
198 " vlc://quit Special item to quit VLC\n"
201 static void Help (vlc_object_t
*p_this
, char const *psz_help_name
)
205 if( psz_help_name
&& !strcmp( psz_help_name
, "help" ) )
207 printf(_(vlc_usage
), "vlc");
208 Usage( p_this
, "=core" );
209 print_help_on_full_help();
211 else if( psz_help_name
&& !strcmp( psz_help_name
, "longhelp" ) )
213 printf(_(vlc_usage
), "vlc");
214 Usage( p_this
, NULL
);
215 print_help_on_full_help();
217 else if( psz_help_name
&& !strcmp( psz_help_name
, "full-help" ) )
219 printf(_(vlc_usage
), "vlc");
220 Usage( p_this
, NULL
);
222 else if( psz_help_name
)
224 Usage( p_this
, psz_help_name
);
230 /*****************************************************************************
231 * Usage: print module usage
232 *****************************************************************************
233 * Print a short inline help. Message interface is initialized at this stage.
234 *****************************************************************************/
235 # define COL(x) "\033[" #x ";1m"
237 # define GREEN COL(32)
238 # define YELLOW COL(33)
239 # define BLUE COL(34)
240 # define MAGENTA COL(35)
241 # define CYAN COL(36)
242 # define WHITE COL(0)
243 # define GRAY "\033[0m"
244 # define LINE_START 8
245 # define PADDING_SPACES 25
247 static void print_section(const module_t
*m
, const module_config_t
**sect
,
248 bool color
, bool desc
)
250 const module_config_t
*item
= *sect
;
256 printf(color
? RED
" %s:\n"GRAY
: " %s:\n",
257 module_gettext(m
, item
->psz_text
));
258 if (desc
&& item
->psz_longtext
!= NULL
)
259 printf(color
? MAGENTA
" %s\n"GRAY
: " %s\n",
260 module_gettext(m
, item
->psz_longtext
));
263 static void print_desc(const char *str
, unsigned margin
, bool color
)
265 unsigned width
= ConsoleWidth() - margin
;
270 const char *word
= str
;
271 int wordlen
= 0, wordwidth
= 0;
278 size_t charlen
= vlc_towc(str
, &cp
);
279 if (unlikely(charlen
== (size_t)-1))
282 int charwidth
= wcwidth(cp
);
292 putchar(' '); /* insert space */
295 fwrite(word
, 1, wordlen
, stdout
); /* write complete word */
304 wordwidth
+= charwidth
;
311 { /* overflow (word wider than line) */
312 fwrite(word
, 1, wordlen
- charlen
, stdout
);
313 word
= str
- charlen
;
315 wordwidth
= charwidth
;
317 printf("\n%*s", margin
, ""); /* new line */
325 printf(color
? "%s\n"GRAY
: "%s\n", word
);
328 static int vlc_swidth(const char *str
)
330 for (int total
= 0;;)
333 size_t charlen
= vlc_towc(str
, &cp
);
337 if (charlen
== (size_t)-1)
348 static void print_item(const vlc_object_t
*p_this
, const module_t
*m
, const module_config_t
*item
,
349 const module_config_t
**section
, bool color
, bool desc
)
352 # define OPTION_VALUE_SEP " "
354 # define OPTION_VALUE_SEP "="
356 const char *bra
= OPTION_VALUE_SEP
"<", *type
, *ket
= ">";
357 const char *prefix
= NULL
, *suffix
= NULL
;
358 char *typebuf
= NULL
;
360 switch (CONFIG_CLASS(item
->i_type
))
362 case 0: // hint class
363 switch (item
->i_type
)
365 case CONFIG_HINT_CATEGORY
:
366 case CONFIG_HINT_USAGE
:
367 printf(color
? GREEN
"\n %s\n" GRAY
: "\n %s\n",
368 module_gettext(m
, item
->psz_text
));
370 if (desc
&& item
->psz_longtext
!= NULL
)
371 printf(color
? CYAN
" %s\n" GRAY
: " %s\n",
372 module_gettext(m
, item
->psz_longtext
));
381 case CONFIG_ITEM_STRING
:
385 char **ppsz_values
, **ppsz_texts
;
387 ssize_t i_count
= config_GetPszChoices(VLC_OBJECT(p_this
), item
->psz_name
, &ppsz_values
, &ppsz_texts
);
393 for (unsigned i
= 0; i
< i_count
; i
++)
394 len
+= strlen(ppsz_values
[i
]) + 1;
396 typebuf
= malloc(len
);
400 bra
= OPTION_VALUE_SEP
"{";
405 for (unsigned i
= 0; i
< i_count
; i
++)
408 strcat(typebuf
, ",");
409 strcat(typebuf
, ppsz_values
[i
]);
413 for (unsigned i
= 0; i
< i_count
; i
++)
415 free(ppsz_values
[i
]);
424 case CONFIG_ITEM_INTEGER
:
431 ssize_t i_count
= config_GetIntChoices(VLC_OBJECT(p_this
), item
->psz_name
, &pi_values
, &ppsz_texts
);
437 for (unsigned i
= 0; i
< i_count
; i
++)
438 len
+= strlen(ppsz_texts
[i
])
439 + 4 * sizeof (int64_t) + 5;
441 typebuf
= malloc(len
);
445 bra
= OPTION_VALUE_SEP
"{";
450 for (unsigned i
= 0; i
< item
->list_count
; i
++)
453 strcat(typebuf
, ", ");
454 sprintf(typebuf
+ strlen(typebuf
), "%"PRIi64
" (%s)",
460 for (unsigned i
= 0; i
< i_count
; i
++)
465 else if (item
->min
.i
!= INT64_MIN
|| item
->max
.i
!= INT64_MAX
)
467 if (asprintf(&typebuf
, "%s [%"PRId64
" .. %"PRId64
"]",
468 type
, item
->min
.i
, item
->max
.i
) >= 0)
475 case CONFIG_ITEM_FLOAT
:
477 if (item
->min
.f
!= FLT_MIN
|| item
->max
.f
!= FLT_MAX
)
479 if (asprintf(&typebuf
, "%s [%f .. %f]", type
,
480 item
->min
.f
, item
->max
.f
) >= 0)
487 case CONFIG_ITEM_BOOL
:
488 bra
= type
= ket
= "";
490 suffix
= item
->value
.i
? _("(default enabled)")
491 : _("(default disabled)");
497 print_section(m
, section
, color
, desc
);
499 /* Add short option if any */
501 if (item
->i_short
!= '\0')
502 sprintf(shortopt
, "-%c,", item
->i_short
);
504 strcpy(shortopt
, " ");
506 if (CONFIG_CLASS(item
->i_type
) == CONFIG_ITEM_BOOL
)
507 printf(color
? WHITE
" %s --%s" "%s%s%s%s%s "GRAY
508 : " %s --%s%s%s%s%s%s ", shortopt
, item
->psz_name
,
509 prefix
, item
->psz_name
, bra
, type
, ket
);
511 printf(color
? WHITE
" %s --%s"YELLOW
"%s%s%s%s%s "GRAY
512 : " %s --%s%s%s%s%s%s ", shortopt
, item
->psz_name
,
513 "", "", /* XXX */ bra
, type
, ket
);
515 /* Wrap description */
516 int offset
= PADDING_SPACES
- strlen(item
->psz_name
)
517 - strlen(bra
) - vlc_swidth(type
) - strlen(ket
) - 1;
518 if (CONFIG_CLASS(item
->i_type
) == CONFIG_ITEM_BOOL
)
519 offset
-= strlen(item
->psz_name
) + vlc_swidth(prefix
);
523 offset
= PADDING_SPACES
+ LINE_START
;
526 printf("%*s", offset
, "");
527 print_desc(module_gettext(m
, item
->psz_text
),
528 PADDING_SPACES
+ LINE_START
, color
);
532 printf("%*s", PADDING_SPACES
+ LINE_START
, "");
533 print_desc(suffix
, PADDING_SPACES
+ LINE_START
, color
);
536 if (desc
&& (item
->psz_longtext
!= NULL
&& item
->psz_longtext
[0]))
537 { /* Wrap long description */
538 printf("%*s", LINE_START
+ 2, "");
539 print_desc(module_gettext(m
, item
->psz_longtext
),
540 LINE_START
+ 2, false);
546 static bool module_match(const module_t
*m
, const char *pattern
, bool strict
)
551 const char *objname
= module_get_object(m
);
553 if (strict
? (strcmp(objname
, pattern
) == 0)
554 : (strstr(objname
, pattern
) != NULL
))
557 for (unsigned i
= 0; i
< m
->i_shortcuts
; i
++)
559 const char *shortcut
= m
->pp_shortcuts
[i
];
561 if (strict
? (strcmp(shortcut
, pattern
) == 0)
562 : (strstr(shortcut
, pattern
) != NULL
))
568 static bool plugin_show(const vlc_plugin_t
*plugin
, bool advanced
)
570 for (size_t i
= 0; i
< plugin
->conf
.size
; i
++)
572 const module_config_t
*item
= plugin
->conf
.items
+ i
;
574 if (!CONFIG_ITEM(item
->i_type
))
578 if ((!advanced
) && item
->b_advanced
)
585 static void Usage (vlc_object_t
*p_this
, char const *psz_search
)
587 bool b_has_advanced
= false;
589 unsigned i_only_advanced
= 0; /* Number of modules ignored because they
590 * only have advanced options */
592 if (psz_search
!= NULL
&& psz_search
[0] == '=')
600 if (isatty(STDOUT_FILENO
))
601 color
= var_InheritBool(p_this
, "color");
604 const bool desc
= var_InheritBool(p_this
, "help-verbose");
605 const bool advanced
= var_InheritBool(p_this
, "advanced");
607 /* Enumerate the config for each module */
608 for (const vlc_plugin_t
*p
= vlc_plugins
; p
!= NULL
; p
= p
->next
)
610 const module_t
*m
= p
->module
;
611 const module_config_t
*section
= NULL
;
612 const char *objname
= module_get_object(m
);
614 if (p
->conf
.count
== 0)
615 continue; /* Ignore modules without config options */
616 if (!module_match(m
, psz_search
, strict
))
620 if (!plugin_show(p
, advanced
))
621 { /* Ignore plugins with only advanced config options if requested */
626 /* Print name of module */
627 printf(color
? "\n " GREEN
"%s" GRAY
" (%s)\n" : "\n %s (%s)\n",
628 module_gettext(m
, m
->psz_longname
), objname
);
629 if (m
->psz_help
!= NULL
)
630 printf(color
? CYAN
" %s\n"GRAY
: " %s\n",
631 module_gettext(m
, m
->psz_help
));
633 /* Print module options */
634 for (size_t j
= 0; j
< p
->conf
.size
; j
++)
636 const module_config_t
*item
= p
->conf
.items
+ j
;
639 continue; /* Skip removed options */
640 if (item
->b_advanced
&& !advanced
)
641 { /* Skip advanced options unless requested */
642 b_has_advanced
= true;
645 print_item(p_this
, m
, item
, §ion
, color
, desc
);
650 printf(color
? "\n" WHITE
"%s" GRAY
" %s\n"
651 : "\n%s %s\n", _( "Note:" ), _( "add --advanced to your "
652 "command line to see advanced options."));
653 if( i_only_advanced
> 0 )
655 printf(color
? "\n" WHITE
"%s" GRAY
" " : "\n%s ", _( "Note:" ) );
656 printf(vlc_ngettext("%u module was not displayed because it only has "
657 "advanced options.\n", "%u modules were not displayed because "
658 "they only have advanced options.\n", i_only_advanced
),
662 printf(color
? "\n" WHITE
"%s" GRAY
"\n" : "\n%s\n",
663 _("No matching module found. Use --list or "
664 "--list-verbose to list available modules."));
667 /*****************************************************************************
668 * ListModules: list the available modules with their description
669 *****************************************************************************
670 * Print a list of all available modules (builtins and plugins) and a short
671 * description for each one.
672 *****************************************************************************/
673 static void ListModules (vlc_object_t
*p_this
, bool b_verbose
)
679 if (isatty(STDOUT_FILENO
))
680 color
= var_InheritBool(p_this
, "color");
685 /* List all modules */
687 module_t
**list
= module_list_get (&count
);
689 /* Enumerate each module */
690 for (size_t j
= 0; j
< count
; j
++)
692 module_t
*p_parser
= list
[j
];
693 const char *objname
= module_get_object (p_parser
);
694 printf(color
? GREEN
" %-22s "WHITE
"%s\n"GRAY
: " %-22s %s\n",
695 objname
, module_gettext(p_parser
, p_parser
->psz_longname
));
699 const char *const *pp_shortcuts
= p_parser
->pp_shortcuts
;
700 for( unsigned i
= 0; i
< p_parser
->i_shortcuts
; i
++ )
701 if( strcmp( pp_shortcuts
[i
], objname
) )
702 printf(color
? CYAN
" s %s\n"GRAY
: " s %s\n",
704 if (p_parser
->psz_capability
!= NULL
)
705 printf(color
? MAGENTA
" c %s (%d)\n"GRAY
: " c %s (%d)\n",
706 p_parser
->psz_capability
, p_parser
->i_score
);
709 module_list_free (list
);
713 /*****************************************************************************
714 * Version: print complete program version
715 *****************************************************************************
716 * Print complete program version and build number.
717 *****************************************************************************/
718 static void Version( void )
721 printf(_("VLC version %s (%s)\n"), VERSION_MESSAGE
, psz_vlc_changeset
);
722 printf(_("Compiled by %s on %s (%s)\n"), VLC_CompileBy(),
723 VLC_CompileHost(), __DATE__
" "__TIME__
);
724 printf(_("Compiler: %s\n"), VLC_Compiler());
725 fputs(LICENSE_MSG
, stdout
);
729 #if defined( _WIN32 ) && !VLC_WINSTORE_APP
730 /*****************************************************************************
731 * ShowConsole: On Win32, create an output console for debug messages
732 *****************************************************************************
733 * This function is useful only on Win32.
734 *****************************************************************************/
735 static void ShowConsole( void )
737 if( getenv( "PWD" ) ) return; /* Cygwin shell or Wine */
739 if( !AllocConsole() ) return;
741 /* Use the ANSI code page (e.g. Windows-1252) as expected by the LibVLC
742 * Unicode/locale subsystem. By default, we have the obsolecent OEM code
743 * page (e.g. CP437 or CP850). */
744 SetConsoleOutputCP (GetACP ());
745 SetConsoleTitle (TEXT("VLC media player version ") TEXT(PACKAGE_VERSION
));
747 freopen( "CONOUT$", "w", stderr
);
748 freopen( "CONIN$", "r", stdin
);
750 if( freopen( "vlc-help.txt", "wt", stdout
) != NULL
)
752 fputs( "\xEF\xBB\xBF", stdout
);
753 fprintf( stderr
, _("\nDumped content to vlc-help.txt file.\n") );
756 freopen( "CONOUT$", "w", stdout
);
759 /*****************************************************************************
760 * PauseConsole: On Win32, wait for a key press before closing the console
761 *****************************************************************************
762 * This function is useful only on Win32.
763 *****************************************************************************/
764 static void PauseConsole( void )
766 if( getenv( "PWD" ) ) return; /* Cygwin shell or Wine */
768 utf8_fprintf( stderr
, _("\nPress the RETURN key to continue...\n") );