Index: stable/2.2/usr.sbin/config/config.h =================================================================== --- stable/2.2/usr.sbin/config/config.h (revision 36728) +++ stable/2.2/usr.sbin/config/config.h (revision 36729) @@ -1,230 +1,232 @@ /* * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)config.h 8.1 (Berkeley) 6/6/93 */ /* * Config. */ #include #include #include #define NODEV ((dev_t)-1) struct file_list { struct file_list *f_next; char *f_fn; /* the name */ int f_type; /* type or count */ u_char f_flags; /* see below */ char *f_special; /* special make rule if present */ char *f_depends; /* additional dependancies */ char *f_clean; /* File list to add to clean rule */ char *f_needs; /* * Random values: * swap space parameters for swap areas * root device, etc. for system specifications */ union { struct { /* when swap specification */ dev_t fuw_swapdev; int fuw_swapsize; int fuw_swapflag; } fuw; struct { /* when system specification */ dev_t fus_rootdev; dev_t fus_dumpdev; } fus; struct { /* when component dev specification */ dev_t fup_compdev; int fup_compinfo; } fup; } fun; #define f_swapdev fun.fuw.fuw_swapdev #define f_swapsize fun.fuw.fuw_swapsize #define f_swapflag fun.fuw.fuw_swapflag #define f_rootdev fun.fus.fus_rootdev #define f_dumpdev fun.fus.fus_dumpdev #define f_compdev fun.fup.fup_compdev #define f_compinfo fun.fup.fup_compinfo }; /* * Types. */ #define DRIVER 1 #define NORMAL 2 #define INVISIBLE 3 #define PROFILING 4 #define SYSTEMSPEC 5 #define SWAPSPEC 6 #define COMPDEVICE 7 #define COMPSPEC 8 /* * Attributes (flags). */ #define CONFIGDEP 1 #define NO_IMPLCT_RULE 2 #define NO_OBJ 4 #define BEFORE_DEPEND 8 struct idlst { char *id; struct idlst *id_next; }; struct device { int d_type; /* CONTROLLER, DEVICE, bus adaptor */ struct device *d_conn; /* what it is connected to */ char *d_name; /* name of device (e.g. rk11) */ struct idlst *d_vec; /* interrupt vectors */ int d_pri; /* interrupt priority */ int d_addr; /* address of csr */ int d_unit; /* unit number */ int d_drive; /* drive number */ int d_target; /* target number */ int d_lun; /* unit number */ int d_slave; /* slave number */ #define QUES -1 /* -1 means '?' */ #define UNKNOWN -2 /* -2 means not set yet */ int d_dk; /* if init 1 set to number for iostat */ int d_flags; /* flags for device init */ int d_conflicts; /* I'm allowed to conflict */ int d_disabled; /* nonzero to skip probe/attach */ char *d_port; /* io port base manifest constant */ int d_portn; /* io port base (if number not manifest) */ char *d_mask; /* interrupt mask */ int d_maddr; /* io memory base */ int d_msize; /* io memory size */ int d_drq; /* DMA request */ int d_irq; /* interrupt request */ struct device *d_next; /* Next one in list */ }; #define TO_NEXUS (struct device *)-1 #define TO_VBA (struct device *)-2 struct config { char *c_dev; char *s_sysname; }; /* * Config has a global notion of which machine type is * being used. It uses the name of the machine in choosing * files and directories. Thus if the name of the machine is ``vax'', * it will build from ``Makefile.vax'' and use ``../vax/inline'' * in the makerules, etc. */ int machine; char *machinename; #define MACHINE_VAX 1 #define MACHINE_TAHOE 2 #define MACHINE_HP300 3 #define MACHINE_I386 4 #define MACHINE_MIPS 5 #define MACHINE_PMAX 6 #define MACHINE_LUNA68K 7 #define MACHINE_NEWS3400 8 /* * For each machine, a set of CPU's may be specified as supported. * These and the options (below) are put in the C flags in the makefile. */ struct cputype { char *cpu_name; struct cputype *cpu_next; } *cputype; /* * A set of options may also be specified which are like CPU types, * but which may also specify values for the options. * A separate set of options may be defined for make-style options. */ struct opt { char *op_name; char *op_value; + int op_line; /* line number for error-reporting */ int op_ownfile; /* true = own file, false = makefile */ struct opt *op_next; } *opt, *mkopt; struct opt_list { char *o_name; char *o_file; struct opt_list *o_next; } *otab; char *ident; char *ns(); char *tc(); char *qu(); char *get_word(); char *get_quoted_word(); char *path(); char *raise(); void moveifchanged(); int do_trace; #if MACHINE_VAX int seen_mba, seen_uba; #endif #if MACHINE_TAHOE int seen_vba; #endif #if MACHINE_I386 int seen_isa; int seen_scbus; #endif int seen_cd; struct device *connect(); struct device *dtab; dev_t nametodev(); char *devtoname(); char errbuf[80]; int yyline; struct file_list *ftab, *conf_list, **confp, *comp_list, **compp; int profiling; int debugging; int maxusers; u_int loadaddress; +extern char *PREFIX; /* Config file name - for error messages */ extern int old_config_present; /* Old config/build directory still there */ #define eq(a,b) (!strcmp(a,b)) Index: stable/2.2/usr.sbin/config/config.y =================================================================== --- stable/2.2/usr.sbin/config/config.y (revision 36728) +++ stable/2.2/usr.sbin/config/config.y (revision 36729) @@ -1,1165 +1,1168 @@ %union { char *str; int val; struct file_list *file; struct idlst *lst; } %token AND %token ANY %token ARGS %token AT %token AUTO %token BIO %token BUS %token CAM %token COMMA %token CONFIG %token CONFLICTS %token CONTROLLER %token CPU %token CSR %token DEVICE %token DISABLE %token DISK %token DRIVE %token DRQ %token DUMPS %token EQUALS %token FLAGS %token IDENT %token INTERLEAVE %token IOMEM %token IOSIZ %token IRQ %token MACHINE %token MAJOR %token MASTER %token MAXUSERS %token MINOR %token MINUS %token NET %token NEXUS %token NONE %token ON %token OPTIONS %token MAKEOPTIONS %token PORT %token PRIORITY %token PSEUDO_DEVICE %token ROOT %token SEMICOLON %token SEQUENTIAL %token SIZE %token SLAVE %token SWAP %token TARGET %token TTY %token TRACE %token UNIT %token VECTOR %token ID %token NUMBER %token FPNUMBER %type Save_id %type Opt_value %type Dev %type Id_list %type optional_size %type optional_sflag %type device_name %type major_minor %type arg_device_spec %type root_device_spec root_device_specs %type dump_device_spec %type swap_device_spec %type comp_device_spec %{ /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)config.y 8.1 (Berkeley) 6/6/93 */ #include "config.h" #include #include #include #include #include #include struct device cur; struct device *curp = 0; char *temp_id; char *val_id; int alreadychecked __P((dev_t, dev_t[], dev_t *)); void deverror __P((char *, char *)); int finddev __P((dev_t)); void init_dev __P((struct device *)); void verifycomp __P((struct file_list *)); %} %% Configuration: Many_specs = { verifysystemspecs(); } ; Many_specs: Many_specs Spec | /* lambda */ ; Spec: Device_spec SEMICOLON = { newdev(&cur); } | Config_spec SEMICOLON | TRACE SEMICOLON = { do_trace = !do_trace; } | SEMICOLON | error SEMICOLON ; Config_spec: MACHINE Save_id = { if (!strcmp($2, "vax")) { machine = MACHINE_VAX; machinename = "vax"; } else if (!strcmp($2, "tahoe")) { machine = MACHINE_TAHOE; machinename = "tahoe"; } else if (!strcmp($2, "hp300")) { machine = MACHINE_HP300; machinename = "hp300"; } else if (!strcmp($2, "i386")) { machine = MACHINE_I386; machinename = "i386"; } else if (!strcmp($2, "mips")) { machine = MACHINE_MIPS; machinename = "mips"; } else if (!strcmp($2, "pmax")) { machine = MACHINE_PMAX; machinename = "pmax"; } else if (!strcmp($2, "luna68k")) { machine = MACHINE_LUNA68K; machinename = "luna68k"; } else if (!strcmp($2, "news3400")) { machine = MACHINE_NEWS3400; machinename = "news3400"; } else yyerror("Unknown machine type"); } | CPU Save_id = { struct cputype *cp = (struct cputype *)malloc(sizeof (struct cputype)); memset(cp, 0, sizeof(*cp)); cp->cpu_name = ns($2); cp->cpu_next = cputype; cputype = cp; free(temp_id); } | OPTIONS Opt_list | MAKEOPTIONS Mkopt_list | IDENT ID = { ident = ns($2); } | System_spec | MAXUSERS NUMBER = { maxusers = $2; }; System_spec: System_id System_parameter_list = { checksystemspec(*confp); } ; System_id: CONFIG Save_id = { mkconf($2); } ; System_parameter_list: System_parameter_list System_parameter | System_parameter ; System_parameter: addr_spec | swap_spec | root_spec | dump_spec | arg_spec ; addr_spec: AT NUMBER = { loadaddress = $2; } ; swap_spec: SWAP optional_on swap_device_list ; swap_device_list: swap_device_list AND swap_device | swap_device ; swap_device: swap_device_spec optional_size optional_sflag = { mkswap(*confp, $1, $2, $3); } ; swap_device_spec: device_name = { struct file_list *fl = newflist(SWAPSPEC); if (eq($1, "generic")) fl->f_fn = $1; else { fl->f_swapdev = nametodev($1, 0, COMPATIBILITY_SLICE, 'b'); fl->f_fn = devtoname(fl->f_swapdev); } $$ = fl; } | major_minor = { struct file_list *fl = newflist(SWAPSPEC); fl->f_swapdev = $1; fl->f_fn = devtoname($1); $$ = fl; } ; root_spec: ROOT optional_on root_device_specs = { struct file_list *fl = *confp; if (fl && fl->f_rootdev != NODEV) yyerror("extraneous root device specification"); else fl->f_rootdev = $3; } ; root_device_specs: root_device_spec AND root_device_specs = { warnx("extraneous root devices ignored"); $$ = $1; } | root_device_spec ; root_device_spec: device_name = { $$ = nametodev($1, 0, COMPATIBILITY_SLICE, 'a'); } | major_minor ; dump_spec: DUMPS optional_on dump_device_spec = { struct file_list *fl = *confp; if (fl && fl->f_dumpdev != NODEV) yyerror("extraneous dump device specification"); else fl->f_dumpdev = $3; } ; dump_device_spec: device_name = { $$ = nametodev($1, 0, COMPATIBILITY_SLICE, 'b'); } | major_minor ; arg_spec: ARGS optional_on arg_device_spec = { yyerror("arg device specification obsolete, ignored"); } ; arg_device_spec: device_name = { $$ = nametodev($1, 0, COMPATIBILITY_SLICE, 'b'); } | major_minor ; major_minor: MAJOR NUMBER MINOR NUMBER = { $$ = makedev($2, $4); } ; optional_on: ON | /* empty */ ; optional_size: SIZE NUMBER = { $$ = $2; } | /* empty */ = { $$ = 0; } ; optional_sflag: SEQUENTIAL = { $$ = 2; } | /* empty */ = { $$ = 0; } ; device_name: Save_id = { $$ = $1; } | Save_id NUMBER = { char buf[80]; (void) snprintf(buf, 80, "%s%d", $1, $2); $$ = ns(buf); free($1); } | Save_id NUMBER ID = { char buf[80]; (void) snprintf(buf, 80, "%s%d%s", $1, $2, $3); $$ = ns(buf); free($1); } | Save_id NUMBER ID NUMBER = { char buf[80]; (void) snprintf(buf, 80, "%s%d%s%d", $1, $2, $3, $4); $$ = ns(buf); free($1); } | Save_id NUMBER ID NUMBER ID = { char buf[80]; (void) snprintf(buf, 80, "%s%d%s%d%s", $1, $2, $3, $4, $5); $$ = ns(buf); free($1); } ; Opt_list: Opt_list COMMA Option | Option ; Option: Save_id = { struct opt *op = (struct opt *)malloc(sizeof (struct opt)); char *s; memset(op, 0, sizeof(*op)); op->op_name = ns($1); op->op_next = opt; op->op_value = 0; + op->op_line = yyline; opt = op; if ((s = strchr(op->op_name, '='))) { /* AARGH!!!! Old-style bogon */ *s = '\0'; op->op_value = ns(s + 1); } free(temp_id); } | Save_id EQUALS Opt_value = { struct opt *op = (struct opt *)malloc(sizeof (struct opt)); memset(op, 0, sizeof(*op)); op->op_name = ns($1); op->op_next = opt; op->op_value = ns($3); + op->op_line = yyline; opt = op; free(temp_id); free(val_id); } ; Opt_value: ID = { $$ = val_id = ns($1); } | NUMBER = { char nb[16]; (void) sprintf(nb, "%d", $1); $$ = val_id = ns(nb); } ; Save_id: ID = { $$ = temp_id = ns($1); } ; Mkopt_list: Mkopt_list COMMA Mkoption | Mkoption ; Mkoption: Save_id EQUALS Opt_value = { struct opt *op = (struct opt *)malloc(sizeof (struct opt)); memset(op, 0, sizeof(*op)); op->op_name = ns($1); op->op_ownfile = 0; /* for now */ op->op_next = mkopt; op->op_value = ns($3); + op->op_line = yyline; mkopt = op; free(temp_id); free(val_id); } ; Dev: ID = { $$ = ns($1); } ; Device_spec: DEVICE Dev_name Dev_info Int_spec = { cur.d_type = DEVICE; } | MASTER Dev_name Dev_info Int_spec = { cur.d_type = MASTER; } | DISK Dev_name Dev_info Int_spec = { cur.d_dk = 1; cur.d_type = DEVICE; } | CONTROLLER Dev_name Dev_info Int_spec = { cur.d_type = CONTROLLER; } | PSEUDO_DEVICE Init_dev Dev = { cur.d_name = $3; cur.d_type = PSEUDO_DEVICE; } | PSEUDO_DEVICE Init_dev Dev NUMBER = { cur.d_name = $3; cur.d_type = PSEUDO_DEVICE; cur.d_slave = $4; } | PSEUDO_DEVICE Dev_name Cdev_init Cdev_info = { if (!eq(cur.d_name, "cd")) yyerror("improper spec for pseudo-device"); seen_cd = 1; cur.d_type = DEVICE; verifycomp(*compp); }; Cdev_init: /* lambda */ = { mkcomp(&cur); }; Cdev_info: optional_on comp_device_list comp_option_list ; comp_device_list: comp_device_list AND comp_device | comp_device ; comp_device: comp_device_spec = { addcomp(*compp, $1); } ; comp_device_spec: device_name = { struct file_list *fl = newflist(COMPSPEC); fl->f_compdev = nametodev($1, 0, COMPATIBILITY_SLICE, 'c'); fl->f_fn = devtoname(fl->f_compdev); $$ = fl; } | major_minor = { struct file_list *fl = newflist(COMPSPEC); fl->f_compdev = $1; fl->f_fn = devtoname($1); $$ = fl; } ; comp_option_list: comp_option_list comp_option | /* lambda */ ; comp_option: INTERLEAVE NUMBER = { cur.d_pri = $2; } | FLAGS NUMBER = { cur.d_flags = $2; }; Dev_name: Init_dev Dev NUMBER = { cur.d_name = $2; if (eq($2, "mba")) seen_mba = 1; else if (eq($2, "uba")) seen_uba = 1; else if (eq($2, "vba")) seen_vba = 1; else if (eq($2, "isa")) seen_isa = 1; else if (eq($2, "scbus")) seen_scbus = 1; cur.d_unit = $3; }; Init_dev: /* lambda */ = { init_dev(&cur); }; Dev_info: Con_info Info_list | /* lambda */ ; Con_info: AT Dev NUMBER = { if (eq(cur.d_name, "mba") || eq(cur.d_name, "uba")) { (void) sprintf(errbuf, "%s must be connected to a nexus", cur.d_name); yyerror(errbuf); } cur.d_conn = connect($2, $3); } | AT NEXUS NUMBER = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; }; Info_list: Info_list Info | /* lambda */ ; Info: CSR NUMBER = { cur.d_addr = $2; } | BUS NUMBER = { if (cur.d_conn != 0 && cur.d_conn->d_type == CONTROLLER) cur.d_slave = $2; else yyerror("can't specify a bus to something " "other than a controller"); } | TARGET NUMBER = { cur.d_target = $2; } | UNIT NUMBER = { cur.d_lun = $2; } | DRIVE NUMBER = { cur.d_drive = $2; } | SLAVE NUMBER = { if (cur.d_conn != 0 && cur.d_conn != TO_NEXUS && cur.d_conn->d_type == MASTER) cur.d_slave = $2; else yyerror("can't specify slave--not to master"); } | IRQ NUMBER = { cur.d_irq = $2; } | DRQ NUMBER = { cur.d_drq = $2; } | IOMEM NUMBER = { cur.d_maddr = $2; } | IOSIZ NUMBER = { cur.d_msize = $2; } | PORT device_name = { cur.d_port = ns($2); } | PORT NUMBER = { cur.d_portn = $2; } | PORT AUTO = { cur.d_portn = -1; } | PORT NONE = { cur.d_portn = -2; } | TTY = { cur.d_mask = "tty"; } | BIO = { cur.d_mask = "bio"; } | CAM = { cur.d_mask = "cam"; } | NET = { cur.d_mask = "net"; } | FLAGS NUMBER = { cur.d_flags = $2; } | DISABLE = { cur.d_disabled = 1; } | CONFLICTS = { cur.d_conflicts = 1; }; Int_spec: VECTOR Id_list = { cur.d_vec = $2; } | PRIORITY NUMBER = { cur.d_pri = $2; } | /* lambda */ ; Id_list: Save_id = { struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst)); memset(a, 0, sizeof(*a)); a->id = $1; a->id_next = 0; $$ = a; } | Save_id Id_list = { struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst)); memset(a, 0, sizeof(*a)); a->id = $1; a->id_next = $2; $$ = a; }; %% void yyerror(s) char *s; { warnx("line %d: %s", yyline + 1, s); } /* * return the passed string in a new space */ char * ns(str) register char *str; { register char *cp; cp = malloc((unsigned)(strlen(str)+1)); (void) strcpy(cp, str); return (cp); } /* * add a device to the list of devices */ void newdev(dp) register struct device *dp; { register struct device *np; np = (struct device *) malloc(sizeof *np); memset(np, 0, sizeof(*np)); *np = *dp; np->d_next = 0; if (curp == 0) dtab = np; else curp->d_next = np; curp = np; } /* * note that a configuration should be made */ void mkconf(sysname) char *sysname; { register struct file_list *fl, **flp; fl = (struct file_list *) malloc(sizeof *fl); memset(fl, 0, sizeof(*fl)); fl->f_type = SYSTEMSPEC; fl->f_needs = sysname; fl->f_rootdev = NODEV; fl->f_dumpdev = NODEV; fl->f_fn = 0; fl->f_next = 0; for (flp = confp; *flp; flp = &(*flp)->f_next) ; *flp = fl; confp = flp; } struct file_list * newflist(ftype) u_char ftype; { struct file_list *fl = (struct file_list *)malloc(sizeof (*fl)); memset(fl, 0, sizeof(*fl)); fl->f_type = ftype; fl->f_next = 0; fl->f_swapdev = NODEV; fl->f_swapsize = 0; fl->f_needs = 0; fl->f_fn = 0; return (fl); } /* * Add a swap device to the system's configuration */ void mkswap(system, fl, size, flag) struct file_list *system, *fl; int size, flag; { register struct file_list **flp; if (system == 0 || system->f_type != SYSTEMSPEC) { yyerror("\"swap\" spec precedes \"config\" specification"); return; } if (size < 0) { yyerror("illegal swap partition size"); return; } /* * Append swap description to the end of the list. */ flp = &system->f_next; for (; *flp && (*flp)->f_type == SWAPSPEC; flp = &(*flp)->f_next) ; fl->f_next = *flp; *flp = fl; fl->f_swapsize = size; fl->f_swapflag = flag; /* * If first swap device for this system, * set up f_fn field to insure swap * files are created with unique names. */ if (system->f_fn) return; if (eq(fl->f_fn, "generic")) system->f_fn = ns(fl->f_fn); else system->f_fn = ns(system->f_needs); } void mkcomp(dp) register struct device *dp; { register struct file_list *fl, **flp; char buf[80]; fl = (struct file_list *) malloc(sizeof *fl); memset(fl, 0, sizeof(*fl)); fl->f_type = COMPDEVICE; fl->f_compinfo = dp->d_unit; fl->f_fn = ns(dp->d_name); (void) sprintf(buf, "%s%d", dp->d_name, dp->d_unit); fl->f_needs = ns(buf); fl->f_next = 0; for (flp = compp; *flp; flp = &(*flp)->f_next) ; *flp = fl; compp = flp; } void addcomp(compdev, fl) struct file_list *compdev, *fl; { register struct file_list **flp; if (compdev == 0 || compdev->f_type != COMPDEVICE) { yyerror("component spec precedes device specification"); return; } /* * Append description to the end of the list. */ flp = &compdev->f_next; for (; *flp && (*flp)->f_type == COMPSPEC; flp = &(*flp)->f_next) ; fl->f_next = *flp; *flp = fl; } /* * find the pointer to connect to the given device and number. * returns 0 if no such device and prints an error message */ struct device * connect(dev, num) register char *dev; register int num; { register struct device *dp; struct device *huhcon(); if (num == QUES) return (huhcon(dev)); for (dp = dtab; dp != 0; dp = dp->d_next) { if ((num != dp->d_unit) || !eq(dev, dp->d_name)) continue; if (dp->d_type != CONTROLLER && dp->d_type != MASTER) { (void) sprintf(errbuf, "%s connected to non-controller", dev); yyerror(errbuf); return (0); } return (dp); } (void) sprintf(errbuf, "%s %d not defined", dev, num); yyerror(errbuf); return (0); } /* * connect to an unspecific thing */ struct device * huhcon(dev) register char *dev; { register struct device *dp, *dcp; struct device rdev; int oldtype; /* * First make certain that there are some of these to wildcard on */ for (dp = dtab; dp != 0; dp = dp->d_next) if (eq(dp->d_name, dev)) break; if (dp == 0) { (void) sprintf(errbuf, "no %s's to wildcard", dev); yyerror(errbuf); return (0); } oldtype = dp->d_type; dcp = dp->d_conn; /* * Now see if there is already a wildcard entry for this device * (e.g. Search for a "uba ?") */ for (; dp != 0; dp = dp->d_next) if (eq(dev, dp->d_name) && dp->d_unit == -1) break; /* * If there isn't, make one because everything needs to be connected * to something. */ if (dp == 0) { dp = &rdev; init_dev(dp); dp->d_unit = QUES; dp->d_name = ns(dev); dp->d_type = oldtype; newdev(dp); dp = curp; /* * Connect it to the same thing that other similar things are * connected to, but make sure it is a wildcard unit * (e.g. up connected to sc ?, here we make connect sc? to a * uba?). If other things like this are on the NEXUS or * if they aren't connected to anything, then make the same * connection, else call ourself to connect to another * unspecific device. */ if (dcp == TO_NEXUS || dcp == 0) dp->d_conn = dcp; else dp->d_conn = connect(dcp->d_name, QUES); } return (dp); } void init_dev(dp) register struct device *dp; { dp->d_name = "OHNO!!!"; dp->d_type = DEVICE; dp->d_conn = 0; dp->d_conflicts = 0; dp->d_disabled = 0; dp->d_vec = 0; dp->d_addr = dp->d_flags = dp->d_dk = 0; dp->d_pri = -1; dp->d_slave = dp->d_lun = dp->d_target = dp->d_drive = dp->d_unit = UNKNOWN; dp->d_port = (char *)0; dp->d_portn = 0; dp->d_irq = -1; dp->d_drq = -1; dp->d_maddr = 0; dp->d_msize = 0; dp->d_mask = "null"; } /* * make certain that this is a reasonable type of thing to connect to a nexus */ void check_nexus(dev, num) register struct device *dev; int num; { switch (machine) { case MACHINE_VAX: if (!eq(dev->d_name, "uba") && !eq(dev->d_name, "mba") && !eq(dev->d_name, "bi")) yyerror("only uba's, mba's, and bi's should be connected to the nexus"); if (num != QUES) yyerror("can't give specific nexus numbers"); break; case MACHINE_TAHOE: if (!eq(dev->d_name, "vba")) yyerror("only vba's should be connected to the nexus"); break; case MACHINE_HP300: case MACHINE_LUNA68K: if (num != QUES) dev->d_addr = num; break; case MACHINE_I386: if (!eq(dev->d_name, "isa")) yyerror("only isa's should be connected to the nexus"); break; case MACHINE_NEWS3400: if (!eq(dev->d_name, "iop") && !eq(dev->d_name, "hb") && !eq(dev->d_name, "vme")) yyerror("only iop's, hb's and vme's should be connected to the nexus"); break; } } /* * Check system specification and apply defaulting * rules on root, argument, dump, and swap devices. */ void checksystemspec(fl) register struct file_list *fl; { char buf[BUFSIZ]; register struct file_list *swap; int generic; if (fl == 0 || fl->f_type != SYSTEMSPEC) { yyerror("internal error, bad system specification"); exit(1); } swap = fl->f_next; generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic"); if (fl->f_rootdev == NODEV && !generic) { yyerror("no root device specified"); exit(1); } /* * Default swap area to be in 'b' partition of root's * device. If root specified to be other than on 'a' * partition, give warning, something probably amiss. */ if (swap == 0 || swap->f_type != SWAPSPEC) { dev_t dev; swap = newflist(SWAPSPEC); dev = fl->f_rootdev; if (dkpart(dev) != 0) { (void) sprintf(buf, "Warning, swap defaulted to 'b' partition with root on '%c' partition", dkpart(dev) + 'a'); yyerror(buf); } swap->f_swapdev = dkmodpart(dev, SWAP_PART); swap->f_fn = devtoname(swap->f_swapdev); mkswap(fl, swap, 0); } /* * Make sure a generic swap isn't specified, along with * other stuff (user must really be confused). */ if (generic) { if (fl->f_rootdev != NODEV) yyerror("root device specified with generic swap"); if (fl->f_dumpdev != NODEV) yyerror("dump device specified with generic swap"); return; } /* * Warn if dump device is not a swap area. */ if (fl->f_dumpdev != NODEV && fl->f_dumpdev != swap->f_swapdev) { struct file_list *p = swap->f_next; for (; p && p->f_type == SWAPSPEC; p = p->f_next) if (fl->f_dumpdev == p->f_swapdev) return; (void) sprintf(buf, "Warning: dump device is not a swap partition"); yyerror(buf); } } /* * Verify all devices specified in the system specification * are present in the device specifications. */ void verifysystemspecs() { register struct file_list *fl; dev_t checked[50], *verifyswap(); register dev_t *pchecked = checked; for (fl = conf_list; fl; fl = fl->f_next) { if (fl->f_type != SYSTEMSPEC) continue; if (!finddev(fl->f_rootdev)) deverror(fl->f_needs, "root"); *pchecked++ = fl->f_rootdev; pchecked = verifyswap(fl->f_next, checked, pchecked); if (!alreadychecked(fl->f_dumpdev, checked, pchecked)) { if (!finddev(fl->f_dumpdev)) deverror(fl->f_needs, "dump"); *pchecked++ = fl->f_dumpdev; } } } /* * Do as above, but for swap devices. */ dev_t * verifyswap(fl, checked, pchecked) register struct file_list *fl; dev_t checked[]; register dev_t *pchecked; { for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) { if (eq(fl->f_fn, "generic")) continue; if (alreadychecked(fl->f_swapdev, checked, pchecked)) continue; if (!finddev(fl->f_swapdev)) warnx("swap device %s not configured", fl->f_fn); *pchecked++ = fl->f_swapdev; } return (pchecked); } /* * Verify that components of a compound device have themselves been config'ed */ void verifycomp(fl) register struct file_list *fl; { char *dname = fl->f_needs; for (fl = fl->f_next; fl; fl = fl->f_next) { if (fl->f_type != COMPSPEC || finddev(fl->f_compdev)) continue; warnx("%s: component device %s not configured", dname, fl->f_needs); } } /* * Has a device already been checked * for its existence in the configuration? */ int alreadychecked(dev, list, last) dev_t dev, list[]; register dev_t *last; { register dev_t *p; for (p = list; p < last; p++) if (dkmodpart(*p, 0) != dkmodpart(dev, 0)) return (1); return (0); } void deverror(systemname, devtype) char *systemname, *devtype; { warnx("%s: %s device not configured", systemname, devtype); } /* * Look for the device in the list of * configured hardware devices. Must * take into account stuff wildcarded. */ /*ARGSUSED*/ int finddev(dev) dev_t dev; { /* punt on this right now */ return (1); } Index: stable/2.2/usr.sbin/config/main.c =================================================================== --- stable/2.2/usr.sbin/config/main.c (revision 36728) +++ stable/2.2/usr.sbin/config/main.c (revision 36729) @@ -1,436 +1,436 @@ /* * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static const char copyright[] = "@(#) Copyright (c) 1980, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint #if 0 static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/6/93"; #endif static const char rcsid[] = - "$Id: main.c,v 1.14.2.3 1997/09/16 06:57:09 charnier Exp $"; + "$Id: main.c,v 1.14.2.4 1997/11/18 03:43:09 jdp Exp $"; #endif /* not lint */ #include #include #include #include #include #include #include #include #include #include "y.tab.h" #include "config.h" #ifndef TRUE #define TRUE (1) #endif #ifndef FALSE #define FALSE (0) #endif -static char *PREFIX; +char *PREFIX; static int no_config_clobber = FALSE; int old_config_present; static void usage __P((void)); void configfile __P((void)); /* * Config builds a set of files for building a UNIX * system given a description of the desired system. */ int main(argc, argv) int argc; char **argv; { struct stat buf; int ch; char *p; while ((ch = getopt(argc, argv, "gpn")) != -1) switch (ch) { case 'g': debugging++; break; case 'p': profiling++; break; case 'n': no_config_clobber = TRUE; break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc != 1) usage(); if (freopen(PREFIX = *argv, "r", stdin) == NULL) err(2, "%s", PREFIX); if (getenv("NO_CONFIG_CLOBBER")) no_config_clobber = TRUE; p = path((char *)NULL); if (stat(p, &buf)) { if (mkdir(p, 0777)) err(2, "%s", p); } else if ((buf.st_mode & S_IFMT) != S_IFDIR) { errx(2, "%s isn't a directory", p); } #ifndef NO_CLOBBER_EVER else if (!no_config_clobber) { char tmp[strlen(p) + 8]; fprintf(stderr, "Removing old directory %s: ", p); fflush(stderr); sprintf(tmp, "rm -rf %s", p); if (system(tmp)) { fprintf(stderr, "Failed!\n"); err(2, "%s", tmp); } fprintf(stderr, "Done.\n"); if (mkdir(p, 0777)) err(2, "%s", p); } #endif else old_config_present++; loadaddress = -1; dtab = NULL; confp = &conf_list; compp = &comp_list; if (yyparse()) exit(3); switch (machine) { case MACHINE_VAX: vax_ioconf(); /* Print ioconf.c */ ubglue(); /* Create ubglue.s */ break; case MACHINE_TAHOE: tahoe_ioconf(); vbglue(); break; case MACHINE_HP300: case MACHINE_LUNA68K: hp300_ioconf(); hpglue(); break; case MACHINE_I386: i386_ioconf(); /* Print ioconf.c */ vector(); /* Create vector.s */ break; case MACHINE_MIPS: case MACHINE_PMAX: pmax_ioconf(); break; case MACHINE_NEWS3400: news_ioconf(); break; default: printf("Specify machine type, e.g. ``machine vax''\n"); exit(1); } /* * make symbolic links in compilation directory * for "sys" (to make genassym.c work along with #include ) * and similarly for "machine". */ { char xxx[80]; (void) sprintf(xxx, "../../%s/include", machinename); (void) symlink(xxx, path("machine")); } options(); /* make options .h files */ makefile(); /* build Makefile */ headers(); /* make a lot of .h files */ swapconf(); /* swap config files */ configfile(); /* put config file into kernel*/ printf("Kernel build directory is %s\n", p); exit(0); } static void usage() { fprintf(stderr, "usage: config [-gpn] sysname\n"); exit(1); } /* * get_word * returns EOF on end of file * NULL on end of line * pointer to the word otherwise */ char * get_word(fp) register FILE *fp; { static char line[80]; register int ch; register char *cp; int escaped_nl = 0; begin: while ((ch = getc(fp)) != EOF) if (ch != ' ' && ch != '\t') break; if (ch == EOF) return ((char *)EOF); if (ch == '\\'){ escaped_nl = 1; goto begin; } if (ch == '\n') if (escaped_nl){ escaped_nl = 0; goto begin; } else return (NULL); cp = line; *cp++ = ch; while ((ch = getc(fp)) != EOF) { if (isspace(ch)) break; *cp++ = ch; } *cp = 0; if (ch == EOF) return ((char *)EOF); (void) ungetc(ch, fp); return (line); } /* * get_quoted_word * like get_word but will accept something in double or single quotes * (to allow embedded spaces). */ char * get_quoted_word(fp) register FILE *fp; { static char line[256]; register int ch; register char *cp; int escaped_nl = 0; begin: while ((ch = getc(fp)) != EOF) if (ch != ' ' && ch != '\t') break; if (ch == EOF) return ((char *)EOF); if (ch == '\\'){ escaped_nl = 1; goto begin; } if (ch == '\n') if (escaped_nl){ escaped_nl = 0; goto begin; } else return (NULL); cp = line; if (ch == '"' || ch == '\'') { register int quote = ch; while ((ch = getc(fp)) != EOF) { if (ch == quote) break; if (ch == '\n') { *cp = 0; printf("config: missing quote reading `%s'\n", line); exit(2); } *cp++ = ch; } } else { *cp++ = ch; while ((ch = getc(fp)) != EOF) { if (isspace(ch)) break; *cp++ = ch; } if (ch != EOF) (void) ungetc(ch, fp); } *cp = 0; if (ch == EOF) return ((char *)EOF); return (line); } /* * prepend the path to a filename */ char * path(file) char *file; { register char *cp; #define CDIR "../../compile/" cp = malloc((unsigned int)(sizeof(CDIR) + strlen(PREFIX) + (file ? strlen(file) : 0) + 2)); (void) strcpy(cp, CDIR); (void) strcat(cp, PREFIX); if (file) { (void) strcat(cp, "/"); (void) strcat(cp, file); } return (cp); } void configfile() { FILE *fi, *fo; char *p; int i; fi = fopen(PREFIX,"r"); if(!fi) err(2, "%s", PREFIX); fo = fopen(p=path("config.c.new"),"w"); if(!fo) err(2, "%s", p); fprintf(fo,"#include \"opt_config.h\"\n"); fprintf(fo,"#ifdef INCLUDE_CONFIG_FILE \n"); fprintf(fo,"static char *config = \"\n"); fprintf(fo,"START CONFIG FILE %s\n___",PREFIX); while (EOF != (i=getc(fi))) { if(i == '\n') { fprintf(fo,"\n___"); } else if(i == '\"') { fprintf(fo,"\\\""); } else if(i == '\\') { fprintf(fo,"\\\\"); } else { putc(i,fo); } } fprintf(fo,"\nEND CONFIG FILE %s\n",PREFIX); fprintf(fo,"\";\n"); fprintf(fo,"\n#endif /* INCLUDE_CONFIG_FILE */\n"); fclose(fi); fclose(fo); moveifchanged(path("config.c.new"), path("config.c")); } /* * moveifchanged -- * compare two files; rename if changed. */ void moveifchanged(const char *from_name, const char *to_name) { char *p, *q; int changed; size_t tsize; struct stat from_sb, to_sb; int from_fd, to_fd; changed = 0; if ((from_fd = open(from_name, O_RDONLY)) < 0) err(EX_OSERR, "moveifchanged open(%s)", from_name); if ((to_fd = open(to_name, O_RDONLY)) < 0) changed++; if (!changed && fstat(from_fd, &from_sb) < 0) err(EX_OSERR, "moveifchanged fstat(%s)", from_name); if (!changed && fstat(to_fd, &to_sb) < 0) err(EX_OSERR, "moveifchanged fstat(%s)", to_name); if (!changed && from_sb.st_size != to_sb.st_size) changed++; tsize = (size_t)from_sb.st_size; if (!changed) { p = mmap(NULL, tsize, PROT_READ, 0, from_fd, (off_t)0); if ((long)p == -1) err(EX_OSERR, "mmap %s", from_name); q = mmap(NULL, tsize, PROT_READ, 0, to_fd, (off_t)0); if ((long)q == -1) err(EX_OSERR, "mmap %s", to_name); changed = memcmp(p, q, tsize); munmap(p, tsize); munmap(q, tsize); } if (changed) { if (rename(from_name, to_name) < 0) err(EX_OSERR, "rename(%s, %s)", from_name, to_name); } else { if (unlink(from_name) < 0) err(EX_OSERR, "unlink(%s)", from_name); } #ifdef DIAG if (changed) printf("CHANGED! rename (%s, %s)\n", from_name, to_name); else printf("SAME! unlink (%s)\n", from_name); #endif return; } Index: stable/2.2/usr.sbin/config/mkmakefile.c =================================================================== --- stable/2.2/usr.sbin/config/mkmakefile.c (revision 36728) +++ stable/2.2/usr.sbin/config/mkmakefile.c (revision 36729) @@ -1,833 +1,833 @@ /* * Copyright (c) 1993, 19801990 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint #if 0 static char sccsid[] = "@(#)mkmakefile.c 8.1 (Berkeley) 6/6/93"; #endif static const char rcsid[] = - "$Id: mkmakefile.c,v 1.18.2.3 1997/09/16 06:57:10 charnier Exp $"; + "$Id: mkmakefile.c,v 1.18.2.4 1998/06/07 13:38:16 thepish Exp $"; #endif /* not lint */ /* * Build the makefile for the system, from * the information in the files files and the * additional files for the machine being compiled to. */ #include #include #include #include "y.tab.h" #include "config.h" #define next_word(fp, wd) \ { register char *word = get_word(fp); \ if (word == (char *)EOF) \ return; \ else \ wd = word; \ } #define next_quoted_word(fp, wd) \ { register char *word = get_quoted_word(fp); \ if (word == (char *)EOF) \ return; \ else \ wd = word; \ } static struct file_list *fcur; char *tail(); extern int old_config_present; void do_swapspec __P((FILE *, char *)); void do_clean __P((FILE *)); void do_load __P((FILE *)); void do_rules __P((FILE *)); void do_sfiles __P((FILE *)); void do_cfiles __P((FILE *)); void do_objs __P((FILE *)); void do_before_depend __P((FILE *)); int opteq __P((char *, char *)); void read_files __P((void)); void makefile __P((void)); /* * Lookup a file, by name. */ struct file_list * fl_lookup(file) register char *file; { register struct file_list *fp; for (fp = ftab ; fp != 0; fp = fp->f_next) { if (eq(fp->f_fn, file)) return (fp); } return (0); } /* * Lookup a file, by final component name. */ struct file_list * fltail_lookup(file) register char *file; { register struct file_list *fp; for (fp = ftab ; fp != 0; fp = fp->f_next) { if (eq(tail(fp->f_fn), tail(file))) return (fp); } return (0); } /* * Make a new file list entry */ struct file_list * new_fent() { register struct file_list *fp; fp = (struct file_list *) malloc(sizeof *fp); bzero(fp, sizeof *fp); if (fcur == 0) fcur = ftab = fp; else fcur->f_next = fp; fcur = fp; return (fp); } static struct users { int u_default; int u_min; int u_max; } users[] = { { 8, 2, 512 }, /* MACHINE_VAX */ { 8, 2, 512 }, /* MACHINE_TAHOE */ { 8, 2, 512 }, /* MACHINE_HP300 */ { 8, 2, 512 }, /* MACHINE_I386 */ { 8, 2, 512 }, /* MACHINE_MIPS */ { 8, 2, 512 }, /* MACHINE_PMAX */ { 8, 2, 512 }, /* MACHINE_LUNA68K */ { 8, 2, 512 }, /* MACHINE_NEWS3400 */ }; #define NUSERS (sizeof (users) / sizeof (users[0])) /* * Build the makefile from the skeleton */ void makefile() { FILE *ifp, *ofp; char line[BUFSIZ]; struct opt *op; struct users *up; int warn_make_clean = 0; read_files(); strcpy(line, "Makefile."); (void) strcat(line, machinename); ifp = fopen(line, "r"); if (ifp == 0) err(1, "%s", line); ofp = fopen(path("Makefile.new"), "w"); if (ofp == 0) err(1, "%s", path("Makefile.new")); fprintf(ofp, "KERN_IDENT=%s\n", raise(ident)); fprintf(ofp, "IDENT="); if (profiling) fprintf(ofp, " -DGPROF"); if (cputype == 0) { printf("cpu type must be specified\n"); exit(1); } #if 0 /* XXX: moved to cputype.h */ { struct cputype *cp; for (cp = cputype; cp; cp = cp->cpu_next) fprintf(ofp, " -D%s", cp->cpu_name); } #endif for (op = opt; op; op = op->op_next) { if (!op->op_ownfile) { warn_make_clean++; if (op->op_value) fprintf(ofp, " -D%s=%s", op->op_name, op->op_value); else fprintf(ofp, " -D%s", op->op_name); printf("%s:%d: unknown option \"%s\"\n", - PREFIX, op->op_line, op->op_name); + PREFIX, op->op_line, op->op_name); } } fprintf(ofp, "\n"); if ((unsigned)machine > NUSERS) { printf("maxusers config info isn't present, using vax\n"); up = &users[MACHINE_VAX-1]; } else up = &users[machine-1]; if (maxusers == 0) { printf("maxusers not specified; %d assumed\n", up->u_default); maxusers = up->u_default; } else if (maxusers < up->u_min) { printf("minimum of %d maxusers assumed\n", up->u_min); maxusers = up->u_min; } else if (maxusers > up->u_max) printf("warning: maxusers > %d (%d)\n", up->u_max, maxusers); fprintf(ofp, "PARAM=-DMAXUSERS=%d\n", maxusers); if (loadaddress != -1) { fprintf(ofp, "LOAD_ADDRESS=%X\n", loadaddress); } for (op = mkopt; op; op = op->op_next) fprintf(ofp, "%s=%s\n", op->op_name, op->op_value); if (debugging) fprintf(ofp, "DEBUG=-g\n"); if (profiling) { fprintf(ofp, "PROF=-pg\n"); fprintf(ofp, "PROFLEVEL=%d\n", profiling); } while (fgets(line, BUFSIZ, ifp) != 0) { if (*line != '%') { fprintf(ofp, "%s", line); continue; } if (eq(line, "%BEFORE_DEPEND\n")) do_before_depend(ofp); else if (eq(line, "%OBJS\n")) do_objs(ofp); else if (eq(line, "%CFILES\n")) do_cfiles(ofp); else if (eq(line, "%SFILES\n")) do_sfiles(ofp); else if (eq(line, "%RULES\n")) do_rules(ofp); else if (eq(line, "%LOAD\n")) do_load(ofp); else if (eq(line, "%CLEAN\n")) do_clean(ofp); else fprintf(stderr, "Unknown %% construct in generic makefile: %s", line); } (void) fclose(ifp); (void) fclose(ofp); moveifchanged(path("Makefile.new"), path("Makefile")); #ifdef notyet if (warn_make_clean) { printf("WARNING: Unknown options used (not in ../../conf/options or ./options.%s).\n", machinename); if (old_config_present) { printf("It is VERY important that you do a ``make clean'' before recompiling!\n"); } } printf("Don't forget to do a ``make depend''\n"); #endif } /* * Read in the information about files used in making the system. * Store it in the ftab linked list. */ void read_files() { FILE *fp; register struct file_list *tp, *pf; register struct device *dp; struct device *save_dp; register struct opt *op; char *wd, *this, *needs, *special, *depends, *clean; char fname[80]; int nreqs, first = 1, configdep, isdup, std, filetype, imp_rule, no_obj, before_depend; ftab = 0; (void) snprintf(fname, sizeof fname, "../../conf/files"); openit: fp = fopen(fname, "r"); if (fp == 0) err(1, "%s", fname); if(ident == NULL) { printf("no ident line specified\n"); exit(1); } next: /* * filename [ standard | optional ] [ config-dependent ] * [ dev* | profiling-routine ] [ device-driver] [ no-obj ] * [ compile-with "compile rule" [no-implicit-rule] ] * [ dependency "dependency-list"] [ before-depend ] * [ clean "file-list"] */ wd = get_word(fp); if (wd == (char *)EOF) { (void) fclose(fp); if (first == 1) { (void) snprintf(fname, sizeof fname, "files.%s", machinename); first++; goto openit; } if (first == 2) { (void) snprintf(fname, sizeof fname, "files.%s", raise(ident)); first++; fp = fopen(fname, "r"); if (fp != 0) goto next; } return; } if (wd == 0) goto next; /*************************************************\ * If it's a comment ignore to the end of the line * \*************************************************/ if(wd[0] == '#') { while( ((wd = get_word(fp)) != (char *)EOF) && wd) ; goto next; } this = ns(wd); next_word(fp, wd); if (wd == 0) { printf("%s: No type for %s.\n", fname, this); exit(1); } if ((pf = fl_lookup(this)) && (pf->f_type != INVISIBLE || pf->f_flags)) isdup = 1; else isdup = 0; tp = 0; if (first == 3 && (tp = fltail_lookup(this)) != 0) printf("%s: Local file %s overrides %s.\n", fname, this, tp->f_fn); nreqs = 0; special = 0; depends = 0; clean = 0; configdep = 0; needs = 0; std = 0; imp_rule = 0; no_obj = 0; before_depend = 0; filetype = NORMAL; if (eq(wd, "standard")) std = 1; else if (!eq(wd, "optional")) { printf("%s: %s must be optional or standard\n", fname, this); exit(1); } nextparam: next_word(fp, wd); if (wd == 0) goto doneparam; if (eq(wd, "config-dependent")) { configdep++; goto nextparam; } if (eq(wd, "no-obj")) { no_obj++; goto nextparam; } if (eq(wd, "no-implicit-rule")) { if (special == 0) { printf("%s: alternate rule required when " "\"no-implicit-rule\" is specified.\n", fname); } imp_rule++; goto nextparam; } if (eq(wd, "before-depend")) { before_depend++; goto nextparam; } if (eq(wd, "dependency")) { next_quoted_word(fp, wd); if (wd == 0) { printf("%s: %s missing compile command string.\n", fname, this); exit(1); } depends = ns(wd); goto nextparam; } if (eq(wd, "clean")) { next_quoted_word(fp, wd); if (wd == 0) { printf("%s: %s missing clean file list.\n", fname, this); exit(1); } clean = ns(wd); goto nextparam; } if (eq(wd, "compile-with")) { next_quoted_word(fp, wd); if (wd == 0) { printf("%s: %s missing compile command string.\n", fname, this); exit(1); } special = ns(wd); goto nextparam; } nreqs++; if (eq(wd, "device-driver")) { filetype = DRIVER; goto nextparam; } if (eq(wd, "profiling-routine")) { filetype = PROFILING; goto nextparam; } if (needs == 0 && nreqs == 1) needs = ns(wd); if (isdup) goto invis; for (dp = dtab; dp != 0; save_dp = dp, dp = dp->d_next) if (eq(dp->d_name, wd)) { if (std && dp->d_type == PSEUDO_DEVICE && dp->d_slave <= 0) dp->d_slave = 1; goto nextparam; } if (std) { dp = (struct device *) malloc(sizeof *dp); bzero(dp, sizeof *dp); init_dev(dp); dp->d_name = ns(wd); dp->d_type = PSEUDO_DEVICE; dp->d_slave = 1; save_dp->d_next = dp; goto nextparam; } for (op = opt; op != 0; op = op->op_next) if (op->op_value == 0 && opteq(op->op_name, wd)) { if (nreqs == 1) { free(needs); needs = 0; } goto nextparam; } invis: while ((wd = get_word(fp)) != 0) ; if (tp == 0) tp = new_fent(); tp->f_fn = this; tp->f_type = INVISIBLE; tp->f_needs = needs; tp->f_flags = isdup; tp->f_special = special; tp->f_depends = depends; tp->f_clean = clean; goto next; doneparam: if (std == 0 && nreqs == 0) { printf("%s: what is %s optional on?\n", fname, this); exit(1); } save: if (wd) { printf("%s: syntax error describing %s\n", fname, this); exit(1); } if (filetype == PROFILING && profiling == 0) goto next; if (tp == 0) tp = new_fent(); tp->f_fn = this; tp->f_type = filetype; tp->f_flags = 0; if (configdep) tp->f_flags |= CONFIGDEP; if (imp_rule) tp->f_flags |= NO_IMPLCT_RULE; if (no_obj) tp->f_flags |= NO_OBJ; if (before_depend) tp->f_flags |= BEFORE_DEPEND; if (imp_rule) tp->f_flags |= NO_IMPLCT_RULE; if (no_obj) tp->f_flags |= NO_OBJ; tp->f_needs = needs; tp->f_special = special; tp->f_depends = depends; tp->f_clean = clean; if (pf && pf->f_type == INVISIBLE) pf->f_flags = 1; /* mark as duplicate */ goto next; } int opteq(cp, dp) char *cp, *dp; { char c, d; for (; ; cp++, dp++) { if (*cp != *dp) { c = isupper(*cp) ? tolower(*cp) : *cp; d = isupper(*dp) ? tolower(*dp) : *dp; if (c != d) return (0); } if (*cp == 0) return (1); } } void do_before_depend(fp) FILE *fp; { register struct file_list *tp; register int lpos, len; fputs("BEFORE_DEPEND=", fp); lpos = 15; for (tp = ftab; tp; tp = tp->f_next) if (tp->f_flags & BEFORE_DEPEND) { len = strlen(tp->f_fn); if ((len = 3 + len) + lpos > 72) { lpos = 8; fputs("\\\n\t", fp); } if (tp->f_flags & NO_IMPLCT_RULE) fprintf(fp, "%s ", tp->f_fn); else fprintf(fp, "$S/%s ", tp->f_fn); lpos += len + 1; } if (lpos != 8) putc('\n', fp); } void do_objs(fp) FILE *fp; { register struct file_list *tp, *fl; register int lpos, len; register char *cp, och, *sp; char swapname[32]; fprintf(fp, "OBJS="); lpos = 6; for (tp = ftab; tp != 0; tp = tp->f_next) { if (tp->f_type == INVISIBLE || tp->f_flags & NO_OBJ) continue; sp = tail(tp->f_fn); for (fl = conf_list; fl; fl = fl->f_next) { if (fl->f_type != SWAPSPEC) continue; (void) sprintf(swapname, "swap%s.c", fl->f_fn); if (eq(sp, swapname)) goto cont; } cp = sp + (len = strlen(sp)) - 1; och = *cp; *cp = 'o'; if (len + lpos > 72) { lpos = 8; fprintf(fp, "\\\n\t"); } fprintf(fp, "%s ", sp); lpos += len + 1; *cp = och; cont: ; } if (lpos != 8) putc('\n', fp); } void do_cfiles(fp) FILE *fp; { register struct file_list *tp, *fl; register int lpos, len; char swapname[32]; fputs("CFILES=", fp); lpos = 8; for (tp = ftab; tp; tp = tp->f_next) if (tp->f_type != INVISIBLE) { len = strlen(tp->f_fn); if (tp->f_fn[len - 1] != 'c') continue; if ((len = 3 + len) + lpos > 72) { lpos = 8; fputs("\\\n\t", fp); } fprintf(fp, "$S/%s ", tp->f_fn); lpos += len + 1; } for (fl = conf_list; fl; fl = fl->f_next) if (fl->f_type == SYSTEMSPEC) { (void) sprintf(swapname, "swap%s.c", fl->f_fn); if ((len = 3 + strlen(swapname)) + lpos > 72) { lpos = 8; fputs("\\\n\t", fp); } if (eq(fl->f_fn, "generic")) fprintf(fp, "$S/%s/%s/%s ", machinename, machinename, swapname); else fprintf(fp, "%s ", swapname); lpos += len + 1; } if (lpos != 8) putc('\n', fp); } void do_sfiles(fp) FILE *fp; { register struct file_list *tp; register int lpos, len; fputs("SFILES=", fp); lpos = 8; for (tp = ftab; tp; tp = tp->f_next) if (tp->f_type != INVISIBLE) { len = strlen(tp->f_fn); if (tp->f_fn[len - 1] != 'S' && tp->f_fn[len - 1] != 's') continue; if ((len = 3 + len) + lpos > 72) { lpos = 8; fputs("\\\n\t", fp); } fprintf(fp, "$S/%s ", tp->f_fn); lpos += len + 1; } if (lpos != 8) putc('\n', fp); } char * tail(fn) char *fn; { register char *cp; cp = rindex(fn, '/'); if (cp == 0) return (fn); return (cp+1); } /* * Create the makerules for each file * which is part of the system. * Devices are processed with the special c2 option -i * which avoids any problem areas with i/o addressing * (e.g. for the VAX); assembler files are processed by as. */ void do_rules(f) FILE *f; { register char *cp, *np, och, *tp; register struct file_list *ftp; char *special; for (ftp = ftab; ftp != 0; ftp = ftp->f_next) { if (ftp->f_type == INVISIBLE) continue; cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1; och = *cp; if (ftp->f_flags & NO_IMPLCT_RULE) { if (ftp->f_depends) fprintf(f, "%s: %s\n", np, ftp->f_depends ); else fprintf(f, "%s: \n", np ); } else { *cp = '\0'; if (och == 'o') { fprintf(f, "%so:\n\t-cp $S/%so .\n\n", tail(np), np); continue; } if (ftp->f_depends) fprintf(f, "%so: $S/%s%c %s\n", tail(np), np, och, ftp->f_depends); else fprintf(f, "%so: $S/%s%c\n", tail(np), np, och); } tp = tail(np); special = ftp->f_special; if (special == 0) { char *ftype; static char cmd[128]; switch (ftp->f_type) { case NORMAL: ftype = "NORMAL"; break; case DRIVER: ftype = "DRIVER"; break; case PROFILING: if (!profiling) continue; ftype = "PROFILE"; break; default: printf("config: don't know rules for %s\n", np); break; } (void)sprintf(cmd, "${%s_%c%s}", ftype, toupper(och), ftp->f_flags & CONFIGDEP? "_C" : ""); special = cmd; } *cp = och; fprintf(f, "\t%s\n\n", special); } } /* * Create the load strings */ void do_load(f) register FILE *f; { register struct file_list *fl; register int first; struct file_list *do_systemspec(); for (first = 1, fl = conf_list; fl; first = 0) fl = fl->f_type == SYSTEMSPEC ? do_systemspec(f, fl, first) : fl->f_next; fputs("all:", f); for (fl = conf_list; fl; fl = fl->f_next) if (fl->f_type == SYSTEMSPEC) fprintf(f, " %s", fl->f_needs); putc('\n', f); } void do_clean(fp) FILE *fp; { register struct file_list *tp; register int lpos, len; fputs("CLEAN=", fp); lpos = 7; for (tp = ftab; tp; tp = tp->f_next) if (tp->f_clean) { len = strlen(tp->f_clean); if (len + lpos > 72) { lpos = 8; fputs("\\\n\t", fp); } fprintf(fp, "%s ", tp->f_clean); lpos += len + 1; } if (lpos != 8) putc('\n', fp); } struct file_list * do_systemspec(f, fl, first) FILE *f; register struct file_list *fl; int first; { fprintf(f, "%s: ${SYSTEM_DEP} swap%s.o", fl->f_needs, fl->f_fn); if (first) fprintf(f, " vers.o"); fprintf(f, "\n\t${SYSTEM_LD_HEAD}\n"); fprintf(f, "\t${SYSTEM_LD} swap%s.o\n", fl->f_fn); fprintf(f, "\t${SYSTEM_LD_TAIL}\n\n"); do_swapspec(f, fl->f_fn); for (fl = fl->f_next; fl; fl = fl->f_next) if (fl->f_type != SWAPSPEC) break; return (fl); } void do_swapspec(f, name) FILE *f; register char *name; { if (!eq(name, "generic")) fprintf(f, "swap%s.o: swap%s.c\n", name, name); else fprintf(f, "swapgeneric.o: $S/%s/%s/swapgeneric.c\n", machinename, machinename); fprintf(f, "\t${NORMAL_C}\n\n"); } char * raise(str) register char *str; { register char *cp = str; while (*str) { if (islower(*str)) *str = toupper(*str); str++; } return (cp); }