]> git.cameronkatri.com Git - apple_cmds.git/blob - bootstrap_cmds/migcom.tproj/mig.c
bootstrap_cmds: Patches all working
[apple_cmds.git] / bootstrap_cmds / migcom.tproj / mig.c
1 /*
2 * Copyright (c) 1999-2018 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*
24 * Mach Operating System
25 * Copyright (c) 1991,1990 Carnegie Mellon University
26 * All Rights Reserved.
27 *
28 * Permission to use, copy, modify and distribute this software and its
29 * documentation is hereby granted, provided that both the copyright
30 * notice and this permission notice appear in all copies of the
31 * software, derivative works or modified versions, and any portions
32 * thereof, and that both notices appear in supporting documentation.
33 *
34 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
35 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
36 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
37 *
38 * Carnegie Mellon requests users of this software to return to
39 *
40 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
41 * School of Computer Science
42 * Carnegie Mellon University
43 * Pittsburgh PA 15213-3890
44 *
45 * any improvements or extensions that they make and grant Carnegie the
46 * rights to redistribute these changes.
47 */
48
49 /*
50 * Switches are;
51 * -[v,Q] verbose or not quiet: prints out type
52 * and routine information as mig runs.
53 * -[V,q] not verbose or quiet : don't print
54 * information during compilation
55 * (this is the default)
56 * -[r,R] do or don't use rpc calls instead of
57 * send/receive pairs. Default is -r.
58 * -[s,S] generate symbol table or not: generate a
59 * table of rpc-name, number, routine triplets
60 * as an external data structure -- main use is
61 * for protection system's specification of rights
62 * and for protection dispatch code. Default is -s.
63 * -[l,L] -L generate code that insert code for logging
64 * the most important events that happen at the
65 * stub level (message conception, target routine
66 * calls). Default is -l.
67 * -[k,K] -K enforces MIG to generate K&R C language, with the
68 * addition of ANSI C syntax under #ifdef __STDC__.
69 * Default is -k.
70 * -[n,N] -n enforces NDR checking and conversion logic generation.
71 * Default is -N (no checking).
72 * -i <prefix>
73 * Put each user routine in its own file. The
74 * file is named <prefix><routine-name>.c.
75 * -user <name>
76 * Name the user-side file <name>
77 * -server <name>
78 * Name the server-side file <name>
79 * -header <name>
80 * Name the user-side header file <name>
81 * -iheader <name>
82 * Name the user-side internal header file <name>
83 * -sheader <name>
84 * Name the server-side header file <name>
85 * -dheader <name>
86 * Name the defines (msgh_ids) header file <name>
87 *
88 * DESIGN:
89 * Mig uses a lexxer module created by lex from lexxer.l and
90 * a parser module created by yacc from parser.y to parse an
91 * interface definitions module for a mach server.
92 * The parser module calls routines in statement.c
93 * and routines.c to build a list of statement structures.
94 * The most interesting statements are the routine definitions
95 * which contain information about the name, type, characteristics
96 * of the routine, an argument list containing information for
97 * each argument type, and a list of special arguments. The
98 * argument type structures are build by routines in type.c
99 * Once parsing is completed, the three code generation modules:
100 * header.c user.c and server.c are called sequentially. These
101 * do some code generation directly and also call the routines
102 * in utils.c for common (parameterized) code generation.
103 *
104 */
105
106 #include <stdlib.h>
107 #include <stdio.h>
108 #include <time.h>
109 #include "error.h"
110 #include "lexxer.h"
111 #include "global.h"
112 #include "write.h"
113
114 extern int yyparse(void);
115 static FILE *myfopen(const char *name, const char *mode);
116
117 static void
118 parseArgs(int argc,char *argv[])
119 {
120 if (argc == 2 && streql(argv[1], "-version")) {
121 PrintVersion = TRUE;
122 return;
123 }
124
125 while (--argc > 0)
126 if ((++argv)[0][0] == '-') {
127 switch (argv[0][1]) {
128
129 case 'q':
130 BeQuiet = TRUE;
131 break;
132
133 case 'Q':
134 BeQuiet = FALSE;
135 break;
136
137 case 'v':
138 BeVerbose = TRUE;
139 break;
140
141 case 'V':
142 BeVerbose = FALSE;
143 break;
144
145 case 'r':
146 UseMsgRPC = TRUE;
147 break;
148
149 case 'R':
150 UseMsgRPC = FALSE;
151 break;
152
153 case 'l':
154 UseEventLogger = FALSE;
155 break;
156
157 case 'L':
158 UseEventLogger = TRUE;
159 break;
160
161 case 'k':
162 BeAnsiC = TRUE;
163 break;
164
165 case 'K':
166 BeAnsiC = FALSE;
167 break;
168
169 case 'n':
170 if (streql(argv[0], "-novouchers")) {
171 IsVoucherCodeAllowed = FALSE;
172 } else {
173 CheckNDR = TRUE;
174 }
175 break;
176
177 case 'N':
178 CheckNDR = FALSE;
179 break;
180
181 case 's':
182 if (streql(argv[0], "-server")) {
183 --argc; ++argv;
184 if (argc == 0)
185 fatal("missing name for -server option");
186 ServerFileName = strmake(argv[0]);
187 }
188 else if (streql(argv[0], "-sheader")) {
189 --argc; ++argv;
190 if (argc == 0)
191 fatal ("missing name for -sheader option");
192 ServerHeaderFileName = strmake(argv[0]);
193 }
194 else if (streql(argv[0], "-split"))
195 UseSplitHeaders = TRUE;
196 else
197 GenSymTab = TRUE;
198 break;
199
200 case 'S':
201 GenSymTab = FALSE;
202 break;
203
204 case 't':
205 warn("Mach RPC traps not fully supported");
206 TestRPCTrap = TRUE;
207 UseRPCTrap = TRUE;
208 break;
209
210 case 'T':
211 UseRPCTrap = FALSE;
212 break;
213
214 case 'i':
215 if (streql(argv[0], "-iheader")) {
216 --argc; ++argv;
217 if (argc == 0)
218 fatal("missing name for -iheader option");
219 InternalHeaderFileName = strmake(argv[0]);
220 }
221 else {
222 --argc; ++argv;
223 if (argc == 0)
224 fatal("missing prefix for -i option");
225 UserFilePrefix = strmake(argv[0]);
226 }
227 break;
228
229 case 'u':
230 if (streql(argv[0], "-user")) {
231 --argc; ++argv;
232 if (argc == 0)
233 fatal("missing name for -user option");
234 UserFileName = strmake(argv[0]);
235 }
236 else
237 fatal("unknown flag: '%s'", argv[0]);
238 break;
239
240 case 'h':
241 if (streql(argv[0], "-header")) {
242 --argc; ++argv;
243 if (argc == 0)
244 fatal("missing name for -header option");
245 UserHeaderFileName = strmake(argv[0]);
246 }
247 else
248 fatal("unknown flag: '%s'", argv[0]);
249 break;
250
251 case 'd':
252 if (streql(argv[0], "-dheader")) {
253 --argc; ++argv;
254 if (argc == 0)
255 fatal("missing name for -dheader option");
256 DefinesHeaderFileName = strmake(argv[0]);
257 }
258 else
259 fatal("unknown flag: '%s'", argv[0]);
260 break;
261
262 case 'm':
263 if (streql(argv[0], "-maxonstack")) {
264 --argc; ++argv;
265 if (argc == 0)
266 fatal("missing size for -maxonstack option");
267 MaxMessSizeOnStack = atoi(argv[0]);
268 }
269 else
270 fatal("unknown flag: '%s'", argv[0]);
271 break;
272
273 case 'X':
274 ShortCircuit = FALSE;
275 break;
276
277 case 'x':
278 ShortCircuit = TRUE;
279 /* fall thru - no longer supported */
280
281 default:
282 fatal("unknown/unsupported flag: '%s'", argv[0]);
283 /*NOTREACHED*/
284 }
285 }
286 else
287 fatal("bad argument: '%s'", *argv);
288 }
289
290 FILE *uheader, *server, *user;
291
292 int
293 main(int argc, char *argv[])
294 {
295 FILE *iheader = 0;
296 FILE *sheader = 0;
297 FILE *dheader = 0;
298 time_t loc;
299 extern string_t GenerationDate;
300
301 set_program_name("mig");
302 parseArgs(argc, argv);
303 if (PrintVersion) {
304 printf("%s\n", MIG_VERSION);
305 fflush(stdout);
306 exit(0);
307 }
308 init_global();
309 init_type();
310 loc = time((time_t *)0);
311 GenerationDate = ctime(&loc);
312
313 LookNormal();
314 (void) yyparse();
315
316 if (mig_errors > 0)
317 fatal("%d errors found. Abort.\n", mig_errors);
318
319 more_global();
320
321 uheader = myfopen(UserHeaderFileName, "w");
322 if (!UserFilePrefix)
323 user = myfopen(UserFileName, "w");
324 server = myfopen(ServerFileName, "w");
325 if (ServerHeaderFileName)
326 sheader = myfopen(ServerHeaderFileName, "w");
327 if (IsKernelServer) {
328 iheader = myfopen(InternalHeaderFileName, "w");
329 }
330 if (DefinesHeaderFileName)
331 dheader = myfopen(DefinesHeaderFileName, "w");
332 if (BeVerbose) {
333 printf("Writing %s ... ", UserHeaderFileName);
334 fflush(stdout);
335 }
336 WriteUserHeader(uheader, stats);
337 fclose(uheader);
338 if (ServerHeaderFileName) {
339 if (BeVerbose) {
340 printf ("done.\nWriting %s ...", ServerHeaderFileName);
341 fflush (stdout);
342 }
343 WriteServerHeader(sheader, stats);
344 fclose(sheader);
345 }
346 if (IsKernelServer) {
347 if (BeVerbose) {
348 printf("done.\nWriting %s ... ", InternalHeaderFileName);
349 fflush(stdout);
350 }
351 WriteInternalHeader(iheader, stats);
352 fclose(iheader);
353 }
354 if (DefinesHeaderFileName) {
355 if (BeVerbose) {
356 printf ("done.\nWriting %s ...", DefinesHeaderFileName);
357 fflush (stdout);
358 }
359 WriteDefinesHeader(dheader, stats);
360 fclose(dheader);
361 }
362 if (UserFilePrefix) {
363 if (BeVerbose) {
364 printf("done.\nWriting individual user files ... ");
365 fflush(stdout);
366 }
367 WriteUserIndividual(stats);
368 }
369 else {
370 if (BeVerbose) {
371 printf("done.\nWriting %s ... ", UserFileName);
372 fflush(stdout);
373 }
374 WriteUser(user, stats);
375 fclose(user);
376 }
377 if (BeVerbose) {
378 printf("done.\nWriting %s ... ", ServerFileName);
379 fflush(stdout);
380 }
381 WriteServer(server, stats);
382 fclose(server);
383 if (BeVerbose)
384 printf("done.\n");
385
386 exit(0);
387 }
388
389 static FILE *
390 myfopen(const char *name, const char *mode)
391 {
392 const char *realname;
393 FILE *file;
394
395 if (name == strNULL)
396 realname = "/dev/null";
397 else
398 realname = name;
399
400 file = fopen(realname, mode);
401 if (file == NULL)
402 fatal("fopen(%s): %s", realname, strerror(errno));
403
404 return file;
405 }