BSD 4_3_Tahoe release
[unix-history] / usr / src / new / courier / compiler / code2.c
CommitLineData
0f4556f1
C
1#ifndef lint
2static char sccsid[] = "@(#)code2.c 4.1 (Berkeley) 7/3/83";
3#endif
4
59cc90dc
C
5#include "Courier.h"
6
7/*
8 * Generate functions for user and server calls to a procedure.
9 */
10proc_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
187program(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 */
205generate_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 */
253generate_binding_functions()
254{
255 fprintf(uf,
256"\nint _%sConnection = -1;\n\
257\n\
258Bind%sToMachine(machine)\n\
259\tString machine;\n\
260{\n\
261\tclose(_%sConnection);\n\
262\t_%sConnection = CourierActivate(\"%s\", machine);\n\
263}\n\
264\n\
265Unbind%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}