|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1993,1991,1990 Carnegie Mellon University
4: * All Rights Reserved.
5: *
6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
11: *
12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
23: * any improvements or extensions that they make and grant Carnegie the
24: * rights to redistribute these changes.
25: */
26:
27: /*
28: * Switches are;
29: * -[v,Q] verbose or not quiet: prints out type
30: * and routine information as mig runs.
31: * -[V,q] not verbose or quiet : don't print
32: * information during compilation
33: * (this is the default)
34: * -[r,R] do or don't use rpc calls instead of
35: * send/receive pairs. Default is -r.
36: * -[s,S] generate symbol table or not: generate a
37: * table of rpc-name, number, routine triplets
38: * as an external data structure -- main use is
39: * for protection system's specification of rights
40: * and for protection dispatch code. Default is -s.
41: * -i <prefix>
42: * Put each user routine in its own file. The
43: * file is named <prefix><routine-name>.c.
44: * -user <name>
45: * Name the user-side file <name>
46: * -server <name>
47: * Name the server-side file <name>
48: * -header <name>
49: * Name the user-side header file <name>
50: * -iheader <name>
51: * Name the user-side internal header file <name>
52: * -sheader <name>
53: * NAme the server-side header file <name>
54: *
55: * DESIGN:
56: * Mig uses a lexxer module created by lex from lexxer.l and
57: * a parser module created by yacc from parser.y to parse an
58: * interface definitions module for a mach server.
59: * The parser module calls routines in statement.c
60: * and routines.c to build a list of statement structures.
61: * The most interesting statements are the routine definitions
62: * which contain information about the name, type, characteristics
63: * of the routine, an argument list containing information for
64: * each argument type, and a list of special arguments. The
65: * argument type structures are build by routines in type.c
66: * Once parsing is completed, the three code generation modules:
67: * header.c user.c and server.c are called sequentially. These
68: * do some code generation directly and also call the routines
69: * in utils.c for common (parameterized) code generation.
70: *
71: */
72:
73: #include <stdio.h>
74:
75: #include "error.h"
76: #include "lexxer.h"
77: #include "global.h"
78: #include "write.h"
79:
80: extern int yyparse();
81: static FILE *myfopen(const char *name, const char *mode);
82:
83: static void
84: parseArgs(int argc, char **argv)
85: {
86: while (--argc > 0)
87: if ((++argv)[0][0] == '-')
88: {
89: switch (argv[0][1])
90: {
91: case 'q':
92: BeQuiet = TRUE;
93: break;
94: case 'Q':
95: BeQuiet = FALSE;
96: break;
97: case 'v':
98: BeVerbose = TRUE;
99: break;
100: case 'V':
101: BeVerbose = FALSE;
102: break;
103: case 'r':
104: UseMsgRPC = TRUE;
105: break;
106: case 'R':
107: UseMsgRPC = FALSE;
108: break;
109: case 's':
110: if (streql(argv[0], "-server"))
111: {
112: --argc; ++argv;
113: if (argc == 0)
114: fatal("missing name for -server option");
115: ServerFileName = strmake(argv[0]);
116: }
117: else if (streql(argv[0], "-sheader"))
118: {
119: --argc; ++argv;
120: if (argc == 0)
121: fatal ("missing name for -sheader option");
122: ServerHeaderFileName = strmake(argv[0]);
123: }
124: else if (streql(argv[0], "-subrprefix"))
125: {
126: --argc; ++argv;
127: if (argc == 0)
128: fatal ("missing string for -subrprefix option");
129: SubrPrefix = strmake(argv[0]);
130: }
131: else
132: GenSymTab = TRUE;
133: break;
134: case 'S':
135: GenSymTab = FALSE;
136: break;
137: case 'i':
138: if (streql(argv[0], "-iheader"))
139: {
140: --argc; ++argv;
141: if (argc == 0)
142: fatal("missing name for -iheader option");
143: InternalHeaderFileName = strmake(argv[0]);
144: }
145: else
146: {
147: --argc; ++argv;
148: if (argc == 0)
149: fatal("missing prefix for -i option");
150: UserFilePrefix = strmake(argv[0]);
151: }
152: break;
153: case 'u':
154: if (streql(argv[0], "-user"))
155: {
156: --argc; ++argv;
157: if (argc == 0)
158: fatal("missing name for -user option");
159: UserFileName = strmake(argv[0]);
160: }
161: else
162: fatal("unknown flag: '%s'", argv[0]);
163: break;
164: case 'h':
165: if (streql(argv[0], "-header"))
166: {
167: --argc; ++argv;
168: if (argc == 0)
169: fatal("missing name for -header option");
170: UserHeaderFileName = strmake(argv[0]);
171: }
172: else
173: fatal("unknown flag: '%s'", argv[0]);
174: break;
175: case 'p':
176: if (streql(argv[0], "-prefix"))
177: {
178: if (--argc == 0)
179: fatal ("missing string for -prefix option");
180: RoutinePrefix = strmake(*++argv);
181: }
182: break;
183: default:
184: fatal("unknown flag: '%s'", argv[0]);
185: /*NOTREACHED*/
186: }
187: }
188: else
189: fatal("bad argument: '%s'", *argv);
190: }
191:
192: void
193: main(int argc, char **argv)
194: {
195: FILE *uheader, *server, *user;
196: FILE *iheader, *sheader;
197:
198: set_program_name("mig");
199: parseArgs(argc, argv);
200: init_global();
201: init_type();
202:
203: LookNormal();
204: (void) yyparse();
205:
206: if (errors > 0)
207: exit(1);
208:
209: more_global();
210:
211: uheader = myfopen(UserHeaderFileName, "w");
212: if (!UserFilePrefix)
213: user = myfopen(UserFileName, "w");
214: server = myfopen(ServerFileName, "w");
215: if (ServerHeaderFileName)
216: sheader = myfopen(ServerHeaderFileName, "w");
217: if (IsKernelServer)
218: {
219: iheader = myfopen(InternalHeaderFileName, "w");
220: }
221:
222: if (BeVerbose)
223: {
224: printf("Writing %s ... ", UserHeaderFileName);
225: fflush(stdout);
226: }
227: WriteUserHeader(uheader, StatementList);
228: fclose(uheader);
229: if (ServerHeaderFileName)
230: {
231: if (BeVerbose)
232: {
233: printf ("done.\nWriting %s ...", ServerHeaderFileName);
234: fflush (stdout);
235: }
236: WriteServerHeader(sheader, StatementList);
237: fclose(sheader);
238: }
239: if (IsKernelServer)
240: {
241: if (BeVerbose)
242: {
243: printf("done.\nWriting %s ... ", InternalHeaderFileName);
244: fflush(stdout);
245: }
246: WriteInternalHeader(iheader, StatementList);
247: fclose(iheader);
248: }
249: if (UserFilePrefix)
250: {
251: if (BeVerbose)
252: {
253: printf("done.\nWriting individual user files ... ");
254: fflush(stdout);
255: }
256: WriteUserIndividual(StatementList);
257: }
258: else
259: {
260: if (BeVerbose)
261: {
262: printf("done.\nWriting %s ... ", UserFileName);
263: fflush(stdout);
264: }
265: WriteUser(user, StatementList);
266: fclose(user);
267: }
268: if (BeVerbose)
269: {
270: printf("done.\nWriting %s ... ", ServerFileName);
271: fflush(stdout);
272: }
273: WriteServer(server, StatementList);
274: fclose(server);
275: if (BeVerbose)
276: printf("done.\n");
277:
278: exit(0);
279: }
280:
281: static FILE *
282: myfopen(const char *name, const char *mode)
283: {
284: const char *realname;
285: FILE *file;
286: extern int errno;
287:
288: if (name == strNULL)
289: realname = "/dev/null";
290: else
291: realname = name;
292:
293: file = fopen(realname, mode);
294: if (file == NULL)
295: fatal("fopen(%s): %s", realname, unix_error_string(errno));
296:
297: return file;
298: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.