/src/vlc/src/config/help.c
Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * help.c: command line help |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 1998-2011 VLC authors and VideoLAN |
5 | | * |
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. |
10 | | * |
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. |
15 | | * |
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 | | *****************************************************************************/ |
20 | | |
21 | | #ifdef HAVE_CONFIG_H |
22 | | # include "config.h" |
23 | | #endif |
24 | | |
25 | | #include <stdatomic.h> |
26 | | #include <stdio.h> |
27 | | #include <string.h> |
28 | | #include <stdlib.h> |
29 | | #include <wchar.h> |
30 | | #include <wctype.h> |
31 | | #include <limits.h> |
32 | | #include <float.h> |
33 | | |
34 | | #include <vlc_common.h> |
35 | | #include <vlc_modules.h> |
36 | | #include <vlc_plugin.h> |
37 | | #include <vlc_charset.h> |
38 | | #include "ansi_term.h" |
39 | | #include "modules/modules.h" |
40 | | #include "config/configuration.h" |
41 | | #include "../libvlc.h" |
42 | | |
43 | | #if defined( _WIN32 ) |
44 | | # define wcwidth(cp) ((void)(cp), 1) /* LOL */ |
45 | | #endif |
46 | | #include <unistd.h> |
47 | | |
48 | | #if defined( _WIN32 ) |
49 | | # if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) |
50 | | # define HAVE_VLC_SHOWCONSOLE |
51 | | # endif |
52 | | #endif |
53 | | |
54 | | #ifdef HAVE_VLC_SHOWCONSOLE |
55 | | static void ShowConsole (void); |
56 | | static void PauseConsole (void); |
57 | | #else |
58 | 0 | # define ShowConsole() (void)0 |
59 | 0 | # define PauseConsole() (void)0 |
60 | | #endif |
61 | | |
62 | | static void Help (libvlc_int_t *, const char *); |
63 | | static void Usage (libvlc_int_t *, const char *); |
64 | | static void Version (void); |
65 | | static void ListModules (libvlc_int_t *, bool); |
66 | | |
67 | | /** |
68 | | * Returns the console width or a best guess. |
69 | | */ |
70 | | static unsigned ConsoleWidth(void) |
71 | 0 | { |
72 | 0 | #ifdef TIOCGWINSZ |
73 | 0 | struct winsize ws; |
74 | |
|
75 | 0 | if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0) |
76 | 0 | return ws.ws_col; |
77 | 0 | #endif |
78 | | #ifdef WIOCGETD |
79 | | struct uwdata uw; |
80 | | |
81 | | if (ioctl(STDOUT_FILENO, WIOCGETD, &uw) == 0) |
82 | | return uw.uw_height / uw.uw_vs; |
83 | | #endif |
84 | | #if defined (_WIN32) |
85 | | #if NTDDI_VERSION >= NTDDI_WIN10_RS1 || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) |
86 | | CONSOLE_SCREEN_BUFFER_INFO buf; |
87 | | |
88 | | if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &buf)) |
89 | | return buf.dwSize.X; |
90 | | #endif |
91 | | #endif |
92 | 0 | return 80; |
93 | 0 | } |
94 | | |
95 | | /** |
96 | | * Checks for help command line options such as --help or --version. |
97 | | * If one is found, print the corresponding text. |
98 | | * \return true if a command line options caused some help message to be |
99 | | * printed, false otherwise. |
100 | | */ |
101 | | bool config_PrintHelp (libvlc_int_t *obj) |
102 | 58 | { |
103 | 58 | char *str; |
104 | | |
105 | | /* Check for version option */ |
106 | 58 | if (var_InheritBool (obj, "version")) |
107 | 0 | { |
108 | 0 | Version(); |
109 | 0 | return true; |
110 | 0 | } |
111 | | |
112 | | /* Check for help on modules */ |
113 | 58 | str = var_InheritString (obj, "module"); |
114 | 58 | if (str != NULL) |
115 | 0 | { |
116 | 0 | Help (obj, str); |
117 | 0 | free (str); |
118 | 0 | return true; |
119 | 0 | } |
120 | | |
121 | | /* Check for full help option */ |
122 | 58 | if (var_InheritBool (obj, "full-help")) |
123 | 0 | { |
124 | 0 | var_Create (obj, "help-verbose", VLC_VAR_BOOL); |
125 | 0 | var_SetBool (obj, "help-verbose", true); |
126 | 0 | Help (obj, "full-help"); |
127 | 0 | return true; |
128 | 0 | } |
129 | | |
130 | | /* Check for long help option */ |
131 | 58 | if (var_InheritBool (obj, "longhelp")) |
132 | 0 | { |
133 | 0 | Help (obj, "longhelp"); |
134 | 0 | return true; |
135 | 0 | } |
136 | | /* Check for short help option */ |
137 | 58 | if (var_InheritBool (obj, "help")) |
138 | 0 | { |
139 | 0 | Help (obj, "help"); |
140 | 0 | return true; |
141 | 0 | } |
142 | | |
143 | 58 | if (var_InheritBool (obj, "list-verbose")) |
144 | 0 | { |
145 | 0 | ListModules (obj, true); |
146 | 0 | return true; |
147 | 0 | } |
148 | | |
149 | | /* Check for module list option */ |
150 | 58 | if (var_InheritBool (obj, "list")) |
151 | 0 | { |
152 | 0 | ListModules (obj, false ); |
153 | 0 | return true; |
154 | 0 | } |
155 | | |
156 | 58 | return false; |
157 | 58 | } |
158 | | |
159 | | /***************************************************************************** |
160 | | * Help: print program help |
161 | | ***************************************************************************** |
162 | | * Print a short inline help. Message interface is initialized at this stage. |
163 | | *****************************************************************************/ |
164 | | static inline void print_help_on_full_help( void ) |
165 | 0 | { |
166 | 0 | putchar('\n'); |
167 | 0 | puts(_("To get exhaustive help, use '-H'.")); |
168 | 0 | } |
169 | | |
170 | | static const char vlc_usage[] = N_( |
171 | | "Usage: %s [options] [stream] ...\n" |
172 | | "You can specify multiple streams on the commandline.\n" |
173 | | "They will be enqueued in the playlist.\n" |
174 | | "The first item specified will be played first.\n" |
175 | | "\n" |
176 | | "Options-styles:\n" |
177 | | " --option A global option that is set for the duration of the program.\n" |
178 | | " -option A single letter version of a global --option.\n" |
179 | | " :option An option that only applies to the stream directly before it\n" |
180 | | " and that overrides previous settings.\n" |
181 | | "\n" |
182 | | "Stream MRL syntax:\n" |
183 | | " [[access][/demux]://]URL[#[title][:chapter][-[title][:chapter]]]\n" |
184 | | " [:option=value ...]\n" |
185 | | "\n" |
186 | | " Many of the global --options can also be used as MRL specific :options.\n" |
187 | | " Multiple :option=value pairs can be specified.\n" |
188 | | "\n" |
189 | | "URL syntax:\n" |
190 | | " file:///path/file Plain media file\n" |
191 | | " http://host[:port]/file HTTP URL\n" |
192 | | " ftp://host[:port]/file FTP URL\n" |
193 | | " mms://host[:port]/file MMS URL\n" |
194 | | " screen:// Screen capture\n" |
195 | | " dvd://[device] DVD device\n" |
196 | | " vcd://[device] VCD device\n" |
197 | | " cdda://[device] Audio CD device\n" |
198 | | " udp://[[<source address>]@[<bind address>][:<bind port>]]\n" |
199 | | " UDP stream sent by a streaming server\n" |
200 | | " vlc://pause:<seconds> Pause the playlist for a certain time\n" |
201 | | " vlc://quit Special item to quit VLC\n" |
202 | | "\n"); |
203 | | |
204 | | static void Help (libvlc_int_t *p_this, char const *psz_help_name) |
205 | 0 | { |
206 | 0 | ShowConsole(); |
207 | |
|
208 | 0 | if( psz_help_name && !strcmp( psz_help_name, "help" ) ) |
209 | 0 | { |
210 | 0 | printf(_(vlc_usage), "vlc"); |
211 | 0 | Usage( p_this, "=core" ); |
212 | 0 | print_help_on_full_help(); |
213 | 0 | } |
214 | 0 | else if( psz_help_name && !strcmp( psz_help_name, "longhelp" ) ) |
215 | 0 | { |
216 | 0 | printf(_(vlc_usage), "vlc"); |
217 | 0 | Usage( p_this, NULL ); |
218 | 0 | print_help_on_full_help(); |
219 | 0 | } |
220 | 0 | else if( psz_help_name && !strcmp( psz_help_name, "full-help" ) ) |
221 | 0 | { |
222 | 0 | printf(_(vlc_usage), "vlc"); |
223 | 0 | Usage( p_this, NULL ); |
224 | 0 | } |
225 | 0 | else if( psz_help_name ) |
226 | 0 | { |
227 | 0 | Usage( p_this, psz_help_name ); |
228 | 0 | } |
229 | |
|
230 | 0 | PauseConsole(); |
231 | 0 | } |
232 | | |
233 | | /***************************************************************************** |
234 | | * Usage: print module usage |
235 | | ***************************************************************************** |
236 | | * Print a short inline help. Message interface is initialized at this stage. |
237 | | *****************************************************************************/ |
238 | 0 | # define LINE_START 8 |
239 | 0 | # define PADDING_SPACES 25 |
240 | | |
241 | | static void print_section(const module_t *m, const module_config_t **sect, |
242 | | bool color, bool desc) |
243 | 0 | { |
244 | 0 | const module_config_t *item = *sect; |
245 | |
|
246 | 0 | if (item == NULL) |
247 | 0 | return; |
248 | 0 | *sect = NULL; |
249 | |
|
250 | 0 | printf(color ? TS_RED_BOLD " %s:\n" TS_RESET : " %s:\n", |
251 | 0 | module_gettext(m, item->psz_text)); |
252 | 0 | if (desc && item->psz_longtext != NULL) |
253 | 0 | printf(color ? TS_MAGENTA_BOLD " %s\n" TS_RESET : " %s\n", |
254 | 0 | module_gettext(m, item->psz_longtext)); |
255 | 0 | } |
256 | | |
257 | | static void print_desc(const char *str, unsigned margin, bool color) |
258 | 0 | { |
259 | 0 | unsigned width = ConsoleWidth() - margin; |
260 | |
|
261 | 0 | if (color) |
262 | 0 | fputs(TS_BLUE_BOLD, stdout); |
263 | |
|
264 | 0 | const char *word = str; |
265 | 0 | size_t wordlen = 0; |
266 | 0 | int wordwidth = 0; |
267 | 0 | unsigned offset = 0; |
268 | 0 | bool newline = true; |
269 | |
|
270 | 0 | while (str[0]) |
271 | 0 | { |
272 | 0 | uint32_t cp; |
273 | 0 | ssize_t charlen = vlc_towc(str, &cp); |
274 | 0 | if (unlikely(charlen == -1)) |
275 | 0 | break; |
276 | | |
277 | 0 | int charwidth = wcwidth(cp); |
278 | 0 | if (charwidth < 0) |
279 | 0 | charwidth = 0; |
280 | |
|
281 | 0 | str += charlen; |
282 | |
|
283 | 0 | if (iswspace(cp)) |
284 | 0 | { |
285 | 0 | if (!newline) |
286 | 0 | { |
287 | 0 | putchar(' '); /* insert space */ |
288 | 0 | charwidth = 1; |
289 | 0 | } |
290 | 0 | fwrite(word, 1, wordlen, stdout); /* write complete word */ |
291 | 0 | word = str; |
292 | 0 | wordlen = 0; |
293 | 0 | wordwidth = 0; |
294 | 0 | newline = false; |
295 | 0 | } |
296 | 0 | else |
297 | 0 | { |
298 | 0 | wordlen += charlen; |
299 | 0 | wordwidth += charwidth; |
300 | 0 | } |
301 | |
|
302 | 0 | offset += charwidth; |
303 | 0 | if (offset >= width) |
304 | 0 | { |
305 | 0 | if (newline) |
306 | 0 | { /* overflow (word wider than line) */ |
307 | 0 | fwrite(word, 1, wordlen - charlen, stdout); |
308 | 0 | word = str - charlen; |
309 | 0 | wordlen = charlen; |
310 | 0 | wordwidth = charwidth; |
311 | 0 | } |
312 | 0 | printf("\n%*s", margin, ""); /* new line */ |
313 | 0 | offset = wordwidth; |
314 | 0 | newline = true; |
315 | 0 | } |
316 | 0 | } |
317 | |
|
318 | 0 | if (!newline) |
319 | 0 | putchar(' '); |
320 | 0 | printf(color ? "%s\n" TS_RESET : "%s\n", word); |
321 | 0 | } |
322 | | |
323 | | static int vlc_swidth(const char *str) |
324 | 0 | { |
325 | 0 | for (int total = 0;;) |
326 | 0 | { |
327 | 0 | uint32_t cp; |
328 | 0 | ssize_t charlen = vlc_towc(str, &cp); |
329 | |
|
330 | 0 | if (charlen == 0) |
331 | 0 | return total; |
332 | 0 | if (charlen == -1) |
333 | 0 | return -1; |
334 | 0 | str += charlen; |
335 | |
|
336 | 0 | int w = wcwidth(cp); |
337 | 0 | if (w == -1) |
338 | 0 | return -1; |
339 | 0 | total += w; |
340 | 0 | } |
341 | 0 | } |
342 | | |
343 | | static void print_item(const module_t *m, const struct vlc_param *param, |
344 | | const module_config_t **section, bool color, bool desc) |
345 | 0 | { |
346 | 0 | const module_config_t *item = ¶m->item; |
347 | 0 | #ifndef _WIN32 |
348 | 0 | # define OPTION_VALUE_SEP " " |
349 | | #else |
350 | | # define OPTION_VALUE_SEP "=" |
351 | | #endif |
352 | 0 | const char *bra = OPTION_VALUE_SEP "<", *type, *ket = ">"; |
353 | 0 | const char *prefix = NULL, *suffix = NULL; |
354 | 0 | char *typebuf = NULL; |
355 | |
|
356 | 0 | switch (CONFIG_CLASS(item->i_type)) |
357 | 0 | { |
358 | 0 | case 0: // hint class |
359 | 0 | switch (item->i_type) |
360 | 0 | { |
361 | 0 | case CONFIG_HINT_CATEGORY: |
362 | 0 | printf(color ? TS_GREEN_BOLD "\n %s\n" TS_RESET : "\n %s\n", |
363 | 0 | module_gettext(m, item->psz_text)); |
364 | |
|
365 | 0 | if (desc && item->psz_longtext != NULL) |
366 | 0 | printf(color ? TS_CYAN_BOLD " %s\n" TS_RESET : " %s\n", |
367 | 0 | module_gettext(m, item->psz_longtext)); |
368 | 0 | break; |
369 | | |
370 | 0 | case CONFIG_SUBCATEGORY: |
371 | | /* We ignore these here, using 'hints' instead */ |
372 | 0 | break; |
373 | | |
374 | 0 | case CONFIG_SECTION: |
375 | 0 | *section = item; |
376 | 0 | break; |
377 | 0 | } |
378 | 0 | return; |
379 | | |
380 | 0 | case CONFIG_ITEM_STRING: |
381 | 0 | { |
382 | 0 | type = _("string"); |
383 | |
|
384 | 0 | char **ppsz_values, **ppsz_texts; |
385 | |
|
386 | 0 | ssize_t i_count = config_GetPszChoices(item->psz_name, &ppsz_values, &ppsz_texts); |
387 | |
|
388 | 0 | if (i_count > 0) |
389 | 0 | { |
390 | 0 | size_t len = 0; |
391 | |
|
392 | 0 | for (size_t i = 0; i < (size_t)i_count; i++) |
393 | 0 | len += strlen(ppsz_values[i]) + 1; |
394 | |
|
395 | 0 | typebuf = malloc(len); |
396 | 0 | if (typebuf == NULL) |
397 | 0 | goto end_string; |
398 | | |
399 | 0 | bra = OPTION_VALUE_SEP "{"; |
400 | 0 | type = typebuf; |
401 | 0 | ket = "}"; |
402 | |
|
403 | 0 | *typebuf = 0; |
404 | 0 | for (size_t i = 0; i < (size_t)i_count; i++) |
405 | 0 | { |
406 | 0 | if (i > 0) |
407 | 0 | strcat(typebuf, ","); |
408 | 0 | strcat(typebuf, ppsz_values[i]); |
409 | 0 | } |
410 | |
|
411 | 0 | end_string: |
412 | 0 | for (size_t i = 0; i < (size_t)i_count; i++) |
413 | 0 | { |
414 | 0 | free(ppsz_values[i]); |
415 | 0 | free(ppsz_texts[i]); |
416 | 0 | } |
417 | 0 | free(ppsz_values); |
418 | 0 | free(ppsz_texts); |
419 | 0 | } |
420 | | |
421 | 0 | break; |
422 | 0 | } |
423 | 0 | case CONFIG_ITEM_INTEGER: |
424 | 0 | { |
425 | 0 | type = _("integer"); |
426 | |
|
427 | 0 | int64_t *pi_values; |
428 | 0 | char **ppsz_texts; |
429 | |
|
430 | 0 | ssize_t i_count = config_GetIntChoices(item->psz_name, &pi_values, &ppsz_texts); |
431 | |
|
432 | 0 | if (i_count > 0) |
433 | 0 | { |
434 | 0 | size_t len = 0; |
435 | |
|
436 | 0 | for (size_t i = 0; i < (size_t)i_count; i++) |
437 | 0 | len += strlen(ppsz_texts[i]) |
438 | 0 | + 4 * sizeof (int64_t) + 5; |
439 | |
|
440 | 0 | typebuf = malloc(len); |
441 | 0 | if (typebuf == NULL) |
442 | 0 | goto end_integer; |
443 | | |
444 | 0 | bra = OPTION_VALUE_SEP "{"; |
445 | 0 | type = typebuf; |
446 | 0 | ket = "}"; |
447 | |
|
448 | 0 | *typebuf = 0; |
449 | 0 | for (size_t i = 0; i < (size_t)i_count; i++) |
450 | 0 | { |
451 | 0 | if (i != 0) |
452 | 0 | strcat(typebuf, ", "); |
453 | 0 | sprintf(typebuf + strlen(typebuf), "%"PRIi64" (%s)", |
454 | 0 | pi_values[i], |
455 | 0 | ppsz_texts[i]); |
456 | 0 | } |
457 | |
|
458 | 0 | end_integer: |
459 | 0 | for (size_t i = 0; i < (size_t)i_count; i++) |
460 | 0 | free(ppsz_texts[i]); |
461 | 0 | free(pi_values); |
462 | 0 | free(ppsz_texts); |
463 | 0 | } |
464 | 0 | else if (item->min.i != INT64_MIN || item->max.i != INT64_MAX ) |
465 | 0 | { |
466 | 0 | if (asprintf(&typebuf, "%s [%"PRId64" .. %"PRId64"]", |
467 | 0 | type, item->min.i, item->max.i) >= 0) |
468 | 0 | type = typebuf; |
469 | 0 | else |
470 | 0 | typebuf = NULL; |
471 | 0 | } |
472 | 0 | break; |
473 | 0 | } |
474 | 0 | case CONFIG_ITEM_FLOAT: |
475 | 0 | type = _("float"); |
476 | 0 | if (item->min.f != -FLT_MAX || item->max.f != FLT_MAX) |
477 | 0 | { |
478 | 0 | if (asprintf(&typebuf, "%s [%f .. %f]", type, |
479 | 0 | item->min.f, item->max.f) >= 0) |
480 | 0 | type = typebuf; |
481 | 0 | else |
482 | 0 | typebuf = NULL; |
483 | 0 | } |
484 | 0 | break; |
485 | | |
486 | 0 | case CONFIG_ITEM_BOOL: |
487 | 0 | bra = type = ket = ""; |
488 | 0 | prefix = ", --no-"; |
489 | 0 | suffix = item->orig.i ? _("(default enabled)") |
490 | 0 | : _("(default disabled)"); |
491 | 0 | break; |
492 | 0 | default: |
493 | 0 | return; |
494 | 0 | } |
495 | | |
496 | 0 | print_section(m, section, color, desc); |
497 | | |
498 | | /* Add short option if any */ |
499 | 0 | char shortopt[4]; |
500 | 0 | if (param->shortname != '\0') |
501 | 0 | sprintf(shortopt, "-%c,", param->shortname); |
502 | 0 | else |
503 | 0 | strcpy(shortopt, " "); |
504 | |
|
505 | 0 | if (CONFIG_CLASS(item->i_type) == CONFIG_ITEM_BOOL) |
506 | 0 | printf(color ? TS_BOLD " %s --%s" "%s%s%s%s%s " TS_RESET |
507 | 0 | : " %s --%s%s%s%s%s%s ", shortopt, item->psz_name, |
508 | 0 | prefix, item->psz_name, bra, type, ket); |
509 | 0 | else |
510 | 0 | printf(color ? TS_BOLD " %s --%s" TS_YELLOW_BOLD "%s%s%s%s%s " TS_RESET |
511 | 0 | : " %s --%s%s%s%s%s%s ", shortopt, item->psz_name, |
512 | 0 | "", "", /* XXX */ bra, type, ket); |
513 | | |
514 | | /* Wrap description */ |
515 | 0 | int offset = PADDING_SPACES - strlen(item->psz_name) |
516 | 0 | - strlen(bra) - vlc_swidth(type) - strlen(ket) - 1; |
517 | 0 | if (CONFIG_CLASS(item->i_type) == CONFIG_ITEM_BOOL) |
518 | 0 | offset -= strlen(item->psz_name) + vlc_swidth(prefix); |
519 | 0 | if (offset < 0) |
520 | 0 | { |
521 | 0 | putchar('\n'); |
522 | 0 | offset = PADDING_SPACES + LINE_START; |
523 | 0 | } |
524 | |
|
525 | 0 | printf("%*s", offset, ""); |
526 | 0 | print_desc(module_gettext(m, item->psz_text), |
527 | 0 | PADDING_SPACES + LINE_START, color); |
528 | |
|
529 | 0 | if (suffix != NULL) |
530 | 0 | { |
531 | 0 | printf("%*s", PADDING_SPACES + LINE_START, ""); |
532 | 0 | print_desc(suffix, PADDING_SPACES + LINE_START, color); |
533 | 0 | } |
534 | |
|
535 | 0 | if (desc && (item->psz_longtext != NULL && item->psz_longtext[0])) |
536 | 0 | { /* Wrap long description */ |
537 | 0 | printf("%*s", LINE_START + 2, ""); |
538 | 0 | print_desc(module_gettext(m, item->psz_longtext), |
539 | 0 | LINE_START + 2, false); |
540 | 0 | } |
541 | |
|
542 | 0 | free(typebuf); |
543 | 0 | } |
544 | | |
545 | | static bool module_match(const module_t *m, const char *pattern, bool strict) |
546 | 0 | { |
547 | 0 | if (pattern == NULL) |
548 | 0 | return true; |
549 | | |
550 | 0 | const char *objname = module_get_object(m); |
551 | |
|
552 | 0 | if (strict ? (strcmp(objname, pattern) == 0) |
553 | 0 | : (strstr(objname, pattern) != NULL)) |
554 | 0 | return true; |
555 | | |
556 | 0 | for (unsigned i = 0; i < m->i_shortcuts; i++) |
557 | 0 | { |
558 | 0 | const char *shortcut = m->pp_shortcuts[i]; |
559 | |
|
560 | 0 | if (strict ? (strcmp(shortcut, pattern) == 0) |
561 | 0 | : (strstr(shortcut, pattern) != NULL)) |
562 | 0 | return true; |
563 | 0 | } |
564 | 0 | return false; |
565 | 0 | } |
566 | | |
567 | | static bool plugin_show(const vlc_plugin_t *plugin) |
568 | 0 | { |
569 | 0 | for (size_t i = 0; i < plugin->conf.size; i++) |
570 | 0 | { |
571 | 0 | const struct vlc_param *param = plugin->conf.params + i; |
572 | 0 | const module_config_t *item = ¶m->item; |
573 | |
|
574 | 0 | if (!CONFIG_ITEM(item->i_type)) |
575 | 0 | continue; |
576 | 0 | if (param->obsolete) |
577 | 0 | continue; |
578 | 0 | return true; |
579 | 0 | } |
580 | 0 | return false; |
581 | 0 | } |
582 | | |
583 | | static void Usage (libvlc_int_t *p_this, char const *psz_search) |
584 | 0 | { |
585 | 0 | bool found = false; |
586 | 0 | bool strict = false; |
587 | 0 | if (psz_search != NULL && psz_search[0] == '=') |
588 | 0 | { |
589 | 0 | strict = true; |
590 | 0 | psz_search++; |
591 | 0 | } |
592 | |
|
593 | 0 | bool color = false; |
594 | 0 | #ifdef HAVE_ISATTY |
595 | 0 | if (isatty(STDOUT_FILENO)) |
596 | 0 | color = var_InheritBool(p_this, "color"); |
597 | 0 | #endif |
598 | |
|
599 | 0 | const bool desc = var_InheritBool(p_this, "help-verbose"); |
600 | | |
601 | | /* Enumerate the config for each module */ |
602 | 0 | for (const vlc_plugin_t *p = vlc_plugins; p != NULL; p = p->next) |
603 | 0 | { |
604 | 0 | const module_t *m = p->module; |
605 | 0 | const module_config_t *section = NULL; |
606 | 0 | const char *objname = module_get_object(m); |
607 | |
|
608 | 0 | if (psz_search == NULL && p->conf.count == 0) |
609 | 0 | continue; /* Ignore modules without config options */ |
610 | 0 | if (!module_match(m, psz_search, strict)) |
611 | 0 | continue; |
612 | 0 | found = true; |
613 | |
|
614 | 0 | if (psz_search == NULL && !plugin_show(p)) |
615 | 0 | continue; |
616 | | |
617 | | /* Print name of module */ |
618 | 0 | printf(color ? "\n " TS_GREEN_BOLD "%s" TS_RESET " (%s)\n" : "\n %s (%s)\n", |
619 | 0 | module_gettext(m, m->psz_longname), objname); |
620 | 0 | if (m->psz_help != NULL) |
621 | 0 | printf(color ? TS_CYAN_BOLD" %s\n" TS_RESET : " %s\n", |
622 | 0 | module_gettext(m, m->psz_help)); |
623 | |
|
624 | 0 | if (psz_search != NULL && p->conf.count == 0) |
625 | 0 | printf(" %s\n", _("This module has no options.")); |
626 | | |
627 | | /* Print module options */ |
628 | 0 | for (size_t j = 0; j < p->conf.size; j++) |
629 | 0 | { |
630 | 0 | const struct vlc_param *param = p->conf.params + j; |
631 | |
|
632 | 0 | if (param->obsolete) |
633 | 0 | continue; /* Skip removed options */ |
634 | | |
635 | 0 | print_item(m, param, §ion, color, desc); |
636 | 0 | } |
637 | 0 | } |
638 | |
|
639 | 0 | if (!found) |
640 | 0 | printf(color ? "\n" TS_BOLD "%s" TS_RESET "\n" : "\n%s\n", |
641 | 0 | _("No matching module found. Use --list or " |
642 | 0 | "--list-verbose to list available modules.")); |
643 | 0 | } |
644 | | |
645 | | /***************************************************************************** |
646 | | * ListModules: list the available modules with their description |
647 | | ***************************************************************************** |
648 | | * Print a list of all available modules (builtins and plugins) and a short |
649 | | * description for each one. |
650 | | *****************************************************************************/ |
651 | | static void ListModules (libvlc_int_t *p_this, bool b_verbose) |
652 | 0 | { |
653 | 0 | bool color = false; |
654 | |
|
655 | 0 | ShowConsole(); |
656 | 0 | #ifdef HAVE_ISATTY |
657 | 0 | if (isatty(STDOUT_FILENO)) |
658 | 0 | color = var_InheritBool(p_this, "color"); |
659 | | #else |
660 | | (void) p_this; |
661 | | #endif |
662 | | |
663 | | /* List all modules */ |
664 | 0 | size_t count; |
665 | 0 | module_t **list = module_list_get (&count); |
666 | | |
667 | | /* Enumerate each module */ |
668 | 0 | for (size_t j = 0; j < count; j++) |
669 | 0 | { |
670 | 0 | module_t *p_parser = list[j]; |
671 | 0 | const char *objname = module_get_object (p_parser); |
672 | 0 | printf(color ? TS_GREEN_BOLD " %-22s " TS_RESET_BOLD "%s\n" TS_RESET : " %-22s %s\n", |
673 | 0 | objname, module_gettext(p_parser, p_parser->psz_longname)); |
674 | |
|
675 | 0 | if( b_verbose ) |
676 | 0 | { |
677 | 0 | const char *const *pp_shortcuts = p_parser->pp_shortcuts; |
678 | 0 | for( unsigned i = 0; i < p_parser->i_shortcuts; i++ ) |
679 | 0 | if( strcmp( pp_shortcuts[i], objname ) ) |
680 | 0 | printf(color ? TS_CYAN_BOLD " s %s\n" TS_RESET : " s %s\n", |
681 | 0 | pp_shortcuts[i]); |
682 | 0 | if (p_parser->psz_capability != NULL) |
683 | 0 | printf(color ? TS_MAGENTA_BOLD " c %s (%d)\n" TS_RESET : " c %s (%d)\n", |
684 | 0 | p_parser->psz_capability, p_parser->i_score); |
685 | 0 | } |
686 | 0 | } |
687 | 0 | module_list_free (list); |
688 | 0 | PauseConsole(); |
689 | 0 | } |
690 | | |
691 | | /***************************************************************************** |
692 | | * Version: print complete program version |
693 | | ***************************************************************************** |
694 | | * Print complete program version and build number. |
695 | | *****************************************************************************/ |
696 | | static void Version( void ) |
697 | 0 | { |
698 | 0 | ShowConsole(); |
699 | 0 | printf(_("VLC version %s (%s)\n"), VERSION_MESSAGE, psz_vlc_changeset); |
700 | 0 | printf(_("Compiled by %s on %s (%s)\n"), VLC_CompileBy(), |
701 | 0 | VLC_CompileHost(), __DATE__" "__TIME__ ); |
702 | 0 | printf(_("Compiler: %s\n"), VLC_Compiler()); |
703 | 0 | fputs(LICENSE_MSG, stdout); |
704 | 0 | PauseConsole(); |
705 | 0 | } |
706 | | |
707 | | #ifdef HAVE_VLC_SHOWCONSOLE |
708 | | /***************************************************************************** |
709 | | * ShowConsole: On Win32, create an output console for debug messages |
710 | | ***************************************************************************** |
711 | | * This function is useful only on Win32. |
712 | | *****************************************************************************/ |
713 | | static void ShowConsole( void ) |
714 | | { |
715 | | if( getenv( "PWD" ) ) return; /* Cygwin shell or Wine */ |
716 | | |
717 | | if( !AllocConsole() ) return; |
718 | | |
719 | | /* Use the ANSI code page (e.g. Windows-1252) as expected by the LibVLC |
720 | | * Unicode/locale subsystem. By default, we have the obsolecent OEM code |
721 | | * page (e.g. CP437 or CP850). */ |
722 | | SetConsoleOutputCP (GetACP ()); |
723 | | SetConsoleTitle (TEXT("VLC media player version ") TEXT(PACKAGE_VERSION)); |
724 | | |
725 | | freopen( "CONOUT$", "w", stderr ); |
726 | | freopen( "CONIN$", "r", stdin ); |
727 | | |
728 | | if( freopen( "vlc-help.txt", "wt", stdout ) != NULL ) |
729 | | { |
730 | | fputs( "\xEF\xBB\xBF", stdout ); |
731 | | fprintf( stderr, _("\nDumped content to vlc-help.txt file.\n") ); |
732 | | } |
733 | | else |
734 | | freopen( "CONOUT$", "w", stdout ); |
735 | | } |
736 | | |
737 | | /***************************************************************************** |
738 | | * PauseConsole: On Win32, wait for a key press before closing the console |
739 | | ***************************************************************************** |
740 | | * This function is useful only on Win32. |
741 | | *****************************************************************************/ |
742 | | static void PauseConsole( void ) |
743 | | { |
744 | | if( getenv( "PWD" ) ) return; /* Cygwin shell or Wine */ |
745 | | |
746 | | utf8_fprintf( stderr, _("\nPress the RETURN key to continue...\n") ); |
747 | | getchar(); |
748 | | fclose( stdout ); |
749 | | } |
750 | | #endif |