|
|
1.1 ! root 1: #ifndef lint ! 2: static char RCSid[] = "$Header: code.c,v 2.4 87/03/17 09:32:16 ed Exp $"; ! 3: #endif ! 4: ! 5: /* $Log: code.c,v $ ! 6: * Revision 2.4 87/03/17 09:32:16 ed ! 7: * changes from Webster integrated ! 8: * ! 9: * Revision 2.4 87/03/17 09:32:16 ed ! 10: * Added -I switch to establish search path for DEPENDS UPON files. ! 11: * ! 12: * Revision 2.3 86/06/30 12:50:28 jqj ! 13: * bugfix to Server() code generation from Jack Callahan -- add "break;" if ! 14: * new Courier procedure call is for a different module. I'm not convinced ! 15: * this is the right fix, but have not had time to examine it in detail. ! 16: * ! 17: * Revision 2.2 86/06/06 07:28:31 jqj ! 18: * many mods for better symbol table management: added CurrentModule, ! 19: * made check_dependency, make_symbol, check_def set/use/use a symbol ! 20: * table instead of a module name string, etc. Result is that we can ! 21: * now handle DEPENDS UPON 2 versions of same program. ! 22: * ! 23: * Revision 2.1 86/01/21 10:04:02 jqj ! 24: * changes from Dan Chernikoff: dereferencing null pointer in code ! 25: * generation for Abort messages from servers. ! 26: * ! 27: * Revision 2.0 85/11/21 07:21:28 jqj ! 28: * 4.3BSD standard release ! 29: * ! 30: * Revision 1.6 85/05/23 06:19:16 jqj ! 31: * *** empty log message *** ! 32: * ! 33: * Revision 1.6 85/05/23 06:19:16 jqj ! 34: * Public Beta-test version, released 24 May 1985 ! 35: * ! 36: * Revision 1.5 85/05/06 08:12:58 jqj ! 37: * Almost Beta-test version. ! 38: * ! 39: * Revision 1.4 85/03/26 06:09:24 jqj ! 40: * Revised public alpha-test version, released 26 March 1985 ! 41: * ! 42: * Revision 1.3 85/03/11 16:38:39 jqj ! 43: * Public alpha-test version, released 11 March 1985 ! 44: * ! 45: * Revision 1.2 85/02/21 11:04:47 jqj ! 46: * alpha test version ! 47: * ! 48: * Revision 1.1 85/02/15 13:55:15 jqj ! 49: * Initial revision ! 50: * ! 51: */ ! 52: ! 53: #include "compiler.h" ! 54: #include <xnscourier/courierdb.h> ! 55: ! 56: char *CurrentProgram = "unknown"; ! 57: struct object *CurrentModule = (struct object *) 0; ! 58: int CurrentNumber = 0; ! 59: int CurrentVersion = 0; ! 60: ! 61: extern char *dirs[]; ! 62: extern int ndirs; ! 63: ! 64: /* ! 65: * Generate comments, #includes, and client binding. ! 66: * This action is called before the module body has been reduced. ! 67: * (jqj) ! 68: */ ! 69: program_header(symbol, number, version) ! 70: char *symbol; ! 71: char *number, *version; ! 72: { ! 73: if (check_dependency(symbol)) { ! 74: error(ERROR,"Module %s already seen.", symbol); ! 75: return; ! 76: } ! 77: CurrentModule = make_module(symbol,number,version); ! 78: CurrentProgram = symbol; ! 79: CurrentVersion = stringtocard(version); ! 80: CurrentNumber = stringtocard(number); ! 81: ! 82: /* ! 83: * only do this stuff for the main Courier program -- generate ! 84: * minimal code for DEPENDS UPON inclusions. ! 85: */ ! 86: if (recursive_flag) { ! 87: fprintf(header1,"/* DEPENDS UPON %s NUMBER %d VERSION %d */\n", ! 88: CurrentProgram, CurrentNumber, CurrentVersion); ! 89: return; ! 90: } ! 91: ! 92: /* ! 93: * Generate initial contents of all sorts of stuff: ! 94: * (1) set up gensym counter, ! 95: * (2) generate beginning of header files, support file, ! 96: * client file, server file ! 97: */ ! 98: setgensym(number,version); ! 99: fprintf(header1, ! 100: "/*\n\ ! 101: * This header file contains inclusions for the main definitions and for\n\ ! 102: * any DEPENDS UPON modules. It also contains #define commands to open\n\ ! 103: * the scope of the main definitons module.\n\ ! 104: *\n\ ! 105: * main inclusion:\n\ ! 106: */\n\ ! 107: #include \"%s%d.h\"\n\n", ! 108: CurrentProgram, CurrentVersion); ! 109: ! 110: /* ! 111: * In the definitions for this module, make sure we don't ! 112: * compile things twice by wrapping everything inside of a ! 113: * #ifndef ... #endif (the #endif is in wrapup_program() ). ! 114: */ ! 115: fprintf(header, ! 116: "/*\n\ ! 117: * Definitions for %s VERSION %s NUMBER %s.\n\ ! 118: */\n\ ! 119: #ifndef __%s%d\n\ ! 120: #define __%s%d\n\ ! 121: #include <xnscourier/courier.h>\n\ ! 122: #include <xnscourier/courierconnection.h>\n\n", ! 123: CurrentProgram, version, number, ! 124: CurrentProgram, CurrentVersion, ! 125: CurrentProgram, CurrentVersion); ! 126: ! 127: fprintf(support1, ! 128: "/*\n\ ! 129: * Support routines for %s.\n\ ! 130: */\n\ ! 131: #include \"%s%d.h\"\n", ! 132: CurrentProgram, CurrentProgram, CurrentVersion); ! 133: ! 134: fprintf(client, ! 135: "/*\n\ ! 136: * Client routines for %s.\n\ ! 137: */\n\ ! 138: #include \"%s%d.h\"\n", ! 139: CurrentProgram, CurrentProgram, CurrentVersion); ! 140: fprintf(server, ! 141: "/*\n\ ! 142: * Server for %s.\n\ ! 143: */\n\ ! 144: #include \"%s%d.h\"\n\ ! 145: #include <xnscourier/except.h>\n\n\ ! 146: extern CourierConnection *_serverConnection;\n", ! 147: CurrentProgram, CurrentProgram, CurrentVersion); ! 148: } ! 149: ! 150: /* ! 151: * Recursively parse a program to get types and constants. ! 152: * as a side effect, enters the program name into the SymbolTables ! 153: * symbol table. ! 154: */ ! 155: ref_program(name, number, version) ! 156: char *name, *number, *version; ! 157: { ! 158: long save_offset; ! 159: char *save_input_file; ! 160: char buf[MAXSTR]; ! 161: int *p; ! 162: int intversion, i; ! 163: extern int *save_parser_state(); ! 164: struct courierdbent *dbent; ! 165: ! 166: intversion = stringtocard(version); ! 167: ! 168: /* ! 169: * in a DEPENDS UPON inclusion, generate minimal code, making ! 170: * sure we don't do it twice. The included program is wrapped in ! 171: * an #ifdef ... #endif ! 172: */ ! 173: if (!recursive_flag) { ! 174: fprintf(header,"\n\ ! 175: /*\n\ ! 176: * Definitions from DEPENDS UPON %s inclusion\n\ ! 177: * (must be linked with %s%d_support.c also)\n\ ! 178: */\n\ ! 179: #include <xnscourier/%s%d.h>\n", ! 180: name, ! 181: name, intversion, ! 182: name, intversion); ! 183: } ! 184: if (check_module_def(name,number,version)) { ! 185: /* we've already parsed this one, so don't bother to redo */ ! 186: /* as a side effect, check_module_def adds this module to */ ! 187: /* the dependency list for CurrentModule */ ! 188: return; ! 189: } ! 190: ! 191: save_offset = ftell(stdin); ! 192: save_input_file = input_file; ! 193: sprintf(buf, "%s%d.cr", name, intversion); ! 194: input_file = buf; ! 195: if (freopen(input_file, "r", stdin) == NULL) { ! 196: /* ! 197: * attempt to find file from include directories ! 198: * -I switch on command line ! 199: */ ! 200: for ( i= 0; i < ndirs ; i++ ) { ! 201: sprintf(buf, "%s%s%s%d.cr", dirs[i], ! 202: (strcmp(dirs[i], "/") == 0 ? "" : "/"), ! 203: name, intversion); ! 204: input_file= buf; ! 205: if (freopen(input_file, "r", stdin) != NULL) ! 206: break; ! 207: } ! 208: /* ! 209: * if all else fails, look in courier description file ! 210: */ ! 211: if ( i >= ndirs ) { ! 212: dbent = getcourierservice(stringtocard(number),intversion); ! 213: if (dbent == NULL || ! 214: dbent->cr_description == NULL || ! 215: (input_file = copy(dbent->cr_description)) == NULL || ! 216: freopen(input_file, "r", stdin) == NULL) { ! 217: error(ERROR, "file %s not found", input_file); ! 218: input_file = save_input_file; ! 219: freopen(input_file, "r", stdin); ! 220: fseek(stdin, save_offset, 0); ! 221: return; ! 222: } ! 223: } ! 224: } ! 225: p = save_parser_state(); ! 226: /* note: recursive_flag is now set */ ! 227: (void) yyparse(); /* recursively parse */ ! 228: restore_parser_state(p); ! 229: input_file = save_input_file; ! 230: freopen(input_file, "r", stdin); ! 231: fseek(stdin, save_offset, 0); ! 232: return; ! 233: } ! 234: ! 235: /* ! 236: * Generate any code needed after DEPENDS UPON modules have been ! 237: * parsed, but before declarations. ! 238: */ ! 239: program_body() ! 240: { ! 241: if (recursive_flag) ! 242: return; ! 243: fprintf(header1, ! 244: "/*\n\ ! 245: * Widen scope to include all symbols defined in main inclusion:\n\ ! 246: */\n"); ! 247: } ! 248: ! 249: /* ! 250: * Generate code relating to binding. ! 251: * This action is called after the entire module has been reduced. ! 252: */ ! 253: wrapup_program(prog) ! 254: char *prog; ! 255: { ! 256: if (recursive_flag) ! 257: return; ! 258: fprintf(header,"\n#endif __%s\n\n", CurrentProgram); ! 259: if (!streq(prog,CurrentProgram)) ! 260: error(FATAL,"internal error (module): conflicting module names, %s and %s", ! 261: prog,CurrentProgram); ! 262: generate_server_binding(); ! 263: generate_client_binding(); ! 264: } ! 265: ! 266: /* ! 267: * Generate export function for server. ! 268: */ ! 269: generate_server_binding() ! 270: { ! 271: list p; ! 272: ! 273: fprintf(server, ! 274: "\nServer(skipcount,skippedwords)\n\ ! 275: \tint skipcount;\n\ ! 276: \tUnspecified skippedwords[];\n\ ! 277: {\n\ ! 278: \tCardinal _procedure;\n\ ! 279: \tregister Unspecified *_buf;\n\ ! 280: \tLongCardinal programnum;\n\ ! 281: \tCardinal versionnum;\n\ ! 282: \tCardinal _n;\n\ ! 283: \n\ ! 284: \tfor (;;) {\n\ ! 285: \t\t_buf = ReceiveCallMessage(&_procedure, skipcount, skippedwords);\n\ ! 286: \t\tDURING switch (_procedure) {\n"); ! 287: /* ! 288: * Find all the procedures declared in the program. ! 289: */ ! 290: for (p = Procedures; p != NIL; p = cdr(p)) { ! 291: fprintf(server, ! 292: "\t\tcase %s:\n\ ! 293: \t\t\tserver_%s(_buf);\n\ ! 294: \t\t\tbreak;\n", ! 295: (char *)cdar(p), (char *)caar(p)); ! 296: } ! 297: fprintf(server, ! 298: "\t\tdefault:\n\ ! 299: \t\t\tNoSuchProcedureValue(\"%s\", _procedure);\n\ ! 300: \t\t\tbreak;\n\ ! 301: \t\t} HANDLER {\n\ ! 302: \t\t Deallocate(_buf);\n\ ! 303: \t\t switch (Exception.Code) {\n", ! 304: CurrentProgram); ! 305: for (p = Errors; p != NIL; p = cdr(p)) { ! 306: struct constant *errconst; ! 307: struct type *errtype; ! 308: errconst = (struct constant *) caar(p); ! 309: errtype = (struct type *) cdar(p); ! 310: if (errtype == TNIL) ! 311: fprintf(server, ! 312: "\t\t case %s:\n\ ! 313: \t\t\t_buf = Allocate(0);\n\ ! 314: \t\t\tSendAbortMessage(Exception.Code-ERROR_OFFSET, 0, _buf);\n\ ! 315: \t\t\tbreak;\n", ! 316: errconst->cn_name); ! 317: /* errtype != TNIL */ ! 318: else if (typename(errtype) == NULL) { ! 319: error(ERROR,"Internal error (server): unexpanded type for %s", ! 320: errconst->cn_name); ! 321: break; ! 322: } ! 323: /* errtype != TNIL && typename(errtype) != NULL */ ! 324: else fprintf(server, ! 325: "\t\t case %s:\n\ ! 326: \t\t\t_n = sizeof_%s((%s *)Exception.Message);\n\ ! 327: \t\t\t_buf = Allocate(_n);\n\ ! 328: \t\t\t(void) %s((%s*)Exception.Message, _buf);\n\ ! 329: \t\t\tSendAbortMessage(Exception.Code-ERROR_OFFSET, _n, _buf);\n\ ! 330: \t\t\tbreak;\n", ! 331: errconst->cn_name, ! 332: typename(errtype), typename(errtype), ! 333: xfn(EXTERNALIZE,errtype), typename(errtype)); ! 334: } ! 335: fprintf(server, ! 336: "\t\t default:\n\ ! 337: \t\t\t_buf = Allocate(0);\n\ ! 338: \t\t\tSendRejectMessage(unspecifiedError, 0, _buf);\n\ ! 339: \t\t\tbreak;\n\ ! 340: \t\t }\n\ ! 341: \t\t} END_HANDLER;\n\ ! 342: \t\tDeallocate(_buf);\n\ ! 343: \t\tfor (;;) {\n\ ! 344: \t\t\tskipcount = LookAheadCallMsg(&programnum, &versionnum,\n\ ! 345: \t\t\t\t\tskippedwords);\n\ ! 346: \t\t\tif (skipcount < 0) return(0);\t/* timed out */\n\ ! 347: \t\t\tif (programnum != %d || versionnum != %d)\n\ ! 348: \t\t\t\tExecCourierProgram(programnum, versionnum,\n\ ! 349: \t\t\t\t\t\tskipcount, skippedwords);\n\ ! 350: \t\t\telse break;\n\ ! 351: \t\t\} /* loop if can't exec that program */\n\ ! 352: \t}\n\ ! 353: }\n", ! 354: CurrentNumber, CurrentVersion ! 355: ); ! 356: } ! 357: ! 358: /* ! 359: * Generate function for importing server module. ! 360: */ ! 361: generate_client_binding() ! 362: { ! 363: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.