@@ -305,8 +305,10 @@ void optionsParse(int argc, char *argv[])
305
305
enum { /* long opt only */
306
306
/* ensure these don't collude with single byte opts. */
307
307
OPT_FORMAT = UCHAR_MAX + 1 ,
308
+ OPT_LIST_OPTS ,
308
309
};
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
310
312
static const struct option lopts [] = {
311
313
{"autoselect" , required_argument , NULL , 'a' },
312
314
{"border" , no_argument , NULL , 'b' },
@@ -338,8 +340,44 @@ void optionsParse(int argc, char *argv[])
338
340
{"compression" , required_argument , NULL , 'Z' },
339
341
{"silent" , no_argument , NULL , 'z' },
340
342
{"format" , required_argument , NULL , OPT_FORMAT },
343
+ {"list-options" , optional_argument , NULL , OPT_LIST_OPTS },
341
344
{0 }
342
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
+ };
343
381
int optch ;
344
382
const char * errmsg ;
345
383
bool FFlagSet = false;
@@ -464,6 +502,51 @@ void optionsParse(int argc, char *argv[])
464
502
case OPT_FORMAT :
465
503
opt .format = optarg ;
466
504
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
+ }
547
+ }
548
+ exit (EXIT_SUCCESS );
549
+ } break ;
467
550
default :
468
551
exit (EXIT_FAILURE );
469
552
}
0 commit comments