Untangle -l and -q options #23

Both are now used stand-alone for their respective purposes.
This commit is contained in:
Thomas Jensen 2021-04-06 21:22:18 +02:00
parent 76880f1c3c
commit 09d5ebcbb4
No known key found for this signature in database
GPG Key ID: A4ACEE270D0FB7DB
13 changed files with 107 additions and 88 deletions

View File

@ -7,7 +7,8 @@ boxes \- text mode box and comment drawing filter
.SH SYNOPSIS .SH SYNOPSIS
.B boxes .B boxes
[\-hlmrv] [\-a\ format] [\-d\ design] [\-f\ file] [\-i\ indent] [\-k\ bool] [\-hlmrv] [\-a\ format] [\-d\ design] [\-f\ file] [\-i\ indent] [\-k\ bool]
[\-n\ encoding] [\-p\ pad] [\-s\ size] [\-t\ tabopts] [infile [outfile]] [\-n\ encoding] [\-p\ pad] [\-q query] [\-s\ size] [\-t\ tabopts]
[infile [outfile]]
.SH DESCRIPTION .SH DESCRIPTION
.I Boxes .I Boxes
is a text filter which can draw any kind of box around its input text. Box is a text filter which can draw any kind of box around its input text. Box
@ -171,10 +172,7 @@ top part or a bottom part, the default is yes.
config file, along with a sample box and information about it's creator. config file, along with a sample box and information about it's creator.
Also checks syntax of the entire config file. If used in connection with Also checks syntax of the entire config file. If used in connection with
.B \-d\fP, .B \-d\fP,
displays detailed information about the specified design. If used in displays detailed information about the specified design.
connection with
.B \-q\fP,
displays only the design and alias names, but no further information.
.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.TP 0.6i .TP 0.6i
.B \-m .B \-m
@ -233,24 +231,26 @@ used.
.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.TP 0.6i .TP 0.6i
.B \-q \fIquery\fP .B \-q \fIquery\fP
Query designs by tag. Can only be used in combination with Query designs by tag. In contrast to
.B \-l\fP. .B \-l\fP,
If used in other contexts, behavior is undefined. this will only print the matching design names. This option is normally used
.br stand-alone; if used in combination with other options, behavior is undefined.
The The
.I query .I query
argument is a comma-separated list of tags which can be present on a design argument is a comma-separated list of tags which can be present on a design
in order to match. A tag may optionally be prefixed with in order to match. A tag may optionally be prefixed with
.I \+ .I \+
in order to require that a tag be present, or with in order to require that it be present, or with
.I \- .I \-
in order to exclude designs which have that tag. in order to exclude designs which have that tag. Each tag can only occur once
per query.
.br .br
Using this option alters the behavior of This option is intended for use by scripts. Alias names are printed below
.B \-l their primary design name, and postfixed with
so that only the design names are printed. This is intended for use by scripts.
Alias names are printed below their primary design name, and postfixed with
.I (alias)\fP. .I (alias)\fP.
.br
Example:
.I boxes -q programming,-comment
.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
.TP 0.6i .TP 0.6i
.B \-r .B \-r

View File

