diff options
Diffstat (limited to 'mig/migcom.c')
-rw-r--r-- | mig/migcom.c | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/mig/migcom.c b/mig/migcom.c new file mode 100644 index 0000000..bfd6724 --- /dev/null +++ b/mig/migcom.c @@ -0,0 +1,298 @@ +/* + * Mach Operating System + * Copyright (c) 1993,1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +/* + * Switches are; + * -[v,Q] verbose or not quiet: prints out type + * and routine information as mig runs. + * -[V,q] not verbose or quiet : don't print + * information during compilation + * (this is the default) + * -[r,R] do or don't use rpc calls instead of + * send/receive pairs. Default is -r. + * -[s,S] generate symbol table or not: generate a + * table of rpc-name, number, routine triplets + * as an external data structure -- main use is + * for protection system's specification of rights + * and for protection dispatch code. Default is -s. + * -i <prefix> + * Put each user routine in its own file. The + * file is named <prefix><routine-name>.c. + * -user <name> + * Name the user-side file <name> + * -server <name> + * Name the server-side file <name> + * -header <name> + * Name the user-side header file <name> + * -iheader <name> + * Name the user-side internal header file <name> + * -sheader <name> + * NAme the server-side header file <name> + * + * DESIGN: + * Mig uses a lexxer module created by lex from lexxer.l and + * a parser module created by yacc from parser.y to parse an + * interface definitions module for a mach server. + * The parser module calls routines in statement.c + * and routines.c to build a list of statement structures. + * The most interesting statements are the routine definitions + * which contain information about the name, type, characteristics + * of the routine, an argument list containing information for + * each argument type, and a list of special arguments. The + * argument type structures are build by routines in type.c + * Once parsing is completed, the three code generation modules: + * header.c user.c and server.c are called sequentially. These + * do some code generation directly and also call the routines + * in utils.c for common (parameterized) code generation. + * + */ + +#include <stdio.h> + +#include "error.h" +#include "lexxer.h" +#include "global.h" +#include "write.h" + +extern int yyparse(); +static FILE *myfopen(const char *name, const char *mode); + +static void +parseArgs(int argc, char **argv) +{ + while (--argc > 0) + if ((++argv)[0][0] == '-') + { + switch (argv[0][1]) + { + case 'q': + BeQuiet = TRUE; + break; + case 'Q': + BeQuiet = FALSE; + break; + case 'v': + BeVerbose = TRUE; + break; + case 'V': + BeVerbose = FALSE; + break; + case 'r': + UseMsgRPC = TRUE; + break; + case 'R': + UseMsgRPC = FALSE; + break; + case 's': + if (streql(argv[0], "-server")) + { + --argc; ++argv; + if (argc == 0) + fatal("missing name for -server option"); + ServerFileName = strmake(argv[0]); + } + else if (streql(argv[0], "-sheader")) + { + --argc; ++argv; + if (argc == 0) + fatal ("missing name for -sheader option"); + ServerHeaderFileName = strmake(argv[0]); + } + else if (streql(argv[0], "-subrprefix")) + { + --argc; ++argv; + if (argc == 0) + fatal ("missing string for -subrprefix option"); + SubrPrefix = strmake(argv[0]); + } + else + GenSymTab = TRUE; + break; + case 'S': + GenSymTab = FALSE; + break; + case 'i': + if (streql(argv[0], "-iheader")) + { + --argc; ++argv; + if (argc == 0) + fatal("missing name for -iheader option"); + InternalHeaderFileName = strmake(argv[0]); + } + else + { + --argc; ++argv; + if (argc == 0) + fatal("missing prefix for -i option"); + UserFilePrefix = strmake(argv[0]); + } + break; + case 'u': + if (streql(argv[0], "-user")) + { + --argc; ++argv; + if (argc == 0) + fatal("missing name for -user option"); + UserFileName = strmake(argv[0]); + } + else + fatal("unknown flag: '%s'", argv[0]); + break; + case 'h': + if (streql(argv[0], "-header")) + { + --argc; ++argv; + if (argc == 0) + fatal("missing name for -header option"); + UserHeaderFileName = strmake(argv[0]); + } + else + fatal("unknown flag: '%s'", argv[0]); + break; + case 'p': + if (streql(argv[0], "-prefix")) + { + if (--argc == 0) + fatal ("missing string for -prefix option"); + RoutinePrefix = strmake(*++argv); + } + break; + default: + fatal("unknown flag: '%s'", argv[0]); + /*NOTREACHED*/ + } + } + else + fatal("bad argument: '%s'", *argv); +} + +void +main(int argc, char **argv) +{ + FILE *uheader, *server, *user; + FILE *iheader, *sheader; + + set_program_name("mig"); + parseArgs(argc, argv); + init_global(); + init_type(); + + LookNormal(); + (void) yyparse(); + + if (errors > 0) + exit(1); + + more_global(); + + uheader = myfopen(UserHeaderFileName, "w"); + if (!UserFilePrefix) + user = myfopen(UserFileName, "w"); + server = myfopen(ServerFileName, "w"); + if (ServerHeaderFileName) + sheader = myfopen(ServerHeaderFileName, "w"); + if (IsKernelServer) + { + iheader = myfopen(InternalHeaderFileName, "w"); + } + + if (BeVerbose) + { + printf("Writing %s ... ", UserHeaderFileName); + fflush(stdout); + } + WriteUserHeader(uheader, StatementList); + fclose(uheader); + if (ServerHeaderFileName) + { + if (BeVerbose) + { + printf ("done.\nWriting %s ...", ServerHeaderFileName); + fflush (stdout); + } + WriteServerHeader(sheader, StatementList); + fclose(sheader); + } + if (IsKernelServer) + { + if (BeVerbose) + { + printf("done.\nWriting %s ... ", InternalHeaderFileName); + fflush(stdout); + } + WriteInternalHeader(iheader, StatementList); + fclose(iheader); + } + if (UserFilePrefix) + { + if (BeVerbose) + { + printf("done.\nWriting individual user files ... "); + fflush(stdout); + } + WriteUserIndividual(StatementList); + } + else + { + if (BeVerbose) + { + printf("done.\nWriting %s ... ", UserFileName); + fflush(stdout); + } + WriteUser(user, StatementList); + fclose(user); + } + if (BeVerbose) + { + printf("done.\nWriting %s ... ", ServerFileName); + fflush(stdout); + } + WriteServer(server, StatementList); + fclose(server); + if (BeVerbose) + printf("done.\n"); + + exit(0); +} + +static FILE * +myfopen(const char *name, const char *mode) +{ + const char *realname; + FILE *file; + extern int errno; + + if (name == strNULL) + realname = "/dev/null"; + else + realname = name; + + file = fopen(realname, mode); + if (file == NULL) + fatal("fopen(%s): %s", realname, unix_error_string(errno)); + + return file; +} |