*/
#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
#include "vsb.h"
#include "vcc_priv.h"
#include "vcc_compile.h"
+static void
+vcc_acl_top(struct tokenlist *tl, const char *acln)
+{
+
+ Fh(tl, 1, "\nstatic struct vrt_acl acl_%s[] = {\n", acln);
+ tl->hindent += INDENT;
+
+}
+
+static void
+vcc_acl_entry(struct tokenlist *tl)
+{
+ unsigned mask, para, not;
+ struct token *t;
+
+ not = para = mask = 0;
+
+ if (tl->t->tok == '(') {
+ para = 1;
+ vcc_NextToken(tl);
+ }
+
+ if (tl->t->tok == '!') {
+ not = 1;
+ vcc_NextToken(tl);
+ }
+
+ ExpectErr(tl, CSTR);
+ /* XXX: try to look it up, warn if failure */
+ t = tl->t;
+ vcc_NextToken(tl);
+ if (tl->t->tok == '/') {
+ vcc_NextToken(tl);
+ ExpectErr(tl, CNUM);
+ mask = vcc_UintVal(tl);
+ }
+ Fh(tl, 1, "{ %u, %u, %u, ", not, mask, para);
+ EncToken(tl->fh, t);
+ Fh(tl, 0, ", \"");
+ if (para)
+ Fh(tl, 0, "(");
+ if (not)
+ Fh(tl, 0, "!");
+ Fh(tl, 0, "\\\"\" ");
+ EncToken(tl->fh, t);
+ Fh(tl, 0, " \"\\\"");
+ if (mask)
+ Fh(tl, 0, "/%u", mask);
+ if (para)
+ Fh(tl, 0, ")");
+ Fh(tl, 0, "\" },\n");
+
+ if (para) {
+ ExpectErr(tl, ')');
+ vcc_NextToken(tl);
+ }
+}
+
+static void
+vcc_acl_bot(struct tokenlist *tl, const char *acln)
+{
+
+ Fh(tl, 1, "{ 0, 0, 0, (void*)0, ""}\n", 0, 0);
+ tl->hindent -= INDENT;
+ Fh(tl, 1, "};\n");
+ Fi(tl, 1, "\tVRT_acl_init(acl_%s);\n", acln);
+ Ff(tl, 1, "\tVRT_acl_fini(acl_%s);\n", acln);
+}
+
void
vcc_Cond_Ip(struct var *vp, struct tokenlist *tl)
{
+ unsigned tcond;
+ char *acln;
(void)vp; /* only client.ip at this time */
PF(tl->t), PF(tl->t));
vcc_NextToken(tl);
break;
+ case T_EQ:
+ case T_NEQ:
+ tcond = tl->t->tok;
+ vcc_NextToken(tl);
+ asprintf(&acln, "acl_%u", tl->cnt);
+ assert(acln != NULL);
+ vcc_acl_top(tl, acln);
+ vcc_acl_entry(tl);
+ vcc_acl_bot(tl, acln);
+ Fb(tl, 1, "%sVRT_acl_match(sp, \"%s\", acl_%s)\n",
+ (tcond == T_NEQ ? "!" : ""), acln, acln);
+ free(acln);
+ break;
default:
vsb_printf(tl->sb, "Illegal condition ");
vcc_ErrToken(tl, tl->t);
void
vcc_Acl(struct tokenlist *tl)
{
- unsigned mask, para, not;
- struct token *t, *an;
+ struct token *an;
+ char *acln;
vcc_NextToken(tl);
vcc_NextToken(tl);
vcc_AddDef(tl, an, R_ACL);
- Fh(tl, 0, "static struct vrt_acl acl_%.*s[];\n", PF(an));
- Fc(tl, 1, "static struct vrt_acl acl_%.*s[] = {\n", PF(an));
+ asprintf(&acln, "%.*s", PF(an));
+ assert(acln != NULL);
- tl->indent += INDENT;
+ vcc_acl_top(tl, acln);
ExpectErr(tl, '{');
vcc_NextToken(tl);
while (tl->t->tok != '}') {
-
- not = para = mask = 0;
-
- if (tl->t->tok == '(') {
- para = 1;
- vcc_NextToken(tl);
- }
-
- if (tl->t->tok == '!') {
- not = 1;
- vcc_NextToken(tl);
- }
-
- ExpectErr(tl, CSTR);
- /* XXX: try to look it up, warn if failure */
- t = tl->t;
- vcc_NextToken(tl);
- if (tl->t->tok == '/') {
- vcc_NextToken(tl);
- ExpectErr(tl, CNUM);
- mask = vcc_UintVal(tl);
- }
- Fc(tl, 1, "{ %u, %u, %u, ", not, mask, para);
- EncToken(tl->fc, t);
- Fc(tl, 0, ", \"");
- if (para)
- Fc(tl, 0, "(");
- if (not)
- Fc(tl, 0, "!");
- Fc(tl, 0, "\\\"\" ");
- EncToken(tl->fc, t);
- Fc(tl, 0, " \"\\\"");
- if (mask)
- Fc(tl, 0, "/%u", mask);
- if (para)
- Fc(tl, 0, ")");
- Fc(tl, 0, "\" },\n");
-
- if (para) {
- ExpectErr(tl, ')');
- vcc_NextToken(tl);
- }
+ vcc_acl_entry(tl);
+ ERRCHK(tl);
ExpectErr(tl, ';');
vcc_NextToken(tl);
}
- Fc(tl, 1, "{ 0, 0, 0, (void*)0, ""}\n", 0, 0);
- tl->indent -= INDENT;
- Fc(tl, 1, "};\n\n");
-
ExpectErr(tl, '}');
vcc_NextToken(tl);
- Fi(tl, 1, "\tVRT_acl_init(acl_%.*s);\n", PF(an));
- Ff(tl, 1, "\tVRT_acl_fini(acl_%.*s);\n", PF(an));
+ vcc_acl_bot(tl, acln);
+
+ free(acln);
}