1/* 2 * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights 7 * Reserved. This file contains Original Code and/or Modifications of 8 * Original Code as defined in and that are subject to the Apple Public 9 * Source License Version 1.0 (the 'License'). You may not use this file 10 * except in compliance with the License. Please obtain a copy of the 11 * License at http://www.apple.com/publicsource and read it before using 12 * this file. 13 * 14 * The Original Code and all software distributed under the License are 15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 19 * License for the specific language governing rights and limitations 20 * under the License." 21 * 22 * @APPLE_LICENSE_HEADER_END@ 23 */ 24/* 25 * Mach Operating System 26 * Copyright (c) 1990 Carnegie-Mellon University 27 * Copyright (c) 1989 Carnegie-Mellon University 28 * Copyright (c) 1988 Carnegie-Mellon University 29 * Copyright (c) 1987 Carnegie-Mellon University 30 * All rights reserved. The CMU software License Agreement specifies 31 * the terms and conditions for use and redistribution. 32 */ 33 34/* 35 * Copyright (c) 1980 Regents of the University of California. 36 * All rights reserved. 37 * 38 * Redistribution and use in source and binary forms are permitted 39 * provided that the above copyright notice and this paragraph are 40 * duplicated in all such forms and that any documentation, 41 * advertising materials, and other materials related to such 42 * distribution and use acknowledge that the software was developed 43 * by the University of California, Berkeley. The name of the 44 * University may not be used to endorse or promote products derived 45 * from this software without specific prior written permission. 46 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 47 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 48 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 49 */ 50 51#ifndef lint 52static char sccsid[] __attribute__((used)) = "@(#)mkheaders.c 5.5 (Berkeley) 6/18/88"; 53#endif /* not lint */ 54 55/* 56 * Make all the .h files for the optional entries 57 */ 58 59#include <stdio.h> 60#include <unistd.h> /* unlink */ 61#include <ctype.h> 62#include "config.h" 63#include "parser.h" 64 65static void do_count(const char *dev, const char *hname, int search); 66static void do_header(const char *dev, const char *hname, int count); 67static int file_needed(const char *name); 68static char *toheader(const char *dev); 69static char *tomacro(const char *dev); 70 71void 72headers(void) 73{ 74 struct file_list *fl; 75 76 for (fl = ftab; fl != 0; fl = fl->f_next) 77 if (fl->f_needs != 0) 78 do_count(fl->f_needs, fl->f_needs, 1); 79} 80 81/* 82 * count all the devices of a certain type and recurse to count 83 * whatever the device is connected to 84 */ 85void 86do_count(const char *dev, const char *hname, int search) 87{ 88 struct device *dp, *mp; 89 int count; 90 91 for (count = 0,dp = dtab; dp != 0; dp = dp->d_next) 92 if (dp->d_unit != -1 && eq(dp->d_name, dev)) { 93 /* 94 * Avoid making .h files for bus types on sun machines 95 */ 96 if ((machine == MACHINE_SUN2 || 97 machine == MACHINE_SUN3 || 98 machine == MACHINE_SUN4) 99 && dp->d_conn == TO_NEXUS){ 100 return; 101 } 102 if (dp->d_type == PSEUDO_DEVICE) { 103 count = 104 dp->d_slave != UNKNOWN ? dp->d_slave : 1; 105 if (dp->d_flags) 106 dev = NULL; 107 break; 108 } 109 if (machine != MACHINE_SUN2 && machine != MACHINE_SUN3 110 && machine != MACHINE_SUN4) 111 /* avoid ie0,ie0,ie1 setting NIE to 3 */ 112 count++; 113 /* 114 * Allow holes in unit numbering, 115 * assumption is unit numbering starts 116 * at zero. 117 */ 118 if (dp->d_unit + 1 > count) 119 count = dp->d_unit + 1; 120 if (search) { 121 mp = dp->d_conn; 122 if (mp != 0 && mp != TO_NEXUS && 123 mp->d_conn != TO_NEXUS) { 124 /* 125 * Check for the case of the 126 * controller that the device 127 * is attached to is in a separate 128 * file (e.g. "sd" and "sc"). 129 * In this case, do NOT define 130 * the number of controllers 131 * in the hname .h file. 132 */ 133 if (!file_needed(mp->d_name)) 134 do_count(mp->d_name, hname, 0); 135 search = 0; 136 } 137 } 138 } 139 do_header(dev, hname, count); 140} 141 142/* 143 * Scan the file list to see if name is needed to bring in a file. 144 */ 145static int 146file_needed(const char *name) 147{ 148 struct file_list *fl; 149 150 for (fl = ftab; fl != 0; fl = fl->f_next) { 151 if (fl->f_needs && strcmp(fl->f_needs, name) == 0) 152 return (1); 153 } 154 return (0); 155} 156 157static void 158do_header(const char *dev, const char *hname, int count) 159{ 160 char *file, *name; 161 const char *inw; 162 char *inwcopy; 163 struct file_list *fl = NULL; /* may exit for(;;) uninitted */ 164 struct file_list *fl_head, *fl_prev; 165 FILE *inf, *outf; 166 int inc, oldcount; 167 168 file = toheader(hname); 169 name = tomacro(dev?dev:hname) + (dev == NULL); 170 inf = fopen(file, "r"); 171 oldcount = -1; 172 if (inf == 0) { 173 (void) unlink(file); 174 outf = fopen(file, "w"); 175 if (outf == 0) { 176 perror(file); 177 exit(1); 178 } 179 fprintf(outf, "#define %s %d\n", name, count); 180 (void) fclose(outf); 181 file = path("meta_features.h"); 182 outf = fopen(file, "a"); 183 if (outf == 0) { 184 perror(file); 185 exit(1); 186 } 187 fprintf(outf, "#include <%s.h>\n", hname); 188 (void) fclose(outf); 189 return; 190 } 191 fl_head = 0; 192 for (;;) { 193 const char *cp; 194 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 195 break; 196 if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) 197 break; 198 inwcopy = ns(inw); 199 cp = get_word(inf); 200 if (cp == 0 || cp == (char *)EOF) 201 break; 202 inc = atoi(cp); 203 if (eq(inwcopy, name)) { 204 oldcount = inc; 205 inc = count; 206 } 207 cp = get_word(inf); 208 if (cp == (char *)EOF) 209 break; 210 fl = (struct file_list *) malloc(sizeof *fl); 211 fl->f_fn = inwcopy; 212 fl->f_type = inc; 213 fl->f_next = fl_head; 214 fl_head = fl; 215 } 216 (void) fclose(inf); 217 if (count == oldcount) { 218 while (fl !=0) { 219 fl_prev = fl; 220 fl = fl->f_next; 221 free((char *)fl_prev); 222 } 223 return; 224 } 225 if (oldcount == -1) { 226 fl = (struct file_list *) malloc(sizeof *fl); 227 fl->f_fn = name; 228 fl->f_type = count; 229 fl->f_next = fl_head; 230 fl_head = fl; 231 } 232 unlink(file); 233 outf = fopen(file, "w"); 234 if (outf == 0) { 235 perror(file); 236 exit(1); 237 } 238 for (fl = fl_head; fl != 0; fl = fl->f_next) { 239 fprintf(outf, "#define %s %d\n", 240 fl->f_fn, count ? fl->f_type : 0); 241 free((char *)fl); 242 } 243 (void) fclose(outf); 244} 245 246/* 247 * convert a dev name to a .h file name 248 */ 249static char * 250toheader(const char *dev) 251{ 252 static char hbuf[MAXPATHLEN]; 253 (void) snprintf(hbuf, sizeof hbuf, "%s.h", path(dev)); 254 hbuf[MAXPATHLEN-1] = '\0'; 255 return (hbuf); 256} 257 258/* 259 * convert a dev name to a macro name 260 */ 261static char * 262tomacro(const char *dev) 263{ 264 static char mbuf[FILENAME_MAX]; 265 char *cp; 266 267 cp = mbuf; 268 *cp++ = 'N'; 269 while (*dev) 270 if (!islower(*dev)) 271 *cp++ = *dev++; 272 else 273 *cp++ = toupper(*dev++); 274 *cp++ = 0; 275 return (mbuf); 276} 277