summaryrefslogtreecommitdiff
path: root/usr.sbin/config/mkmakefile.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /usr.sbin/config/mkmakefile.c
initial import of NetBSD tree
Diffstat (limited to 'usr.sbin/config/mkmakefile.c')
-rw-r--r--usr.sbin/config/mkmakefile.c368
1 files changed, 368 insertions, 0 deletions
diff --git a/usr.sbin/config/mkmakefile.c b/usr.sbin/config/mkmakefile.c
new file mode 100644
index 00000000000..5fe766b01e2
--- /dev/null
+++ b/usr.sbin/config/mkmakefile.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * 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, Lawrence Berkeley Laboratories.
+ *
+ * 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.
+ *
+ * from: @(#)mkmakefile.c 8.1 (Berkeley) 6/6/93
+ * $Id: mkmakefile.c,v 1.1 1995/10/18 08:48:34 deraadt Exp $
+ */
+
+#include <sys/param.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "config.h"
+#include "sem.h"
+/*
+ * Make the Makefile.
+ */
+
+static int emitdefs __P((FILE *));
+static int emitobjs __P((FILE *));
+static int emitcfiles __P((FILE *));
+static int emitsfiles __P((FILE *));
+static int emitfiles __P((FILE *, int));
+static int emitrules __P((FILE *));
+static int emitload __P((FILE *));
+
+int
+mkmakefile()
+{
+ register FILE *ifp, *ofp;
+ register int lineno;
+ register int (*fn) __P((FILE *));
+ register char *ofname;
+ char line[BUFSIZ], ifname[200];
+
+ (void)sprintf(ifname, "Makefile.%s", machine);
+ if ((ifp = fopen(ifname, "r")) == NULL) {
+ (void)fprintf(stderr, "config: cannot read %s: %s\n",
+ ifname, strerror(errno));
+ return (1);
+ }
+ ofname = path("Makefile");
+ if ((ofp = fopen(ofname, "w")) == NULL) {
+ (void)fprintf(stderr, "config: cannot write %s: %s\n",
+ ofname, strerror(errno));
+ free(ofname);
+ return (1);
+ }
+ if (emitdefs(ofp) != 0)
+ goto wrerror;
+ lineno = 0;
+ while (fgets(line, sizeof(line), ifp) != NULL) {
+ lineno++;
+ if (line[0] != '%') {
+ if (fputs(line, ofp) < 0)
+ goto wrerror;
+ continue;
+ }
+ if (strcmp(line, "%OBJS\n") == 0)
+ fn = emitobjs;
+ else if (strcmp(line, "%CFILES\n") == 0)
+ fn = emitcfiles;
+ else if (strcmp(line, "%SFILES\n") == 0)
+ fn = emitsfiles;
+ else if (strcmp(line, "%RULES\n") == 0)
+ fn = emitrules;
+ else if (strcmp(line, "%LOAD\n") == 0)
+ fn = emitload;
+ else {
+ xerror(ifname, lineno,
+ "unknown %% construct ignored: %s", line);
+ continue;
+ }
+ if ((*fn)(ofp))
+ goto wrerror;
+ }
+ if (ferror(ifp)) {
+ (void)fprintf(stderr,
+ "config: error reading %s (at line %d): %s\n",
+ ifname, lineno, strerror(errno));
+ goto bad;
+ /* (void)unlink(ofname); */
+ free(ofname);
+ return (1);
+ }
+ if (fclose(ofp)) {
+ ofp = NULL;
+ goto wrerror;
+ }
+ (void)fclose(ifp);
+ free(ofname);
+ return (0);
+wrerror:
+ (void)fprintf(stderr, "config: error writing %s: %s\n",
+ ofname, strerror(errno));
+bad:
+ if (ofp != NULL)
+ (void)fclose(ofp);
+ /* (void)unlink(ofname); */
+ free(ofname);
+ return (1);
+}
+
+static int
+emitdefs(fp)
+ register FILE *fp;
+{
+ register struct nvlist *nv;
+ register char *sp;
+
+ if (fputs("IDENT=", fp) < 0)
+ return (1);
+ sp = "";
+ for (nv = options; nv != NULL; nv = nv->nv_next) {
+ if (fprintf(fp, "%s-D%s", sp, nv->nv_name) < 0)
+ return 1;
+ if (nv->nv_str)
+ if (fprintf(fp, "=\"%s\"", nv->nv_str) < 0)
+ return 1;
+ sp = " ";
+ }
+ if (putc('\n', fp) < 0)
+ return (1);
+ if (fprintf(fp, "PARAM=-DMAXUSERS=%d\n", maxusers) < 0)
+ return (1);
+ for (nv = mkoptions; nv != NULL; nv = nv->nv_next)
+ if (fprintf(fp, "%s=%s\n", nv->nv_name, nv->nv_str) < 0)
+ return (1);
+ return (0);
+}
+
+static int
+emitobjs(fp)
+ register FILE *fp;
+{
+ register struct files *fi;
+ register int lpos, len, sp;
+
+ if (fputs("OBJS=", fp) < 0)
+ return (1);
+ sp = '\t';
+ lpos = 7;
+ for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
+ if ((fi->fi_flags & FI_SEL) == 0)
+ continue;
+ len = strlen(fi->fi_base) + 2;
+ if (lpos + len > 72) {
+ if (fputs(" \\\n", fp) < 0)
+ return (1);
+ sp = '\t';
+ lpos = 7;
+ }
+ if (fprintf(fp, "%c%s.o", sp, fi->fi_base) < 0)
+ return (1);
+ lpos += len + 1;
+ sp = ' ';
+ }
+ if (lpos != 7 && putc('\n', fp) < 0)
+ return (1);
+ return (0);
+}
+
+static int
+emitcfiles(fp)
+ FILE *fp;
+{
+
+ return (emitfiles(fp, 'c'));
+}
+
+static int
+emitsfiles(fp)
+ FILE *fp;
+{
+
+ return (emitfiles(fp, 's'));
+}
+
+static int
+emitfiles(fp, suffix)
+ register FILE *fp;
+ int suffix;
+{
+ register struct files *fi;
+ register struct config *cf;
+ register int lpos, len, sp;
+ char swapname[100];
+
+ if (fprintf(fp, "%cFILES=", toupper(suffix)) < 0)
+ return (1);
+ sp = '\t';
+ lpos = 7;
+ for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
+ if ((fi->fi_flags & FI_SEL) == 0)
+ continue;
+ len = strlen(fi->fi_path);
+ if (fi->fi_path[len - 1] != suffix)
+ continue;
+ if (*fi->fi_path != '/')
+ len += 3; /* "$S/" */
+ if (lpos + len > 72) {
+ if (fputs(" \\\n", fp) < 0)
+ return (1);
+ sp = '\t';
+ lpos = 7;
+ }
+ if (fprintf(fp, "%c%s%s", sp, *fi->fi_path != '/' ? "$S/" : "",
+ fi->fi_path) < 0)
+ return (1);
+ lpos += len + 1;
+ sp = ' ';
+ }
+ /*
+ * The allfiles list does not include the configuration-specific
+ * C source files. These files should be eliminated someday, but
+ * for now, we have to add them to ${CFILES} (and only ${CFILES}).
+ */
+ if (suffix == 'c') {
+ for (cf = allcf; cf != NULL; cf = cf->cf_next) {
+ if (cf->cf_root == NULL)
+ (void)sprintf(swapname,
+ "$S/arch/%s/%s/swapgeneric.c",
+ machine, machine);
+ else
+ (void)sprintf(swapname, "swap%s.c",
+ cf->cf_name);
+ len = strlen(swapname);
+ if (lpos + len > 72) {
+ if (fputs(" \\\n", fp) < 0)
+ return (1);
+ sp = '\t';
+ lpos = 7;
+ }
+ if (fprintf(fp, "%c%s", sp, swapname) < 0)
+ return (1);
+ lpos += len + 1;
+ sp = ' ';
+ }
+ }
+ if (lpos != 7 && putc('\n', fp) < 0)
+ return (1);
+ return (0);
+}
+
+/*
+ * Emit the make-rules.
+ */
+static int
+emitrules(fp)
+ register FILE *fp;
+{
+ register struct files *fi;
+ register const char *cp;
+ int ch;
+ char buf[200];
+
+ for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
+ if ((fi->fi_flags & FI_SEL) == 0)
+ continue;
+ if (fprintf(fp, "%s.o: %s%s\n", fi->fi_base,
+ *fi->fi_path != '/' ? "$S/" : "", fi->fi_path) < 0)
+ return (1);
+ if ((cp = fi->fi_mkrule) == NULL) {
+ cp = fi->fi_flags & FI_DRIVER ? "DRIVER" : "NORMAL";
+ ch = fi->fi_lastc;
+ if (islower(ch))
+ ch = toupper(ch);
+ (void)sprintf(buf, "${%s_%c%s}", cp, ch,
+ fi->fi_flags & FI_CONFIGDEP ? "_C" : "");
+ cp = buf;
+ }
+ if (fprintf(fp, "\t%s\n\n", cp) < 0)
+ return (1);
+ }
+ return (0);
+}
+
+/*
+ * Emit the load commands.
+ *
+ * This function is not to be called `spurt'.
+ */
+static int
+emitload(fp)
+ register FILE *fp;
+{
+ register struct config *cf;
+ register const char *nm, *swname;
+ int first;
+
+ if (fputs("all:", fp) < 0)
+ return (1);
+ for (cf = allcf; cf != NULL; cf = cf->cf_next) {
+ if (fprintf(fp, " %s", cf->cf_name) < 0)
+ return (1);
+ }
+ if (fputs("\n\n", fp) < 0)
+ return (1);
+ for (first = 1, cf = allcf; cf != NULL; cf = cf->cf_next) {
+ nm = cf->cf_name;
+ swname =
+ cf->cf_root != NULL ? cf->cf_name : "generic";
+ if (fprintf(fp, "%s: ${SYSTEM_DEP} swap%s.o", nm, swname) < 0)
+ return (1);
+ if (first) {
+ if (fputs(" newvers", fp) < 0)
+ return (1);
+ first = 0;
+ }
+ if (fprintf(fp, "\n\
+\t${SYSTEM_LD_HEAD}\n\
+\t${SYSTEM_LD} swap%s.o\n\
+\t${SYSTEM_LD_TAIL}\n\
+\n\
+swap%s.o: ", swname, swname) < 0)
+ return (1);
+ if (cf->cf_root != NULL) {
+ if (fprintf(fp, "swap%s.c\n", nm) < 0)
+ return (1);
+ } else {
+ if (fprintf(fp, "$S/arch/%s/%s/swapgeneric.c\n",
+ machine, machine) < 0)
+ return (1);
+ }
+ if (fputs("\t${NORMAL_C}\n\n", fp) < 0)
+ return (1);
+ }
+ return (0);
+}