37 |
|
|
38 |
static void rc_asgn_destroy(RC_ASGN *asgn); |
static void rc_asgn_destroy(RC_ASGN *asgn); |
39 |
|
|
|
static void rc_regex_destroy(RC_REGEX *re); |
|
|
static int compile_regex(char *string, RC_REGEX *rp); |
|
|
static int compile_unquoted_regex(char *string, RC_REGEX *rp, int *revp); |
|
|
|
|
40 |
static void rc_bool_destroy(RC_BOOL *bool); |
static void rc_bool_destroy(RC_BOOL *bool); |
41 |
|
|
42 |
static RC_NODE *rc_node_create(enum rc_node_type t); |
static RC_NODE *rc_node_create(enum rc_node_type t); |
70 |
RC_COND cond; |
RC_COND cond; |
71 |
RC_RULE rule; |
RC_RULE rule; |
72 |
RC_NODE *node; |
RC_NODE *node; |
73 |
|
RC_REGEX *regex; |
74 |
int num; |
int num; |
75 |
}; |
}; |
76 |
|
|
87 |
%type <stmt> stmt asgn_stmt cond_stmt rule_stmt |
%type <stmt> stmt asgn_stmt cond_stmt rule_stmt |
88 |
%type <cond> cond |
%type <cond> cond |
89 |
%type <num> cond_lhs |
%type <num> cond_lhs |
90 |
%type <node> cond_rhs compat_rx compat_rx_list rx_list regex rule_start |
%type <node> cond_rhs compat_rx_list rx_list regex rule_start |
91 |
|
%type <regex> compat_rx |
92 |
|
|
93 |
%% |
%% |
94 |
|
|
120 |
{ |
{ |
121 |
$$ = rc_section_create($1, $2.head); |
$$ = rc_section_create($1, $2.head); |
122 |
} |
} |
123 |
|
| begin end |
124 |
|
{ |
125 |
|
$$ = NULL; |
126 |
|
} |
127 |
; |
; |
128 |
|
|
129 |
begin : T_BEGIN IDENT EOL |
begin : T_BEGIN { verbatim(); } STRING EOL |
130 |
{ |
{ |
131 |
$$ = $2; |
$$ = $3; |
132 |
} |
} |
133 |
| D_BEGIN EOL |
| D_BEGIN EOL |
134 |
; |
; |
168 |
$$->v.asgn.lhs = $1; |
$$->v.asgn.lhs = $1; |
169 |
$$->v.asgn.rhs = $4; |
$$->v.asgn.rhs = $4; |
170 |
} |
} |
171 |
; |
| keyword REGEX /* Compatibility syntax */ |
172 |
|
{ |
173 |
|
$$ = rc_stmt_create(rc_stmt_asgn); |
174 |
|
$$->v.asgn.lhs = $1; |
175 |
|
$$->v.asgn.rhs = $2; |
176 |
|
} |
177 |
|
; |
178 |
|
|
179 |
keyword : IDENT |
keyword : IDENT |
180 |
; |
; |
231 |
; |
; |
232 |
|
|
233 |
compat_rx_list: compat_rx |
compat_rx_list: compat_rx |
234 |
|
{ |
235 |
|
$$ = rc_node_create(rc_node_re); |
236 |
|
$$->v.re = $1; |
237 |
|
} |
238 |
| compat_rx_list compat_rx |
| compat_rx_list compat_rx |
239 |
{ |
{ |
240 |
|
RC_NODE *node; |
241 |
|
|
242 |
|
node = rc_node_create(rc_node_bool); |
243 |
|
node->v.bool.op = bool_not; |
244 |
|
node->v.bool.left = rc_node_create(rc_node_re); |
245 |
|
node->v.bool.left->v.re = $2; |
246 |
|
|
247 |
$$ = rc_node_create(rc_node_bool); |
$$ = rc_node_create(rc_node_bool); |
248 |
$$->v.bool.op = bool_and; |
$$->v.bool.op = bool_and; |
249 |
$$->v.bool.left = $1; |
$$->v.bool.left = $1; |
250 |
$$->v.bool.right = $2; |
$$->v.bool.right = node; |
251 |
} |
} |
252 |
; |
; |
253 |
|
|
254 |
compat_rx: REGEX |
compat_rx: REGEX |
255 |
{ |
{ |
256 |
RC_REGEX re; |
$$ = anubis_regex_compile($1, reg_opt); |
257 |
RC_NODE *node; |
if (!$$) |
|
int not; |
|
|
|
|
|
if (compile_unquoted_regex($1, &re, ¬)) |
|
258 |
YYERROR; |
YYERROR; |
|
|
|
|
node = rc_node_create(rc_node_re); |
|
|
node->v.re = re; |
|
|
|
|
|
if (not) { |
|
|
RC_NODE *p = rc_node_create(rc_node_bool); |
|
|
p->v.bool.op = bool_not; |
|
|
p->v.bool.left = node; |
|
|
p->v.bool.right = NULL; |
|
|
node = p; |
|
|
} |
|
|
$$ = node; |
|
259 |
} |
} |
260 |
; |
; |
261 |
|
|
282 |
} |
} |
283 |
| EQ STRING |
| EQ STRING |
284 |
{ |
{ |
285 |
RC_REGEX re; |
RC_REGEX *re = anubis_regex_compile($2, reg_opt); |
286 |
|
|
287 |
if (compile_regex($2, &re)) |
if (!re) |
288 |
YYERROR; |
YYERROR; |
289 |
$$ = rc_node_create(rc_node_re); |
$$ = rc_node_create(rc_node_re); |
290 |
$$->v.re = re; |
$$->v.re = re; |
291 |
} |
} |
292 |
| NE STRING |
| NE STRING |
293 |
{ |
{ |
294 |
RC_REGEX re; |
RC_REGEX *re = anubis_regex_compile($2, reg_opt); |
295 |
|
|
296 |
if (compile_regex($2, &re)) |
if (!re) |
297 |
YYERROR; |
YYERROR; |
298 |
|
|
299 |
$$ = rc_node_create(rc_node_bool); |
$$ = rc_node_create(rc_node_bool); |
441 |
xfree(asgn->rhs); |
xfree(asgn->rhs); |
442 |
} |
} |
443 |
|
|
|
/* Regex manipulations */ |
|
|
|
|
|
void |
|
|
rc_regex_destroy(RC_REGEX *re) |
|
|
{ |
|
|
#ifdef HAVE_PCRE |
|
|
if (re->perlre) |
|
|
/*FIXME*/; |
|
|
else |
|
|
#endif |
|
|
regfree(&re->v.re); |
|
|
} |
|
|
|
|
|
int |
|
|
compile_regex(char *string, RC_REGEX *rp) |
|
|
{ |
|
|
int rc; |
|
|
|
|
|
rp->src = string; |
|
|
#ifdef HAVE_PCRE |
|
|
if (perlre) { |
|
|
const char *error; |
|
|
int error_offset; |
|
|
int cflags = 0; |
|
|
|
|
|
if (!(reg_opt & R_SCASE)) |
|
|
cflags |= PCRE_CASELESS; |
|
|
|
|
|
rp->re.pre = pcre_compile(string, cflags, |
|
|
&error, &error_offset, 0); |
|
|
if (rp->re.pre == 0) { |
|
|
anubis_error(SOFT, |
|
|
_("pcre_compile() failed at offset %d: %s."), |
|
|
error_offset, error); |
|
|
yyerror(_("Regexp error")); |
|
|
return 1; |
|
|
} |
|
|
return 0; |
|
|
} |
|
|
#endif |
|
|
rc = regcomp(&rp->v.re, string, reg_opt); |
|
|
if (rc) { |
|
|
char errbuf[512]; |
|
|
regerror(rc, &rp->v.re, errbuf, sizeof(errbuf)); |
|
|
yyerror(errbuf); |
|
|
return 1; |
|
|
} |
|
|
return 0; |
|
|
} |
|
|
|
|
|
int |
|
|
compile_unquoted_regex(char *string, RC_REGEX *rp, int *revp) |
|
|
{ |
|
|
if (string[0] == '!') { |
|
|
*revp = 1; |
|
|
string++; |
|
|
} else |
|
|
*revp = 0; |
|
|
return compile_regex(string + 1, rp); |
|
|
} |
|
|
|
|
444 |
/* Bools */ |
/* Bools */ |
445 |
|
|
446 |
void |
void |
472 |
break; |
break; |
473 |
|
|
474 |
case rc_node_re: |
case rc_node_re: |
475 |
rc_regex_destroy(&node->v.re); |
anubis_regex_free(node->v.re); |
476 |
} |
} |
477 |
xfree(node); |
xfree(node); |
478 |
} |
} |
482 |
{ |
{ |
483 |
switch (node->type) { |
switch (node->type) { |
484 |
case rc_node_re: |
case rc_node_re: |
485 |
printf("%s", node->v.re.src); |
printf("%s", anubis_regex_source(node->v.re)); |
486 |
break; |
break; |
487 |
|
|
488 |
case rc_node_bool: |
case rc_node_bool: |
608 |
void |
void |
609 |
reg_option_init() |
reg_option_init() |
610 |
{ |
{ |
611 |
perlre = 0; |
reg_opt = 0; |
|
reg_opt = REG_EXTENDED; |
|
612 |
} |
} |
613 |
|
|
614 |
int |
int |
615 |
reg_option_add(char *opt) |
reg_option_add(char *opt) |
616 |
{ |
{ |
617 |
if (strcasecmp(opt, "basic") == 0) |
if (strcasecmp(opt, "basic") == 0) |
618 |
reg_opt &= ~REG_EXTENDED; |
reg_opt |= R_BASIC; |
619 |
else if (strcasecmp(opt, "scase") == 0) |
else if (strcasecmp(opt, "scase") == 0) |
620 |
reg_opt |= REG_ICASE; |
reg_opt |= R_SCASE; |
621 |
#ifdef HAVE_PCRE |
#ifdef HAVE_PCRE |
622 |
else if (strcasecmp(opt, "perlre") == 0) |
else if (strcasecmp(opt, "perlre") == 0) |
623 |
perlre = 1; |
reg_opt |= R_PERLRE; |
624 |
#endif |
#endif |
625 |
else { |
else { |
626 |
yyerror(_("Unknown regexp option")); |
yyerror(_("Unknown regexp option")); |
706 |
int |
int |
707 |
node_eval(struct eval_env *env, RC_NODE *node) |
node_eval(struct eval_env *env, RC_NODE *node) |
708 |
{ |
{ |
709 |
int rc; |
int rc; /* It won't be used uninitialized despite what cc says. |
710 |
|
Note default: branch below */ |
711 |
|
|
712 |
switch (node->type) { |
switch (node->type) { |
713 |
case rc_node_bool: |
case rc_node_bool: |
719 |
env->refstr = NULL; |
env->refstr = NULL; |
720 |
env->refcnt = 0; |
env->refcnt = 0; |
721 |
} |
} |
722 |
rc = anubis_regexp_match(&node->v.re, env->line, |
rc = anubis_regex_match(node->v.re, env->line, |
723 |
&env->refcnt, &env->refstr); |
&env->refcnt, &env->refstr); |
724 |
|
break; |
725 |
|
|
726 |
|
default: |
727 |
|
abort(); |
728 |
} |
} |
729 |
return rc; |
return rc; |
730 |
} |
} |
805 |
stmt_list_eval(&env, sec->stmt); |
stmt_list_eval(&env, sec->stmt); |
806 |
if (env.refstr) |
if (env.refstr) |
807 |
xfree_pptr(env.refstr); |
xfree_pptr(env.refstr); |
808 |
|
|
809 |
return; |
return; |
810 |
} |
} |
811 |
anubis_error(SOFT, |
anubis_error(SOFT, |