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