[master] c8174af68 Refactor "preprocesing" of VCL.

Poul-Henning Kamp phk at FreeBSD.org
Tue Apr 13 13:20:05 UTC 2021


commit c8174af68956206115972e72e75ceddbd758116e
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Apr 13 13:19:00 2021 +0000

    Refactor "preprocesing" of VCL.

diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c
index 1bb0ba32b..88d558a93 100644
--- a/lib/libvcc/vcc_compile.c
+++ b/lib/libvcc/vcc_compile.c
@@ -638,7 +638,7 @@ vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile)
 		AN(vcc_builtin);
 		VTAILQ_INSERT_TAIL(&tl->sources, sp, list);
 		sp->idx = tl->nsources++;
-		vcc_Lexer(tl, sp, 0);
+		vcc_lex_source(tl, sp, 0);
 		if (tl->err)
 			return (NULL);
 	}
@@ -648,12 +648,11 @@ vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile)
 	assert(sp != NULL);
 	VTAILQ_INSERT_TAIL(&tl->sources, sp, list);
 	sp->idx = tl->nsources++;
-	vcc_Lexer(tl, sp, 1);
+	vcc_lex_source(tl, sp, 1);
 	if (tl->err)
 		return (NULL);
 
 	/* Expand and lex any includes in the token string */
-	vcc_resolve_includes(tl);
 	if (tl->err)
 		return (NULL);
 
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index aeca3d5c7..76e923693 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -57,11 +57,18 @@
 /*---------------------------------------------------------------------*/
 
 struct acl;
-struct vsb;
-struct token;
-struct sockaddr_storage;
+struct acl_e;
+struct expr;
 struct method;
+struct proc;
+struct sockaddr_storage;
+struct symbol;
 struct symtab;
+struct token;
+struct vcc;
+struct vjsn_val;
+struct vmod_obj;
+struct vsb;
 
 unsigned vcl_fixed_token(const char *p, const char **q);
 extern const char * const vcl_tnames[256];
@@ -71,14 +78,6 @@ void vcl_output_lang_h(struct vsb *sb);
 
 #define INDENT		2
 
