Coverage Report

Created: 2026-04-12 07:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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 = &param->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 = &param->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, &section, 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