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