-struct acl_e;
-struct proc;
-struct expr;
-struct vcc;
-struct vjsn_val;
-struct symbol;
-struct vmod_obj;
-
 struct source {
 	VTAILQ_ENTRY(source)	list;
 	char			*name;
@@ -88,6 +87,7 @@ struct source {
 	char			*freeit;
 	const struct source	*parent;
 	const struct token	*parent_tok;
+	VTAILQ_HEAD(, token)	src_tokens;
 };
 
 struct token {
@@ -96,6 +96,7 @@ struct token {
 	const char		*e;
 	const struct source	*src;
 	VTAILQ_ENTRY(token)	list;
+	VTAILQ_ENTRY(token)	src_list;
 	unsigned		cnt;
 	char			*dec;
 };
@@ -365,7 +366,7 @@ sym_act_f vcc_Act_If;
 /* vcc_source.c */
 struct source * vcc_new_source(const char *src, const char *name);
 struct source *vcc_file_source(const struct vcc *tl, const char *fn);
-void vcc_resolve_includes(struct vcc *tl);
+void vcc_lex_source(struct vcc *tl, struct source *sp, int eoi);
 
 /* vcc_storage.c */
 void vcc_stevedore(struct vcc *vcc, const char *stv_name);
@@ -410,7 +411,7 @@ void vcc_Warn(struct vcc *);
 void vcc__Expect(struct vcc *tl, unsigned tok, unsigned line);
 int vcc_IdIs(const struct token *t, const char *p);
 void vcc_ExpectVid(struct vcc *tl, const char *what);
-void vcc_Lexer(struct vcc *tl, const struct source *sp, int eoi);
+void vcc_Lexer(struct vcc *tl, struct source *sp);
 void vcc_NextToken(struct vcc *tl);
 void vcc__ErrInternal(struct vcc *tl, const char *func,
     unsigned line);
diff --git a/lib/libvcc/vcc_source.c b/lib/libvcc/vcc_source.c
index 61095e778..48f50553e 100644
--- a/lib/libvcc/vcc_source.c
+++ b/lib/libvcc/vcc_source.c
@@ -51,6 +51,7 @@ vcc_new_source(const char *src, const char *name)
 	REPLACE(sp->name, name);
 	sp->b = src;
 	sp->e = strchr(src, '\0');
+	VTAILQ_INIT(&sp->src_tokens);
 	return (sp);
 }
 
@@ -98,93 +99,110 @@ vcc_file_source(const struct vcc *tl, const char *fn)
 
 /*--------------------------------------------------------------------*/
 
-void
-vcc_resolve_includes(struct vcc *tl)
+static struct source *
+vcc_include_file(struct vcc *tl, const struct source *src_sp,
+    const char *filename, const struct token *parent_token)
 {
-	struct token *t, *t1, *t2;
 	struct source *sp;
 	const struct source *sp1;
 	struct vsb *vsb;
 	const char *p;
 
-	VTAILQ_FOREACH(t, &tl->tokens, list) {
-		if (t->tok != ID || !vcc_IdIs(t, "include"))
+	if (filename[0] == '.' && filename[1] == '/') {
+		/*
+		 * Nested include filenames, starting with "./" are
+		 * resolved relative to the VCL file which contains
+		 * the include directive.
+		 */
+		if (src_sp->name[0] != '/') {
+			VSB_cat(tl->sb,
+			    "include \"./xxxxx\"; needs absolute "
+			    "filename of including file.\n");
+			return (NULL);
+		}
+		vsb = VSB_new_auto();
+		AN(vsb);
+		p = strrchr(src_sp->name, '/');
+		AN(p);
+		VSB_bcat(vsb, src_sp->name, p - src_sp->name);
+		VSB_cat(vsb, filename + 1);
+		AZ(VSB_finish(vsb));
+		sp = vcc_file_source(tl, VSB_data(vsb));
+		VSB_destroy(&vsb);
+	} else {
+		sp = vcc_file_source(tl, filename);
+	}
+	if (sp == NULL)
+		return (sp);
+
+	for (sp1 = src_sp; sp1 != NULL; sp1 = sp1->parent)
+		if (!strcmp(sp1->name, sp->name))
+			break;
+	if (sp1 != NULL) {
+		VSB_printf(tl->sb,
+		    "Recursive include of \"%s\"\n\n", sp->name);
+		vcc_destroy_source(&sp);
+		return (NULL);
+	}
+	sp->parent = src_sp;
+	VTAILQ_INSERT_TAIL(&tl->sources, sp, list);
+	sp->idx = tl->nsources++;
+	sp->parent_tok = parent_token;
+	vcc_lex_source(tl, sp, 0);
+	return (sp);
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+vcc_lex_source(struct vcc *tl, struct source *src_sp, int eoi)
+{
+	struct token *t, *t1;
+	struct source *sp;
+	const struct source *sp1;
+
+	vcc_Lexer(tl, src_sp);
+	if (tl->err)
+		return;
+	VTAILQ_FOREACH(t, &src_sp->src_tokens, src_list) {
+		if (!eoi && t->tok == EOI)
+			break;
+
+		if (t->tok != ID || !vcc_IdIs(t, "include")) {
+			VTAILQ_INSERT_TAIL(&tl->tokens, t, list);
 			continue;
+		}
 
-		t1 = VTAILQ_NEXT(t, list);
+		t1 = VTAILQ_NEXT(t, src_list);
 		AN(t1);			/* There's always an EOI */
 		if (t1->tok != CSTR) {
 			VSB_cat(tl->sb,
 			    "include not followed by string constant.\n");
+			/* Not vcc_ErrWhere2(): tokens not on final list */
 			vcc_ErrWhere(tl, t1);
 			return;
 		}
-		t2 = VTAILQ_NEXT(t1, list);
-		AN(t2);			/* There's always an EOI */
+		t = VTAILQ_NEXT(t1, src_list);
+		AN(t);			/* There's always an EOI */
 
-		if (t2->tok != ';') {
+		if (t->tok != ';') {
 			VSB_cat(tl->sb,
 			    "include <string> not followed by semicolon.\n");
+			/* Not vcc_ErrWhere2(): tokens not on final list */
 			vcc_ErrWhere(tl, t1);
 			return;
 		}
 
-		if (t1->dec[0] == '.' && t1->dec[1] == '/') {
-			/*
-			 * Nested include filenames, starting with "./" are
-			 * resolved relative to the VCL file which contains
-			 * the include directive.
-			 */
-			if (t1->src->name[0] != '/') {
-				VSB_cat(tl->sb,
-				    "include \"./xxxxx\"; needs absolute "
-				    "filename of including file.\n");
-				vcc_ErrWhere(tl, t1);
-				return;
-			}
-			vsb = VSB_new_auto();
-			AN(vsb);
-			p = strrchr(t1->src->name, '/');
-			AN(p);
-			VSB_bcat(vsb, t1->src->name, p - t1->src->name);
-			VSB_cat(vsb, t1->dec + 1);
-			AZ(VSB_finish(vsb));
-			sp = vcc_file_source(tl, VSB_data(vsb));
-			VSB_destroy(&vsb);
-		} else {
-			sp = vcc_file_source(tl, t1->dec);
-		}
+		sp = vcc_include_file(tl, src_sp, t1->dec, t1);
 		if (sp == NULL) {
 			vcc_ErrWhere(tl, t1);
-			return;
-		}
-
-		for (sp1 = t->src; sp1 != NULL; sp1 = sp1->parent)
-			if (!strcmp(sp1->name, sp->name))
-				break;
-		if (sp1 != NULL) {
-			VSB_printf(tl->sb,
-			    "Recursive include of \"%s\"\n\n", sp->name);
-			vcc_ErrWhere(tl, t1);
-			for (sp1 = t->src; sp1 != NULL; sp1 = sp1->parent) {
-				if (sp1->parent_tok)
-					vcc_ErrWhere(tl, sp1->parent_tok);
+			for (sp1 = src_sp; sp1 != NULL; sp1 = sp1->parent) {
+				if (sp1->parent_tok == NULL)
+					break;
+				vcc_ErrWhere(tl, sp1->parent_tok);
 			}
-			vcc_destroy_source(&sp);
-			return;
 		}
-		sp->parent = t->src;
-		sp->parent_tok = t1;
-		VTAILQ_INSERT_TAIL(&tl->sources, sp, list);
-		sp->idx = tl->nsources++;
-		tl->t = t2;
-		vcc_Lexer(tl, sp, 0);
-
-		VTAILQ_REMOVE(&tl->tokens, t, list);
-		VTAILQ_REMOVE(&tl->tokens, t1, list);
-		VTAILQ_REMOVE(&tl->tokens, t2, list);
-		if (!tl->err)
-			vcc_resolve_includes(tl);
-		return;
+		if (tl->err)
+			return;
 	}
 }
diff --git a/lib/libvcc/vcc_token.c b/lib/libvcc/vcc_token.c
index 9edff6226..cc8392196 100644
--- a/lib/libvcc/vcc_token.c
+++ b/lib/libvcc/vcc_token.c
@@ -365,7 +365,7 @@ vcc_decstr(struct vcc *tl, unsigned sep)
 
 static void
 vcc_addtoken(struct vcc *tl, unsigned tok,
-    const struct source *sp, const char *b, const char *e)
+    struct source *sp, const char *b, const char *e)
 {
 	struct token *t;
 
@@ -375,10 +375,7 @@ vcc_addtoken(struct vcc *tl, unsigned tok,
 	t->b = b;
 	t->e = e;
 	t->src = sp;
-	if (tl->t != NULL)
-		VTAILQ_INSERT_AFTER(&tl->tokens, tl->t, t, list);
-	else
-		VTAILQ_INSERT_TAIL(&tl->tokens, t, list);
+	VTAILQ_INSERT_TAIL(&sp->src_tokens, t, src_list);
 	tl->t = t;
 }
 
@@ -405,7 +402,7 @@ static const struct delim_def {
 };
 
 static unsigned
-vcc_delim_token(struct vcc *tl, const struct source *sp, const char *p,
+vcc_delim_token(struct vcc *tl, struct source *sp, const char *p,
     const char **qp)
 {
 	const struct delim_def *dd;
@@ -445,7 +442,7 @@ vcc_delim_token(struct vcc *tl, const struct source *sp, const char *p,
  */
 
 void
-vcc_Lexer(struct vcc *tl, const struct source *sp, int eoi)
+vcc_Lexer(struct vcc *tl, struct source *sp)
 {
 	const char *p, *q, *r;
 	unsigned u;
@@ -611,6 +608,5 @@ vcc_Lexer(struct vcc *tl, const struct source *sp, int eoi)
 		vcc_ErrWhere(tl, tl->t);
 		return;
 	}
-	if (eoi)
-		vcc_addtoken(tl, EOI, sp, sp->e, sp->e);
+	vcc_addtoken(tl, EOI, sp, sp->e, sp->e);
 }


More information about the varnish-commit mailing list