157492Storek /*
2*61818Sbostic * Copyright (c) 1992, 1993
3*61818Sbostic * The Regents of the University of California. All rights reserved.
457492Storek *
557492Storek * This software was developed by the Computer Systems Engineering group
657492Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
757492Storek * contributed to Berkeley.
857492Storek *
957492Storek * All advertising materials mentioning features or use of this software
1057492Storek * must display the following acknowledgement:
1157492Storek * This product includes software developed by the University of
1257492Storek * California, Lawrence Berkeley Laboratories.
1357492Storek *
1457492Storek * %sccs.include.redist.c%
1557492Storek *
16*61818Sbostic * @(#)mkmakefile.c 8.1 (Berkeley) 06/06/93
1757492Storek */
1857492Storek
1957492Storek #include <sys/param.h>
2057492Storek #include <ctype.h>
2157492Storek #include <errno.h>
2257492Storek #include <stdio.h>
2357492Storek #include <stdlib.h>
2457492Storek #include <string.h>
2557492Storek #include "config.h"
2657492Storek
2757492Storek /*
2857492Storek * Make the Makefile.
2957492Storek */
3057492Storek
3157492Storek static int emitdefs __P((FILE *));
3257492Storek static int emitobjs __P((FILE *));
3357492Storek static int emitcfiles __P((FILE *));
3457492Storek static int emitsfiles __P((FILE *));
3557492Storek static int emitfiles __P((FILE *, int));
3657492Storek static int emitrules __P((FILE *));
3757492Storek static int emitload __P((FILE *));
3857492Storek
3957492Storek int
mkmakefile()4057492Storek mkmakefile()
4157492Storek {
4257492Storek register FILE *ifp, *ofp;
4357492Storek register int lineno;
4457492Storek register int (*fn) __P((FILE *));
4557492Storek register char *ofname;
4657492Storek char line[BUFSIZ], ifname[200];
4757492Storek
4857492Storek (void)sprintf(ifname, "Makefile.%s", machine);
4957492Storek if ((ifp = fopen(ifname, "r")) == NULL) {
5057492Storek (void)fprintf(stderr, "config: cannot read %s: %s\n",
5157492Storek ifname, strerror(errno));
5257492Storek return (1);
5357492Storek }
5457492Storek ofname = path("Makefile");
5557492Storek if ((ofp = fopen(ofname, "w")) == NULL) {
5657492Storek (void)fprintf(stderr, "config: cannot write %s: %s\n",
5757492Storek ofname, strerror(errno));
5857492Storek free(ofname);
5957492Storek return (1);
6057492Storek }
6157492Storek if (emitdefs(ofp) != 0)
6257492Storek goto wrerror;
6357492Storek lineno = 0;
6457492Storek while (fgets(line, sizeof(line), ifp) != NULL) {
6557492Storek lineno++;
6657492Storek if (line[0] != '%') {
6757492Storek if (fputs(line, ofp) < 0)
6857492Storek goto wrerror;
6957492Storek continue;
7057492Storek }
7157492Storek if (strcmp(line, "%OBJS\n") == 0)
7257492Storek fn = emitobjs;
7357492Storek else if (strcmp(line, "%CFILES\n") == 0)
7457492Storek fn = emitcfiles;
7557492Storek else if (strcmp(line, "%SFILES\n") == 0)
7657492Storek fn = emitsfiles;
7757492Storek else if (strcmp(line, "%RULES\n") == 0)
7857492Storek fn = emitrules;
7957492Storek else if (strcmp(line, "%LOAD\n") == 0)
8057492Storek fn = emitload;
8157492Storek else {
8257492Storek xerror(ifname, lineno,
8357492Storek "unknown %% construct ignored: %s", line);
8457492Storek continue;
8557492Storek }
8657492Storek if ((*fn)(ofp))
8757492Storek goto wrerror;
8857492Storek }
8957492Storek if (ferror(ifp)) {
9057492Storek (void)fprintf(stderr,
9157492Storek "config: error reading %s (at line %d): %s\n",
9257492Storek ifname, lineno, strerror(errno));
9357492Storek goto bad;
9457492Storek /* (void)unlink(ofname); */
9557492Storek free(ofname);
9657492Storek return (1);
9757492Storek }
9857492Storek if (fclose(ofp)) {
9957492Storek ofp = NULL;
10057492Storek goto wrerror;
10157492Storek }
10257492Storek (void)fclose(ifp);
10357492Storek free(ofname);
10457492Storek return (0);
10557492Storek wrerror:
10657492Storek (void)fprintf(stderr, "config: error writing %s: %s\n",
10757492Storek ofname, strerror(errno));
10857492Storek bad:
10957492Storek if (ofp != NULL)
11057492Storek (void)fclose(ofp);
11157492Storek /* (void)unlink(ofname); */
11257492Storek free(ofname);
11357492Storek return (1);
11457492Storek }
11557492Storek
11657492Storek static int
emitdefs(fp)11757492Storek emitdefs(fp)
11857492Storek register FILE *fp;
11957492Storek {
12057492Storek register struct nvlist *nv;
12157492Storek register char *sp;
12257492Storek
12357492Storek if (fputs("IDENT=", fp) < 0)
12457492Storek return (1);
12557492Storek sp = "";
12657492Storek for (nv = options; nv != NULL; nv = nv->nv_next) {
12757492Storek if (fprintf(fp, "%s-D%s%s%s", sp, nv->nv_name,
12857492Storek nv->nv_str ? "=" : "", nv->nv_str ? nv->nv_str : "") < 0)
12957492Storek return (1);
13057492Storek sp = " ";
13157492Storek }
13257492Storek if (putc('\n', fp) < 0)
13357492Storek return (1);
13457492Storek if (fprintf(fp, "PARAM=-DMAXUSERS=%d\n", maxusers) < 0)
13557492Storek return (1);
13657492Storek for (nv = mkoptions; nv != NULL; nv = nv->nv_next)
13757492Storek if (fprintf(fp, "%s=%s\n", nv->nv_name, nv->nv_str) < 0)
13857492Storek return (1);
13957492Storek return (0);
14057492Storek }
14157492Storek
14257492Storek static int
emitobjs(fp)14357492Storek emitobjs(fp)
14457492Storek register FILE *fp;
14557492Storek {
14657492Storek register struct files *fi;
14757492Storek register int lpos, len, sp;
14857492Storek
14957492Storek if (fputs("OBJS=", fp) < 0)
15057492Storek return (1);
15157492Storek sp = '\t';
15257492Storek lpos = 7;
15357492Storek for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
15457492Storek if ((fi->fi_flags & FI_SEL) == 0)
15557492Storek continue;
15657492Storek len = strlen(fi->fi_base) + 2;
15757492Storek if (lpos + len > 72) {
15857492Storek if (fputs(" \\\n", fp) < 0)
15957492Storek return (1);
16057492Storek sp = '\t';
16157492Storek lpos = 7;
16257492Storek }
16357492Storek if (fprintf(fp, "%c%s.o", sp, fi->fi_base) < 0)
16457492Storek return (1);
16557492Storek lpos += len + 1;
16657492Storek sp = ' ';
16757492Storek }
16857492Storek if (lpos != 7 && putc('\n', fp) < 0)
16957492Storek return (1);
17057492Storek return (0);
17157492Storek }
17257492Storek
17357492Storek static int
emitcfiles(fp)17457492Storek emitcfiles(fp)
17557492Storek FILE *fp;
17657492Storek {
17757492Storek
17857492Storek return (emitfiles(fp, 'c'));
17957492Storek }
18057492Storek
18157492Storek static int
emitsfiles(fp)18257492Storek emitsfiles(fp)
18357492Storek FILE *fp;
18457492Storek {
18557492Storek
18657492Storek return (emitfiles(fp, 's'));
18757492Storek }
18857492Storek
18957492Storek static int
emitfiles(fp,suffix)19057492Storek emitfiles(fp, suffix)
19157492Storek register FILE *fp;
19257492Storek int suffix;
19357492Storek {
19457492Storek register struct files *fi;
19557492Storek register struct config *cf;
19657492Storek register int lpos, len, sp;
19757492Storek char swapname[100];
19857492Storek
19957492Storek if (fprintf(fp, "%cFILES=", toupper(suffix)) < 0)
20057492Storek return (1);
20157492Storek sp = '\t';
20257492Storek lpos = 7;
20357492Storek for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
20457492Storek if ((fi->fi_flags & FI_SEL) == 0)
20557492Storek continue;
20657492Storek len = strlen(fi->fi_path);
20757492Storek if (fi->fi_path[len - 1] != suffix)
20857492Storek continue;
20957492Storek if (*fi->fi_path != '/')
21057492Storek len += 3; /* "$S/" */
21157492Storek if (lpos + len > 72) {
21257492Storek if (fputs(" \\\n", fp) < 0)
21357492Storek return (1);
21457492Storek sp = '\t';
21557492Storek lpos = 7;
21657492Storek }
21757492Storek if (fprintf(fp, "%c%s%s", sp, *fi->fi_path != '/' ? "$S/" : "",
21857492Storek fi->fi_path) < 0)
21957492Storek return (1);
22057492Storek lpos += len + 1;
22157492Storek sp = ' ';
22257492Storek }
22360253Storek /*
22460253Storek * The allfiles list does not include the configuration-specific
22560253Storek * C source files. These files should be eliminated someday, but
22660253Storek * for now, we have to add them to ${CFILES} (and only ${CFILES}).
22760253Storek */
22860253Storek if (suffix == 'c') {
22960253Storek for (cf = allcf; cf != NULL; cf = cf->cf_next) {
23060253Storek if (cf->cf_root == NULL)
23160253Storek (void)sprintf(swapname,
23260253Storek "$S/%s/%s/swapgeneric.c",
23360253Storek machine, machine);
23460253Storek else
23560253Storek (void)sprintf(swapname, "swap%s.c",
23660253Storek cf->cf_name);
23760253Storek len = strlen(swapname);
23860253Storek if (lpos + len > 72) {
23960253Storek if (fputs(" \\\n", fp) < 0)
24060253Storek return (1);
24160253Storek sp = '\t';
24260253Storek lpos = 7;
24360253Storek }
24460253Storek if (fprintf(fp, "%c%s", sp, swapname) < 0)
24557492Storek return (1);
24660253Storek lpos += len + 1;
24760253Storek sp = ' ';
24857492Storek }
24957492Storek }
25057492Storek if (lpos != 7 && putc('\n', fp) < 0)
25157492Storek return (1);
25257492Storek return (0);
25357492Storek }
25457492Storek
25557492Storek /*
25657492Storek * Emit the make-rules.
25757492Storek */
25857492Storek static int
emitrules(fp)25957492Storek emitrules(fp)
26057492Storek register FILE *fp;
26157492Storek {
26257492Storek register struct files *fi;
26357492Storek register const char *cp;
26457492Storek int ch;
26557492Storek char buf[200];
26657492Storek
26757492Storek for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
26857492Storek if ((fi->fi_flags & FI_SEL) == 0)
26957492Storek continue;
27057492Storek if (fprintf(fp, "%s.o: %s%s\n", fi->fi_base,
27157492Storek *fi->fi_path != '/' ? "$S/" : "", fi->fi_path) < 0)
27257492Storek return (1);
27357492Storek if ((cp = fi->fi_mkrule) == NULL) {
27457492Storek cp = fi->fi_flags & FI_DRIVER ? "DRIVER" : "NORMAL";
27557492Storek ch = fi->fi_lastc;
27657492Storek if (islower(ch))
27757492Storek ch = toupper(ch);
27857492Storek (void)sprintf(buf, "${%s_%c%s}", cp, ch,
27957492Storek fi->fi_flags & FI_CONFIGDEP ? "_C" : "");
28057492Storek cp = buf;
28157492Storek }
28257492Storek if (fprintf(fp, "\t%s\n\n", cp) < 0)
28357492Storek return (1);
28457492Storek }
28557492Storek return (0);
28657492Storek }
28757492Storek
28857492Storek /*
28957492Storek * Emit the load commands.
29057492Storek *
29157492Storek * This function is not to be called `spurt'.
29257492Storek */
29357492Storek static int
emitload(fp)29457492Storek emitload(fp)
29557492Storek register FILE *fp;
29657492Storek {
29757492Storek register struct config *cf;
29857492Storek register const char *nm, *swname;
29957492Storek int first;
30057492Storek
30157492Storek if (fputs("all:", fp) < 0)
30257492Storek return (1);
30357492Storek for (cf = allcf; cf != NULL; cf = cf->cf_next) {
30457492Storek if (fprintf(fp, " %s", cf->cf_name) < 0)
30557492Storek return (1);
30657492Storek }
30757492Storek if (fputs("\n\n", fp) < 0)
30857492Storek return (1);
30957492Storek for (first = 1, cf = allcf; cf != NULL; cf = cf->cf_next) {
31057492Storek nm = cf->cf_name;
31157492Storek swname = cf->cf_root != NULL ? cf->cf_name : "generic";
31257492Storek if (fprintf(fp, "%s: ${SYSTEM_DEP} swap%s.o", nm, swname) < 0)
31357492Storek return (1);
31457492Storek if (first) {
31557492Storek if (fputs(" newvers", fp) < 0)
31657492Storek return (1);
31757492Storek first = 0;
31857492Storek }
31957492Storek if (fprintf(fp, "\n\
32057492Storek \t${SYSTEM_LD_HEAD}\n\
32157492Storek \t${SYSTEM_LD} swap%s.o\n\
32257492Storek \t${SYSTEM_LD_TAIL}\n\
32357492Storek \n\
32457492Storek swap%s.o: ", swname, swname) < 0)
32557492Storek return (1);
32657492Storek if (cf->cf_root != NULL) {
32757492Storek if (fprintf(fp, "swap%s.c\n", nm) < 0)
32857492Storek return (1);
32957492Storek } else {
33057492Storek if (fprintf(fp, "$S/%s/%s/swapgeneric.c\n",
33157492Storek machine, machine) < 0)
33257492Storek return (1);
33357492Storek }
33457492Storek if (fputs("\t${NORMAL_C}\n\n", fp) < 0)
33557492Storek return (1);
33657492Storek }
33757492Storek return (0);
33857492Storek }
339