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