]> git.saurik.com Git - apple/boot.git/blame - i386/util/sig.c
boot-111.tar.gz
[apple/boot.git] / i386 / util / sig.c
CommitLineData
14c7c974
A
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
f083c6c3
A
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.
14c7c974
A
14 *
15 * The Original Code and all software distributed under the License are
f083c6c3 16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14c7c974
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
f083c6c3
A
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.
14c7c974
A
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
55typedef enum {NO=0, YES=1} BOOL;
56#define strdup(str) ((char *)strcpy(malloc(strlen(str)+1),str))
57extern int getopt();
58
59enum {
60 none,
61 external,
62 internal,
63 table,
64 defs
65} which;
66char *osuffix[] = {
67 "none",
68 "_external.h",
69 "_internal.h",
70 "_table.c",
71 "_defs.h"
72};
73
74FILE *ofile;
75int lineNumber, outputNumber;
76char *moduleName;
77char *moduleNameCaps;
78
79char *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
89char *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
99inline BOOL
100isIdentifier(char c)
101{
102 if (isalnum(c) || c == '_')
103 return YES;
104 else
105 return NO;
106}
107
108void
109outputLine(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
142void
143parseLine(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
179syntax_error:
180 fprintf(stderr, "Syntax error at line %d\n",lineNumber);
181 return;
182}
183
184int
185getLineThru(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
203int
204peekf(FILE *file)
205{
206 int c = fgetc(file);
207 ungetc(c, file);
208 return c;
209}
210
211void
212skipWhitespace(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
221void
222parseFile(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
247int
248main(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}