mkheaders.c revision 61523
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 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint 35#if 0 36static char sccsid[] = "@(#)mkheaders.c 8.1 (Berkeley) 6/6/93"; 37#endif 38static const char rcsid[] = 39 "$FreeBSD: head/usr.sbin/config/mkheaders.c 61523 2000-06-10 22:13:40Z peter $"; 40#endif /* not lint */ 41 42/* 43 * Make all the .h files for the optional entries 44 */ 45 46#include <ctype.h> 47#include <err.h> 48#include <stdio.h> 49#include <string.h> 50#include "config.h" 51#include "y.tab.h" 52 53static void do_header __P((char *, int)); 54static void do_count __P((char *)); 55static char *toheader __P((char *)); 56static char *tomacro __P((char *)); 57 58void 59headers() 60{ 61 register struct file_list *fl; 62 struct device *dp; 63 64 for (fl = ftab; fl != 0; fl = fl->f_next) { 65 if (fl->f_needs != 0) { 66 for (dp = dtab; dp != 0; dp = dp->d_next) { 67 if (eq(dp->d_name, fl->f_needs)) { 68 if ((dp->d_type & TYPEMASK) == PSEUDO_DEVICE) 69 dp->d_type |= DEVDONE; 70 else if ((dp->d_type & TYPEMASK) == DEVICE) 71 dp->d_type |= DEVDONE; 72 } 73 } 74 if (fl->f_flags & NEED_COUNT) 75 do_count(fl->f_needs); 76 } 77 } 78 for (dp = dtab; dp != 0; dp = dp->d_next) { 79 if ((dp->d_type & TYPEMASK) == PSEUDO_DEVICE) { 80 if (!(dp->d_type & DEVDONE)) 81 printf("Warning: pseudo-device \"%s\" is unknown\n", 82 dp->d_name); 83 } 84 if ((dp->d_type & TYPEMASK) == DEVICE) { 85 if (!(dp->d_type & DEVDONE)) 86 printf("Warning: device \"%s\" is unknown\n", 87 dp->d_name); 88 } 89 } 90} 91 92/* 93 * count all the devices of a certain type and recurse to count 94 * whatever the device is connected to 95 */ 96static void 97do_count(dev) 98 register char *dev; 99{ 100 register struct device *dp; 101 register int count, hicount; 102 103 /* 104 * After this loop, "count" will be the actual number of units, 105 * and "hicount" will be the highest unit declared. do_header() 106 * must use this higher of these values. 107 */ 108 for (hicount = count = 0, dp = dtab; dp != 0; dp = dp->d_next) { 109 if (dp->d_unit != -1 && eq(dp->d_name, dev)) { 110 if ((dp->d_type & TYPEMASK) == PSEUDO_DEVICE) { 111 count = 112 dp->d_count != UNKNOWN ? dp->d_count : 1; 113 break; 114 } 115 count++; 116 /* 117 * Allow holes in unit numbering, 118 * assumption is unit numbering starts 119 * at zero. 120 */ 121 if (dp->d_unit + 1 > hicount) 122 hicount = dp->d_unit + 1; 123 } 124 } 125 do_header(dev, count > hicount ? count : hicount); 126} 127 128static void 129do_header(dev, count) 130 char *dev; 131 int count; 132{ 133 char *file, *name, *inw; 134 struct file_list *fl, *fl_head, *tflp; 135 FILE *inf, *outf; 136 int inc, oldcount; 137 138 file = toheader(dev); 139 name = tomacro(dev); 140 inf = fopen(file, "r"); 141 oldcount = -1; 142 if (inf == 0) { 143 outf = fopen(file, "w"); 144 if (outf == 0) 145 err(1, "%s", file); 146 fprintf(outf, "#define %s %d\n", name, count); 147 (void) fclose(outf); 148 return; 149 } 150 fl_head = NULL; 151 for (;;) { 152 char *cp; 153 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 154 break; 155 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 156 break; 157 inw = ns(inw); 158 cp = get_word(inf); 159 if (cp == 0 || cp == (char *)EOF) 160 break; 161 inc = atoi(cp); 162 if (eq(inw, name)) { 163 oldcount = inc; 164 inc = count; 165 } 166 cp = get_word(inf); 167 if (cp == (char *)EOF) 168 break; 169 fl = (struct file_list *) malloc(sizeof *fl); 170 bzero(fl, sizeof(*fl)); 171 fl->f_fn = inw; /* malloced */ 172 fl->f_type = inc; 173 fl->f_next = fl_head; 174 fl_head = fl; 175 } 176 (void) fclose(inf); 177 if (count == oldcount) { 178 for (fl = fl_head; fl != NULL; fl = tflp) { 179 tflp = fl->f_next; 180 free(fl->f_fn); 181 free(fl); 182 } 183 return; 184 } 185 if (oldcount == -1) { 186 fl = (struct file_list *) malloc(sizeof *fl); 187 bzero(fl, sizeof(*fl)); 188 fl->f_fn = ns(name); 189 fl->f_type = count; 190 fl->f_next = fl_head; 191 fl_head = fl; 192 } 193 outf = fopen(file, "w"); 194 if (outf == 0) 195 err(1, "%s", file); 196 for (fl = fl_head; fl != NULL; fl = tflp) { 197 fprintf(outf, 198 "#define %s %u\n", fl->f_fn, count ? fl->f_type : 0); 199 tflp = fl->f_next; 200 free(fl->f_fn); 201 free(fl); 202 } 203 (void) fclose(outf); 204} 205 206/* 207 * convert a dev name to a .h file name 208 */ 209static char * 210toheader(dev) 211 char *dev; 212{ 213 static char hbuf[80]; 214 215 (void) strcpy(hbuf, path(dev)); 216 (void) strcat(hbuf, ".h"); 217 return (hbuf); 218} 219 220/* 221 * convert a dev name to a macro name 222 */ 223static char * 224tomacro(dev) 225 register char *dev; 226{ 227 static char mbuf[20]; 228 register char *cp; 229 230 cp = mbuf; 231 *cp++ = 'N'; 232 while (*dev) 233 *cp++ = islower(*dev) ? toupper(*dev++) : *dev++; 234 *cp++ = 0; 235 return (mbuf); 236} 237