Consolidate undocumented options into -x command line option

This commit is contained in:
Thomas Jensen 2024-06-01 15:54:46 +02:00
parent c0bba2adf1
commit 083fc37b12
No known key found for this signature in database
GPG Key ID: A4ACEE270D0FB7DB
7 changed files with 72 additions and 35 deletions

View File

@ -512,7 +512,7 @@ int main(int argc, char *argv[])
}
/* If "-q" option was given, print results of tag query and exit. */
if (opt.query != NULL && opt.query[0] != NULL && !query_is_undoc()) {
if (opt.query != NULL && opt.query[0] != NULL) {
rc = query_by_tag();
exit(rc);
}

View File

@ -143,7 +143,6 @@ typedef struct { /* Command line options: */
char *eol; /** `-e`: line break to use. Never NULL, default to "\n". */
int eol_overridden; /** `-e`: 0: value in `eol` is the default; 1: value in `eol` specified via `-e` */
char *f; /** `-f`: config file path */
int *debug; /** `-g`: activate debug logging for given debug log areas */
int help; /** `-h`: flags if help argument was specified */
char indentmode; /** `-i`: 'b', 't', 'n', or '\0' */
int killblank; /** `-k`: kill blank lines, -1 if not set */
@ -158,6 +157,8 @@ typedef struct { /* Command line options: */
int tabstop; /** `-t`: tab stop distance */
char tabexp; /** `-t`: tab expansion mode (for leading tabs) */
int version_requested; /** `-v`: request to show version number */
int *debug; /** `-x debug:`: activate debug logging for given debug log areas */
int qundoc; /** `-x (undoc)`: flag if "(undoc)" was specified, put directly before "debug:" */
FILE *infile;
FILE *outfile;
} opt_t;

View File

@ -32,6 +32,7 @@
#endif
#include "boxes.h"
#include "bxstring.h"
#include "discovery.h"
#include "logging.h"
#include "query.h"
@ -58,6 +59,9 @@ extern int optind; /* for getopt() */
#define EOL_DEFAULT "\n"
#endif
#define EXTRA_UNDOC "(undoc)"
#define EXTRA_DEBUG "debug"
/**
@ -92,7 +96,6 @@ void usage_long(FILE *st)
strcmp(EOL_DEFAULT, "\r\n") == 0 ? "CRLF" : "LF");
fprintf(st, " -f, --config <file> Configuration file [default: %s]\n",
config_file != NULL ? bxs_to_output(config_file) : "none");
/* fprintf(st, " -g, --debug <areas> Activate debug logging for specified log areas [default area: MAIN]"); // undocumented */
fprintf(st, " -h, --help Print usage information\n");
fprintf(st, " -i, --indent <mode> Indentation mode [default: box]\n");
fprintf(st, " -k <bool> Leading/trailing blank line retention on removal\n");
@ -102,11 +105,14 @@ void usage_long(FILE *st)
fprintf(st, " -m, --mend Mend (repair) box\n");
fprintf(st, " -n, --encoding <enc> Character encoding of input and output [default: %s]\n", locale_charset());
fprintf(st, " -p, --padding <fmt> Padding [default: none]\n");
fprintf(st, " -q, --tag-query <qry> Query the list of designs by tag\n"); /* with "(undoc)" as query, trigger undocumented behavior instead */
fprintf(st, " -q, --tag-query <qry> Query the list of designs by tag\n");
fprintf(st, " -r, --remove Remove box\n");
fprintf(st, " -s, --size <wxh> Box size (width w and/or height h)\n");
fprintf(st, " -t, --tabs <str> Tab stop distance and expansion [default: %de]\n", DEF_TABSTOP);
fprintf(st, " -v, --version Print version information\n");
/* fprintf(st, " -x, --extra <arg> If <arg> starts with "debug:", activate debug logging for specified log
areas which follow in a comma-separated list [default area: MAIN]. If <arg> is "(undoc)", trigger
undocumented behavior of design detail lister."); // undocumented */
bxs_free(config_file);
}
@ -494,7 +500,10 @@ static int debug_areas(opt_t *result, char *optarg)
}
}
if (!valid) {
bx_fprintf(stderr, "%s: invalid debug area -- %s\n", PROJECT, trimmed);
bx_fprintf(stderr, "%s: invalid debug area -- %s. Valid values: ", PROJECT, trimmed);
for (size_t i = 1; i < NUM_LOG_AREAS + 2; i++) {
bx_fprintf(stderr, "%s%s", log_area_names[i], i < (NUM_LOG_AREAS + 2 - 1) ? ", " : "\n");
}
BFREE(trimmed);
return 1;
}
@ -553,6 +562,48 @@ static int tab_handling(opt_t *result, char *optarg)
/**
* Handle undocumented options (-x).
* @param result the options struct we are building
* @param optarg the argument to `-x` on the command line
* @returns 0 on success, anything else on error
*/
static int undocumented_options(opt_t *result, char *optarg)
{
char *s = optarg;
if (strncmp(s, EXTRA_UNDOC, strlen(EXTRA_UNDOC)) == 0) {
result->qundoc = 1;
s += strlen(EXTRA_UNDOC);
}
if (strncasecmp(s, EXTRA_DEBUG, strlen(EXTRA_DEBUG)) == 0) {
s += strlen(EXTRA_DEBUG);
if (*s == ':') {
if (debug_areas(result, s + 1) != 0) {
return 1;
}
}
else if (*s == '\0') {
/* default to MAIN */
debug_areas(result, NULL);
}
else {
bx_fprintf(stderr, "%s: invalid option -x %s\n", PROJECT, optarg);
return 2;
}
activate_debug_logging(result->debug);
}
if (!result->qundoc && !is_debug_activated()) {
bx_fprintf(stderr, "%s: invalid option -x %s\n", PROJECT, optarg);
return 3;
}
return 0;
}
/**
* Set *stdout* to binary mode, so that we can control the line terminator. This function only ever does anything on
* Windows, because on Linux, we already do have control over line terminators.
@ -639,7 +690,7 @@ static void print_debug_info(opt_t *result)
log_debug(__FILE__, MAIN, " - Design Definition W shape (-c): %s\n", result->cld ? result->cld : "n/a");
log_debug(__FILE__, MAIN, " - Color mode: %d\n", result->color);
log_debug(__FILE__, MAIN, " - Debug areas: ");
log_debug(__FILE__, MAIN, " - Debug areas (-x debug:...): ");
int dbgfirst = 1;
for (size_t i = 0; i < NUM_LOG_AREAS; i++) {
if (result->debug[i]) {
@ -658,7 +709,7 @@ static void print_debug_info(opt_t *result)
log_debug(__FILE__, MAIN, " - Padding (-p): l:%d t:%d r:%d b:%d\n",
result->padding[BLEF], result->padding[BTOP], result->padding[BRIG], result->padding[BBOT]);
log_debug(__FILE__, MAIN, " - Tag Query / Special handling for Web UI (-q): ");
log_debug(__FILE__, MAIN, " - Tag Query (-q): ");
if (result->query != NULL) {
for (size_t qidx = 0; result->query[qidx] != NULL; ++qidx) {
log_debug_cont(MAIN, "%s%s", qidx > 0 ? ", " : "", result->query[qidx]);
@ -668,6 +719,7 @@ static void print_debug_info(opt_t *result)
}
log_debug_cont(MAIN, "\n");
log_debug(__FILE__, MAIN, " - qundoc (-x): %d\n", result->qundoc);
log_debug(__FILE__, MAIN, " - Remove box (-r): %d\n", result->r);
log_debug(__FILE__, MAIN, " - Requested box size (-s): %ldx%ld\n", result->reqwidth, result->reqheight);
log_debug(__FILE__, MAIN, " - Tabstop distance (-t): %d\n", result->tabstop);
@ -703,7 +755,6 @@ opt_t *process_commandline(int argc, char *argv[])
{ "create", required_argument, NULL, 'c' },
{ "color", no_argument, NULL, OPT_COLOR },
{ "no-color", no_argument, NULL, OPT_NO_COLOR },
{ "debug", optional_argument, NULL, 'g' },
{ "design", required_argument, NULL, 'd' },
{ "eol", required_argument, NULL, 'e' },
{ "config", required_argument, NULL, 'f' },
@ -720,9 +771,10 @@ opt_t *process_commandline(int argc, char *argv[])
{ "size", required_argument, NULL, 's' },
{ "tabs", required_argument, NULL, 't' },
{ "version", no_argument, NULL, 'v' },
{ "extra", required_argument, NULL, 'x' },
{ NULL, 0, NULL, 0 }
};
const char *short_options = "a:c:d:e:f:g::hi:k:lmn:p:q:rs:t:v";
const char *short_options = "a:c:d:e:f:hi:k:lmn:p:q:rs:t:vx:";
int oc; /* option character */
do {
@ -770,14 +822,6 @@ opt_t *process_commandline(int argc, char *argv[])
result->f = strdup(optarg); /* input file */
break;
case 'g':
if (debug_areas(result, optarg) != 0) {
BFREE(result);
return NULL;
}
activate_debug_logging(result->debug);
break;
case 'h':
result->help = 1;
return result;
@ -863,6 +907,13 @@ opt_t *process_commandline(int argc, char *argv[])
result->version_requested = 1; /* print version number */
return result;
case 'x':
if (undocumented_options(result, optarg) != 0) {
BFREE(result);
return NULL;
}
break;
case ':':
case '?':
/* Missing argument or illegal option - do nothing else */

View File

@ -321,7 +321,7 @@ static void print_design_details(design_t *d)
/*
* Display all shapes
*/
if (query_is_undoc()) {
if (opt.qundoc) {
fprintf(opt.outfile, "Sample:%s%s%s", opt.eol, bxs_to_output(d->sample), opt.eol);
}
else {

View File

@ -314,7 +314,7 @@ static int full_parse_required()
{
int result = 0;
if (!opt.design_choice_by_user) {
result = opt.r || opt.l || (opt.query != NULL && !query_is_undoc());
result = opt.r || opt.l || (opt.query != NULL && !opt.qundoc);
}
#ifdef DEBUG
fprintf(stderr, " Parser: full_parse_required() -> %s\n", result ? "true" : "false");

View File

@ -30,13 +30,12 @@
#define QUERY_ALL "(all)"
#define QUERY_UNDOC "(undoc)"
static int validate_tag(char *tag)
{
if (strcmp(tag, QUERY_ALL) == 0 || strcmp(tag, QUERY_UNDOC) == 0) {
if (strcmp(tag, QUERY_ALL) == 0) {
return 1;
}
return tag_is_valid(tag);
@ -117,13 +116,6 @@ char **parse_query(char *optarg)
int query_is_undoc()
{
return opt.query != NULL && strcmp(opt.query[0], QUERY_UNDOC) == 0 && opt.query[1] == NULL;
}
static int filter_by_tag(char **tags)
{
#ifdef DEBUG

View File

@ -29,13 +29,6 @@
char **parse_query(char *optarg);
/**
* Check if -q "(undoc)" was specified.
* @returns flag
*/
int query_is_undoc();
/**
* Perform the tag query based on the global design list and the query from the global `opt` struct.
* @returns 0 if successful; anything else on error (then the program should exit)