1331722Seadler/* 2230051Skevlo * Copyright (c) 1980, 1990, 1993 31553Srgrimes * The Regents of the University of California. All rights reserved. 41553Srgrimes * 51553Srgrimes * Redistribution and use in source and binary forms, with or without 61553Srgrimes * modification, are permitted provided that the following conditions 71553Srgrimes * are met: 81553Srgrimes * 1. Redistributions of source code must retain the above copyright 91553Srgrimes * notice, this list of conditions and the following disclaimer. 101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111553Srgrimes * notice, this list of conditions and the following disclaimer in the 121553Srgrimes * documentation and/or other materials provided with the distribution. 131553Srgrimes * 4. Neither the name of the University nor the names of its contributors 141553Srgrimes * may be used to endorse or promote products derived from this software 151553Srgrimes * without specific prior written permission. 161553Srgrimes * 171553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271553Srgrimes * SUCH DAMAGE. 281553Srgrimes */ 291553Srgrimes 301553Srgrimes#ifndef lint 3129451Scharnier#if 0 321553Srgrimesstatic char sccsid[] = "@(#)mkmakefile.c 8.1 (Berkeley) 6/6/93"; 3329451Scharnier#endif 3429451Scharnierstatic const char rcsid[] = 3550479Speter "$FreeBSD: stable/11/usr.sbin/config/mkmakefile.c 346587 2019-04-23 02:37:12Z kevans $"; 361553Srgrimes#endif /* not lint */ 371553Srgrimes 381553Srgrimes/* 391553Srgrimes * Build the makefile for the system, from 401553Srgrimes * the information in the files files and the 411553Srgrimes * additional files for the machine being compiled to. 421553Srgrimes */ 431553Srgrimes 4429451Scharnier#include <ctype.h> 4529451Scharnier#include <err.h> 46261444Simp#include <stdarg.h> 47335863Skevans#include <stdbool.h> 481553Srgrimes#include <stdio.h> 4920458Sjoerg#include <string.h> 50337333Skevans#include <sys/cnv.h> 51337333Skevans#include <sys/nv.h> 5269004Simp#include <sys/param.h> 5316073Sphk#include "y.tab.h" 541553Srgrimes#include "config.h" 5530638Speter#include "configvers.h" 561553Srgrimes 5761640Speterstatic char *tail(char *); 5861640Speterstatic void do_clean(FILE *); 5961640Speterstatic void do_rules(FILE *); 6069135Speterstatic void do_xxfiles(char *, FILE *); 6161640Speterstatic void do_objs(FILE *); 6261640Speterstatic void do_before_depend(FILE *); 6361640Speterstatic void read_files(void); 64337333Skevansstatic void sanitize_envline(char *result, const char *src); 65337335Skevansstatic bool preprocess(char *line, char *result); 66337333Skevansstatic void process_into_file(char *line, FILE *ofp); 67337333Skevansstatic void process_into_nvlist(char *line, nvlist_t *nvl); 68337333Skevansstatic void dump_nvlist(nvlist_t *nvl, FILE *ofp); 6929451Scharnier 70261444Simpstatic void errout(const char *fmt, ...) 71261444Simp{ 72261444Simp va_list ap; 73261501Simp 74261444Simp va_start(ap, fmt); 75261444Simp vfprintf(stderr, fmt, ap); 76261444Simp va_end(ap); 77261444Simp exit(1); 78261444Simp} 79261444Simp 801553Srgrimes/* 811553Srgrimes * Lookup a file, by name. 821553Srgrimes */ 8345744Speterstatic struct file_list * 8461640Speterfl_lookup(char *file) 851553Srgrimes{ 8661640Speter struct file_list *fp; 871553Srgrimes 88110895Sru STAILQ_FOREACH(fp, &ftab, f_next) { 891553Srgrimes if (eq(fp->f_fn, file)) 901553Srgrimes return (fp); 911553Srgrimes } 921553Srgrimes return (0); 931553Srgrimes} 941553Srgrimes 951553Srgrimes/* 961553Srgrimes * Make a new file list entry 971553Srgrimes */ 9845744Speterstatic struct file_list * 9961640Speternew_fent(void) 1001553Srgrimes{ 10161640Speter struct file_list *fp; 1021553Srgrimes 103159362Sdelphij fp = (struct file_list *) calloc(1, sizeof *fp); 104205880Sru if (fp == NULL) 105205880Sru err(EXIT_FAILURE, "calloc"); 106110895Sru STAILQ_INSERT_TAIL(&ftab, fp, f_next); 1071553Srgrimes return (fp); 1081553Srgrimes} 1091553Srgrimes 1101553Srgrimes/* 111207260Simp * Open the correct Makefile and return it, or error out. 1121553Srgrimes */ 113207260SimpFILE * 114207260Simpopen_makefile_template(void) 1151553Srgrimes{ 116207260Simp FILE *ifp; 1171553Srgrimes char line[BUFSIZ]; 1181553Srgrimes 11955614Speter snprintf(line, sizeof(line), "../../conf/Makefile.%s", machinename); 1201553Srgrimes ifp = fopen(line, "r"); 121298687Saraujo if (ifp == NULL) { 12255614Speter snprintf(line, sizeof(line), "Makefile.%s", machinename); 12355614Speter ifp = fopen(line, "r"); 12455614Speter } 125298687Saraujo if (ifp == NULL) 12629451Scharnier err(1, "%s", line); 127207260Simp return (ifp); 128207260Simp} 12912772Speter 130207260Simp/* 131207260Simp * Build the makefile from the skeleton 132207260Simp */ 133207260Simpvoid 134207260Simpmakefile(void) 135207260Simp{ 136207260Simp FILE *ifp, *ofp; 137207260Simp char line[BUFSIZ]; 138207260Simp struct opt *op, *t; 139207260Simp 140207260Simp read_files(); 141207260Simp ifp = open_makefile_template(); 14299923Sbde ofp = fopen(path("Makefile.new"), "w"); 143298687Saraujo if (ofp == NULL) 14499923Sbde err(1, "%s", path("Makefile.new")); 145113951Sdes fprintf(ofp, "KERN_IDENT=%s\n", ident); 146218544Simp fprintf(ofp, "MACHINE=%s\n", machinename); 147218544Simp fprintf(ofp, "MACHINE_ARCH=%s\n", machinearch); 148185186Sthompsa SLIST_FOREACH_SAFE(op, &mkopt, op_next, t) { 149185186Sthompsa fprintf(ofp, "%s=%s", op->op_name, op->op_value); 150185186Sthompsa while ((op = SLIST_NEXT(op, op_append)) != NULL) 151185186Sthompsa fprintf(ofp, " %s", op->op_value); 152185186Sthompsa fprintf(ofp, "\n"); 153185186Sthompsa } 1541553Srgrimes if (debugging) 1551553Srgrimes fprintf(ofp, "DEBUG=-g\n"); 15699923Sbde if (profiling) 15720395Sbde fprintf(ofp, "PROFLEVEL=%d\n", profiling); 15852653Smarcel if (*srcdir != '\0') 15952653Smarcel fprintf(ofp,"S=%s\n", srcdir); 160230044Skevlo while (fgets(line, BUFSIZ, ifp) != NULL) { 1611553Srgrimes if (*line != '%') { 1621553Srgrimes fprintf(ofp, "%s", line); 1631553Srgrimes continue; 1641553Srgrimes } 1655325Sgibbs if (eq(line, "%BEFORE_DEPEND\n")) 1665325Sgibbs do_before_depend(ofp); 1675325Sgibbs else if (eq(line, "%OBJS\n")) 1681553Srgrimes do_objs(ofp); 16969135Speter else if (strncmp(line, "%FILES.", 7) == 0) 17069135Speter do_xxfiles(line, ofp); 1711553Srgrimes else if (eq(line, "%RULES\n")) 1721553Srgrimes do_rules(ofp); 1736803Sgibbs else if (eq(line, "%CLEAN\n")) 1746803Sgibbs do_clean(ofp); 175207260Simp else if (strncmp(line, "%VERSREQ=", 9) == 0) 176207260Simp line[0] = '\0'; /* handled elsewhere */ 177207260Simp else 1781553Srgrimes fprintf(stderr, 1791553Srgrimes "Unknown %% construct in generic makefile: %s", 1801553Srgrimes line); 1811553Srgrimes } 1821553Srgrimes (void) fclose(ifp); 1831553Srgrimes (void) fclose(ofp); 18413400Speter moveifchanged(path("Makefile.new"), path("Makefile")); 185153888Sru} 18634619Seivind 187335863Skevansstatic void 188335863Skevanssanitize_envline(char *result, const char *src) 189335863Skevans{ 190335863Skevans const char *eq; 191335863Skevans char c, *dst; 192335863Skevans bool leading; 193335863Skevans 194335863Skevans /* If there is no '=' it's not a well-formed name=value line. */ 195335863Skevans if ((eq = strchr(src, '=')) == NULL) { 196335863Skevans *result = 0; 197335863Skevans return; 198335863Skevans } 199335863Skevans dst = result; 200335863Skevans 201335863Skevans /* Copy chars before the '=', skipping any leading spaces/quotes. */ 202335863Skevans leading = true; 203335863Skevans while (src < eq) { 204335863Skevans c = *src++; 205335863Skevans if (leading && (isspace(c) || c == '"')) 206335863Skevans continue; 207335863Skevans *dst++ = c; 208335863Skevans leading = false; 209335863Skevans } 210335863Skevans 211335863Skevans /* If it was all leading space, we don't have a well-formed line. */ 212335863Skevans if (leading) { 213335863Skevans *result = 0; 214335863Skevans return; 215335863Skevans } 216335863Skevans 217335863Skevans /* Trim spaces/quotes immediately before the '=', then copy the '='. */ 218335863Skevans while (isspace(dst[-1]) || dst[-1] == '"') 219335863Skevans --dst; 220335863Skevans *dst++ = *src++; 221335863Skevans 222335863Skevans /* Copy chars after the '=', skipping any leading whitespace. */ 223335863Skevans leading = true; 224335863Skevans while ((c = *src++) != 0) { 225335863Skevans if (leading && (isspace(c) || c == '"')) 226335863Skevans continue; 227335863Skevans *dst++ = c; 228335863Skevans leading = false; 229335863Skevans } 230335863Skevans 231335863Skevans /* If it was all leading space, it's a valid 'var=' (nil value). */ 232335863Skevans if (leading) { 233335863Skevans *dst = 0; 234335863Skevans return; 235335863Skevans } 236335863Skevans 237335863Skevans /* Trim trailing whitespace and quotes. */ 238335863Skevans while (isspace(dst[-1]) || dst[-1] == '"') 239335863Skevans --dst; 240335863Skevans 241335863Skevans *dst = 0; 242335863Skevans} 243335863Skevans 244337335Skevans/* 245337335Skevans * Returns true if the caller may use the string. 246337335Skevans */ 247337335Skevansstatic bool 248337335Skevanspreprocess(char *line, char *result) 249337335Skevans{ 250337335Skevans char *s; 251337335Skevans 252337335Skevans /* Strip any comments */ 253337335Skevans if ((s = strchr(line, '#')) != NULL) 254337335Skevans *s = '\0'; 255337335Skevans sanitize_envline(result, line); 256337335Skevans /* Return true if it's non-empty */ 257337335Skevans return (*result != '\0'); 258337335Skevans} 259337335Skevans 260337333Skevansstatic void 261337333Skevansprocess_into_file(char *line, FILE *ofp) 262337333Skevans{ 263337333Skevans char result[BUFSIZ]; 264337333Skevans 265337335Skevans if (preprocess(line, result)) 266337335Skevans fprintf(ofp, "\"%s\\0\"\n", result); 267337333Skevans} 268337333Skevans 269337333Skevansstatic void 270337333Skevansprocess_into_nvlist(char *line, nvlist_t *nvl) 271337333Skevans{ 272337333Skevans char result[BUFSIZ], *s; 273337333Skevans 274337335Skevans if (preprocess(line, result)) { 275337335Skevans s = strchr(result, '='); 276337335Skevans *s = '\0'; 277337335Skevans if (nvlist_exists(nvl, result)) 278337335Skevans nvlist_free(nvl, result); 279337335Skevans nvlist_add_string(nvl, result, s + 1); 280337335Skevans } 281337333Skevans} 282337333Skevans 283337333Skevansstatic void 284337333Skevansdump_nvlist(nvlist_t *nvl, FILE *ofp) 285337333Skevans{ 286337333Skevans const char *name; 287337333Skevans void *cookie; 288337333Skevans 289337333Skevans if (nvl == NULL) 290337333Skevans return; 291337333Skevans 292337333Skevans while (!nvlist_empty(nvl)) { 293337333Skevans cookie = NULL; 294337333Skevans name = nvlist_next(nvl, NULL, &cookie); 295337333Skevans fprintf(ofp, "\"%s=%s\\0\"\n", name, 296337333Skevans cnvlist_get_string(cookie)); 297337333Skevans 298337333Skevans cnvlist_free_string(cookie); 299337333Skevans } 300337333Skevans} 301337333Skevans 302153888Sru/* 303337333Skevans * Build hints.c from the skeleton 304337333Skevans */ 305337333Skevansvoid 306337333Skevansmakehints(void) 307337333Skevans{ 308337333Skevans FILE *ifp, *ofp; 309337333Skevans nvlist_t *nvl; 310337333Skevans char line[BUFSIZ]; 311337333Skevans struct hint *hint; 312337333Skevans 313337333Skevans ofp = fopen(path("hints.c.new"), "w"); 314337333Skevans if (ofp == NULL) 315337333Skevans err(1, "%s", path("hints.c.new")); 316337333Skevans fprintf(ofp, "#include <sys/types.h>\n"); 317337333Skevans fprintf(ofp, "#include <sys/systm.h>\n"); 318337333Skevans fprintf(ofp, "\n"); 319337333Skevans /* 320337333Skevans * Write out hintmode for older kernels. Remove when config(8) major 321337333Skevans * version rolls over. 322337333Skevans */ 323337333Skevans if (versreq <= CONFIGVERS_ENVMODE_REQ) 324337333Skevans fprintf(ofp, "int hintmode = %d;\n", 325337333Skevans !STAILQ_EMPTY(&hints) ? 1 : 0); 326337333Skevans fprintf(ofp, "char static_hints[] = {\n"); 327337333Skevans nvl = nvlist_create(0); 328337333Skevans STAILQ_FOREACH(hint, &hints, hint_next) { 329337333Skevans ifp = fopen(hint->hint_name, "r"); 330337333Skevans if (ifp == NULL) 331337333Skevans err(1, "%s", hint->hint_name); 332337333Skevans while (fgets(line, BUFSIZ, ifp) != NULL) 333337333Skevans process_into_nvlist(line, nvl); 334337333Skevans dump_nvlist(nvl, ofp); 335337333Skevans fclose(ifp); 336337333Skevans } 337337333Skevans nvlist_destroy(nvl); 338337333Skevans fprintf(ofp, "\"\\0\"\n};\n"); 339337333Skevans fclose(ofp); 340337333Skevans moveifchanged(path("hints.c.new"), path("hints.c")); 341337333Skevans} 342337333Skevans 343337333Skevans/* 344153888Sru * Build env.c from the skeleton 345153888Sru */ 346153888Sruvoid 347153888Srumakeenv(void) 348153888Sru{ 349153888Sru FILE *ifp, *ofp; 350337333Skevans nvlist_t *nvl; 351337333Skevans char line[BUFSIZ]; 352335863Skevans struct envvar *envvar; 353153888Sru 35482393Speter ofp = fopen(path("env.c.new"), "w"); 35582393Speter if (ofp == NULL) 35682393Speter err(1, "%s", path("env.c.new")); 35783594Speter fprintf(ofp, "#include <sys/types.h>\n"); 35883594Speter fprintf(ofp, "#include <sys/systm.h>\n"); 35983594Speter fprintf(ofp, "\n"); 360337333Skevans /* 361337333Skevans * Write out envmode for older kernels. Remove when config(8) major 362337333Skevans * version rolls over. 363337333Skevans */ 364337333Skevans if (versreq <= CONFIGVERS_ENVMODE_REQ) 365337333Skevans fprintf(ofp, "int envmode = %d;\n", 366337333Skevans !STAILQ_EMPTY(&envvars) ? 1 : 0); 36782393Speter fprintf(ofp, "char static_env[] = {\n"); 368337333Skevans nvl = nvlist_create(0); 369336343Skevans STAILQ_FOREACH(envvar, &envvars, envvar_next) { 370336343Skevans if (envvar->env_is_file) { 371336343Skevans ifp = fopen(envvar->env_str, "r"); 372336343Skevans if (ifp == NULL) 373336343Skevans err(1, "%s", envvar->env_str); 374337333Skevans while (fgets(line, BUFSIZ, ifp) != NULL) 375337333Skevans process_into_nvlist(line, nvl); 376337333Skevans dump_nvlist(nvl, ofp); 377336343Skevans fclose(ifp); 378337333Skevans } else 379337333Skevans process_into_file(envvar->env_str, ofp); 38082393Speter } 381337333Skevans nvlist_destroy(nvl); 38282393Speter fprintf(ofp, "\"\\0\"\n};\n"); 38382393Speter fclose(ofp); 38482393Speter moveifchanged(path("env.c.new"), path("env.c")); 3851553Srgrimes} 3861553Srgrimes 387129119Scognetstatic void 388129073Scognetread_file(char *fname) 3891553Srgrimes{ 390162936Sru char ifname[MAXPATHLEN]; 3911553Srgrimes FILE *fp; 392152811Sru struct file_list *tp; 39361640Speter struct device *dp; 39461640Speter struct opt *op; 395152811Sru char *wd, *this, *compilewith, *depends, *clean, *warning; 396219819Sjeff const char *objprefix; 397261493Simp int compile, match, nreqs, std, filetype, not, 398261436Simp imp_rule, no_obj, before_depend, nowerror; 3991553Srgrimes 4001553Srgrimes fp = fopen(fname, "r"); 401298687Saraujo if (fp == NULL) 40229451Scharnier err(1, "%s", fname); 4031553Srgrimesnext: 4041553Srgrimes /* 405162936Sru * include "filename" 406261436Simp * filename [ standard | optional ] 407152862Sru * [ dev* [ | dev* ... ] | profiling-routine ] [ no-obj ] 4088857Srgrimes * [ compile-with "compile rule" [no-implicit-rule] ] 4096803Sgibbs * [ dependency "dependency-list"] [ before-depend ] 41054490Speter * [ clean "file-list"] [ warning "text warning" ] 411219819Sjeff * [ obj-prefix "file prefix"] 4121553Srgrimes */ 4131553Srgrimes wd = get_word(fp); 4141553Srgrimes if (wd == (char *)EOF) { 4151553Srgrimes (void) fclose(fp); 4161553Srgrimes return; 417129073Scognet } 418298687Saraujo if (wd == NULL) 4191553Srgrimes goto next; 42052098Speter if (wd[0] == '#') 4211566Srgrimes { 42252098Speter while (((wd = get_word(fp)) != (char *)EOF) && wd) 42352098Speter ; 4241566Srgrimes goto next; 4251566Srgrimes } 426162936Sru if (eq(wd, "include")) { 427261435Simp wd = get_quoted_word(fp); 428298687Saraujo if (wd == (char *)EOF || wd == NULL) 429261444Simp errout("%s: missing include filename.\n", fname); 430162936Sru (void) snprintf(ifname, sizeof(ifname), "../../%s", wd); 431162936Sru read_file(ifname); 432162936Sru while (((wd = get_word(fp)) != (char *)EOF) && wd) 433162936Sru ; 434162936Sru goto next; 435162936Sru } 4361553Srgrimes this = ns(wd); 437261435Simp wd = get_word(fp); 438261435Simp if (wd == (char *)EOF) 439261435Simp return; 440298687Saraujo if (wd == NULL) 441261444Simp errout("%s: No type for %s.\n", fname, this); 442152811Sru tp = fl_lookup(this); 443152862Sru compile = 0; 444152862Sru match = 1; 4451553Srgrimes nreqs = 0; 44673199Speter compilewith = 0; 4474571Sgibbs depends = 0; 4486803Sgibbs clean = 0; 44972684Speter warning = 0; 450261436Simp std = 0; 4514571Sgibbs imp_rule = 0; 4524571Sgibbs no_obj = 0; 4535325Sgibbs before_depend = 0; 45491002Speter nowerror = 0; 455261493Simp not = 0; 4561553Srgrimes filetype = NORMAL; 457219819Sjeff objprefix = ""; 458261444Simp if (eq(wd, "standard")) 4591553Srgrimes std = 1; 460261444Simp else if (!eq(wd, "optional")) 461261444Simp errout("%s: \"%s\" %s must be optional or standard\n", 462214654Sobrien fname, wd, this); 463261446Simp for (wd = get_word(fp); wd; wd = get_word(fp)) { 464261446Simp if (wd == (char *)EOF) 465261446Simp return; 466261493Simp if (eq(wd, "!")) { 467261493Simp not = 1; 468261493Simp continue; 469261493Simp } 470261446Simp if (eq(wd, "|")) { 471261446Simp if (nreqs == 0) 472261446Simp errout("%s: syntax error describing %s\n", 473261446Simp fname, this); 474274936Sian compile += match; 475261446Simp match = 1; 476261446Simp nreqs = 0; 477261446Simp continue; 478261435Simp } 479261446Simp if (eq(wd, "no-obj")) { 480261446Simp no_obj++; 481261446Simp continue; 482261446Simp } 483261446Simp if (eq(wd, "no-implicit-rule")) { 484298687Saraujo if (compilewith == NULL) 485261446Simp errout("%s: alternate rule required when " 486261446Simp "\"no-implicit-rule\" is specified for" 487261446Simp " %s.\n", 488261446Simp fname, this); 489261446Simp imp_rule++; 490261446Simp continue; 491261446Simp } 492261446Simp if (eq(wd, "before-depend")) { 493261446Simp before_depend++; 494261446Simp continue; 495261446Simp } 496261446Simp if (eq(wd, "dependency")) { 497261446Simp wd = get_quoted_word(fp); 498298687Saraujo if (wd == (char *)EOF || wd == NULL) 499261446Simp errout("%s: %s missing dependency string.\n", 500261446Simp fname, this); 501261446Simp depends = ns(wd); 502261446Simp continue; 503261446Simp } 504261446Simp if (eq(wd, "clean")) { 505261446Simp wd = get_quoted_word(fp); 506298687Saraujo if (wd == (char *)EOF || wd == NULL) 507261446Simp errout("%s: %s missing clean file list.\n", 508261446Simp fname, this); 509261446Simp clean = ns(wd); 510261446Simp continue; 511261446Simp } 512261446Simp if (eq(wd, "compile-with")) { 513261446Simp wd = get_quoted_word(fp); 514298687Saraujo if (wd == (char *)EOF || wd == NULL) 515261446Simp errout("%s: %s missing compile command string.\n", 516261446Simp fname, this); 517261446Simp compilewith = ns(wd); 518261446Simp continue; 519261446Simp } 520261446Simp if (eq(wd, "warning")) { 521261446Simp wd = get_quoted_word(fp); 522298687Saraujo if (wd == (char *)EOF || wd == NULL) 523261446Simp errout("%s: %s missing warning text string.\n", 524261446Simp fname, this); 525261446Simp warning = ns(wd); 526261446Simp continue; 527261446Simp } 528261446Simp if (eq(wd, "obj-prefix")) { 529261446Simp wd = get_quoted_word(fp); 530298687Saraujo if (wd == (char *)EOF || wd == NULL) 531261446Simp errout("%s: %s missing object prefix string.\n", 532261446Simp fname, this); 533261446Simp objprefix = ns(wd); 534261446Simp continue; 535261446Simp } 536261446Simp if (eq(wd, "nowerror")) { 537261446Simp nowerror = 1; 538261446Simp continue; 539261446Simp } 540261446Simp if (eq(wd, "local")) { 541261446Simp filetype = LOCAL; 542261446Simp continue; 543261446Simp } 544261446Simp if (eq(wd, "no-depend")) { 545261446Simp filetype = NODEPEND; 546261446Simp continue; 547261446Simp } 548261446Simp nreqs++; 549261446Simp if (eq(wd, "profiling-routine")) { 550261446Simp filetype = PROFILING; 551261446Simp continue; 552261446Simp } 553261446Simp if (std) 554261446Simp errout("standard entry %s has optional inclusion specifier %s!\n", 555261446Simp this, wd); 556261446Simp STAILQ_FOREACH(dp, &dtab, d_next) 557261446Simp if (eq(dp->d_name, wd)) { 558274936Sian if (not) 559274936Sian match = 0; 560274936Sian else 561274936Sian dp->d_done |= DEVDONE; 562261446Simp goto nextparam; 563261446Simp } 564261446Simp SLIST_FOREACH(op, &opt, op_next) 565346587Skevans if (op->op_value == 0 && 566346587Skevans strcasecmp(op->op_name, wd) == 0) { 567274936Sian if (not) 568274936Sian match = 0; 569261446Simp goto nextparam; 570274936Sian } 571274936Sian match &= not; 572261501Simpnextparam:; 573274936Sian not = 0; 574113397Sphk } 575274936Sian compile += match; 576261446Simp if (compile && tp == NULL) { 577261446Simp if (std == 0 && nreqs == 0) 578261446Simp errout("%s: what is %s optional on?\n", 579261446Simp fname, this); 580261446Simp if (filetype == PROFILING && profiling == 0) 581261446Simp goto next; 582261446Simp tp = new_fent(); 583261446Simp tp->f_fn = this; 584261446Simp tp->f_type = filetype; 585336938Skevans if (filetype == LOCAL) 586336938Skevans tp->f_srcprefix = ""; 587336938Skevans else 588336938Skevans tp->f_srcprefix = "$S/"; 589261446Simp if (imp_rule) 590261446Simp tp->f_flags |= NO_IMPLCT_RULE; 591261446Simp if (no_obj) 592261446Simp tp->f_flags |= NO_OBJ; 593261446Simp if (before_depend) 594261446Simp tp->f_flags |= BEFORE_DEPEND; 595261446Simp if (nowerror) 596261446Simp tp->f_flags |= NOWERROR; 597261446Simp tp->f_compilewith = compilewith; 598261446Simp tp->f_depends = depends; 599261446Simp tp->f_clean = clean; 600261446Simp tp->f_warn = warning; 601261446Simp tp->f_objprefix = objprefix; 602152862Sru } 603261446Simp goto next; 6041553Srgrimes} 6051553Srgrimes 606129073Scognet/* 607129073Scognet * Read in the information about files used in making the system. 608129073Scognet * Store it in the ftab linked list. 609129073Scognet */ 610129073Scognetstatic void 611129073Scognetread_files(void) 612129073Scognet{ 613129073Scognet char fname[MAXPATHLEN]; 614129073Scognet struct files_name *nl, *tnl; 615129073Scognet 616129073Scognet (void) snprintf(fname, sizeof(fname), "../../conf/files"); 617129073Scognet read_file(fname); 618129073Scognet (void) snprintf(fname, sizeof(fname), 619129073Scognet "../../conf/files.%s", machinename); 620129073Scognet read_file(fname); 621129073Scognet for (nl = STAILQ_FIRST(&fntab); nl != NULL; nl = tnl) { 622129073Scognet read_file(nl->f_name); 623129073Scognet tnl = STAILQ_NEXT(nl, f_next); 624129073Scognet free(nl->f_name); 625129073Scognet free(nl); 626129073Scognet } 627129073Scognet} 628129073Scognet 62945744Speterstatic void 63061640Speterdo_before_depend(FILE *fp) 6315325Sgibbs{ 63261640Speter struct file_list *tp; 63361640Speter int lpos, len; 6345325Sgibbs 6355325Sgibbs fputs("BEFORE_DEPEND=", fp); 6365325Sgibbs lpos = 15; 637110895Sru STAILQ_FOREACH(tp, &ftab, f_next) 6385325Sgibbs if (tp->f_flags & BEFORE_DEPEND) { 6395325Sgibbs len = strlen(tp->f_fn); 6405325Sgibbs if ((len = 3 + len) + lpos > 72) { 6415325Sgibbs lpos = 8; 6425325Sgibbs fputs("\\\n\t", fp); 6435325Sgibbs } 6445325Sgibbs if (tp->f_flags & NO_IMPLCT_RULE) 6455325Sgibbs fprintf(fp, "%s ", tp->f_fn); 6465325Sgibbs else 647336938Skevans fprintf(fp, "%s%s ", tp->f_srcprefix, 648336938Skevans tp->f_fn); 6495325Sgibbs lpos += len + 1; 6505325Sgibbs } 6515325Sgibbs if (lpos != 8) 6525325Sgibbs putc('\n', fp); 6535325Sgibbs} 6545325Sgibbs 65545744Speterstatic void 65661640Speterdo_objs(FILE *fp) 6571553Srgrimes{ 65861640Speter struct file_list *tp; 65961640Speter int lpos, len; 66061640Speter char *cp, och, *sp; 6611553Srgrimes 6621553Srgrimes fprintf(fp, "OBJS="); 6631553Srgrimes lpos = 6; 664110895Sru STAILQ_FOREACH(tp, &ftab, f_next) { 665152811Sru if (tp->f_flags & NO_OBJ) 6661553Srgrimes continue; 6671553Srgrimes sp = tail(tp->f_fn); 6681553Srgrimes cp = sp + (len = strlen(sp)) - 1; 6691553Srgrimes och = *cp; 6701553Srgrimes *cp = 'o'; 671219819Sjeff len += strlen(tp->f_objprefix); 6721553Srgrimes if (len + lpos > 72) { 6731553Srgrimes lpos = 8; 6741553Srgrimes fprintf(fp, "\\\n\t"); 6751553Srgrimes } 676219819Sjeff fprintf(fp, "%s%s ", tp->f_objprefix, sp); 6771553Srgrimes lpos += len + 1; 6781553Srgrimes *cp = och; 6791553Srgrimes } 6801553Srgrimes if (lpos != 8) 6811553Srgrimes putc('\n', fp); 6821553Srgrimes} 6831553Srgrimes 68445744Speterstatic void 68569135Speterdo_xxfiles(char *tag, FILE *fp) 6861553Srgrimes{ 68761640Speter struct file_list *tp; 68869135Speter int lpos, len, slen; 68969135Speter char *suff, *SUFF; 6901553Srgrimes 69169135Speter if (tag[strlen(tag) - 1] == '\n') 69269135Speter tag[strlen(tag) - 1] = '\0'; 69369135Speter 69469135Speter suff = ns(tag + 7); 69569135Speter SUFF = ns(suff); 69669135Speter raisestr(SUFF); 69769135Speter slen = strlen(suff); 69869135Speter 69969135Speter fprintf(fp, "%sFILES=", SUFF); 700289262Srpaulo free(SUFF); 7011553Srgrimes lpos = 8; 702110895Sru STAILQ_FOREACH(tp, &ftab, f_next) 703152811Sru if (tp->f_type != NODEPEND) { 7041553Srgrimes len = strlen(tp->f_fn); 70569135Speter if (tp->f_fn[len - slen - 1] != '.') 7061553Srgrimes continue; 70769135Speter if (strcasecmp(&tp->f_fn[len - slen], suff) != 0) 70869135Speter continue; 7091553Srgrimes if ((len = 3 + len) + lpos > 72) { 7101553Srgrimes lpos = 8; 7111553Srgrimes fputs("\\\n\t", fp); 7121553Srgrimes } 713336938Skevans fprintf(fp, "%s%s ", tp->f_srcprefix, tp->f_fn); 7141553Srgrimes lpos += len + 1; 7151553Srgrimes } 716289262Srpaulo free(suff); 7171553Srgrimes if (lpos != 8) 7181553Srgrimes putc('\n', fp); 7191553Srgrimes} 7201553Srgrimes 72145744Speterstatic char * 72261640Spetertail(char *fn) 7231553Srgrimes{ 72461640Speter char *cp; 7251553Srgrimes 726229403Sed cp = strrchr(fn, '/'); 727298687Saraujo if (cp == NULL) 7281553Srgrimes return (fn); 7291553Srgrimes return (cp+1); 7301553Srgrimes} 7311553Srgrimes 7321553Srgrimes/* 7331553Srgrimes * Create the makerules for each file 7341553Srgrimes * which is part of the system. 7351553Srgrimes */ 73645744Speterstatic void 73761640Speterdo_rules(FILE *f) 7381553Srgrimes{ 739160495Sstefanf char *cp, *np, och; 74061640Speter struct file_list *ftp; 74173199Speter char *compilewith; 742209135Simp char cmd[128]; 7431553Srgrimes 744110895Sru STAILQ_FOREACH(ftp, &ftab, f_next) { 74554490Speter if (ftp->f_warn) 746210144Simp fprintf(stderr, "WARNING: %s\n", ftp->f_warn); 7471553Srgrimes cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1; 7481553Srgrimes och = *cp; 7494571Sgibbs if (ftp->f_flags & NO_IMPLCT_RULE) { 7504571Sgibbs if (ftp->f_depends) 751219819Sjeff fprintf(f, "%s%s: %s\n", 752219819Sjeff ftp->f_objprefix, np, ftp->f_depends); 7534571Sgibbs else 754219819Sjeff fprintf(f, "%s%s: \n", ftp->f_objprefix, np); 7551553Srgrimes } 7564571Sgibbs else { 7574571Sgibbs *cp = '\0'; 7584571Sgibbs if (och == 'o') { 759336938Skevans fprintf(f, "%s%so:\n\t-cp %s%so .\n\n", 760336938Skevans ftp->f_objprefix, tail(np), 761336938Skevans ftp->f_srcprefix, np); 7624571Sgibbs continue; 7634571Sgibbs } 764116450Smarkm if (ftp->f_depends) { 765336938Skevans fprintf(f, "%s%sln: %s%s%c %s\n", 766336938Skevans ftp->f_objprefix, tail(np), 767336938Skevans ftp->f_srcprefix, np, och, 768219819Sjeff ftp->f_depends); 769116450Smarkm fprintf(f, "\t${NORMAL_LINT}\n\n"); 770336938Skevans fprintf(f, "%s%so: %s%s%c %s\n", 771336938Skevans ftp->f_objprefix, tail(np), 772336938Skevans ftp->f_srcprefix, np, och, 773219819Sjeff ftp->f_depends); 774116450Smarkm } 775116450Smarkm else { 776336938Skevans fprintf(f, "%s%sln: %s%s%c\n", 777336938Skevans ftp->f_objprefix, tail(np), 778336938Skevans ftp->f_srcprefix, np, och); 779116450Smarkm fprintf(f, "\t${NORMAL_LINT}\n\n"); 780336938Skevans fprintf(f, "%s%so: %s%s%c\n", 781336938Skevans ftp->f_objprefix, tail(np), 782336938Skevans ftp->f_srcprefix, np, och); 783116450Smarkm } 7844571Sgibbs } 78573199Speter compilewith = ftp->f_compilewith; 786298687Saraujo if (compilewith == NULL) { 78772684Speter const char *ftype = NULL; 7881553Srgrimes 7891553Srgrimes switch (ftp->f_type) { 7901553Srgrimes case NORMAL: 7911553Srgrimes ftype = "NORMAL"; 7921553Srgrimes break; 7931553Srgrimes case PROFILING: 7941553Srgrimes if (!profiling) 7951553Srgrimes continue; 7961553Srgrimes ftype = "PROFILE"; 7971553Srgrimes break; 7981553Srgrimes default: 799210144Simp fprintf(stderr, 800210144Simp "config: don't know rules for %s\n", np); 8011553Srgrimes break; 8021553Srgrimes } 803209135Simp snprintf(cmd, sizeof(cmd), 804241395Sjhb "${%s_%c%s}", ftype, 80591002Speter toupper(och), 80691002Speter ftp->f_flags & NOWERROR ? "_NOWERROR" : ""); 80773199Speter compilewith = cmd; 8081553Srgrimes } 8091553Srgrimes *cp = och; 810219819Sjeff if (strlen(ftp->f_objprefix)) 811336938Skevans fprintf(f, "\t%s %s%s\n", compilewith, 812336938Skevans ftp->f_srcprefix, np); 813219819Sjeff else 814227429Srstone fprintf(f, "\t%s\n", compilewith); 815227429Srstone 816227429Srstone if (!(ftp->f_flags & NO_OBJ)) 817228153Sfjoe fprintf(f, "\t${NORMAL_CTFCONVERT}\n\n"); 818227429Srstone else 819227429Srstone fprintf(f, "\n"); 8201553Srgrimes } 8211553Srgrimes} 8221553Srgrimes 82345744Speterstatic void 82461640Speterdo_clean(FILE *fp) 8256803Sgibbs{ 82661640Speter struct file_list *tp; 82761640Speter int lpos, len; 8286803Sgibbs 8296803Sgibbs fputs("CLEAN=", fp); 8306803Sgibbs lpos = 7; 831110895Sru STAILQ_FOREACH(tp, &ftab, f_next) 8326803Sgibbs if (tp->f_clean) { 8336803Sgibbs len = strlen(tp->f_clean); 8346803Sgibbs if (len + lpos > 72) { 8356803Sgibbs lpos = 8; 8366803Sgibbs fputs("\\\n\t", fp); 8376803Sgibbs } 8386803Sgibbs fprintf(fp, "%s ", tp->f_clean); 8396803Sgibbs lpos += len + 1; 8406803Sgibbs } 8416803Sgibbs if (lpos != 8) 8426803Sgibbs putc('\n', fp); 8436803Sgibbs} 8446803Sgibbs 8451553Srgrimeschar * 84661640Speterraisestr(char *str) 8471553Srgrimes{ 84861640Speter char *cp = str; 8491553Srgrimes 8501553Srgrimes while (*str) { 8511553Srgrimes if (islower(*str)) 8521553Srgrimes *str = toupper(*str); 8531553Srgrimes str++; 8541553Srgrimes } 8551553Srgrimes return (cp); 8561553Srgrimes} 857