@@ -76,7 +76,85 @@ struct ScrotOptions opt = {
76
76
.lineColor = "gray" ,
77
77
};
78
78
79
+ enum { /* long opt only */
80
+ /* ensure these don't collide with single byte opts. */
81
+ OPT_FORMAT = UCHAR_MAX + 1 ,
82
+ OPT_LIST_OPTS ,
83
+ };
84
+ static const char stropts [] = "a:bC:cD:d:e:F:fhik::l:M:mn:opq:S:s::t:uvw:Z:z" ;
85
+ // NOTE: make sure lopts and opt_description indexes are kept in sync
86
+ static const struct option lopts [] = {
87
+ {"autoselect" , required_argument , NULL , 'a' },
88
+ {"border" , no_argument , NULL , 'b' },
89
+ {"class" , required_argument , NULL , 'C' },
90
+ {"count" , no_argument , NULL , 'c' },
91
+ {"display" , required_argument , NULL , 'D' },
92
+ {"delay" , required_argument , NULL , 'd' },
93
+ {"exec" , required_argument , NULL , 'e' },
94
+ {"file" , required_argument , NULL , 'F' },
95
+ {"freeze" , no_argument , NULL , 'f' },
96
+ {"help" , no_argument , NULL , 'h' },
97
+ {"ignorekeyboard" , no_argument , NULL , 'i' },
98
+ {"stack" , optional_argument , NULL , 'k' },
99
+ {"line" , required_argument , NULL , 'l' },
100
+ {"monitor" , required_argument , NULL , 'M' },
101
+ {"multidisp" , no_argument , NULL , 'm' },
102
+ {"note" , required_argument , NULL , 'n' },
103
+ {"overwrite" , no_argument , NULL , 'o' },
104
+ {"pointer" , no_argument , NULL , 'p' },
105
+ {"quality" , required_argument , NULL , 'q' },
106
+ {"script" , required_argument , NULL , 'S' },
107
+ {"select" , optional_argument , NULL , 's' },
108
+ {"thumb" , required_argument , NULL , 't' },
109
+ {"focused" , no_argument , NULL , 'u' },
110
+ /* macquarie dictionary has both spellings */
111
+ {"focussed" , no_argument , NULL , 'u' },
112
+ {"version" , no_argument , NULL , 'v' },
113
+ {"window" , required_argument , NULL , 'w' },
114
+ {"compression" , required_argument , NULL , 'Z' },
115
+ {"silent" , no_argument , NULL , 'z' },
116
+ {"format" , required_argument , NULL , OPT_FORMAT },
117
+ {"list-options" , optional_argument , NULL , OPT_LIST_OPTS },
118
+ {0 }
119
+ };
120
+ static const char OPT_DEPRECATED [] = "" ;
121
+ static const struct option_desc {
122
+ const char * description , * arg_description ;
123
+ } opt_description [] = {
124
+ /* a */ { "autoselect provided region" , "x,y,w,h" },
125
+ /* b */ { "capture the window borders as well" , "" },
126
+ /* C */ { "capture specified window class" , "NAME" },
127
+ /* c */ { "display a countdown for delay" , "" },
128
+ /* D */ { "capture specified display" , "DISPLAY" },
129
+ /* d */ { "add delay before screenshot" , "[b]SEC" },
130
+ /* e */ { "execute command on saved image" , "CMD" },
131
+ /* F */ { "specify output file" , "FILE" },
132
+ /* f */ { "freeze the screen when -s is used" , "" },
133
+ /* h */ { "display help and exit" , "" },
134
+ /* i */ { "ignore keyboard" , "" },
135
+ /* k */ { "capture overlapped window and join them" , "v|h" },
136
+ /* l */ { "specify the style of the selection line" , "STYLE" },
137
+ /* M */ { "capture monitor" , "NUM" },
138
+ /* m */ { "capture all monitors" , "" },
139
+ /* n */ { OPT_DEPRECATED , OPT_DEPRECATED },
140
+ /* o */ { "overwrite the output file if needed" , "" },
141
+ /* p */ { "capture the mouse pointer as well" , "" },
142
+ /* q */ { "image quality" , "NUM" },
143
+ /* S */ { OPT_DEPRECATED , OPT_DEPRECATED },
144
+ /* s */ { "interactively select a region to capture" , "OPTS" },
145
+ /* t */ { "also generate a thumbnail" , "% | WxH" },
146
+ /* u */ { "capture the currently focused window" , "" },
147
+ /* u */ { "capture the currently focused window" , "" },
148
+ /* v */ { "output version and exit" , "" },
149
+ /* w */ { "X window ID to capture" , "WID" },
150
+ /* Z */ { "image compression level" , "LVL" },
151
+ /* z */ { "prevent beeping" , "" },
152
+ /* OPT_FORMAT */ { "specify output file format" , "FMT" },
153
+ /* OPT_LIST_OPTS */ { "list all options" , "human|tsv" },
154
+ };
155
+
79
156
static void showUsage (void );
157
+ static void showOptions (bool human );
80
158
static void showVersion (void );
81
159
static long long optionsParseNumBase (const char * , long long , long long ,
82
160
const char * [static 1 ], int );
@@ -302,82 +380,6 @@ static const char *getPathOfStdout(void)
302
380
303
381
void optionsParse (int argc , char * argv [])
304
382
{
305
- enum { /* long opt only */
306
- /* ensure these don't collude with single byte opts. */
307
- OPT_FORMAT = UCHAR_MAX + 1 ,
308
- OPT_LIST_OPTS ,
309
- };
310
- static const char stropts [] = "a:bC:cD:d:e:F:fhik::l:M:mn:opq:S:s::t:uvw:Z:z" ;
311
- // NOTE: make sure lopts and opt_description indexes are kept in sync
312
- static const struct option lopts [] = {
313
- {"autoselect" , required_argument , NULL , 'a' },
314
- {"border" , no_argument , NULL , 'b' },
315
- {"class" , required_argument , NULL , 'C' },
316
- {"count" , no_argument , NULL , 'c' },
317
- {"display" , required_argument , NULL , 'D' },
318
- {"delay" , required_argument , NULL , 'd' },
319
- {"exec" , required_argument , NULL , 'e' },
320
- {"file" , required_argument , NULL , 'F' },
321
- {"freeze" , no_argument , NULL , 'f' },
322
- {"help" , no_argument , NULL , 'h' },
323
- {"ignorekeyboard" , no_argument , NULL , 'i' },
324
- {"stack" , optional_argument , NULL , 'k' },
325
- {"line" , required_argument , NULL , 'l' },
326
- {"monitor" , required_argument , NULL , 'M' },
327
- {"multidisp" , no_argument , NULL , 'm' },
328
- {"note" , required_argument , NULL , 'n' },
329
- {"overwrite" , no_argument , NULL , 'o' },
330
- {"pointer" , no_argument , NULL , 'p' },
331
- {"quality" , required_argument , NULL , 'q' },
332
- {"script" , required_argument , NULL , 'S' },
333
- {"select" , optional_argument , NULL , 's' },
334
- {"thumb" , required_argument , NULL , 't' },
335
- {"focused" , no_argument , NULL , 'u' },
336
- /* macquarie dictionary has both spellings */
337
- {"focussed" , no_argument , NULL , 'u' },
338
- {"version" , no_argument , NULL , 'v' },
339
- {"window" , required_argument , NULL , 'w' },
340
- {"compression" , required_argument , NULL , 'Z' },
341
- {"silent" , no_argument , NULL , 'z' },
342
- {"format" , required_argument , NULL , OPT_FORMAT },
343
- {"list-options" , optional_argument , NULL , OPT_LIST_OPTS },
344
- {0 }
345
- };
346
- static const char OPT_DEPRECATED [] = "" ;
347
- static const struct option_desc {
348
- const char * description , * arg_description ;
349
- } opt_description [] = {
350
- /* a */ { "autoselect provided region" , "x,y,w,h" },
351
- /* b */ { "capture the window borders as well" , "" },
352
- /* C */ { "capture specified window class" , "NAME" },
353
- /* c */ { "display a countdown for delay" , "" },
354
- /* D */ { "capture specified display" , "DISPLAY" },
355
- /* d */ { "add delay before screenshot" , "[b]SEC" },
356
- /* e */ { "execute command on saved image" , "CMD" },
357
- /* F */ { "specify output file" , "FILE" },
358
- /* f */ { "freeze the screen when -s is used" , "" },
359
- /* h */ { "display help and exit" , "" },
360
- /* i */ { "ignore keyboard" , "" },
361
- /* k */ { "capture overlapped window and join them" , "v|h" },
362
- /* l */ { "specify the style of the selection line" , "STYLE" },
363
- /* M */ { "capture monitor" , "NUM" },
364
- /* m */ { "capture all monitors" , "" },
365
- /* n */ { OPT_DEPRECATED , OPT_DEPRECATED },
366
- /* o */ { "overwrite the output file if needed" , "" },
367
- /* p */ { "capture the mouse pointer as well" , "" },
368
- /* q */ { "image quality" , "NUM" },
369
- /* S */ { OPT_DEPRECATED , OPT_DEPRECATED },
370
- /* s */ { "interactively select a region to capture" , "OPTS" },
371
- /* t */ { "also generate a thumbnail" , "% | WxH" },
372
- /* u */ { "capture the currently focused window" , "" },
373
- /* u */ { "capture the currently focused window" , "" },
374
- /* v */ { "output version and exit" , "" },
375
- /* w */ { "X window ID to capture" , "WID" },
376
- /* Z */ { "image compression level" , "LVL" },
377
- /* z */ { "prevent beeping" , "" },
378
- /* OPT_FORMAT */ { "specify output file format" , "FMT" },
379
- /* OPT_LIST_OPTS */ { "list all options" , "human|tsv" },
380
- };
381
383
int optch ;
382
384
const char * errmsg ;
383
385
bool FFlagSet = false;
@@ -502,51 +504,16 @@ void optionsParse(int argc, char *argv[])
502
504
case OPT_FORMAT :
503
505
opt .format = optarg ;
504
506
break ;
505
- case OPT_LIST_OPTS : {
506
- bool tsv = false;
507
- if (optarg != NULL ) {
508
- if (strcmp (optarg , "tsv" ) == 0 ) {
509
- tsv = true;
510
- } else if (strcmp (optarg , "human" ) == 0 ) {
511
- // no-op
512
- } else {
513
- errx (EXIT_FAILURE ,
514
- "unknown argument for --list-options: `%s`" , optarg );
515
- }
516
- }
517
-
518
- for (size_t i = 0 ; i < ARRAY_COUNT (opt_description ); ++ i ) {
519
- const struct option * o = & lopts [i ];
520
- const struct option_desc * d = & opt_description [i ];
521
- if (d -> description == OPT_DEPRECATED )
522
- continue ;
523
-
524
- if (!tsv ) {
525
- int n = 0 ;
526
- if (o -> val <= UCHAR_MAX )
527
- n += printf ("-%c, " , o -> val );
528
- n += printf ("--%s" , o -> name );
529
- if (o -> has_arg == required_argument )
530
- n += printf (" <%s>" , d -> arg_description );
531
- else if (o -> has_arg == optional_argument )
532
- n += printf ("[=%s]" , d -> arg_description );
533
- for (; n >= 0 && n < 32 ; ++ n )
534
- putchar (' ' );
535
- printf ("%s\n" , d -> description );
536
- } else {
537
- printf ("%c\t" , o -> val <= UCHAR_MAX ? o -> val : ' ' );
538
- printf ("%s\t" , o -> name );
539
- if (o -> has_arg == required_argument )
540
- printf ("R:%s\t" , d -> arg_description );
541
- else if (o -> has_arg == optional_argument )
542
- printf ("O:%s\t" , d -> arg_description );
543
- else
544
- printf ("N:\t" );
545
- printf ("%s\n" , d -> description );
546
- }
507
+ case OPT_LIST_OPTS :
508
+ if (optarg == NULL || strcmp (optarg , "human" ) == 0 )
509
+ showOptions (true);
510
+ else if (strcmp (optarg , "tsv" ) == 0 )
511
+ showOptions (false);
512
+ else {
513
+ errx (EXIT_FAILURE ,
514
+ "unknown argument for --list-options: `%s`" , optarg );
547
515
}
548
- exit (EXIT_SUCCESS );
549
- } break ;
516
+ break ;
550
517
default :
551
518
exit (EXIT_FAILURE );
552
519
}
@@ -595,14 +562,49 @@ void optionsParse(int argc, char *argv[])
595
562
596
563
static void showUsage (void )
597
564
{
598
- fputs ("usage : " /* Check that everything lines up after any changes. */
599
- PACKAGE_NAME " [-bcfhimopuvz] [-a X,Y,W,H] [-C NAME] [-D DISPLAY] \n"
600
- " [-d SEC] [-e CMD] [-k OPT] [-l STYLE] [-M NUM] [-q NUM]\n "
601
- " [-s OPTS] [-t % | WxH] [[-F] FILE]\n" ,
602
- stdout );
565
+ fputs ("Usage : " PACKAGE_NAME " [OPTIONS...] [FILE]\n\n"
566
+ "A list of options with brief description is given below. \n"
567
+ "For more detailed description, "
568
+ "consult the " PACKAGE_NAME "(1) manpage.\n\n" , stdout );
569
+ showOptions (true );
603
570
exit (0 );
604
571
}
605
572
573
+ static void showOptions (bool human )
574
+ {
575
+ for (size_t i = 0 ; i < ARRAY_COUNT (opt_description ); ++ i ) {
576
+ const struct option * o = & lopts [i ];
577
+ const struct option_desc * d = & opt_description [i ];
578
+ if (d -> description == OPT_DEPRECATED )
579
+ continue ;
580
+
581
+ if (human ) {
582
+ int n = 0 ;
583
+ if (o -> val <= UCHAR_MAX )
584
+ n += printf ("-%c, " , o -> val );
585
+ n += printf ("--%s" , o -> name );
586
+ if (o -> has_arg == required_argument )
587
+ n += printf (" <%s>" , d -> arg_description );
588
+ else if (o -> has_arg == optional_argument )
589
+ n += printf ("[=%s]" , d -> arg_description );
590
+ for (; n >= 0 && n < 32 ; ++ n )
591
+ putchar (' ' );
592
+ printf ("%s\n" , d -> description );
593
+ } else {
594
+ printf ("%c\t" , o -> val <= UCHAR_MAX ? o -> val : ' ' );
595
+ printf ("%s\t" , o -> name );
596
+ if (o -> has_arg == required_argument )
597
+ printf ("R:%s\t" , d -> arg_description );
598
+ else if (o -> has_arg == optional_argument )
599
+ printf ("O:%s\t" , d -> arg_description );
600
+ else
601
+ printf ("N:\t" );
602
+ printf ("%s\n" , d -> description );
603
+ }
604
+ }
605
+ exit (EXIT_SUCCESS );
606
+ }
607
+
606
608
static void showVersion (void )
607
609
{
608
610
puts (PACKAGE_NAME " version " PACKAGE_VERSION );
0 commit comments