]> git.saurik.com Git - apple/boot.git/blob - i386/util/sig.c
boot-111.tar.gz
[apple/boot.git] / i386 / util / sig.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * Copyright 1993 NeXT Computer, Inc.
27 * All rights reserved.
28 */
29
30 /*
31 * Standalone Interface Generator
32 *
33 * Input file format: a series of lines of the form:
34 *
35 * #<text>
36 * or
37 * <function declaration> <arg list> ;
38 *
39 * e.g.:
40 * void *malloc(int len) len;
41 *
42 * Lines starting with '#' are passed through unchanged.
43 * Lines starting with '/' are ignored.
44 *
45 *
46 */
47
48 #import <stdio.h>
49 #import <ctype.h>
50 #import <string.h>
51 #import <stdlib.h>
52 #import <sys/param.h>
53
54 #define MAXLINE 65535
55 typedef enum {NO=0, YES=1} BOOL;
56 #define strdup(str) ((char *)strcpy(malloc(strlen(str)+1),str))
57 extern int getopt();
58
59 enum {
60 none,
61 external,
62 internal,
63 table,
64 defs
65 } which;
66 char *osuffix[] = {
67 "none",
68 "_external.h",
69 "_internal.h",
70 "_table.c",
71 "_defs.h"
72 };
73
74 FILE *ofile;
75 int lineNumber, outputNumber;
76 char *moduleName;
77 char *moduleNameCaps;
78
79 char *stringToLower(char *string)
80 {
81 char *new = strdup(string);
82 char *p = new;
83
84 while (*p)
85 *p = tolower(*p++);
86 return new;
87 }
88
89 char *stringToUpper(char *string)
90 {
91 char *new = strdup(string);
92 char *p = new;
93
94 while (*p)
95 *p = toupper(*p++);
96 return new;
97 }
98
99 inline BOOL
100 isIdentifier(char c)
101 {
102 if (isalnum(c) || c == '_')
103 return YES;
104 else
105 return NO;
106 }
107
108 void
109 outputLine(char *decl, char *function, char *args, char *arglist)
110 {
111 if (which == table) {
112 static int struct_started;
113 if (struct_started == 0) {
114 fprintf(ofile, "unsigned long (*%s_functions[])() = {\n",
115 moduleName);
116 struct_started = 1;
117 }
118 fprintf(ofile, "(unsigned long (*)())_%s,\t\t/* %d */\n", function, outputNumber);
119 }
120
121 if (which == defs) {
122 fprintf(ofile, "#define %s _%s\n",function,function);
123 }
124
125 if (which == internal) {
126 fprintf(ofile, "extern %s _%s(%s);\n", decl, function, args);
127 }
128
129 if (which == external) {
130 fprintf(ofile, "#define %s_%s_FN %d\n",
131 moduleNameCaps, function, outputNumber);
132 fprintf(ofile,
133 "static inline %s %s ( %s ) {\n", decl, function, args);
134 fprintf(ofile,
135 "\treturn (%s)(*%s_FN[%d])(%s);\n",
136 decl, moduleNameCaps, outputNumber, arglist);
137 fprintf(ofile, "}\n");
138 }
139 outputNumber++;
140 }
141
142 void
143 parseLine(char *line)
144 {
145 char *paren, *parenEnd;
146 char *ident, *identEnd;
147 char *arglist, *arglistEnd;
148 char *function;
149
150 paren = strchr(line, '(');
151 if (paren == NULL)
152 goto syntax_error;
153 for (identEnd = paren - 1; !isIdentifier(*identEnd); identEnd--)
154 continue;
155 for (ident = identEnd; isIdentifier(*ident); ident--)
156 continue;
157 ident++;
158 *++identEnd = '\0';
159 paren++;
160 parenEnd = strchr(paren, ')');
161 if (parenEnd == NULL)
162 goto syntax_error;
163 *parenEnd = '\0';
164
165 arglist = parenEnd + 1;
166 while (isspace(*arglist))
167 arglist++;
168 arglistEnd = strchr(arglist, ';');
169 if (arglistEnd == NULL)
170 goto syntax_error;
171 *arglistEnd = '\0';
172
173 function = strdup(ident);
174 *ident = '\0';
175 outputLine(line, function, paren, arglist);
176 free(function);
177 return;
178
179 syntax_error:
180 fprintf(stderr, "Syntax error at line %d\n",lineNumber);
181 return;
182 }
183
184 int
185 getLineThru(FILE *file, char *linebuf, char stop, int len)
186 {
187 char *p = linebuf;
188 int c, gotten;
189
190 gotten = 0;
191 while (((c = fgetc(file)) != EOF) && len) {
192 *p++ = c;
193 len--;
194 gotten++;
195 if (c == '\n') lineNumber++;
196 if (c == stop)
197 break;
198 }
199 *p = '\0';
200 return gotten;
201 }
202
203 int
204 peekf(FILE *file)
205 {
206 int c = fgetc(file);
207 ungetc(c, file);
208 return c;
209 }
210
211 void
212 skipWhitespace(FILE *file)
213 {
214 int c;
215
216 while ((c = fgetc(file)) != EOF && isspace(c))
217 if (c == '\n') ++lineNumber;
218 ungetc(c, file);
219 }
220
221 void
222 parseFile(FILE *file)
223 {
224 char *line, c;
225 int len, lineNumber;
226
227 line = malloc(MAXLINE+1);
228 lineNumber = 1;
229
230 skipWhitespace(file);
231
232 while (!feof(file)) {
233 c = peekf(file);
234 if (c == '#' || c == '/') {
235 len = getLineThru(file, line, '\n', MAXLINE);
236 if (c == '#')
237 fprintf(ofile, line);
238 } else {
239 len = getLineThru(file, line, ';', MAXLINE);
240 parseLine(line);
241 }
242 skipWhitespace(file);
243 }
244 free(line);
245 }
246
247 int
248 main(int argc, char **argv)
249 {
250 extern char *optarg;
251 extern int optind;
252 FILE *file;
253 int c, errflag = 0;
254 char ofilename[MAXPATHLEN];
255 char *ifile, *odir = ".";
256
257 while ((c = getopt(argc, argv, "d:n:")) != EOF)
258 switch (c) {
259 case 'd':
260 odir = optarg;
261 break;
262 case 'n':
263 moduleName = optarg;
264 moduleNameCaps = stringToUpper(moduleName);
265 break;
266 default:
267 errflag++;
268 break;
269 }
270
271 ofile = stdout;
272 if ((ifile = argv[optind]) != NULL) {
273 file = fopen(argv[optind], "r");
274 if (file == NULL) {
275 perror("open");
276 exit(1);
277 }
278 } else {
279 fprintf(stderr,"No input file specified\n");
280 exit(2);
281 }
282
283 if (moduleName == NULL) {
284 char *newName, *dot;
285 int len;
286 newName = strchr(ifile, '/');
287 if (newName == NULL)
288 newName = ifile;
289 dot = strchr(newName, '.');
290 if (dot == NULL)
291 dot = &newName[strlen(newName)];
292 len = dot - newName;
293 moduleName = (char *)malloc(len + 1);
294 strncpy(moduleName, newName, len);
295 moduleName[len] = '\0';
296 moduleNameCaps = stringToUpper(moduleName);
297 }
298
299 for (which = external; which <= defs; which++) {
300 rewind(file);
301 lineNumber = 1;
302 outputNumber = 0;
303 sprintf(ofilename, "%s/%s%s", odir, moduleName, osuffix[which]);
304 ofile = fopen((const char *)ofilename, "w");
305 if (ofile == NULL) {
306 fprintf(stderr,"error opening output file %s\n",ofilename);
307 exit(3);
308 }
309
310 if (which == table) {
311 fprintf(ofile, "#define %s_TABLE 1\n", moduleNameCaps);
312 fprintf(ofile, "#import \"%s_internal.h\"\n",moduleName);
313 }
314
315 if (which == internal) {
316 fprintf(ofile, "#define %s_INTERNAL 1\n", moduleNameCaps);
317 }
318
319 if (which == defs) {
320 fprintf(ofile, "#define %s_DEFS 1\n", moduleNameCaps);
321 }
322
323 if (which == external) {
324 fprintf(ofile, "#import \"memory.h\"\n");
325 fprintf(ofile, "#define %s_EXTERNAL 1\n", moduleNameCaps);
326 fprintf(ofile,
327 "#define %s_FN (*(unsigned long (***)())%s_TABLE_POINTER)\n\n",
328 moduleNameCaps, moduleNameCaps);
329 }
330 parseFile(file);
331
332 if (which == table) {
333 fprintf(ofile, "};\n\n");
334 }
335 }
336 return 0;
337 }