1 /* 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This software was developed by the Computer Systems Engineering group 6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7 * contributed to Berkeley. 8 * 9 * All advertising materials mentioning features or use of this software 10 * must display the following acknowledgement: 11 * This product includes software developed by the University of 12 * California, Lawrence Berkeley Laboratories. 13 * 14 * %sccs.include.redist.c% 15 * 16 * @(#)mkmakefile.c 5.3 (Berkeley) 05/24/93 17 */ 18 19 #include <sys/param.h> 20 #include <ctype.h> 21 #include <errno.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include "config.h" 26 27 /* 28 * Make the Makefile. 29 */ 30 31 static int emitdefs __P((FILE *)); 32 static int emitobjs __P((FILE *)); 33 static int emitcfiles __P((FILE *)); 34 static int emitsfiles __P((FILE *)); 35 static int emitfiles __P((FILE *, int)); 36 static int emitrules __P((FILE *)); 37 static int emitload __P((FILE *)); 38 39 int 40 mkmakefile() 41 { 42 register FILE *ifp, *ofp; 43 register int lineno; 44 register int (*fn) __P((FILE *)); 45 register char *ofname; 46 char line[BUFSIZ], ifname[200]; 47 48 (void)sprintf(ifname, "Makefile.%s", machine); 49 if ((ifp = fopen(ifname, "r")) == NULL) { 50 (void)fprintf(stderr, "config: cannot read %s: %s\n", 51 ifname, strerror(errno)); 52 return (1); 53 } 54 ofname = path("Makefile"); 55 if ((ofp = fopen(ofname, "w")) == NULL) { 56 (void)fprintf(stderr, "config: cannot write %s: %s\n", 57 ofname, strerror(errno)); 58 free(ofname); 59 return (1); 60 } 61 if (emitdefs(ofp) != 0) 62 goto wrerror; 63 lineno = 0; 64 while (fgets(line, sizeof(line), ifp) != NULL) { 65 lineno++; 66 if (line[0] != '%') { 67 if (fputs(line, ofp) < 0) 68 goto wrerror; 69 continue; 70 } 71 if (strcmp(line, "%OBJS\n") == 0) 72 fn = emitobjs; 73 else if (strcmp(line, "%CFILES\n") == 0) 74 fn = emitcfiles; 75 else if (strcmp(line, "%SFILES\n") == 0) 76 fn = emitsfiles; 77 else if (strcmp(line, "%RULES\n") == 0) 78 fn = emitrules; 79 else if (strcmp(line, "%LOAD\n") == 0) 80 fn = emitload; 81 else { 82 xerror(ifname, lineno, 83 "unknown %% construct ignored: %s", line); 84 continue; 85 } 86 if ((*fn)(ofp)) 87 goto wrerror; 88 } 89 if (ferror(ifp)) { 90 (void)fprintf(stderr, 91 "config: error reading %s (at line %d): %s\n", 92 ifname, lineno, strerror(errno)); 93 goto bad; 94 /* (void)unlink(ofname); */ 95 free(ofname); 96 return (1); 97 } 98 if (fclose(ofp)) { 99 ofp = NULL; 100 goto wrerror; 101 } 102 (void)fclose(ifp); 103 free(ofname); 104 return (0); 105 wrerror: 106 (void)fprintf(stderr, "config: error writing %s: %s\n", 107 ofname, strerror(errno)); 108 bad: 109 if (ofp != NULL) 110 (void)fclose(ofp); 111 /* (void)unlink(ofname); */ 112 free(ofname); 113 return (1); 114 } 115 116 static int 117 emitdefs(fp) 118 register FILE *fp; 119 { 120 register struct nvlist *nv; 121 register char *sp; 122 123 if (fputs("IDENT=", fp) < 0) 124 return (1); 125 sp = ""; 126 for (nv = options; nv != NULL; nv = nv->nv_next) { 127 if (fprintf(fp, "%s-D%s%s%s", sp, nv->nv_name, 128 nv->nv_str ? "=" : "", nv->nv_str ? nv->nv_str : "") < 0) 129 return (1); 130 sp = " "; 131 } 132 if (putc('\n', fp) < 0) 133 return (1); 134 if (fprintf(fp, "PARAM=-DMAXUSERS=%d\n", maxusers) < 0) 135 return (1); 136 for (nv = mkoptions; nv != NULL; nv = nv->nv_next) 137 if (fprintf(fp, "%s=%s\n", nv->nv_name, nv->nv_str) < 0) 138 return (1); 139 return (0); 140 } 141 142 static int 143 emitobjs(fp) 144 register FILE *fp; 145 { 146 register struct files *fi; 147 register int lpos, len, sp; 148 149 if (fputs("OBJS=", fp) < 0) 150 return (1); 151 sp = '\t'; 152 lpos = 7; 153 for (fi = allfiles; fi != NULL; fi = fi->fi_next) { 154 if ((fi->fi_flags & FI_SEL) == 0) 155 continue; 156 len = strlen(fi->fi_base) + 2; 157 if (lpos + len > 72) { 158 if (fputs(" \\\n", fp) < 0) 159 return (1); 160 sp = '\t'; 161 lpos = 7; 162 } 163 if (fprintf(fp, "%c%s.o", sp, fi->fi_base) < 0) 164 return (1); 165 lpos += len + 1; 166 sp = ' '; 167 } 168 if (lpos != 7 && putc('\n', fp) < 0) 169 return (1); 170 return (0); 171 } 172 173 static int 174 emitcfiles(fp) 175 FILE *fp; 176 { 177 178 return (emitfiles(fp, 'c')); 179 } 180 181 static int 182 emitsfiles(fp) 183 FILE *fp; 184 { 185 186 return (emitfiles(fp, 's')); 187 } 188 189 static int 190 emitfiles(fp, suffix) 191 register FILE *fp; 192 int suffix; 193 { 194 register struct files *fi; 195 register struct config *cf; 196 register int lpos, len, sp; 197 char swapname[100]; 198 199 if (fprintf(fp, "%cFILES=", toupper(suffix)) < 0) 200 return (1); 201 sp = '\t'; 202 lpos = 7; 203 for (fi = allfiles; fi != NULL; fi = fi->fi_next) { 204 if ((fi->fi_flags & FI_SEL) == 0) 205 continue; 206 len = strlen(fi->fi_path); 207 if (fi->fi_path[len - 1] != suffix) 208 continue; 209 if (*fi->fi_path != '/') 210 len += 3; /* "$S/" */ 211 if (lpos + len > 72) { 212 if (fputs(" \\\n", fp) < 0) 213 return (1); 214 sp = '\t'; 215 lpos = 7; 216 } 217 if (fprintf(fp, "%c%s%s", sp, *fi->fi_path != '/' ? "$S/" : "", 218 fi->fi_path) < 0) 219 return (1); 220 lpos += len + 1; 221 sp = ' '; 222 } 223 /* 224 * The allfiles list does not include the configuration-specific 225 * C source files. These files should be eliminated someday, but 226 * for now, we have to add them to ${CFILES} (and only ${CFILES}). 227 */ 228 if (suffix == 'c') { 229 for (cf = allcf; cf != NULL; cf = cf->cf_next) { 230 if (cf->cf_root == NULL) 231 (void)sprintf(swapname, 232 "$S/%s/%s/swapgeneric.c", 233 machine, machine); 234 else 235 (void)sprintf(swapname, "swap%s.c", 236 cf->cf_name); 237 len = strlen(swapname); 238 if (lpos + len > 72) { 239 if (fputs(" \\\n", fp) < 0) 240 return (1); 241 sp = '\t'; 242 lpos = 7; 243 } 244 if (fprintf(fp, "%c%s", sp, swapname) < 0) 245 return (1); 246 lpos += len + 1; 247 sp = ' '; 248 } 249 } 250 if (lpos != 7 && putc('\n', fp) < 0) 251 return (1); 252 return (0); 253 } 254 255 /* 256 * Emit the make-rules. 257 */ 258 static int 259 emitrules(fp) 260 register FILE *fp; 261 { 262 register struct files *fi; 263 register const char *cp; 264 int ch; 265 char buf[200]; 266 267 for (fi = allfiles; fi != NULL; fi = fi->fi_next) { 268 if ((fi->fi_flags & FI_SEL) == 0) 269 continue; 270 if (fprintf(fp, "%s.o: %s%s\n", fi->fi_base, 271 *fi->fi_path != '/' ? "$S/" : "", fi->fi_path) < 0) 272 return (1); 273 if ((cp = fi->fi_mkrule) == NULL) { 274 cp = fi->fi_flags & FI_DRIVER ? "DRIVER" : "NORMAL"; 275 ch = fi->fi_lastc; 276 if (islower(ch)) 277 ch = toupper(ch); 278 (void)sprintf(buf, "${%s_%c%s}", cp, ch, 279 fi->fi_flags & FI_CONFIGDEP ? "_C" : ""); 280 cp = buf; 281 } 282 if (fprintf(fp, "\t%s\n\n", cp) < 0) 283 return (1); 284 } 285 return (0); 286 } 287 288 /* 289 * Emit the load commands. 290 * 291 * This function is not to be called `spurt'. 292 */ 293 static int 294 emitload(fp) 295 register FILE *fp; 296 { 297 register struct config *cf; 298 register const char *nm, *swname; 299 int first; 300 301 if (fputs("all:", fp) < 0) 302 return (1); 303 for (cf = allcf; cf != NULL; cf = cf->cf_next) { 304 if (fprintf(fp, " %s", cf->cf_name) < 0) 305 return (1); 306 } 307 if (fputs("\n\n", fp) < 0) 308 return (1); 309 for (first = 1, cf = allcf; cf != NULL; cf = cf->cf_next) { 310 nm = cf->cf_name; 311 swname = cf->cf_root != NULL ? cf->cf_name : "generic"; 312 if (fprintf(fp, "%s: ${SYSTEM_DEP} swap%s.o", nm, swname) < 0) 313 return (1); 314 if (first) { 315 if (fputs(" newvers", fp) < 0) 316 return (1); 317 first = 0; 318 } 319 if (fprintf(fp, "\n\ 320 \t${SYSTEM_LD_HEAD}\n\ 321 \t${SYSTEM_LD} swap%s.o\n\ 322 \t${SYSTEM_LD_TAIL}\n\ 323 \n\ 324 swap%s.o: ", swname, swname) < 0) 325 return (1); 326 if (cf->cf_root != NULL) { 327 if (fprintf(fp, "swap%s.c\n", nm) < 0) 328 return (1); 329 } else { 330 if (fprintf(fp, "$S/%s/%s/swapgeneric.c\n", 331 machine, machine) < 0) 332 return (1); 333 } 334 if (fputs("\t${NORMAL_C}\n\n", fp) < 0) 335 return (1); 336 } 337 return (0); 338 } 339