|
|
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.