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

Reply via email to