11553Srgrimes/* 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$"; 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> 46269825Simp#include <stdarg.h> 471553Srgrimes#include <stdio.h> 4820458Sjoerg#include <string.h> 4969004Simp#include <sys/param.h> 5016073Sphk#include "y.tab.h" 511553Srgrimes#include "config.h" 5230638Speter#include "configvers.h" 531553Srgrimes 5461640Speterstatic char *tail(char *); 5561640Speterstatic void do_clean(FILE *); 5661640Speterstatic void do_rules(FILE *); 5769135Speterstatic void do_xxfiles(char *, FILE *); 5861640Speterstatic void do_objs(FILE *); 5961640Speterstatic void do_before_depend(FILE *); 6072684Speterstatic int opteq(const char *, const char *); 6161640Speterstatic void read_files(void); 6229451Scharnier 63269825Simpstatic void errout(const char *fmt, ...) 64269825Simp{ 65269825Simp va_list ap; 66269825Simp 67269825Simp va_start(ap, fmt); 68269825Simp vfprintf(stderr, fmt, ap); 69269825Simp va_end(ap); 70269825Simp exit(1); 71269825Simp} 72269825Simp 731553Srgrimes/* 741553Srgrimes * Lookup a file, by name. 751553Srgrimes */ 7645744Speterstatic struct file_list * 7761640Speterfl_lookup(char *file) 781553Srgrimes{ 7961640Speter struct file_list *fp; 801553Srgrimes 81110895Sru STAILQ_FOREACH(fp, &ftab, f_next) { 821553Srgrimes if (eq(fp->f_fn, file)) 831553Srgrimes return (fp); 841553Srgrimes } 851553Srgrimes return (0); 861553Srgrimes} 871553Srgrimes 881553Srgrimes/* 891553Srgrimes * Make a new file list entry 901553Srgrimes */ 9145744Speterstatic struct file_list * 9261640Speternew_fent(void) 931553Srgrimes{ 9461640Speter struct file_list *fp; 951553Srgrimes 96159362Sdelphij fp = (struct file_list *) calloc(1, sizeof *fp); 97205880Sru if (fp == NULL) 98205880Sru err(EXIT_FAILURE, "calloc"); 99110895Sru STAILQ_INSERT_TAIL(&ftab, fp, f_next); 1001553Srgrimes return (fp); 1011553Srgrimes} 1021553Srgrimes 1031553Srgrimes/* 104207260Simp * Open the correct Makefile and return it, or error out. 1051553Srgrimes */ 106207260SimpFILE * 107207260Simpopen_makefile_template(void) 1081553Srgrimes{ 109207260Simp FILE *ifp; 1101553Srgrimes char line[BUFSIZ]; 1111553Srgrimes 11255614Speter snprintf(line, sizeof(line), "../../conf/Makefile.%s", machinename); 1131553Srgrimes ifp = fopen(line, "r"); 11455614Speter if (ifp == 0) { 11555614Speter snprintf(line, sizeof(line), "Makefile.%s", machinename); 11655614Speter ifp = fopen(line, "r"); 11755614Speter } 11829451Scharnier if (ifp == 0) 11929451Scharnier err(1, "%s", line); 120207260Simp return (ifp); 121207260Simp} 12212772Speter 123207260Simp/* 124207260Simp * Build the makefile from the skeleton 125207260Simp */ 126207260Simpvoid 127207260Simpmakefile(void) 128207260Simp{ 129207260Simp FILE *ifp, *ofp; 130207260Simp char line[BUFSIZ]; 131207260Simp struct opt *op, *t; 132207260Simp 133207260Simp read_files(); 134207260Simp ifp = open_makefile_template(); 13599923Sbde ofp = fopen(path("Makefile.new"), "w"); 13699923Sbde if (ofp == 0) 13799923Sbde err(1, "%s", path("Makefile.new")); 138113951Sdes fprintf(ofp, "KERN_IDENT=%s\n", ident); 139218544Simp fprintf(ofp, "MACHINE=%s\n", machinename); 140218544Simp fprintf(ofp, "MACHINE_ARCH=%s\n", machinearch); 141185186Sthompsa SLIST_FOREACH_SAFE(op, &mkopt, op_next, t) { 142185186Sthompsa fprintf(ofp, "%s=%s", op->op_name, op->op_value); 143185186Sthompsa while ((op = SLIST_NEXT(op, op_append)) != NULL) 144185186Sthompsa fprintf(ofp, " %s", op->op_value); 145185186Sthompsa fprintf(ofp, "\n"); 146185186Sthompsa } 1471553Srgrimes if (debugging) 1481553Srgrimes fprintf(ofp, "DEBUG=-g\n"); 14999923Sbde if (profiling) 15020395Sbde fprintf(ofp, "PROFLEVEL=%d\n", profiling); 15152653Smarcel if (*srcdir != '\0') 15252653Smarcel fprintf(ofp,"S=%s\n", srcdir); 153230044Skevlo while (fgets(line, BUFSIZ, ifp) != NULL) { 1541553Srgrimes if (*line != '%') { 1551553Srgrimes fprintf(ofp, "%s", line); 1561553Srgrimes continue; 1571553Srgrimes } 1585325Sgibbs if (eq(line, "%BEFORE_DEPEND\n")) 1595325Sgibbs do_before_depend(ofp); 1605325Sgibbs else if (eq(line, "%OBJS\n")) 1611553Srgrimes do_objs(ofp); 16269135Speter else if (strncmp(line, "%FILES.", 7) == 0) 16369135Speter do_xxfiles(line, ofp); 1641553Srgrimes else if (eq(line, "%RULES\n")) 1651553Srgrimes do_rules(ofp); 1666803Sgibbs else if (eq(line, "%CLEAN\n")) 1676803Sgibbs do_clean(ofp); 168207260Simp else if (strncmp(line, "%VERSREQ=", 9) == 0) 169207260Simp line[0] = '\0'; /* handled elsewhere */ 170207260Simp else 1711553Srgrimes fprintf(stderr, 1721553Srgrimes "Unknown %% construct in generic makefile: %s", 1731553Srgrimes line); 1741553Srgrimes } 1751553Srgrimes (void) fclose(ifp); 1761553Srgrimes (void) fclose(ofp); 17713400Speter moveifchanged(path("Makefile.new"), path("Makefile")); 178153888Sru} 17934619Seivind 180153888Sru/* 181153888Sru * Build hints.c from the skeleton 182153888Sru */ 183153888Sruvoid 184153888Srumakehints(void) 185153888Sru{ 186163640Simp FILE *ifp, *ofp; 187153888Sru char line[BUFSIZ]; 188153888Sru char *s; 189163638Simp struct hint *hint; 190153888Sru 19161640Speter ofp = fopen(path("hints.c.new"), "w"); 19261640Speter if (ofp == NULL) 19361640Speter err(1, "%s", path("hints.c.new")); 19483594Speter fprintf(ofp, "#include <sys/types.h>\n"); 19583594Speter fprintf(ofp, "#include <sys/systm.h>\n"); 19683594Speter fprintf(ofp, "\n"); 19765091Speter fprintf(ofp, "int hintmode = %d;\n", hintmode); 19861640Speter fprintf(ofp, "char static_hints[] = {\n"); 199163638Simp STAILQ_FOREACH(hint, &hints, hint_next) { 200163638Simp ifp = fopen(hint->hint_name, "r"); 201163638Simp if (ifp == NULL) 202163638Simp err(1, "%s", hint->hint_name); 203230044Skevlo while (fgets(line, BUFSIZ, ifp) != NULL) { 20461640Speter /* zap trailing CR and/or LF */ 205229403Sed while ((s = strrchr(line, '\n')) != NULL) 20661640Speter *s = '\0'; 207229403Sed while ((s = strrchr(line, '\r')) != NULL) 20861640Speter *s = '\0'; 20961640Speter /* remove # comments */ 210229403Sed s = strchr(line, '#'); 21161640Speter if (s) 21261640Speter *s = '\0'; 21361640Speter /* remove any whitespace and " characters */ 21461640Speter s = line; 21561640Speter while (*s) { 21661640Speter if (*s == ' ' || *s == '\t' || *s == '"') { 21761640Speter while (*s) { 21861640Speter s[0] = s[1]; 21961640Speter s++; 22061640Speter } 22161640Speter /* start over */ 22261640Speter s = line; 22361640Speter continue; 22461640Speter } 22561640Speter s++; 22661640Speter } 22761640Speter /* anything left? */ 22861640Speter if (*line == '\0') 22961652Speter continue; 23061640Speter fprintf(ofp, "\"%s\\0\"\n", line); 23161640Speter } 232163640Simp fclose(ifp); 23361640Speter } 23461640Speter fprintf(ofp, "\"\\0\"\n};\n"); 23561640Speter fclose(ofp); 23661640Speter moveifchanged(path("hints.c.new"), path("hints.c")); 237153888Sru} 23882393Speter 239153888Sru/* 240153888Sru * Build env.c from the skeleton 241153888Sru */ 242153888Sruvoid 243153888Srumakeenv(void) 244153888Sru{ 245153888Sru FILE *ifp, *ofp; 246153888Sru char line[BUFSIZ]; 247153888Sru char *s; 248153888Sru 24982393Speter if (env) { 25082393Speter ifp = fopen(env, "r"); 25182393Speter if (ifp == NULL) 25282393Speter err(1, "%s", env); 25382393Speter } else { 25482393Speter ifp = NULL; 25582393Speter } 25682393Speter ofp = fopen(path("env.c.new"), "w"); 25782393Speter if (ofp == NULL) 25882393Speter err(1, "%s", path("env.c.new")); 25983594Speter fprintf(ofp, "#include <sys/types.h>\n"); 26083594Speter fprintf(ofp, "#include <sys/systm.h>\n"); 26183594Speter fprintf(ofp, "\n"); 26282393Speter fprintf(ofp, "int envmode = %d;\n", envmode); 26382393Speter fprintf(ofp, "char static_env[] = {\n"); 26482393Speter if (ifp) { 265230044Skevlo while (fgets(line, BUFSIZ, ifp) != NULL) { 26682393Speter /* zap trailing CR and/or LF */ 267229403Sed while ((s = strrchr(line, '\n')) != NULL) 26882393Speter *s = '\0'; 269229403Sed while ((s = strrchr(line, '\r')) != NULL) 27082393Speter *s = '\0'; 27182393Speter /* remove # comments */ 272229403Sed s = strchr(line, '#'); 27382393Speter if (s) 27482393Speter *s = '\0'; 27582393Speter /* remove any whitespace and " characters */ 27682393Speter s = line; 27782393Speter while (*s) { 27882393Speter if (*s == ' ' || *s == '\t' || *s == '"') { 27982393Speter while (*s) { 28082393Speter s[0] = s[1]; 28182393Speter s++; 28282393Speter } 28382393Speter /* start over */ 28482393Speter s = line; 28582393Speter continue; 28682393Speter } 28782393Speter s++; 28882393Speter } 28982393Speter /* anything left? */ 29082393Speter if (*line == '\0') 29182393Speter continue; 29282393Speter fprintf(ofp, "\"%s\\0\"\n", line); 29382393Speter } 29482393Speter } 29582393Speter fprintf(ofp, "\"\\0\"\n};\n"); 29682393Speter if (ifp) 29782393Speter fclose(ifp); 29882393Speter fclose(ofp); 29982393Speter moveifchanged(path("env.c.new"), path("env.c")); 3001553Srgrimes} 3011553Srgrimes 302129119Scognetstatic void 303129073Scognetread_file(char *fname) 3041553Srgrimes{ 305162936Sru char ifname[MAXPATHLEN]; 3061553Srgrimes FILE *fp; 307152811Sru struct file_list *tp; 30861640Speter struct device *dp; 30961640Speter struct opt *op; 310152811Sru char *wd, *this, *compilewith, *depends, *clean, *warning; 311219819Sjeff const char *objprefix; 312269825Simp int compile, match, nreqs, std, filetype, not, 313269825Simp imp_rule, no_obj, before_depend, nowerror; 3141553Srgrimes 3151553Srgrimes fp = fopen(fname, "r"); 31629451Scharnier if (fp == 0) 31729451Scharnier err(1, "%s", fname); 3181553Srgrimesnext: 3191553Srgrimes /* 320162936Sru * include "filename" 321269825Simp * filename [ standard | optional ] 322152862Sru * [ dev* [ | dev* ... ] | profiling-routine ] [ no-obj ] 3238857Srgrimes * [ compile-with "compile rule" [no-implicit-rule] ] 3246803Sgibbs * [ dependency "dependency-list"] [ before-depend ] 32554490Speter * [ clean "file-list"] [ warning "text warning" ] 326219819Sjeff * [ obj-prefix "file prefix"] 3271553Srgrimes */ 3281553Srgrimes wd = get_word(fp); 3291553Srgrimes if (wd == (char *)EOF) { 3301553Srgrimes (void) fclose(fp); 3311553Srgrimes return; 332129073Scognet } 3331553Srgrimes if (wd == 0) 3341553Srgrimes goto next; 33552098Speter if (wd[0] == '#') 3361566Srgrimes { 33752098Speter while (((wd = get_word(fp)) != (char *)EOF) && wd) 33852098Speter ; 3391566Srgrimes goto next; 3401566Srgrimes } 341162936Sru if (eq(wd, "include")) { 342269825Simp wd = get_quoted_word(fp); 343269825Simp if (wd == (char *)EOF || wd == 0) 344269825Simp errout("%s: missing include filename.\n", fname); 345162936Sru (void) snprintf(ifname, sizeof(ifname), "../../%s", wd); 346162936Sru read_file(ifname); 347162936Sru while (((wd = get_word(fp)) != (char *)EOF) && wd) 348162936Sru ; 349162936Sru goto next; 350162936Sru } 3511553Srgrimes this = ns(wd); 352269825Simp wd = get_word(fp); 353269825Simp if (wd == (char *)EOF) 354269825Simp return; 355269825Simp if (wd == 0) 356269825Simp errout("%s: No type for %s.\n", fname, this); 357152811Sru tp = fl_lookup(this); 358152862Sru compile = 0; 359152862Sru match = 1; 3601553Srgrimes nreqs = 0; 36173199Speter compilewith = 0; 3624571Sgibbs depends = 0; 3636803Sgibbs clean = 0; 36472684Speter warning = 0; 365269825Simp std = 0; 3664571Sgibbs imp_rule = 0; 3674571Sgibbs no_obj = 0; 3685325Sgibbs before_depend = 0; 36991002Speter nowerror = 0; 370269825Simp not = 0; 3711553Srgrimes filetype = NORMAL; 372219819Sjeff objprefix = ""; 373269825Simp if (eq(wd, "standard")) 3741553Srgrimes std = 1; 375269825Simp else if (!eq(wd, "optional")) 376269825Simp errout("%s: \"%s\" %s must be optional or standard\n", 377214654Sobrien fname, wd, this); 378269825Simp for (wd = get_word(fp); wd; wd = get_word(fp)) { 379269825Simp if (wd == (char *)EOF) 380269825Simp return; 381269825Simp if (eq(wd, "!")) { 382269825Simp not = 1; 383269825Simp continue; 384152862Sru } 385269825Simp if (eq(wd, "|")) { 386269825Simp if (nreqs == 0) 387269825Simp errout("%s: syntax error describing %s\n", 388269825Simp fname, this); 389269825Simp if (not) 390269825Simp compile += !match; 391269825Simp else 392269825Simp compile += match; 393269825Simp match = 1; 394269825Simp nreqs = 0; 395269825Simp not = 0; 396269825Simp continue; 3974571Sgibbs } 398269825Simp if (eq(wd, "no-obj")) { 399269825Simp no_obj++; 400269825Simp continue; 4014571Sgibbs } 402269825Simp if (eq(wd, "no-implicit-rule")) { 403269825Simp if (compilewith == 0) 404269825Simp errout("%s: alternate rule required when " 405269825Simp "\"no-implicit-rule\" is specified for" 406269825Simp " %s.\n", 407269825Simp fname, this); 408269825Simp imp_rule++; 409269825Simp continue; 4105325Sgibbs } 411269825Simp if (eq(wd, "before-depend")) { 412269825Simp before_depend++; 413269825Simp continue; 4141553Srgrimes } 415269825Simp if (eq(wd, "dependency")) { 416269825Simp wd = get_quoted_word(fp); 417269825Simp if (wd == (char *)EOF || wd == 0) 418269825Simp errout("%s: %s missing dependency string.\n", 419269825Simp fname, this); 420269825Simp depends = ns(wd); 421269825Simp continue; 42254490Speter } 423269825Simp if (eq(wd, "clean")) { 424269825Simp wd = get_quoted_word(fp); 425269825Simp if (wd == (char *)EOF || wd == 0) 426269825Simp errout("%s: %s missing clean file list.\n", 427269825Simp fname, this); 428269825Simp clean = ns(wd); 429269825Simp continue; 430219819Sjeff } 431269825Simp if (eq(wd, "compile-with")) { 432269825Simp wd = get_quoted_word(fp); 433269825Simp if (wd == (char *)EOF || wd == 0) 434269825Simp errout("%s: %s missing compile command string.\n", 435269825Simp fname, this); 436269825Simp compilewith = ns(wd); 437269825Simp continue; 438152811Sru } 439269825Simp if (eq(wd, "warning")) { 440269825Simp wd = get_quoted_word(fp); 441269825Simp if (wd == (char *)EOF || wd == 0) 442269825Simp errout("%s: %s missing warning text string.\n", 443269825Simp fname, this); 444269825Simp warning = ns(wd); 445269825Simp continue; 446269825Simp } 447269825Simp if (eq(wd, "obj-prefix")) { 448269825Simp wd = get_quoted_word(fp); 449269825Simp if (wd == (char *)EOF || wd == 0) 450269825Simp errout("%s: %s missing object prefix string.\n", 451269825Simp fname, this); 452269825Simp objprefix = ns(wd); 453269825Simp continue; 454269825Simp } 455269825Simp if (eq(wd, "nowerror")) { 456269825Simp nowerror = 1; 457269825Simp continue; 458269825Simp } 459269825Simp if (eq(wd, "local")) { 460269825Simp filetype = LOCAL; 461269825Simp continue; 462269825Simp } 463269825Simp if (eq(wd, "no-depend")) { 464269825Simp filetype = NODEPEND; 465269825Simp continue; 466269825Simp } 467269825Simp nreqs++; 468269825Simp if (eq(wd, "profiling-routine")) { 469269825Simp filetype = PROFILING; 470269825Simp continue; 471269825Simp } 472269825Simp if (std) 473269825Simp errout("standard entry %s has optional inclusion specifier %s!\n", 474269825Simp this, wd); 475269825Simp STAILQ_FOREACH(dp, &dtab, d_next) 476269825Simp if (eq(dp->d_name, wd)) { 477269825Simp dp->d_done |= DEVDONE; 478269825Simp goto nextparam; 479269825Simp } 480269825Simp SLIST_FOREACH(op, &opt, op_next) 481269825Simp if (op->op_value == 0 && opteq(op->op_name, wd)) 482269825Simp goto nextparam; 483269825Simp match = 0; 484269825Simpnextparam:; 48530796Sjoerg } 486269825Simp if (not) 487269825Simp compile += !match; 488269825Simp else 489269825Simp compile += match; 490269825Simp if (compile && tp == NULL) { 491269825Simp if (std == 0 && nreqs == 0) 492269825Simp errout("%s: what is %s optional on?\n", 493269825Simp fname, this); 494269825Simp if (filetype == PROFILING && profiling == 0) 495269825Simp goto next; 496269825Simp tp = new_fent(); 497269825Simp tp->f_fn = this; 498269825Simp tp->f_type = filetype; 499269825Simp if (imp_rule) 500269825Simp tp->f_flags |= NO_IMPLCT_RULE; 501269825Simp if (no_obj) 502269825Simp tp->f_flags |= NO_OBJ; 503269825Simp if (before_depend) 504269825Simp tp->f_flags |= BEFORE_DEPEND; 505269825Simp if (nowerror) 506269825Simp tp->f_flags |= NOWERROR; 507269825Simp tp->f_compilewith = compilewith; 508269825Simp tp->f_depends = depends; 509269825Simp tp->f_clean = clean; 510269825Simp tp->f_warn = warning; 511269825Simp tp->f_objprefix = objprefix; 5121553Srgrimes } 5131553Srgrimes goto next; 5141553Srgrimes} 5151553Srgrimes 516129073Scognet/* 517129073Scognet * Read in the information about files used in making the system. 518129073Scognet * Store it in the ftab linked list. 519129073Scognet */ 520129073Scognetstatic void 521129073Scognetread_files(void) 522129073Scognet{ 523129073Scognet char fname[MAXPATHLEN]; 524129073Scognet struct files_name *nl, *tnl; 525129073Scognet 526129073Scognet (void) snprintf(fname, sizeof(fname), "../../conf/files"); 527129073Scognet read_file(fname); 528129073Scognet (void) snprintf(fname, sizeof(fname), 529129073Scognet "../../conf/files.%s", machinename); 530129073Scognet read_file(fname); 531129073Scognet for (nl = STAILQ_FIRST(&fntab); nl != NULL; nl = tnl) { 532129073Scognet read_file(nl->f_name); 533129073Scognet tnl = STAILQ_NEXT(nl, f_next); 534129073Scognet free(nl->f_name); 535129073Scognet free(nl); 536129073Scognet } 537129073Scognet} 538129073Scognet 53945744Speterstatic int 54072684Speteropteq(const char *cp, const char *dp) 5411553Srgrimes{ 5421553Srgrimes char c, d; 5431553Srgrimes 5441553Srgrimes for (; ; cp++, dp++) { 5451553Srgrimes if (*cp != *dp) { 5461553Srgrimes c = isupper(*cp) ? tolower(*cp) : *cp; 5471553Srgrimes d = isupper(*dp) ? tolower(*dp) : *dp; 5481553Srgrimes if (c != d) 5491553Srgrimes return (0); 5501553Srgrimes } 5511553Srgrimes if (*cp == 0) 5521553Srgrimes return (1); 5531553Srgrimes } 5541553Srgrimes} 5551553Srgrimes 55645744Speterstatic void 55761640Speterdo_before_depend(FILE *fp) 5585325Sgibbs{ 55961640Speter struct file_list *tp; 56061640Speter int lpos, len; 5615325Sgibbs 5625325Sgibbs fputs("BEFORE_DEPEND=", fp); 5635325Sgibbs lpos = 15; 564110895Sru STAILQ_FOREACH(tp, &ftab, f_next) 5655325Sgibbs if (tp->f_flags & BEFORE_DEPEND) { 5665325Sgibbs len = strlen(tp->f_fn); 5675325Sgibbs if ((len = 3 + len) + lpos > 72) { 5685325Sgibbs lpos = 8; 5695325Sgibbs fputs("\\\n\t", fp); 5705325Sgibbs } 5715325Sgibbs if (tp->f_flags & NO_IMPLCT_RULE) 5725325Sgibbs fprintf(fp, "%s ", tp->f_fn); 5735325Sgibbs else 5745325Sgibbs fprintf(fp, "$S/%s ", tp->f_fn); 5755325Sgibbs lpos += len + 1; 5765325Sgibbs } 5775325Sgibbs if (lpos != 8) 5785325Sgibbs putc('\n', fp); 5795325Sgibbs} 5805325Sgibbs 58145744Speterstatic void 58261640Speterdo_objs(FILE *fp) 5831553Srgrimes{ 58461640Speter struct file_list *tp; 58561640Speter int lpos, len; 58661640Speter char *cp, och, *sp; 5871553Srgrimes 5881553Srgrimes fprintf(fp, "OBJS="); 5891553Srgrimes lpos = 6; 590110895Sru STAILQ_FOREACH(tp, &ftab, f_next) { 591152811Sru if (tp->f_flags & NO_OBJ) 5921553Srgrimes continue; 5931553Srgrimes sp = tail(tp->f_fn); 5941553Srgrimes cp = sp + (len = strlen(sp)) - 1; 5951553Srgrimes och = *cp; 5961553Srgrimes *cp = 'o'; 597219819Sjeff len += strlen(tp->f_objprefix); 5981553Srgrimes if (len + lpos > 72) { 5991553Srgrimes lpos = 8; 6001553Srgrimes fprintf(fp, "\\\n\t"); 6011553Srgrimes } 602219819Sjeff fprintf(fp, "%s%s ", tp->f_objprefix, sp); 6031553Srgrimes lpos += len + 1; 6041553Srgrimes *cp = och; 6051553Srgrimes } 6061553Srgrimes if (lpos != 8) 6071553Srgrimes putc('\n', fp); 6081553Srgrimes} 6091553Srgrimes 61045744Speterstatic void 61169135Speterdo_xxfiles(char *tag, FILE *fp) 6121553Srgrimes{ 61361640Speter struct file_list *tp; 61469135Speter int lpos, len, slen; 61569135Speter char *suff, *SUFF; 6161553Srgrimes 61769135Speter if (tag[strlen(tag) - 1] == '\n') 61869135Speter tag[strlen(tag) - 1] = '\0'; 61969135Speter 62069135Speter suff = ns(tag + 7); 62169135Speter SUFF = ns(suff); 62269135Speter raisestr(SUFF); 62369135Speter slen = strlen(suff); 62469135Speter 62569135Speter fprintf(fp, "%sFILES=", SUFF); 6261553Srgrimes lpos = 8; 627110895Sru STAILQ_FOREACH(tp, &ftab, f_next) 628152811Sru if (tp->f_type != NODEPEND) { 6291553Srgrimes len = strlen(tp->f_fn); 63069135Speter if (tp->f_fn[len - slen - 1] != '.') 6311553Srgrimes continue; 63269135Speter if (strcasecmp(&tp->f_fn[len - slen], suff) != 0) 63369135Speter continue; 6341553Srgrimes if ((len = 3 + len) + lpos > 72) { 6351553Srgrimes lpos = 8; 6361553Srgrimes fputs("\\\n\t", fp); 6371553Srgrimes } 63838782Snsouch if (tp->f_type != LOCAL) 63938782Snsouch fprintf(fp, "$S/%s ", tp->f_fn); 64038782Snsouch else 64138782Snsouch fprintf(fp, "%s ", tp->f_fn); 6421553Srgrimes lpos += len + 1; 6431553Srgrimes } 6441553Srgrimes if (lpos != 8) 6451553Srgrimes putc('\n', fp); 6461553Srgrimes} 6471553Srgrimes 64845744Speterstatic char * 64961640Spetertail(char *fn) 6501553Srgrimes{ 65161640Speter char *cp; 6521553Srgrimes 653229403Sed cp = strrchr(fn, '/'); 6541553Srgrimes if (cp == 0) 6551553Srgrimes return (fn); 6561553Srgrimes return (cp+1); 6571553Srgrimes} 6581553Srgrimes 6591553Srgrimes/* 6601553Srgrimes * Create the makerules for each file 6611553Srgrimes * which is part of the system. 6621553Srgrimes */ 66345744Speterstatic void 66461640Speterdo_rules(FILE *f) 6651553Srgrimes{ 666160495Sstefanf char *cp, *np, och; 66761640Speter struct file_list *ftp; 66873199Speter char *compilewith; 669209135Simp char cmd[128]; 6701553Srgrimes 671110895Sru STAILQ_FOREACH(ftp, &ftab, f_next) { 67254490Speter if (ftp->f_warn) 673210144Simp fprintf(stderr, "WARNING: %s\n", ftp->f_warn); 6741553Srgrimes cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1; 6751553Srgrimes och = *cp; 6764571Sgibbs if (ftp->f_flags & NO_IMPLCT_RULE) { 6774571Sgibbs if (ftp->f_depends) 678219819Sjeff fprintf(f, "%s%s: %s\n", 679219819Sjeff ftp->f_objprefix, np, ftp->f_depends); 6804571Sgibbs else 681219819Sjeff fprintf(f, "%s%s: \n", ftp->f_objprefix, np); 6821553Srgrimes } 6834571Sgibbs else { 6844571Sgibbs *cp = '\0'; 6854571Sgibbs if (och == 'o') { 686219819Sjeff fprintf(f, "%s%so:\n\t-cp $S/%so .\n\n", 687219819Sjeff ftp->f_objprefix, tail(np), np); 6884571Sgibbs continue; 6894571Sgibbs } 690116450Smarkm if (ftp->f_depends) { 691219819Sjeff fprintf(f, "%s%sln: $S/%s%c %s\n", 692219819Sjeff ftp->f_objprefix, tail(np), np, och, 693219819Sjeff ftp->f_depends); 694116450Smarkm fprintf(f, "\t${NORMAL_LINT}\n\n"); 695219819Sjeff fprintf(f, "%s%so: $S/%s%c %s\n", 696219819Sjeff ftp->f_objprefix, tail(np), np, och, 697219819Sjeff ftp->f_depends); 698116450Smarkm } 699116450Smarkm else { 700219819Sjeff fprintf(f, "%s%sln: $S/%s%c\n", 701219819Sjeff ftp->f_objprefix, tail(np), np, och); 702116450Smarkm fprintf(f, "\t${NORMAL_LINT}\n\n"); 703219819Sjeff fprintf(f, "%s%so: $S/%s%c\n", 704219819Sjeff ftp->f_objprefix, tail(np), np, och); 705116450Smarkm } 7064571Sgibbs } 70773199Speter compilewith = ftp->f_compilewith; 70873199Speter if (compilewith == 0) { 70972684Speter const char *ftype = NULL; 7101553Srgrimes 7111553Srgrimes switch (ftp->f_type) { 7121553Srgrimes case NORMAL: 7131553Srgrimes ftype = "NORMAL"; 7141553Srgrimes break; 7151553Srgrimes case PROFILING: 7161553Srgrimes if (!profiling) 7171553Srgrimes continue; 7181553Srgrimes ftype = "PROFILE"; 7191553Srgrimes break; 7201553Srgrimes default: 721210144Simp fprintf(stderr, 722210144Simp "config: don't know rules for %s\n", np); 7231553Srgrimes break; 7241553Srgrimes } 725209135Simp snprintf(cmd, sizeof(cmd), 726241395Sjhb "${%s_%c%s}", ftype, 72791002Speter toupper(och), 72891002Speter ftp->f_flags & NOWERROR ? "_NOWERROR" : ""); 72973199Speter compilewith = cmd; 7301553Srgrimes } 7311553Srgrimes *cp = och; 732219819Sjeff if (strlen(ftp->f_objprefix)) 733227429Srstone fprintf(f, "\t%s $S/%s\n", compilewith, np); 734219819Sjeff else 735227429Srstone fprintf(f, "\t%s\n", compilewith); 736227429Srstone 737227429Srstone if (!(ftp->f_flags & NO_OBJ)) 738228153Sfjoe fprintf(f, "\t${NORMAL_CTFCONVERT}\n\n"); 739227429Srstone else 740227429Srstone fprintf(f, "\n"); 7411553Srgrimes } 7421553Srgrimes} 7431553Srgrimes 74445744Speterstatic void 74561640Speterdo_clean(FILE *fp) 7466803Sgibbs{ 74761640Speter struct file_list *tp; 74861640Speter int lpos, len; 7496803Sgibbs 7506803Sgibbs fputs("CLEAN=", fp); 7516803Sgibbs lpos = 7; 752110895Sru STAILQ_FOREACH(tp, &ftab, f_next) 7536803Sgibbs if (tp->f_clean) { 7546803Sgibbs len = strlen(tp->f_clean); 7556803Sgibbs if (len + lpos > 72) { 7566803Sgibbs lpos = 8; 7576803Sgibbs fputs("\\\n\t", fp); 7586803Sgibbs } 7596803Sgibbs fprintf(fp, "%s ", tp->f_clean); 7606803Sgibbs lpos += len + 1; 7616803Sgibbs } 7626803Sgibbs if (lpos != 8) 7636803Sgibbs putc('\n', fp); 7646803Sgibbs} 7656803Sgibbs 7661553Srgrimeschar * 76761640Speterraisestr(char *str) 7681553Srgrimes{ 76961640Speter char *cp = str; 7701553Srgrimes 7711553Srgrimes while (*str) { 7721553Srgrimes if (islower(*str)) 7731553Srgrimes *str = toupper(*str); 7741553Srgrimes str++; 7751553Srgrimes } 7761553Srgrimes return (cp); 7771553Srgrimes} 778