[master] eabe58bc6 vcc: Avoid direct usage of the token list

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Tue Jun 1 13:50:07 UTC 2021


commit eabe58bc6633012dd01ba8f2a131f4e8cd351b2e
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Tue May 25 12:39:38 2021 +0200

    vcc: Avoid direct usage of the token list
    
    This migrates the remaining candidates for vcc_Peek*() functions using a
    coccinelle semantic patch. When vcc_PeekToken*() is used in an assignment
    statement it's straightforward to patch. In an expression a careful
    review is needed, that's why the generated code is meant not to compile
    on purpose. That's how the pattern for vcc_PrintTokens() was noticed.

diff --git a/lib/libvcc/vcc_acl.c b/lib/libvcc/vcc_acl.c
index 4ae7bb6a5..d7e4a63b3 100644
--- a/lib/libvcc/vcc_acl.c
+++ b/lib/libvcc/vcc_acl.c
@@ -457,7 +457,7 @@ vcc_acl_entry(struct vcc *tl)
  */
 
 static void
-vcc_acl_emit_tokens(const struct vcc *tl, const struct acl_e *ae)
+vcc_acl_emit_tokens(struct vcc *tl, const struct acl_e *ae)
 {
 	struct token *t;
 	const char *sep = "";
@@ -476,7 +476,8 @@ vcc_acl_emit_tokens(const struct vcc *tl, const struct acl_e *ae)
 		}
 		if (t == ae->t_mask)
 			break;
-		t = VTAILQ_NEXT(t, list);
+		t = vcc_PeekTokenFrom(tl, t);
+		ERRCHK(tl);
 		AN(t);
 		sep = " ";
 	} while (ae->t_mask != NULL);
@@ -489,7 +490,7 @@ vcc_acl_emit_tokens(const struct vcc *tl, const struct acl_e *ae)
  */
 
 static unsigned
-vcc_acl_emit_tables(const struct vcc *tl, unsigned n, const char *name)
+vcc_acl_emit_tables(struct vcc *tl, unsigned n, const char *name)
 {
 	struct acl_e *ae;
 	unsigned rv = sizeof(ae->data) + 3;
diff --git a/lib/libvcc/vcc_symb.c b/lib/libvcc/vcc_symb.c
index 0d98ed084..b41334b79 100644
--- a/lib/libvcc/vcc_symb.c
+++ b/lib/libvcc/vcc_symb.c
@@ -293,11 +293,11 @@ VCC_SymbolGet(struct vcc *tl, vcc_ns_t ns, vcc_kind_t kind,
 			st2 = st;
 			tn2 = tn;
 		}
-		tn1 = VTAILQ_NEXT(tn, list);
-		if (tn1->tok != '.')
+		tn1 = vcc_PeekTokenFrom(tl, tn);
+		if (tn1 == NULL || tn1->tok != '.')
 			break;
-		tn1 = VTAILQ_NEXT(tn1, list);
-		if (tn1->tok != ID)
+		tn1 = vcc_PeekTokenFrom(tl, tn1);
+		if (tn1 == NULL || tn1->tok != ID)
 			break;
 		tn = tn1;
 	}
@@ -309,13 +309,15 @@ VCC_SymbolGet(struct vcc *tl, vcc_ns_t ns, vcc_kind_t kind,
 	} else if (st != st2) {
 		sym = NULL;
 	}
-	if (sym == NULL && e->noerr)
+	if (tl->err || (sym == NULL && e->noerr))
 		return (sym);
 	AN(st);
 	AN(tn);
 	if (sym == NULL && e == SYMTAB_CREATE)
 		sym = vcc_new_symbol(tl, st, kind, tl->syntax, tl->syntax);
-	tl->t = VTAILQ_NEXT(tn, list);
+	tl->t = vcc_PeekTokenFrom(tl, tn);
+	if (tl->err)
+		return (NULL);
 	if (sym == NULL) {
 		VSB_printf(tl->sb, "%s: '", e->name);
 		vcc_PrintTokens(tl, t0, tl->t);
diff --git a/lib/libvcc/vcc_utils.c b/lib/libvcc/vcc_utils.c
index 7ced4edc1..de064bea0 100644
--- a/lib/libvcc/vcc_utils.c
+++ b/lib/libvcc/vcc_utils.c
@@ -380,10 +380,13 @@ vcc_IsFlagRaw(struct vcc *tl, const struct token *t1, const struct token *t2)
 int
 vcc_IsFlag(struct vcc *tl)
 {
+	struct token *t;
 	int retval;
 
-
-	retval = vcc_IsFlagRaw(tl, tl->t, VTAILQ_NEXT(tl->t, list));
+	t = vcc_PeekToken(tl);
+	if (t == NULL)
+		return (-1);
+	retval = vcc_IsFlagRaw(tl, tl->t, t);
 	if (retval >= 0)
 		vcc_NextToken(tl);
 	return (retval);
diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c
index 8c676096f..d0719ec47 100644
--- a/lib/libvcc/vcc_vmod.c
+++ b/lib/libvcc/vcc_vmod.c
@@ -315,7 +315,8 @@ vcc_ParseImport(struct vcc *tl)
 
 	ExpectErr(tl, ID);		/* "vmod_name" */
 	mod = tl->t;
-	tmod = VTAILQ_NEXT(mod, list);
+	tmod = vcc_PeekTokenFrom(tl, mod);
+	ERRCHK(tl);
 	if (tmod->tok == ID && vcc_IdIs(tmod, "as")) {
 		vcc_NextToken(tl);		/* "vmod_name" */
 		vcc_NextToken(tl);		/* "as" */
diff --git a/lib/libvcc/vcc_xref.c b/lib/libvcc/vcc_xref.c
index 433f5e7b8..cf2be5532 100644
--- a/lib/libvcc/vcc_xref.c
+++ b/lib/libvcc/vcc_xref.c
@@ -122,8 +122,10 @@ vcc_AddUses(struct vcc *tl, const struct token *t1, const struct token *t2,
 	AN(use->name);
 	pu->t1 = t1;
 	pu->t2 = t2;
-	if (pu->t2 == NULL)
-		pu->t2 = VTAILQ_NEXT(t1, list);
+	if (pu->t2 == NULL) {
+		pu->t2 = vcc_PeekTokenFrom(tl, t1);
+		ERRCHK(tl);
+	}
 	pu->sym = sym;
 	pu->use = use;
 	pu->fm = tl->curproc;
diff --git a/tools/coccinelle/archive/vcc_peek.cocci b/tools/coccinelle/archive/vcc_peek.cocci
new file mode 100644
index 000000000..ab0726d22
--- /dev/null
+++ b/tools/coccinelle/archive/vcc_peek.cocci
@@ -0,0 +1,35 @@
+/*
+ * Provide an API to avoid direct next token access.
+ */
+
+@@
+struct vcc *tl;
+expression e;
+@@
+
+-e = VTAILQ_NEXT(tl->t, list);
++e = vcc_PeekToken(tl);
++ERRCHK(tl);
+
+@@
+struct token *t;
+expression e;
+@@
+
+-e = VTAILQ_NEXT(t, list);
++e = vcc_PeekTokenFrom(tl, t);
++ERRCHK(tl);
+
+@@
+struct vcc *tl;
+@@
+
+-VTAILQ_NEXT(tl->t, list)
++TODO_vcc_PeekToken_with_ERRCHK(tl)
+
+@@
+struct token *t;
+@@
+
+-VTAILQ_NEXT(t, list)
++TODO_vcc_Peek_with_ERRCHK(tl, t)


More information about the varnish-commit mailing list