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