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