mirror of
https://github.com/ascii-boxes/boxes.git
synced 2024-12-12 09:51:10 +01:00
Fix a bug where alias names could be defined twice
This could happen when configs are inherited, but aliases redefined (a rare case so far).
This commit is contained in:
parent
d6433d3d41
commit
00153f8068
@ -76,14 +76,14 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *name; /* primary name of the box design */
|
||||
char **aliases; /* zero-terminated array of alias names of the design */
|
||||
char *author; /* creator of the configuration file entry */
|
||||
char *designer; /* creator of the original ASCII artwork */
|
||||
char *created; /* date created, free format */
|
||||
char *revision; /* revision number of design */
|
||||
char *revdate; /* date of current revision */
|
||||
char *sample;
|
||||
char *sample; /* the complete sample block in one string */
|
||||
char indentmode; /* 'b', 't', or 'n' */
|
||||
sentry_t shape[NUM_SHAPES];
|
||||
size_t maxshapeheight; /* height of highest shape in design */
|
||||
|
@ -323,6 +323,20 @@ void recover(pass_to_bison *bison_args)
|
||||
|
||||
|
||||
|
||||
static int design_has_alias(design_t *design, char *alias)
|
||||
{
|
||||
int result = 0;
|
||||
for (size_t aidx = 0; design->aliases[aidx] != NULL; ++aidx) {
|
||||
if (strcasecmp(alias, design->aliases[aidx]) == 0) {
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int design_has_name(design_t *design, char *name)
|
||||
{
|
||||
int result = 0;
|
||||
@ -330,12 +344,7 @@ static int design_has_name(design_t *design, char *name)
|
||||
result = 1;
|
||||
}
|
||||
else {
|
||||
for (size_t aidx = 0; design->aliases[aidx] != NULL; ++aidx) {
|
||||
if (strcasecmp(name, design->aliases[aidx]) == 0) {
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = design_has_alias(design, name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -390,6 +399,20 @@ static int design_name_exists(pass_to_bison *bison_args, char *name)
|
||||
|
||||
|
||||
|
||||
static int alias_exists_in_child_configs(pass_to_bison *bison_args, char *alias)
|
||||
{
|
||||
int result = 0;
|
||||
for (size_t i = 0; i < bison_args->num_child_configs; ++i) {
|
||||
if (design_has_alias(bison_args->child_configs + i, alias)) {
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int tag_add(pass_to_bison *bison_args, char *tag)
|
||||
{
|
||||
int rc = RC_SUCCESS;
|
||||
@ -921,10 +944,17 @@ int action_add_alias(pass_to_bison *bison_args, char *alias_name)
|
||||
yyerror(bison_args, "alias already in use -- %s", alias_name);
|
||||
return RC_ERROR;
|
||||
}
|
||||
if (alias_exists_in_child_configs(bison_args, alias_name)) {
|
||||
#ifdef PARSER_DEBUG
|
||||
fprintf (stderr, "alias already used by child config, dropping: %s\n", alias_name);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
size_t num_aliases = array_count0(curdes.aliases);
|
||||
curdes.aliases = (char **) realloc(curdes.aliases, (num_aliases + 2) * sizeof(char *));
|
||||
curdes.aliases[num_aliases] = strdup(alias_name);
|
||||
curdes.aliases[num_aliases + 1] = NULL;
|
||||
}
|
||||
return RC_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,12 @@ typedef struct {
|
||||
/** index into `*designs` */
|
||||
int design_idx;
|
||||
|
||||
/** Box designs already parsed from child config files, if any. Else NULL */
|
||||
design_t *child_configs;
|
||||
|
||||
/** the size of `*child_configs` */
|
||||
size_t num_child_configs;
|
||||
|
||||
/** the path to the config file we are parsing */
|
||||
char *config_file;
|
||||
|
||||
|
@ -161,13 +161,15 @@ static pass_to_flex new_flex_extra_data(pass_to_bison *bison_args)
|
||||
|
||||
|
||||
|
||||
static pass_to_bison parse_config_file(const char *config_file)
|
||||
static pass_to_bison parse_config_file(const char *config_file, design_t *child_configs, size_t num_child_configs)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Parsing Config File %s ...\n", config_file);
|
||||
#endif
|
||||
|
||||
pass_to_bison bison_args = new_bison_args(config_file);
|
||||
bison_args.child_configs = child_configs;
|
||||
bison_args.num_child_configs = num_child_configs;
|
||||
pass_to_flex flex_extra_data = new_flex_extra_data(&bison_args);
|
||||
current_bison_args = &bison_args;
|
||||
|
||||
@ -272,7 +274,7 @@ design_t *parse_config_files(const char *p_first_config_file, size_t *r_num_desi
|
||||
first_config_file = p_first_config_file;
|
||||
const char *config_file = p_first_config_file;
|
||||
do {
|
||||
pass_to_bison bison_args = parse_config_file(config_file);
|
||||
pass_to_bison bison_args = parse_config_file(config_file, result, *r_num_designs);
|
||||
++parents_parsed;
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "bison_args returned: "
|
||||
|
18
test/165_design_alias_parent_override.cfg
Normal file
18
test/165_design_alias_parent_override.cfg
Normal file
@ -0,0 +1,18 @@
|
||||
parent 165_design_alias_parent_override.parent.cfg
|
||||
|
||||
# the following designA will have these 2 alias names. alias2 will be gone
|
||||
BOX designA, alias1, alias3
|
||||
|
||||
sample
|
||||
A from regular config
|
||||
ends
|
||||
|
||||
shapes {
|
||||
w ("Ab")
|
||||
}
|
||||
|
||||
elastic (
|
||||
w
|
||||
)
|
||||
|
||||
END designA
|
15
test/165_design_alias_parent_override.parent.cfg
Normal file
15
test/165_design_alias_parent_override.parent.cfg
Normal file
@ -0,0 +1,15 @@
|
||||
BOX designA, alias1, alias2
|
||||
|
||||
sample
|
||||
A from parent config
|
||||
ends
|
||||
|
||||
shapes {
|
||||
w ("A")
|
||||
}
|
||||
|
||||
elastic (
|
||||
w
|
||||
)
|
||||
|
||||
END designA
|
27
test/165_design_alias_parent_override.txt
Normal file
27
test/165_design_alias_parent_override.txt
Normal file
@ -0,0 +1,27 @@
|
||||
:DESC
|
||||
Test that when overriding a design that has alias names, the alias names in the child design do not cause a uniqueness
|
||||
error, and properly override the parent alias names.
|
||||
|
||||
:ARGS
|
||||
-f 165_design_alias_parent_override.cfg -d designA -l
|
||||
:INPUT
|
||||
:OUTPUT-FILTER
|
||||
:EXPECTED
|
||||
Complete Design Information for "designA":
|
||||
------------------------------------------
|
||||
Alias Names: alias1, alias3
|
||||
Author: (unknown author)
|
||||
Original Designer: (unknown artist)
|
||||
Creation Date: (unknown)
|
||||
Current Revision: (unknown)
|
||||
Configuration File: 165_design_alias_parent_override.cfg
|
||||
Indentation Mode: box (indent box)
|
||||
Replacement Rules: none
|
||||
Reversion Rules: none
|
||||
Minimum Box Dimensions: 4 x 3 (width x height)
|
||||
Default Padding: none
|
||||
Default Killblank: no
|
||||
Tags: none
|
||||
Elastic Shapes: N, E, S, W
|
||||
Defined Shapes: W: "Ab"
|
||||
:EOF
|
18
test/166_design_alias_parent_clash.cfg
Normal file
18
test/166_design_alias_parent_clash.cfg
Normal file
@ -0,0 +1,18 @@
|
||||
parent 166_design_alias_parent_clash.parent.cfg
|
||||
|
||||
# the following designB claims alias1, which means designA from the parent config loses it
|
||||
BOX designB, alias1
|
||||
|
||||
sample
|
||||
B from regular config
|
||||
ends
|
||||
|
||||
shapes {
|
||||
w ("B")
|
||||
}
|
||||
|
||||
elastic (
|
||||
w
|
||||
)
|
||||
|
||||
END designB
|
15
test/166_design_alias_parent_clash.parent.cfg
Normal file
15
test/166_design_alias_parent_clash.parent.cfg
Normal file
@ -0,0 +1,15 @@
|
||||
BOX designA, alias1, alias2
|
||||
|
||||
sample
|
||||
A from parent config
|
||||
ends
|
||||
|
||||
shapes {
|
||||
w ("A")
|
||||
}
|
||||
|
||||
elastic (
|
||||
w
|
||||
)
|
||||
|
||||
END designA
|
28
test/166_design_alias_parent_clash.txt
Normal file
28
test/166_design_alias_parent_clash.txt
Normal file
@ -0,0 +1,28 @@
|
||||
:DESC
|
||||
Test that when an alias is defined in a child config AND in a parent config, the child config wins. The parent design
|
||||
loses the alias.
|
||||
|
||||
:ARGS
|
||||
-f 166_design_alias_parent_clash.cfg -l
|
||||
:INPUT
|
||||
:OUTPUT-FILTER
|
||||
:EXPECTED
|
||||
2 Available Styles:
|
||||
-------------------
|
||||
|
||||
Configuration Files:
|
||||
- 166_design_alias_parent_clash.cfg
|
||||
- 166_design_alias_parent_clash.parent.cfg (parent)
|
||||
|
||||
|
||||
designA alias alias2:
|
||||
|
||||
A from parent config
|
||||
|
||||
|
||||
designB alias alias1:
|
||||
|
||||
B from regular config
|
||||
|
||||
|
||||
:EOF
|
35
test/167_duplicate_primary_name.cfg
Normal file
35
test/167_duplicate_primary_name.cfg
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
BOX designA
|
||||
|
||||
sample
|
||||
designA
|
||||
ends
|
||||
|
||||
shapes {
|
||||
w ("A")
|
||||
}
|
||||
|
||||
elastic (
|
||||
w
|
||||
)
|
||||
|
||||
END designA
|
||||
|
||||
|
||||
|
||||
|
||||
BOX designA
|
||||
|
||||
sample
|
||||
designA (duplicate)
|
||||
ends
|
||||
|
||||
shapes {
|
||||
w ("A-dup")
|
||||
}
|
||||
|
||||
elastic (
|
||||
w
|
||||
)
|
||||
|
||||
END designA
|
19
test/167_duplicate_primary_name.txt
Normal file
19
test/167_duplicate_primary_name.txt
Normal file
@ -0,0 +1,19 @@
|
||||
:DESC
|
||||
Test that two designs in the same file may not have the same name. The second one is invalid and should be skipped.
|
||||
|
||||
:ARGS
|
||||
-f 167_duplicate_primary_name.cfg -l
|
||||
:INPUT
|
||||
:OUTPUT-FILTER
|
||||
:EXPECTED
|
||||
boxes: 167_duplicate_primary_name.cfg: line 35: duplicate box design name -- designA
|
||||
boxes: 167_duplicate_primary_name.cfg: line 35: skipping to next design
|
||||
1 Available Style in "167_duplicate_primary_name.cfg":
|
||||
------------------------------------------------------
|
||||
|
||||
designA:
|
||||
|
||||
designA
|
||||
|
||||
|
||||
:EOF
|
Loading…
Reference in New Issue
Block a user