@ -97,7 +97,7 @@ static void usage(FILE *st)
fprintf(st, " -m mend box, i.e. remove it and redraw it afterwards\n"); fprintf(st, " -m mend box, i.e. remove it and redraw it afterwards\n");
fprintf(st, " -n enc Character encoding of input and output [default: %s]\n", locale_charset()); fprintf(st, " -n enc Character encoding of input and output [default: %s]\n", locale_charset());
fprintf(st, " -p fmt padding [default: none]\n"); fprintf(st, " -p fmt padding [default: none]\n");
fprintf(st, " -q qry in combination with -l, query design list by tag\n"); /* with (undoc) arg, trigger undocumented webui stuff */ fprintf(st, " -q qry query the list of designs by tag\n"); /* with "(undoc)" as query, trigger undocumented webui stuff instead */
fprintf(st, " -r remove box\n"); fprintf(st, " -r remove box\n");
fprintf(st, " -s wxh box size (width w and/or height h)\n"); fprintf(st, " -s wxh box size (width w and/or height h)\n");
fprintf(st, " -t str tab stop distance and expansion [default: %de]\n", DEF_TABSTOP); fprintf(st, " -t str tab stop distance and expansion [default: %de]\n", DEF_TABSTOP);
@ -948,16 +948,35 @@ static void print_tags(tagstats_t *tagstats, size_t num_tags)
static int list_styles() /**
/* * Create a sorted shallow copy of the design array.
* @returns a new array, for which memory was allocated. All pointers in the array point to the original data.
* Returns `NULL` when out of memory.
*/
static design_t **sort_designs_by_name()
{
design_t **result = (design_t **) malloc(anz_designs * sizeof(design_t *));
if (result != NULL) {
for (int i = 0; i < anz_designs; ++i) {
result[i] = &(designs[i]);
}
qsort(result, anz_designs, sizeof(design_t *), style_sort);
}
else {
perror(PROJECT);
}
return result;
}
/**
* Generate sorted listing of available box styles. * Generate sorted listing of available box styles.
* Uses design name from BOX spec and sample picture plus author. * Uses design name from BOX spec and sample picture plus author.
* * @returns != 0 on error (out of memory);
* RETURNS: != 0 on error (out of memory)
* == 0 on success * == 0 on success
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/ */
static int list_styles()
{ {
int i; int i;
@ -1136,34 +1155,15 @@ static int list_styles()
else { else {
design_t **list; /* temp list for sorting */
list = (design_t **) calloc(anz_designs, sizeof(design_t *));
if (list == NULL) {
perror(PROJECT);
return 1;
}
for (i = 0; i < anz_designs; ++i) {
list[i] = &(designs[i]);
}
qsort(list, anz_designs, sizeof(design_t *), style_sort);
tagstats_t *tagstats = NULL; tagstats_t *tagstats = NULL;
size_t num_tags = 0; size_t num_tags = 0;
if (opt.query == NULL) { design_t **list = sort_designs_by_name(); /* temp list for sorting */
if (list == NULL) {
return 1;
}
print_design_list_header(); print_design_list_header();
}
for (i = 0; i < anz_designs; ++i) { for (i = 0; i < anz_designs; ++i) {
if (opt.query != NULL) {
if (filter_by_tag(list[i]->tags)) {
fprintf(opt.outfile, "%s\n", list[i]->name);
for (size_t aidx = 0; list[i]->aliases[aidx] != NULL; ++aidx) {
fprintf(opt.outfile, "%s (alias)\n", list[i]->aliases[aidx]);
}
}
}
else {
char *all_names = names(list[i]); char *all_names = names(list[i]);
if (list[i]->author && list[i]->designer && strcmp(list[i]->author, list[i]->designer) != 0) { if (list[i]->author && list[i]->designer && strcmp(list[i]->author, list[i]->designer) != 0) {
fprintf(opt.outfile, "%s\n%s, coded by %s:\n\n%s\n\n", all_names, fprintf(opt.outfile, "%s\n%s, coded by %s:\n\n%s\n\n", all_names,
@ -1185,20 +1185,37 @@ static int list_styles()
count_tag(list[i]->tags[tidx], &tagstats, &num_tags); count_tag(list[i]->tags[tidx], &tagstats, &num_tags);
} }
} }
}
BFREE(list); BFREE(list);
if (opt.query == NULL) {
print_tags(tagstats, num_tags); print_tags(tagstats, num_tags);
BFREE(tagstats); BFREE(tagstats);
} }
}
return 0; return 0;
} }
static int query_by_tag()
{
design_t **list = sort_designs_by_name(); /* temp list for sorting */
if (list == NULL) {
return 1;
}
for (int i = 0; i < anz_designs; ++i) {
if (filter_by_tag(list[i]->tags)) {
fprintf(opt.outfile, "%s\n", list[i]->name);
for (size_t aidx = 0; list[i]->aliases[aidx] != NULL; ++aidx) {
fprintf(opt.outfile, "%s (alias)\n", list[i]->aliases[aidx]);
}
}
}
BFREE(list);
return 0;
}
static int get_indent(const line_t *lines, const size_t lines_size) static int get_indent(const line_t *lines, const size_t lines_size)
/* /*
* Determine indentation of given lines in spaces. * Determine indentation of given lines in spaces.
@ -1626,6 +1643,14 @@ int main(int argc, char *argv[])
exit(rc); exit(rc);
} }
/*
* If "-q" option was given, print results of tag query and exit.
*/
if (opt.query != NULL && opt.query[0] != NULL && !query_is_undoc()) {
rc = query_by_tag();
exit(rc);
}
/* /*
* Adjust box size and indentmode to command line specification * Adjust box size and indentmode to command line specification
* Increase box width/height by width/height of empty sides in order * Increase box width/height by width/height of empty sides in order

View File

@ -348,7 +348,7 @@ static int design_needed(pass_to_bison *bison_args)
return design_has_name(&(curdes), (char *) opt.design); return design_has_name(&(curdes), (char *) opt.design);
} }
else { else {
if (opt.r || opt.l) { if (opt.r || opt.l || (opt.query != NULL && !query_is_undoc())) {
return 1; return 1;
} }
if (bison_args->design_idx == 0) { if (bison_args->design_idx == 0) {
@ -748,9 +748,9 @@ int action_add_design(pass_to_bison *bison_args, char *design_primary_name, char
/* /*
* Check if we need to continue parsing. If not, return. * Check if we need to continue parsing. If not, return.
* The condition here must correspond to design_needed() in parsecode.c. * The condition here must correspond to the function design_needed().
*/ */
if (opt.design_choice_by_user || (!opt.r && !opt.l)) { if (opt.design_choice_by_user || (!opt.r && !opt.l && (opt.query == NULL || query_is_undoc()))) {
bison_args->num_designs = bison_args->design_idx + 1; bison_args->num_designs = bison_args->design_idx + 1;
return RC_ACCEPT; return RC_ACCEPT;
} }

View File

@ -1,5 +1,5 @@
:ARGS :ARGS
-f 14x_tag_query.cfg -l -q tag1,tag2 -f 14x_tag_query.cfg -q tag1,tag2
:INPUT :INPUT
:OUTPUT-FILTER :OUTPUT-FILTER
:EXPECTED :EXPECTED

View File

@ -1,5 +1,5 @@
:ARGS :ARGS
-f 14x_tag_query.cfg -l -q +tag1,tag2 -f 14x_tag_query.cfg -q +tag1,tag2
:INPUT :INPUT
:OUTPUT-FILTER :OUTPUT-FILTER
:EXPECTED :EXPECTED

View File

@ -1,5 +1,5 @@
:ARGS :ARGS
-f 14x_tag_query.cfg -l -q +tag1,+tag3 -f 14x_tag_query.cfg -q +tag1,+tag3
:INPUT :INPUT
:OUTPUT-FILTER :OUTPUT-FILTER
:EXPECTED :EXPECTED

View File

@ -1,5 +1,5 @@
:ARGS :ARGS
-f 14x_tag_query.cfg -l -q -tag1 -f 14x_tag_query.cfg -q -tag1
:INPUT :INPUT
:OUTPUT-FILTER :OUTPUT-FILTER
:EXPECTED :EXPECTED

View File

@ -1,5 +1,5 @@
:ARGS :ARGS
-f 14x_tag_query.cfg -l -q -tag1,-tag2 -f 14x_tag_query.cfg -q -tag1,-tag2
:INPUT :INPUT
:OUTPUT-FILTER :OUTPUT-FILTER
:EXPECTED :EXPECTED

View File

@ -1,5 +1,5 @@
:ARGS :ARGS
-f 14x_tag_query.cfg -l -q (all) -f 14x_tag_query.cfg -q (all)
:INPUT :INPUT
:OUTPUT-FILTER :OUTPUT-FILTER
:EXPECTED :EXPECTED

View File

@ -1,5 +1,5 @@
:ARGS :ARGS
-f 146_tag_query.cfg -l -q INVALID -f 146_tag_query.cfg -q INVALID
:INPUT :INPUT
:OUTPUT-FILTER :OUTPUT-FILTER
:EXPECTED-ERROR 1 :EXPECTED-ERROR 1

View File

@ -1,5 +1,5 @@
:ARGS :ARGS
-f 14x_tag_query.cfg -l -q -tag1,+tag1 -f 14x_tag_query.cfg -q -tag1,+tag1
:INPUT :INPUT
:OUTPUT-FILTER :OUTPUT-FILTER
:EXPECTED-ERROR 1 :EXPECTED-ERROR 1

View File

@ -1,5 +1,5 @@
:ARGS :ARGS
-f 14x_tag_query.cfg -l -q -tag1,tag1 -f 14x_tag_query.cfg -q -tag1,tag1
:INPUT :INPUT
:OUTPUT-FILTER :OUTPUT-FILTER
:EXPECTED-ERROR 1 :EXPECTED-ERROR 1

View File

@ -1,6 +0,0 @@
:ARGS
-f 14x_tag_query.cfg -l -q non-existent
:INPUT
:OUTPUT-FILTER
:EXPECTED
:EOF