mkmakefile.c revision 336938
1/* 2 * Copyright (c) 1980, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#ifndef lint 31#if 0 32static char sccsid[] = "@(#)mkmakefile.c 8.1 (Berkeley) 6/6/93"; 33#endif 34static const char rcsid[] = 35 "$FreeBSD: stable/11/usr.sbin/config/mkmakefile.c 336938 2018-07-30 21:24:27Z kevans $"; 36#endif /* not lint */ 37 38/* 39 * Build the makefile for the system, from 40 * the information in the files files and the 41 * additional files for the machine being compiled to. 42 */ 43 44#include <ctype.h> 45#include <err.h> 46#include <stdarg.h> 47#include <stdbool.h> 48#include <stdio.h> 49#include <string.h> 50#include <sys/param.h> 51#include "y.tab.h" 52#include "config.h" 53#include "configvers.h" 54 55static char *tail(char *); 56static void do_clean(FILE *); 57static void do_rules(FILE *); 58static void do_xxfiles(char *, FILE *); 59static void do_objs(FILE *); 60static void do_before_depend(FILE *); 61static int opteq(const char *, const char *); 62static void read_files(void); 63 64static void errout(const char *fmt, ...) 65{ 66 va_list ap; 67 68 va_start(ap, fmt); 69 vfprintf(stderr, fmt, ap); 70 va_end(ap); 71 exit(1); 72} 73 74/* 75 * Lookup a file, by name. 76 */ 77static struct file_list * 78fl_lookup(char *file) 79{ 80 struct file_list *fp; 81 82 STAILQ_FOREACH(fp, &ftab, f_next) { 83 if (eq(fp->f_fn, file)) 84 return (fp); 85 } 86 return (0); 87} 88 89/* 90 * Make a new file list entry 91 */ 92static struct file_list * 93new_fent(void) 94{ 95 struct file_list *fp; 96 97 fp = (struct file_list *) calloc(1, sizeof *fp); 98 if (fp == NULL) 99 err(EXIT_FAILURE, "calloc"); 100 STAILQ_INSERT_TAIL(&ftab, fp, f_next); 101 return (fp); 102} 103 104/* 105 * Open the correct Makefile and return it, or error out. 106 */ 107FILE * 108open_makefile_template(void) 109{ 110 FILE *ifp; 111 char line[BUFSIZ]; 112 113 snprintf(line, sizeof(line), "../../conf/Makefile.%s", machinename); 114 ifp = fopen(line, "r"); 115 if (ifp == NULL) { 116 snprintf(line, sizeof(line), "Makefile.%s", machinename); 117 ifp = fopen(line, "r"); 118 } 119 if (ifp == NULL) 120 err(1, "%s", line); 121 return (ifp); 122} 123 124/* 125 * Build the makefile from the skeleton 126 */ 127void 128makefile(void) 129{ 130 FILE *ifp, *ofp; 131 char line[BUFSIZ]; 132 struct opt *op, *t; 133 134 read_files(); 135 ifp = open_makefile_template(); 136 ofp = fopen(path("Makefile.new"), "w"); 137 if (ofp == NULL) 138 err(1, "%s", path("Makefile.new")); 139 fprintf(ofp, "KERN_IDENT=%s\n", ident); 140 fprintf(ofp, "MACHINE=%s\n", machinename); 141 fprintf(ofp, "MACHINE_ARCH=%s\n", machinearch); 142 SLIST_FOREACH_SAFE(op, &mkopt, op_next, t) { 143 fprintf(ofp, "%s=%s", op->op_name, op->op_value); 144 while ((op = SLIST_NEXT(op, op_append)) != NULL) 145 fprintf(ofp, " %s", op->op_value); 146 fprintf(ofp, "\n"); 147 } 148 if (debugging) 149 fprintf(ofp, "DEBUG=-g\n"); 150 if (profiling) 151 fprintf(ofp, "PROFLEVEL=%d\n", profiling); 152 if (*srcdir != '\0') 153 fprintf(ofp,"S=%s\n", srcdir); 154 while (fgets(line, BUFSIZ, ifp) != NULL) { 155 if (*line != '%') { 156 fprintf(ofp, "%s", line); 157 continue; 158 } 159 if (eq(line, "%BEFORE_DEPEND\n")) 160 do_before_depend(ofp); 161 else if (eq(line, "%OBJS\n")) 162 do_objs(ofp); 163 else if (strncmp(line, "%FILES.", 7) == 0) 164 do_xxfiles(line, ofp); 165 else if (eq(line, "%RULES\n")) 166 do_rules(ofp); 167 else if (eq(line, "%CLEAN\n")) 168 do_clean(ofp); 169 else if (strncmp(line, "%VERSREQ=", 9) == 0) 170 line[0] = '\0'; /* handled elsewhere */ 171 else 172 fprintf(stderr, 173 "Unknown %% construct in generic makefile: %s", 174 line); 175 } 176 (void) fclose(ifp); 177 (void) fclose(ofp); 178 moveifchanged(path("Makefile.new"), path("Makefile")); 179} 180 181/* 182 * Build hints.c from the skeleton 183 */ 184void 185makehints(void) 186{ 187 FILE *ifp, *ofp; 188 char line[BUFSIZ]; 189 char *s; 190 struct hint *hint; 191 192 ofp = fopen(path("hints.c.new"), "w"); 193 if (ofp == NULL) 194 err(1, "%s", path("hints.c.new")); 195 fprintf(ofp, "#include <sys/types.h>\n"); 196 fprintf(ofp, "#include <sys/systm.h>\n"); 197 fprintf(ofp, "\n"); 198 fprintf(ofp, "int hintmode = %d;\n", hintmode); 199 fprintf(ofp, "char static_hints[] = {\n"); 200 STAILQ_FOREACH(hint, &hints, hint_next) { 201 ifp = fopen(hint->hint_name, "r"); 202 if (ifp == NULL) 203 err(1, "%s", hint->hint_name); 204 while (fgets(line, BUFSIZ, ifp) != NULL) { 205 /* zap trailing CR and/or LF */ 206 while ((s = strrchr(line, '\n')) != NULL) 207 *s = '\0'; 208 while ((s = strrchr(line, '\r')) != NULL) 209 *s = '\0'; 210 /* remove # comments */ 211 s = strchr(line, '#'); 212 if (s) 213 *s = '\0'; 214 /* remove any whitespace and " characters */ 215 s = line; 216 while (*s) { 217 if (*s == ' ' || *s == '\t' || *s == '"') { 218 while (*s) { 219 s[0] = s[1]; 220 s++; 221 } 222 /* start over */ 223 s = line; 224 continue; 225 } 226 s++; 227 } 228 /* anything left? */ 229 if (*line == '\0') 230 continue; 231 fprintf(ofp, "\"%s\\0\"\n", line); 232 } 233 fclose(ifp); 234 } 235 fprintf(ofp, "\"\\0\"\n};\n"); 236 fclose(ofp); 237 moveifchanged(path("hints.c.new"), path("hints.c")); 238} 239 240static void 241sanitize_envline(char *result, const char *src) 242{ 243 const char *eq; 244 char c, *dst; 245 bool leading; 246 247 /* If there is no '=' it's not a well-formed name=value line. */ 248 if ((eq = strchr(src, '=')) == NULL) { 249 *result = 0; 250 return; 251 } 252 dst = result; 253 254 /* Copy chars before the '=', skipping any leading spaces/quotes. */ 255 leading = true; 256 while (src < eq) { 257 c = *src++; 258 if (leading && (isspace(c) || c == '"')) 259 continue; 260 *dst++ = c; 261 leading = false; 262 } 263 264 /* If it was all leading space, we don't have a well-formed line. */ 265 if (leading) { 266 *result = 0; 267 return; 268 } 269 270 /* Trim spaces/quotes immediately before the '=', then copy the '='. */ 271 while (isspace(dst[-1]) || dst[-1] == '"') 272 --dst; 273 *dst++ = *src++; 274 275 /* Copy chars after the '=', skipping any leading whitespace. */ 276 leading = true; 277 while ((c = *src++) != 0) { 278 if (leading && (isspace(c) || c == '"')) 279 continue; 280 *dst++ = c; 281 leading = false; 282 } 283 284 /* If it was all leading space, it's a valid 'var=' (nil value). */ 285 if (leading) { 286 *dst = 0; 287 return; 288 } 289 290 /* Trim trailing whitespace and quotes. */ 291 while (isspace(dst[-1]) || dst[-1] == '"') 292 --dst; 293 294 *dst = 0; 295} 296 297/* 298 * Build env.c from the skeleton 299 */ 300void 301makeenv(void) 302{ 303 FILE *ifp, *ofp; 304 char line[BUFSIZ], result[BUFSIZ], *linep; 305 struct envvar *envvar; 306 307 ofp = fopen(path("env.c.new"), "w"); 308 if (ofp == NULL) 309 err(1, "%s", path("env.c.new")); 310 fprintf(ofp, "#include <sys/types.h>\n"); 311 fprintf(ofp, "#include <sys/systm.h>\n"); 312 fprintf(ofp, "\n"); 313 fprintf(ofp, "int envmode = %d;\n", envmode); 314 fprintf(ofp, "char static_env[] = {\n"); 315 STAILQ_FOREACH(envvar, &envvars, envvar_next) { 316 if (envvar->env_is_file) { 317 ifp = fopen(envvar->env_str, "r"); 318 if (ifp == NULL) 319 err(1, "%s", envvar->env_str); 320 while (fgets(line, BUFSIZ, ifp) != NULL) { 321 sanitize_envline(result, line); 322 /* anything left? */ 323 if (*result == '\0') 324 continue; 325 fprintf(ofp, "\"%s\\0\"\n", result); 326 } 327 fclose(ifp); 328 } else { 329 linep = envvar->env_str; 330 sanitize_envline(result, linep); 331 if (*result == '\0') 332 continue; 333 fprintf(ofp, "\"%s\\0\"\n", result); 334 } 335 } 336 fprintf(ofp, "\"\\0\"\n};\n"); 337 fclose(ofp); 338 moveifchanged(path("env.c.new"), path("env.c")); 339} 340 341static void 342read_file(char *fname) 343{ 344 char ifname[MAXPATHLEN]; 345 FILE *fp; 346 struct file_list *tp; 347 struct device *dp; 348 struct opt *op; 349 char *wd, *this, *compilewith, *depends, *clean, *warning; 350 const char *objprefix; 351 int compile, match, nreqs, std, filetype, not, 352 imp_rule, no_obj, before_depend, nowerror; 353 354 fp = fopen(fname, "r"); 355 if (fp == NULL) 356 err(1, "%s", fname); 357next: 358 /* 359 * include "filename" 360 * filename [ standard | optional ] 361 * [ dev* [ | dev* ... ] | profiling-routine ] [ no-obj ] 362 * [ compile-with "compile rule" [no-implicit-rule] ] 363 * [ dependency "dependency-list"] [ before-depend ] 364 * [ clean "file-list"] [ warning "text warning" ] 365 * [ obj-prefix "file prefix"] 366 */ 367 wd = get_word(fp); 368 if (wd == (char *)EOF) { 369 (void) fclose(fp); 370 return; 371 } 372 if (wd == NULL) 373 goto next; 374 if (wd[0] == '#') 375 { 376 while (((wd = get_word(fp)) != (char *)EOF) && wd) 377 ; 378 goto next; 379 } 380 if (eq(wd, "include")) { 381 wd = get_quoted_word(fp); 382 if (wd == (char *)EOF || wd == NULL) 383 errout("%s: missing include filename.\n", fname); 384 (void) snprintf(ifname, sizeof(ifname), "../../%s", wd); 385 read_file(ifname); 386 while (((wd = get_word(fp)) != (char *)EOF) && wd) 387 ; 388 goto next; 389 } 390 this = ns(wd); 391 wd = get_word(fp); 392 if (wd == (char *)EOF) 393 return; 394 if (wd == NULL) 395 errout("%s: No type for %s.\n", fname, this); 396 tp = fl_lookup(this); 397 compile = 0; 398 match = 1; 399 nreqs = 0; 400 compilewith = 0; 401 depends = 0; 402 clean = 0; 403 warning = 0; 404 std = 0; 405 imp_rule = 0; 406 no_obj = 0; 407 before_depend = 0; 408 nowerror = 0; 409 not = 0; 410 filetype = NORMAL; 411 objprefix = ""; 412 if (eq(wd, "standard")) 413 std = 1; 414 else if (!eq(wd, "optional")) 415 errout("%s: \"%s\" %s must be optional or standard\n", 416 fname, wd, this); 417 for (wd = get_word(fp); wd; wd = get_word(fp)) { 418 if (wd == (char *)EOF) 419 return; 420 if (eq(wd, "!")) { 421 not = 1; 422 continue; 423 } 424 if (eq(wd, "|")) { 425 if (nreqs == 0) 426 errout("%s: syntax error describing %s\n", 427 fname, this); 428 compile += match; 429 match = 1; 430 nreqs = 0; 431 continue; 432 } 433 if (eq(wd, "no-obj")) { 434 no_obj++; 435 continue; 436 } 437 if (eq(wd, "no-implicit-rule")) { 438 if (compilewith == NULL) 439 errout("%s: alternate rule required when " 440 "\"no-implicit-rule\" is specified for" 441 " %s.\n", 442 fname, this); 443 imp_rule++; 444 continue; 445 } 446 if (eq(wd, "before-depend")) { 447 before_depend++; 448 continue; 449 } 450 if (eq(wd, "dependency")) { 451 wd = get_quoted_word(fp); 452 if (wd == (char *)EOF || wd == NULL) 453 errout("%s: %s missing dependency string.\n", 454 fname, this); 455 depends = ns(wd); 456 continue; 457 } 458 if (eq(wd, "clean")) { 459 wd = get_quoted_word(fp); 460 if (wd == (char *)EOF || wd == NULL) 461 errout("%s: %s missing clean file list.\n", 462 fname, this); 463 clean = ns(wd); 464 continue; 465 } 466 if (eq(wd, "compile-with")) { 467 wd = get_quoted_word(fp); 468 if (wd == (char *)EOF || wd == NULL) 469 errout("%s: %s missing compile command string.\n", 470 fname, this); 471 compilewith = ns(wd); 472 continue; 473 } 474 if (eq(wd, "warning")) { 475 wd = get_quoted_word(fp); 476 if (wd == (char *)EOF || wd == NULL) 477 errout("%s: %s missing warning text string.\n", 478 fname, this); 479 warning = ns(wd); 480 continue; 481 } 482 if (eq(wd, "obj-prefix")) { 483 wd = get_quoted_word(fp); 484 if (wd == (char *)EOF || wd == NULL) 485 errout("%s: %s missing object prefix string.\n", 486 fname, this); 487 objprefix = ns(wd); 488 continue; 489 } 490 if (eq(wd, "nowerror")) { 491 nowerror = 1; 492 continue; 493 } 494 if (eq(wd, "local")) { 495 filetype = LOCAL; 496 continue; 497 } 498 if (eq(wd, "no-depend")) { 499 filetype = NODEPEND; 500 continue; 501 } 502 nreqs++; 503 if (eq(wd, "profiling-routine")) { 504 filetype = PROFILING; 505 continue; 506 } 507 if (std) 508 errout("standard entry %s has optional inclusion specifier %s!\n", 509 this, wd); 510 STAILQ_FOREACH(dp, &dtab, d_next) 511 if (eq(dp->d_name, wd)) { 512 if (not) 513 match = 0; 514 else 515 dp->d_done |= DEVDONE; 516 goto nextparam; 517 } 518 SLIST_FOREACH(op, &opt, op_next) 519 if (op->op_value == 0 && opteq(op->op_name, wd)) { 520 if (not) 521 match = 0; 522 goto nextparam; 523 } 524 match &= not; 525nextparam:; 526 not = 0; 527 } 528 compile += match; 529 if (compile && tp == NULL) { 530 if (std == 0 && nreqs == 0) 531 errout("%s: what is %s optional on?\n", 532 fname, this); 533 if (filetype == PROFILING && profiling == 0) 534 goto next; 535 tp = new_fent(); 536 tp->f_fn = this; 537 tp->f_type = filetype; 538 if (filetype == LOCAL) 539 tp->f_srcprefix = ""; 540 else 541 tp->f_srcprefix = "$S/"; 542 if (imp_rule) 543 tp->f_flags |= NO_IMPLCT_RULE; 544 if (no_obj) 545 tp->f_flags |= NO_OBJ; 546 if (before_depend) 547 tp->f_flags |= BEFORE_DEPEND; 548 if (nowerror) 549 tp->f_flags |= NOWERROR; 550 tp->f_compilewith = compilewith; 551 tp->f_depends = depends; 552 tp->f_clean = clean; 553 tp->f_warn = warning; 554 tp->f_objprefix = objprefix; 555 } 556 goto next; 557} 558 559/* 560 * Read in the information about files used in making the system. 561 * Store it in the ftab linked list. 562 */ 563static void 564read_files(void) 565{ 566 char fname[MAXPATHLEN]; 567 struct files_name *nl, *tnl; 568 569 (void) snprintf(fname, sizeof(fname), "../../conf/files"); 570 read_file(fname); 571 (void) snprintf(fname, sizeof(fname), 572 "../../conf/files.%s", machinename); 573 read_file(fname); 574 for (nl = STAILQ_FIRST(&fntab); nl != NULL; nl = tnl) { 575 read_file(nl->f_name); 576 tnl = STAILQ_NEXT(nl, f_next); 577 free(nl->f_name); 578 free(nl); 579 } 580} 581 582static int 583opteq(const char *cp, const char *dp) 584{ 585 char c, d; 586 587 for (; ; cp++, dp++) { 588 if (*cp != *dp) { 589 c = isupper(*cp) ? tolower(*cp) : *cp; 590 d = isupper(*dp) ? tolower(*dp) : *dp; 591 if (c != d) 592 return (0); 593 } 594 if (*cp == 0) 595 return (1); 596 } 597} 598 599static void 600do_before_depend(FILE *fp) 601{ 602 struct file_list *tp; 603 int lpos, len; 604 605 fputs("BEFORE_DEPEND=", fp); 606 lpos = 15; 607 STAILQ_FOREACH(tp, &ftab, f_next) 608 if (tp->f_flags & BEFORE_DEPEND) { 609 len = strlen(tp->f_fn); 610 if ((len = 3 + len) + lpos > 72) { 611 lpos = 8; 612 fputs("\\\n\t", fp); 613 } 614 if (tp->f_flags & NO_IMPLCT_RULE) 615 fprintf(fp, "%s ", tp->f_fn); 616 else 617 fprintf(fp, "%s%s ", tp->f_srcprefix, 618 tp->f_fn); 619 lpos += len + 1; 620 } 621 if (lpos != 8) 622 putc('\n', fp); 623} 624 625static void 626do_objs(FILE *fp) 627{ 628 struct file_list *tp; 629 int lpos, len; 630 char *cp, och, *sp; 631 632 fprintf(fp, "OBJS="); 633 lpos = 6; 634 STAILQ_FOREACH(tp, &ftab, f_next) { 635 if (tp->f_flags & NO_OBJ) 636 continue; 637 sp = tail(tp->f_fn); 638 cp = sp + (len = strlen(sp)) - 1; 639 och = *cp; 640 *cp = 'o'; 641 len += strlen(tp->f_objprefix); 642 if (len + lpos > 72) { 643 lpos = 8; 644 fprintf(fp, "\\\n\t"); 645 } 646 fprintf(fp, "%s%s ", tp->f_objprefix, sp); 647 lpos += len + 1; 648 *cp = och; 649 } 650 if (lpos != 8) 651 putc('\n', fp); 652} 653 654static void 655do_xxfiles(char *tag, FILE *fp) 656{ 657 struct file_list *tp; 658 int lpos, len, slen; 659 char *suff, *SUFF; 660 661 if (tag[strlen(tag) - 1] == '\n') 662 tag[strlen(tag) - 1] = '\0'; 663 664 suff = ns(tag + 7); 665 SUFF = ns(suff); 666 raisestr(SUFF); 667 slen = strlen(suff); 668 669 fprintf(fp, "%sFILES=", SUFF); 670 free(SUFF); 671 lpos = 8; 672 STAILQ_FOREACH(tp, &ftab, f_next) 673 if (tp->f_type != NODEPEND) { 674 len = strlen(tp->f_fn); 675 if (tp->f_fn[len - slen - 1] != '.') 676 continue; 677 if (strcasecmp(&tp->f_fn[len - slen], suff) != 0) 678 continue; 679 if ((len = 3 + len) + lpos > 72) { 680 lpos = 8; 681 fputs("\\\n\t", fp); 682 } 683 fprintf(fp, "%s%s ", tp->f_srcprefix, tp->f_fn); 684 lpos += len + 1; 685 } 686 free(suff); 687 if (lpos != 8) 688 putc('\n', fp); 689} 690 691static char * 692tail(char *fn) 693{ 694 char *cp; 695 696 cp = strrchr(fn, '/'); 697 if (cp == NULL) 698 return (fn); 699 return (cp+1); 700} 701 702/* 703 * Create the makerules for each file 704 * which is part of the system. 705 */ 706static void 707do_rules(FILE *f) 708{ 709 char *cp, *np, och; 710 struct file_list *ftp; 711 char *compilewith; 712 char cmd[128]; 713 714 STAILQ_FOREACH(ftp, &ftab, f_next) { 715 if (ftp->f_warn) 716 fprintf(stderr, "WARNING: %s\n", ftp->f_warn); 717 cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1; 718 och = *cp; 719 if (ftp->f_flags & NO_IMPLCT_RULE) { 720 if (ftp->f_depends) 721 fprintf(f, "%s%s: %s\n", 722 ftp->f_objprefix, np, ftp->f_depends); 723 else 724 fprintf(f, "%s%s: \n", ftp->f_objprefix, np); 725 } 726 else { 727 *cp = '\0'; 728 if (och == 'o') { 729 fprintf(f, "%s%so:\n\t-cp %s%so .\n\n", 730 ftp->f_objprefix, tail(np), 731 ftp->f_srcprefix, np); 732 continue; 733 } 734 if (ftp->f_depends) { 735 fprintf(f, "%s%sln: %s%s%c %s\n", 736 ftp->f_objprefix, tail(np), 737 ftp->f_srcprefix, np, och, 738 ftp->f_depends); 739 fprintf(f, "\t${NORMAL_LINT}\n\n"); 740 fprintf(f, "%s%so: %s%s%c %s\n", 741 ftp->f_objprefix, tail(np), 742 ftp->f_srcprefix, np, och, 743 ftp->f_depends); 744 } 745 else { 746 fprintf(f, "%s%sln: %s%s%c\n", 747 ftp->f_objprefix, tail(np), 748 ftp->f_srcprefix, np, och); 749 fprintf(f, "\t${NORMAL_LINT}\n\n"); 750 fprintf(f, "%s%so: %s%s%c\n", 751 ftp->f_objprefix, tail(np), 752 ftp->f_srcprefix, np, och); 753 } 754 } 755 compilewith = ftp->f_compilewith; 756 if (compilewith == NULL) { 757 const char *ftype = NULL; 758 759 switch (ftp->f_type) { 760 case NORMAL: 761 ftype = "NORMAL"; 762 break; 763 case PROFILING: 764 if (!profiling) 765 continue; 766 ftype = "PROFILE"; 767 break; 768 default: 769 fprintf(stderr, 770 "config: don't know rules for %s\n", np); 771 break; 772 } 773 snprintf(cmd, sizeof(cmd), 774 "${%s_%c%s}", ftype, 775 toupper(och), 776 ftp->f_flags & NOWERROR ? "_NOWERROR" : ""); 777 compilewith = cmd; 778 } 779 *cp = och; 780 if (strlen(ftp->f_objprefix)) 781 fprintf(f, "\t%s %s%s\n", compilewith, 782 ftp->f_srcprefix, np); 783 else 784 fprintf(f, "\t%s\n", compilewith); 785 786 if (!(ftp->f_flags & NO_OBJ)) 787 fprintf(f, "\t${NORMAL_CTFCONVERT}\n\n"); 788 else 789 fprintf(f, "\n"); 790 } 791} 792 793static void 794do_clean(FILE *fp) 795{ 796 struct file_list *tp; 797 int lpos, len; 798 799 fputs("CLEAN=", fp); 800 lpos = 7; 801 STAILQ_FOREACH(tp, &ftab, f_next) 802 if (tp->f_clean) { 803 len = strlen(tp->f_clean); 804 if (len + lpos > 72) { 805 lpos = 8; 806 fputs("\\\n\t", fp); 807 } 808 fprintf(fp, "%s ", tp->f_clean); 809 lpos += len + 1; 810 } 811 if (lpos != 8) 812 putc('\n', fp); 813} 814 815char * 816raisestr(char *str) 817{ 818 char *cp = str; 819 820 while (*str) { 821 if (islower(*str)) 822 *str = toupper(*str); 823 str++; 824 } 825 return (cp); 826} 827