Skip to content

Commit bab75f7

Browse files
authored
Merge pull request #493 from hibtc/bugfix-select
Bugfix select
2 parents efb5291 + 556a550 commit bab75f7

File tree

4 files changed

+51
-38
lines changed

4 files changed

+51
-38
lines changed

src/mad_select.c

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -99,76 +99,88 @@ get_select_ex_ranges(struct sequence* sequ, struct command_list* select, struct
9999

100100
// public interface
101101

102+
static int _pass_select_pat(const char* name, struct command* sc);
103+
102104
int
103-
pass_select(char* name, struct command* sc)
105+
pass_select(const char* name, struct command* sc)
104106
/* checks name against class (if element) and pattern that may
105107
(but need not) be contained in command sc;
106108
0: does not pass, 1: passes */
107109
/* Don't use for selecting elements. It may not find all elements. */
108110
{
109111
struct element* el = find_element(strip(name), element_list);
110-
return pass_select_el(el, sc);
112+
return el ? pass_select_el(el, sc) : pass_select_str(name, sc);
111113
}
112114

113-
114115
int
115116
pass_select_el(struct element* el, struct command* sc)
116-
/* checks name against class (if element) and pattern that may
117+
/* checks element against class and pattern that may
117118
(but need not) be contained in command sc;
118119
0: does not pass, 1: passes */
119120
/* Should use this function in favor of `pass_select` where possible. It
120121
works for all elements and is faster if knowing the element in advance. */
121122
{
122123
struct name_list* nl = sc->par_names;
123124
struct command_parameter_list* pl = sc->par;
124-
int pos, in = 0, any = 0;
125-
char *class, *pattern;
126-
127-
pos = name_list_pos("class", nl);
125+
int pos = name_list_pos("class", nl);
128126
if (pos > -1 && nl->inform[pos]) /* parameter has been read */
129127
{
130-
if (el != NULL)
131-
{
132-
class = pl->parameters[pos]->string;
133-
in = belongs_to_class(el, class);
134-
if (in == 0) return 0;
135-
}
128+
char* class = pl->parameters[pos]->string;
129+
if (!belongs_to_class(el, class))
130+
return 0;
136131
}
137-
any = in = 0;
138-
pos = name_list_pos("pattern", nl);
132+
return _pass_select_pat(el->name, sc);
133+
}
134+
135+
int pass_select_str(const char* name, struct command* sc)
136+
{
137+
/* checks name against pattern that may
138+
(but need not) be contained in command sc;
139+
considers only SELECT commands *without CLASS*!
140+
0: does not pass, 1: passes */
141+
// if the command has CLASS attribute, it is supposed to match elements:
142+
if (par_present("class", sc, NULL)) /* parameter has been read */
143+
return 0;
144+
return _pass_select_pat(name, sc);
145+
}
146+
147+
int _pass_select_pat(const char* name, struct command* sc)
148+
{
149+
/* used internally. */
150+
struct name_list* nl = sc->par_names;
151+
struct command_parameter_list* pl = sc->par;
152+
int pos = name_list_pos("pattern", nl);
139153
if (pos > -1 && nl->inform[pos]) /* parameter has been read */
140154
{
141-
any = 1;
142-
pattern = stolower(pl->parameters[pos]->string);
143-
if(myregex(pattern, strip(el->name)) == 0) in = 1;
155+
char* pattern = stolower(pl->parameters[pos]->string);
156+
return myregex(pattern, strip(name)) == 0;
144157
}
145-
if (any == 0) return 1;
146-
else return in;
158+
return 1;
147159
}
148160

149161
int
150-
pass_select_list(char* name, struct command_list* cl)
162+
pass_select_list_str(const char* name, struct command_list* cl)
151163
/* returns 0 (does not pass) or 1 (passes) for a list of selects */
152-
/* Don't use for selecting elements. It may not find all elements. */
164+
/* Don't use for selecting elements! It may not find all elements. */
153165
{
154-
struct element* el = find_element(strip(name), element_list);
155-
return pass_select_list_el(el, cl);
166+
for (int i = 0; i < cl->curr; i++) {
167+
if (pass_select_str(name, cl->commands[i]))
168+
return 1;
169+
}
170+
return cl->curr == 0;
156171
}
157172

158-
159173
int
160174
pass_select_list_el(struct element* el, struct command_list* cl)
161175
/* returns 0 (does not pass) or 1 (passes) for a list of selects */
162176
/* Should use this function in favor of `pass_select_list` where possible. It
163177
works for all elements and is faster if knowing the element in advance. */
164178
{
165-
int i, ret = 0;
166-
if (cl->curr == 0) return 1;
167-
for (i = 0; i < cl->curr; i++)
168-
{
169-
if ((ret = pass_select_el(el, cl->commands[i]))) break;
179+
for (int i = 0; i < cl->curr; i++) {
180+
if (pass_select_el(el, cl->commands[i]))
181+
return 1;
170182
}
171-
return ret;
183+
return cl->curr == 0;
172184
}
173185

174186
int

src/mad_select.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ struct element;
1818

1919
void store_select(struct in_cmd*);
2020
void store_deselect(struct in_cmd*);
21-
int pass_select(char* name, struct command*); // deprecated
22-
int pass_select_list(char* name, struct command_list*); // deprecated
21+
int pass_select(const char* name, struct command*); // deprecated
22+
int pass_select_str(const char* name, struct command*); // not for elements!
2323
int pass_select_el(struct element* el, struct command*);
24+
int pass_select_list_str(const char* name, struct command_list*); // not for elements!
2425
int pass_select_list_el(struct element* el, struct command_list*);
2526
void get_select_t_ranges(struct command_list* select, struct command_list* deselect, struct table*);
2627
int get_select_ranges(struct sequence* sequ, struct command_list* select, struct node_list* s_ranges);

src/mad_seq.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ export_sequ_8(struct sequence* sequ, struct command_list* cl, FILE* file)
754754

755755
seqref = sequ->ref_flag; /* uncomment line to get entry or exit */
756756

757-
if (pass_select_list(sequ->name, cl) == 0) return;
757+
if (pass_select_list_str(sequ->name, cl) == 0) return;
758758

759759
*c_dum->c = '\0';
760760
strcat(c_dum->c, sequ->export_name);
@@ -820,7 +820,7 @@ write_sequs(struct sequence_list* sql,struct command_list* cl, FILE* file, int n
820820
for (i = 0; i < sql->curr; i++)
821821
if(sql->sequs[i]->nested == j)
822822
{
823-
if (pass_select_list(sql->sequs[i]->name, cl))
823+
if (pass_select_list_str(sql->sequs[i]->name, cl))
824824
export_sequence(sql->sequs[i], file, noexpr);
825825
}
826826
}

src/mad_var.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ void
253253
write_vars(struct var_list* varl, struct command_list* cl, FILE* file, int noexpr)
254254
{
255255
for (int i = 0; i < varl->curr; i++) {
256-
if (predef_var(varl->vars[i]) == 0 && pass_select_list(varl->vars[i]->name, cl))
256+
if (predef_var(varl->vars[i]) == 0 && pass_select_list_str(varl->vars[i]->name, cl))
257257
export_variable(varl->vars[i], file, noexpr);
258258
}
259259
}
@@ -265,7 +265,7 @@ write_vars_8(struct var_list* varl, struct command_list* cl, FILE* file)
265265
for (i = 0; i < varl->curr; i++)
266266
{
267267
if (predef_var(varl->vars[i]) == 0
268-
&& pass_select_list(varl->vars[i]->name, cl))
268+
&& pass_select_list_str(varl->vars[i]->name, cl))
269269
export_var_8(varl->vars[i], file);
270270
}
271271
}

0 commit comments

Comments
 (0)