Subject: Patch to config(8) to allow inclusions relative to the file being included
To: None <tech-kern@netbsd.org>
From: Jason Thorpe <thorpej@wasabisystems.com>
List: tech-kern
Date: 09/03/2003 11:55:24
--Apple-Mail-3-556261988
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed
Hi folks...
The following patch allows file inclusions relative to the file being
included. This is useful if, say, you have a config file with multiple
fragments that is kept outside the kernel source tree. It allows you
to e.g.:
include "arch/i386/conf/GENERIC"
include "./CONFIG.frag1"
include "./CONFIG.frag2"
include "./../../feature/config.feature"
...and "config.feature" would be able to say:
include "./../someotherfeature/config.someotherfeature"
What the change does is track the "current directory" of the file
currently being parsed, and when it encouters "./" at the beginning of
an include'd file name, interprets the remainder of the file name as
relative to the "current directory".
I decided on the "./" as the trigger mostly to avoid changing the
syntax for traditional include directives. In a perfect world,
srcdir-relative includes would be include <...> and curdir-relative
includes would be include "...", but alas, we do not live in a perfect
world at the moment.
Since the change is simple, and does not affect any existing config
file or fragment, I'll check it in now.
-- Jason R. Thorpe <thorpej@wasabisystems.com>
--Apple-Mail-3-556261988
Content-Disposition: attachment;
filename=config-include.diff
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
x-unix-mode=0644;
name="config-include.diff"
Index: defs.h
===================================================================
RCS file: /cvsroot/src/usr.sbin/config/defs.h,v
retrieving revision 1.12
diff -c -r1.12 defs.h
*** defs.h 2003/08/07 11:25:15 1.12
--- defs.h 2003/09/03 18:39:57
***************
*** 394,399 ****
--- 394,400 ----
SLIST_HEAD(, prefix) prefixes, /* prefix stack */
allprefixes; /* all prefixes used (after popped) */
+ SLIST_HEAD(, prefix) curdirs; /* curdir stack */
struct devi **packed; /* arrayified table for packed devi's */
int npacked; /* size of packed table, <= ndevi */
Index: scan.l
===================================================================
RCS file: /cvsroot/src/usr.sbin/config/scan.l,v
retrieving revision 1.38
diff -c -r1.38 scan.l
*** scan.l 2003/08/07 11:25:17 1.38
--- scan.l 2003/09/03 18:39:57
***************
*** 193,198 ****
--- 193,238 ----
int interesting = 1;
+ static int
+ curdir_push(const char *fname)
+ {
+ struct prefix *pf;
+ char *p, *d, *f;
+
+ /* Set up the initial "current directory" for include directives. */
+ d = dirname(f = estrdup(fname));
+ free(f);
+ if (*d == '/')
+ p = estrdup(d);
+ else {
+ char *cwd, buf[PATH_MAX];
+
+ if ((cwd = getcwd(buf, sizeof(buf))) == NULL)
+ return (-1);
+ p = emalloc(strlen(cwd) + strlen(d) + 2);
+ sprintf(p, "%s/%s", cwd, d);
+ }
+ pf = emalloc(sizeof(*pf));
+ pf->pf_prefix = p;
+ SLIST_INSERT_HEAD(&curdirs, pf, pf_next);
+
+ return (0);
+ }
+
+ static void
+ curdir_pop(void)
+ {
+ struct prefix *pf;
+
+ pf = SLIST_FIRST(&curdirs);
+ SLIST_REMOVE_HEAD(&curdirs, pf_next);
+ if (SLIST_EMPTY(&curdirs))
+ panic("curdirs is empty");
+ /* LINTED cast away const (pf_prefix is malloc'd for curdirs) */
+ free((void *)pf->pf_prefix);
+ free(pf);
+ }
+
/*
* Open the "main" file (conffile).
*/
***************
*** 206,211 ****
--- 246,255 ----
if ((yyin = fopen(fname, "r")) == NULL)
#endif
return (-1);
+
+ if (curdir_push(fname) == -1)
+ return (-1);
+
yyfile = conffile = fname;
yyline = 1;
return (0);
***************
*** 261,267 ****
setupdirs();
}
! s = (*fname == '/') ? estrdup(fname) : sourcepath(fname);
if ((fp = fopen(s, "r")) == NULL) {
if (conditional == 0)
error("cannot open %s for reading: %s\n", s,
--- 305,318 ----
setupdirs();
}
! if (fname[0] == '/')
! s = estrdup(fname);
! else if (fname[0] == '.' && fname[1] == '/') {
! struct prefix *pf = SLIST_FIRST(&curdirs);
! s = emalloc(strlen(pf->pf_prefix) + strlen(fname));
! sprintf(s, "%s/%s", pf->pf_prefix, fname + 2);
! } else
! s = sourcepath(fname);
if ((fp = fopen(s, "r")) == NULL) {
if (conditional == 0)
error("cannot open %s for reading: %s\n", s,
***************
*** 272,277 ****
--- 323,334 ----
free(s);
return (-1);
}
+ if (curdir_push(s) == -1) {
+ error("cannot record current working directory for %s\n", s);
+ fclose(fp);
+ free(s);
+ return (-1);
+ }
in = emalloc(sizeof *in);
in->in_prev = incl;
in->in_buf = YY_CURRENT_BUFFER;
***************
*** 299,304 ****
--- 356,362 ----
struct incl *in;
int ateof;
+ curdir_pop();
if ((in = incl) == NULL)
panic("endinclude");
incl = in->in_prev;
--Apple-Mail-3-556261988--