tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: config: conditional at clause (was: vio9p vs. GENERIC.local vs. XEN3_DOM[0U])



On Tue, Aug 13, 2024 at 11:16:01 +0300, Valery Ushakov wrote:

> On the second thought at? vs at prevents copy-pasting of config
> chunks, so a form of ifdef that checks instantiation is probably
> better and is pretty trivial to add
> 
>   ifinstance virtio
>   vio9p* at virtio?
>   endif
> 
> in GENERIC.local makes both GENERIC and XEN* config ok with vio9p
> configured in GENERIC.

The diff (though, without copy-pasted (el)?ifn? variants).

Index: scan.l
===================================================================
RCS file: /cvsroot/src/usr.bin/config/scan.l,v
retrieving revision 1.36
diff -u -p -p -r1.36 scan.l
--- scan.l	13 Aug 2024 10:14:04 -0000	1.36
+++ scan.l	13 Aug 2024 13:57:22 -0000
@@ -116,6 +116,7 @@ static struct incl *incl;
 static int endinclude(void);
 static int getincludepath(void);
 static int getcurifdef(void);
+static int getcurinst(void);
 
 SLIST_HEAD(, prefix)	curdirs;	/* curdir stack */
 
@@ -209,6 +210,23 @@ with		return WITH;
 		yyline++;
 	}
 
+<*>{WS}ifinstance[ \t]+{WORD}{RESTOFLINE} {
+		ifdefstate <<= IDS_SHIFT;
+		if (++ifdefshift >= IDS_MAX_DEPTH) {
+			yyerror("too many levels of conditional");
+		}
+		IDS_ENTER(ifdef, 0);
+		if (IDS_PARENT_DISABLED || !getcurinst()) {
+			ifdefstate &= (uint64_t)~IDS_ENABLED;
+			BEGIN(IGNORED);
+		} else {
+			ifdefstate |= IDS_MATCH|IDS_ENABLED;
+			BEGIN(INITIAL);
+		}
+		IDS_EXIT(ifdef, 0);
+		yyline++;
+	}
+
 <*>{WS}ifndef[ \t]+{WORD}{RESTOFLINE} {
 		ifdefstate <<= IDS_SHIFT;
 		if (++ifdefshift >= IDS_MAX_DEPTH) {
@@ -660,3 +678,29 @@ getcurifdef(void)
 
 	return ht_lookup(attrtab, intern(p)) != NULL;
 }
+
+/*
+ * Get device name that comes after "ifinstance" and variants, check
+ * that it's a known base device that has been selected for
+ * instantiation.
+ */
+static int
+getcurinst(void)
+{
+	char *p = yytext;
+
+	/* skip the "if" keyword and the whitespace after it */
+	while (*p && isascii((unsigned char)*p) && !isspace((unsigned char)*p))
+		p++;
+	while (*p && isascii((unsigned char)*p) && isspace((unsigned char)*p))
+		p++;
+
+	/* device name */
+	const char *name = p;
+	while (*p && isascii((unsigned char)*p) && !isspace((unsigned char)*p))
+		p++;
+	*p = '\0';
+
+	const struct devbase *d = ht_lookup(devbasetab, intern(name));
+	return d != NULL && d->d_ihead != NULL;
+}



-uwe


Home | Main Index | Thread Index | Old Index