mirror of
https://github.com/ascii-boxes/boxes.git
synced 2024-12-04 14:03:53 +01:00
Untangle -l and -q options #23
Both are now used stand-alone for their respective purposes.
This commit is contained in:
parent
76880f1c3c
commit
09d5ebcbb4
@ -7,7 +7,8 @@ boxes \- text mode box and comment drawing filter
|
||||
.SH SYNOPSIS
|
||||
.B boxes
|
||||
[\-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
|
||||
.I Boxes
|
||||
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.
|
||||
Also checks syntax of the entire config file. If used in connection with
|
||||
.B \-d\fP,
|
||||
displays detailed information about the specified design. If used in
|
||||
connection with
|
||||
.B \-q\fP,
|
||||
displays only the design and alias names, but no further information.
|
||||
displays detailed information about the specified design.
|
||||
.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
.TP 0.6i
|
||||
.B \-m
|
||||
@ -233,24 +231,26 @@ used.
|
||||
.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
.TP 0.6i
|
||||
.B \-q \fIquery\fP
|
||||
Query designs by tag. Can only be used in combination with
|
||||
.B \-l\fP.
|
||||
If used in other contexts, behavior is undefined.
|
||||
.br
|
||||
Query designs by tag. In contrast to
|
||||
.B \-l\fP,
|
||||
this will only print the matching design names. This option is normally used
|
||||
stand-alone; if used in combination with other options, behavior is undefined.
|
||||
The
|
||||
.I query
|
||||
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
|
||||
.I \+
|
||||
in order to require that a tag be present, or with
|
||||
in order to require that it be present, or with
|
||||
.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
|
||||
Using this option alters the behavior of
|
||||
.B \-l
|
||||
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
|
||||
This option is intended for use by scripts. Alias names are printed below
|
||||
their primary design name, and postfixed with
|
||||
.I (alias)\fP.
|
||||
.br
|
||||
Example:
|
||||
.I boxes -q programming,-comment
|
||||
.\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
.TP 0.6i
|
||||
.B \-r
|
||||
|
135
src/boxes.c
135
src/boxes.c
@ -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, " -n enc Character encoding of input and output [default: %s]\n", locale_charset());
|
||||
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, " -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);
|
||||
@ -948,16 +948,35 @@ static void print_tags(tagstats_t *tagstats, size_t num_tags)
|
||||
|
||||
|
||||
|
||||
static int list_styles()
|
||||
/*
|
||||
* Generate sorted listing of available box styles.
|
||||
* Uses design name from BOX spec and sample picture plus author.
|
||||
*
|
||||
* RETURNS: != 0 on error (out of memory)
|
||||
* == 0 on success
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
/**
|
||||
* 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.
|
||||
* Uses design name from BOX spec and sample picture plus author.
|
||||
* @returns != 0 on error (out of memory);
|
||||
* == 0 on success
|
||||
*/
|
||||
static int list_styles()
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -1136,62 +1155,40 @@ static int list_styles()
|
||||
|
||||
|
||||
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;
|
||||
size_t num_tags = 0;
|
||||
if (opt.query == NULL) {
|
||||
print_design_list_header();
|
||||
design_t **list = sort_designs_by_name(); /* temp list for sorting */
|
||||
if (list == NULL) {
|
||||
return 1;
|
||||
}
|
||||
print_design_list_header();
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
char *all_names = names(list[i]);
|
||||
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,
|
||||
list[i]->designer, list[i]->author, list[i]->sample);
|
||||
}
|
||||
else if (list[i]->designer) {
|
||||
fprintf(opt.outfile, "%s\n%s:\n\n%s\n\n", all_names, list[i]->designer, list[i]->sample);
|
||||
}
|
||||
else if (list[i]->author) {
|
||||
fprintf(opt.outfile, "%s\nunknown artist, coded by %s:\n\n%s\n\n", all_names,
|
||||
list[i]->author, list[i]->sample);
|
||||
}
|
||||
else {
|
||||
char *all_names = names(list[i]);
|
||||
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,
|
||||
list[i]->designer, list[i]->author, list[i]->sample);
|
||||
}
|
||||
else if (list[i]->designer) {
|
||||
fprintf(opt.outfile, "%s\n%s:\n\n%s\n\n", all_names, list[i]->designer, list[i]->sample);
|
||||
}
|
||||
else if (list[i]->author) {
|
||||
fprintf(opt.outfile, "%s\nunknown artist, coded by %s:\n\n%s\n\n", all_names,
|
||||
list[i]->author, list[i]->sample);
|
||||
}
|
||||
else {
|
||||
fprintf(opt.outfile, "%s:\n\n%s\n\n", all_names, list[i]->sample);
|
||||
}
|
||||
BFREE(all_names);
|
||||
fprintf(opt.outfile, "%s:\n\n%s\n\n", all_names, list[i]->sample);
|
||||
}
|
||||
BFREE(all_names);
|
||||
|
||||
for (size_t tidx = 0; list[i]->tags[tidx] != NULL; ++tidx) {
|
||||
count_tag(list[i]->tags[tidx], &tagstats, &num_tags);
|
||||
}
|
||||
for (size_t tidx = 0; list[i]->tags[tidx] != NULL; ++tidx) {
|
||||
count_tag(list[i]->tags[tidx], &tagstats, &num_tags);
|
||||
}
|
||||
}
|
||||
BFREE(list);
|
||||
|
||||
if (opt.query == NULL) {
|
||||
print_tags(tagstats, num_tags);
|
||||
BFREE(tagstats);
|
||||
}
|
||||
print_tags(tagstats, num_tags);
|
||||
BFREE(tagstats);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1199,6 +1196,26 @@ static int list_styles()
|
||||
|
||||
|
||||
|
||||
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)
|
||||
/*
|
||||
* Determine indentation of given lines in spaces.
|
||||
@ -1626,6 +1643,14 @@ int main(int argc, char *argv[])
|
||||
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
|
||||
* Increase box width/height by width/height of empty sides in order
|
||||
|
@ -348,7 +348,7 @@ static int design_needed(pass_to_bison *bison_args)
|
||||
return design_has_name(&(curdes), (char *) opt.design);
|
||||
}
|
||||
else {
|
||||
if (opt.r || opt.l) {
|
||||
if (opt.r || opt.l || (opt.query != NULL && !query_is_undoc())) {
|
||||
return 1;
|
||||
}
|
||||
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.
|
||||
* 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;
|
||||
return RC_ACCEPT;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
:ARGS
|
||||
-f 14x_tag_query.cfg -l -q tag1,tag2
|
||||
-f 14x_tag_query.cfg -q tag1,tag2
|
||||
:INPUT
|
||||
:OUTPUT-FILTER
|
||||
:EXPECTED
|
||||
|
@ -1,5 +1,5 @@
|
||||
:ARGS
|
||||
-f 14x_tag_query.cfg -l -q +tag1,tag2
|
||||
-f 14x_tag_query.cfg -q +tag1,tag2
|
||||
:INPUT
|
||||
:OUTPUT-FILTER
|
||||
:EXPECTED
|
||||
|
@ -1,5 +1,5 @@
|
||||
:ARGS
|
||||
-f 14x_tag_query.cfg -l -q +tag1,+tag3
|
||||
-f 14x_tag_query.cfg -q +tag1,+tag3
|
||||
:INPUT
|
||||
:OUTPUT-FILTER
|
||||
:EXPECTED
|
||||
|
@ -1,5 +1,5 @@
|
||||
:ARGS
|
||||
-f 14x_tag_query.cfg -l -q -tag1
|
||||
-f 14x_tag_query.cfg -q -tag1
|
||||
:INPUT
|
||||
:OUTPUT-FILTER
|
||||
:EXPECTED
|
||||
|
@ -1,5 +1,5 @@
|
||||
:ARGS
|
||||
-f 14x_tag_query.cfg -l -q -tag1,-tag2
|
||||
-f 14x_tag_query.cfg -q -tag1,-tag2
|
||||
:INPUT
|
||||
:OUTPUT-FILTER
|
||||
:EXPECTED
|
||||
|
@ -1,5 +1,5 @@
|
||||
:ARGS
|
||||
-f 14x_tag_query.cfg -l -q (all)
|
||||
-f 14x_tag_query.cfg -q (all)
|
||||
:INPUT
|
||||
:OUTPUT-FILTER
|
||||
:EXPECTED
|
||||
|
@ -1,5 +1,5 @@
|
||||
:ARGS
|
||||
-f 146_tag_query.cfg -l -q INVALID
|
||||
-f 146_tag_query.cfg -q INVALID
|
||||
:INPUT
|
||||
:OUTPUT-FILTER
|
||||
:EXPECTED-ERROR 1
|
||||
|
@ -1,5 +1,5 @@
|
||||
:ARGS
|
||||
-f 14x_tag_query.cfg -l -q -tag1,+tag1
|
||||
-f 14x_tag_query.cfg -q -tag1,+tag1
|
||||
:INPUT
|
||||
:OUTPUT-FILTER
|
||||
:EXPECTED-ERROR 1
|
||||
|
@ -1,5 +1,5 @@
|
||||
:ARGS
|
||||
-f 14x_tag_query.cfg -l -q -tag1,tag1
|
||||
-f 14x_tag_query.cfg -q -tag1,tag1
|
||||
:INPUT
|
||||
:OUTPUT-FILTER
|
||||
:EXPECTED-ERROR 1
|
||||
|
@ -1,6 +0,0 @@
|
||||
:ARGS
|
||||
-f 14x_tag_query.cfg -l -q non-existent
|
||||
:INPUT
|
||||
:OUTPUT-FILTER
|
||||
:EXPECTED
|
||||
:EOF
|
Loading…
Reference in New Issue
Block a user