|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)code2.c 4.1 (Berkeley) 7/3/83";
3: #endif
4:
5: #include "Courier.h"
6:
7: /*
8: * Generate functions for user and server calls to a procedure.
9: */
10: proc_functions(proc_name, type, value)
11: char *proc_name;
12: struct object *type, *value;
13: {
14: list p, q;
15: int nresults;
16: struct object *t, *result_type;
17: char *result_name, *func, *ref;
18:
19: /*
20: * Make sure there is at most one result returned.
21: */
22: nresults = length(type->t_results);
23: if (nresults == 1)
24: /* could be multiple names with one type */
25: nresults = length(car(car(type->t_results)));
26: if (nresults > 1) {
27: yyerror("Procedures that return multiple results are not supported");
28: return;
29: }
30: if (nresults) {
31: result_name = name_of(car(car(car(type->t_results))));
32: result_type = (struct object *) cdr(car(type->t_results));
33: }
34:
35: /*
36: * Server routine.
37: */
38: if (nresults) {
39: fprintf(sf, "\nextern ");
40: print_decl(sf, proc_name, result_type, 1);
41: fprintf(sf, "();\n");
42: } else
43: fprintf(sf, "\nextern void %s();\n", proc_name);
44: fprintf(sf,
45: "\nServer_%s(_buf)\n\
46: \tregister Unspecified *_buf;\n\
47: {\n\
48: \tregister Unspecified *_bp;\n\
49: \tregister LongCardinal _n;\n",
50: proc_name);
51: print_level++;
52: for (p = type->t_args; p != NIL; p = cdr(p)) {
53: t = (struct object *) cdr(car(p));
54: for (q = car(car(p)); q != NIL; q = cdr(q))
55: print_decl(sf, name_of(car(q)), t, 0);
56: }
57: if (nresults)
58: print_decl(sf, result_name, result_type, 0);
59: print_level--;
60: fprintf(sf, "\n\t_bp = _buf;\n");
61: for (p = type->t_args; p != NIL; p = cdr(p)) {
62: t = (struct object *) cdr(car(p));
63: ref = refstr(t);
64: for (q = car(car(p)); q != NIL; q = cdr(q))
65: fprintf(sf, "\t_bp += %s(%s%s, _bp);\n",
66: unpack_function(t), ref, name_of(car(q)));
67: }
68: if (nresults)
69: fprintf(sf, "\t%s = %s(", result_name, proc_name);
70: else
71: fprintf(sf, "\t%s(", proc_name);
72: for (p = type->t_args; p != NIL; p = cdr(p)) {
73: for (q = car(car(p)); q != NIL; q = cdr(q)) {
74: fprintf(sf, "%s", name_of(car(q)));
75: if (cdr(q) != NIL)
76: fprintf(sf, ", ");
77: }
78: if (cdr(p) != NIL)
79: fprintf(sf, ", ");
80: }
81: fprintf(sf, ");\n");
82: if (nresults) {
83: func = pack_function(result_type);
84: ref = refstr(result_type);
85: fprintf(sf,
86: "\t_n = %s(%s%s, 0, 0);\n\
87: \t_bp = Allocate(_n);\n\
88: \t%s(%s%s, _bp, 1);\n\
89: \tSendReturnMessage(_n, _bp);\n\
90: \tDeallocate(_bp);\n",
91: func, ref, result_name, func, ref, result_name);
92: }
93: fprintf(sf, "}\n");
94:
95: /*
96: * Remote access routine.
97: */
98: if (nresults) {
99: fprintf(hf, "\nextern ");
100: print_decl(hf, proc_name, result_type, 1);
101: fprintf(hf, "();\n");
102:
103: fprintf(uf, "\n");
104: print_decl(uf, proc_name, result_type, 1);
105: fprintf(uf, "(");
106: } else {
107: fprintf(hf, "\nextern void %s();\n", proc_name);
108: fprintf(uf, "\nvoid %s(", proc_name);
109: }
110: if (explicit) {
111: fprintf(uf, "_machine");
112: if (type->t_args != NIL)
113: fprintf(uf, ", ");
114: }
115: for (p = type->t_args; p != NIL; p = cdr(p)) {
116: for (q = car(car(p)); q != NIL; q = cdr(q)) {
117: fprintf(uf, "%s", name_of(car(q)));
118: if (cdr(q) != NIL)
119: fprintf(uf, ", ");
120: }
121: if (cdr(p) != NIL)
122: fprintf(uf, ", ");
123: }
124: fprintf(uf, ")\n");
125: if (explicit)
126: fprintf(uf, "\tString _machine;\n");
127: print_level++;
128: for (p = type->t_args; p != NIL; p = cdr(p)) {
129: t = (struct object *) cdr(car(p));
130: for (q = car(car(p)); q != NIL; q = cdr(q))
131: print_decl(uf, name_of(car(q)), t, 0);
132: }
133: fprintf(uf, "{\n");
134: if (nresults)
135: print_decl(uf, result_name, result_type, 0);
136: fprintf(uf,
137: "\tregister Unspecified *_buf, *_bp;\n\
138: \tregister LongCardinal _n;\n\
139: \n\
140: \t_n = 0;\n");
141: print_level--;
142: for (p = type->t_args; p != NIL; p = cdr(p)) {
143: t = (struct object *) cdr(car(p));
144: ref = refstr(t);
145: for (q = car(car(p)); q != NIL; q = cdr(q))
146: fprintf(uf, "\t_n += %s(%s%s, 0, 0);\n",
147: pack_function(t), ref, name_of(car(q)));
148: }
149: fprintf(uf,
150: "\t_buf = Allocate(_n);\n\
151: \t_bp = _buf;\n");
152: for (p = type->t_args; p != NIL; p = cdr(p)) {
153: t = (struct object *) cdr(car(p));
154: ref = refstr(t);
155: for (q = car(car(p)); q != NIL; q = cdr(q))
156: fprintf(uf, "\t_bp += %s(%s%s, _bp, 1);\n",
157: pack_function(t), ref, name_of(car(q)));
158: }
159: if (explicit)
160: fprintf(uf,
161: "\tSendCallMessage(CourierProgram(\"%s\", _machine), %s, _n, _buf);\n",
162: program_name, obj_rep(value));
163: else
164: fprintf(uf,
165: "\tSendCallMessage(_%sConnection, %s, _n, _buf);\n",
166: program_name, obj_rep(value));
167: fprintf(uf, "\tDeallocate(_buf);\n");
168: if (nresults) {
169: if (explicit)
170: fprintf(uf,
171: "\t_bp = ReceiveReturnMessage(CourierProgram(\"%s\", _machine));\n",
172: program_name);
173: else
174: fprintf(uf,
175: "\t_bp = ReceiveReturnMessage(_%sConnection);\n",
176: program_name);
177: fprintf(uf,
178: "\t%s(%s%s, _bp);\n\
179: \tDeallocate(_bp);\n\
180: \treturn (%s);\n",
181: unpack_function(result_type), refstr(result_type),
182: result_name, result_name);
183: }
184: fprintf(uf, "}\n");
185: }
186:
187: program(prog)
188: struct object *prog;
189: {
190: /*
191: * Program_name should have been set by now,
192: * but a little paranoia never hurt anyone.
193: */
194: if (! streq(name_of(prog), program_name)) {
195: yyerror("Internal error: conflicting program names %s and %s\n",
196: name_of(prog), program_name);
197: exit(1);
198: }
199: generate_server();
200: }
201:
202: /*
203: * Generate main loop for server program.
204: */
205: generate_server()
206: {
207: list p;
208: struct object *t, *proc, *v;
209:
210: fprintf(sf,
211: "\nServer()\n\
212: {\n\
213: \tCardinal procedure;\n\
214: \tregister Unspecified *buf;\n\
215: \n\
216: \tServerInit();\n\
217: \tfor (;;) {\n\
218: \t\tbuf = ReceiveCallMessage(&procedure);\n\
219: \t\tswitch (procedure) {\n"
220: );
221: /*
222: * Find all the procedures declared in the program.
223: */
224: for (p = Types; p != NIL; p = cdr(p)) {
225: t = (struct object *) cdr(car(p));
226: if (t->t_constr == C_PROCEDURE) {
227: proc = (struct object *) car(car(p));
228: v = lookup(Values, proc);
229: fprintf(sf,
230: "\t\tcase %s:\n\
231: \t\t\tServer_%s(buf);\n\
232: \t\t\tbreak;\n",
233: obj_rep(v), name_of(proc));
234: }
235: }
236: fprintf(sf,
237: "\t\tdefault:\n\
238: \t\t\tNoSuchProcedureValue(\"%s\", procedure);\n\
239: \t\t\tbreak;\n\
240: \t\t}\n\
241: \t\tDeallocate(buf);\n\
242: \t}\n\
243: }\n",
244: program_name);
245: }
246:
247: /*
248: * When implicit binding is used, this routine generates functions to
249: * bind the remote Courier program to a machine by setting the global
250: * connection variable for the program, and to remove the binding by
251: * closing the connection.
252: */
253: generate_binding_functions()
254: {
255: fprintf(uf,
256: "\nint _%sConnection = -1;\n\
257: \n\
258: Bind%sToMachine(machine)\n\
259: \tString machine;\n\
260: {\n\
261: \tclose(_%sConnection);\n\
262: \t_%sConnection = CourierActivate(\"%s\", machine);\n\
263: }\n\
264: \n\
265: Unbind%s()\n\
266: {\n\
267: \tclose(_%sConnection);\n\
268: \t_%sConnection = -1;\n\
269: }\n",
270: program_name, program_name, program_name, program_name,
271: program_name, program_name, program_name, program_name);
272: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.