static char sccsid
[] = "@(#)code2.c 4.1 (Berkeley) 7/3/83";
* Generate functions for user and server calls to a procedure.
proc_functions(proc_name
, type
, value
)
struct object
*type
, *value
;
struct object
*t
, *result_type
;
char *result_name
, *func
, *ref
;
* Make sure there is at most one result returned.
nresults
= length(type
->t_results
);
/* could be multiple names with one type */
nresults
= length(car(car(type
->t_results
)));
yyerror("Procedures that return multiple results are not supported");
result_name
= name_of(car(car(car(type
->t_results
))));
result_type
= (struct object
*) cdr(car(type
->t_results
));
fprintf(sf
, "\nextern ");
print_decl(sf
, proc_name
, result_type
, 1);
fprintf(sf
, "\nextern void %s();\n", proc_name
);
\tregister Unspecified *_buf;\n\
\tregister Unspecified *_bp;\n\
\tregister LongCardinal _n;\n",
for (p
= type
->t_args
; p
!= NIL
; p
= cdr(p
)) {
t
= (struct object
*) cdr(car(p
));
for (q
= car(car(p
)); q
!= NIL
; q
= cdr(q
))
print_decl(sf
, name_of(car(q
)), t
, 0);
print_decl(sf
, result_name
, result_type
, 0);
fprintf(sf
, "\n\t_bp = _buf;\n");
for (p
= type
->t_args
; p
!= NIL
; p
= cdr(p
)) {
t
= (struct object
*) cdr(car(p
));
for (q
= car(car(p
)); q
!= NIL
; q
= cdr(q
))
fprintf(sf
, "\t_bp += %s(%s%s, _bp);\n",
unpack_function(t
), ref
, name_of(car(q
)));
fprintf(sf
, "\t%s = %s(", result_name
, proc_name
);
fprintf(sf
, "\t%s(", proc_name
);
for (p
= type
->t_args
; p
!= NIL
; p
= cdr(p
)) {
for (q
= car(car(p
)); q
!= NIL
; q
= cdr(q
)) {
fprintf(sf
, "%s", name_of(car(q
)));
func
= pack_function(result_type
);
ref
= refstr(result_type
);
"\t_n = %s(%s%s, 0, 0);\n\
\tSendReturnMessage(_n, _bp);\n\
func
, ref
, result_name
, func
, ref
, result_name
);
fprintf(hf
, "\nextern ");
print_decl(hf
, proc_name
, result_type
, 1);
print_decl(uf
, proc_name
, result_type
, 1);
fprintf(hf
, "\nextern void %s();\n", proc_name
);
fprintf(uf
, "\nvoid %s(", proc_name
);
for (p
= type
->t_args
; p
!= NIL
; p
= cdr(p
)) {
for (q
= car(car(p
)); q
!= NIL
; q
= cdr(q
)) {
fprintf(uf
, "%s", name_of(car(q
)));
fprintf(uf
, "\tString _machine;\n");
for (p
= type
->t_args
; p
!= NIL
; p
= cdr(p
)) {
t
= (struct object
*) cdr(car(p
));
for (q
= car(car(p
)); q
!= NIL
; q
= cdr(q
))
print_decl(uf
, name_of(car(q
)), t
, 0);
print_decl(uf
, result_name
, result_type
, 0);
"\tregister Unspecified *_buf, *_bp;\n\
\tregister LongCardinal _n;\n\
for (p
= type
->t_args
; p
!= NIL
; p
= cdr(p
)) {
t
= (struct object
*) cdr(car(p
));
for (q
= car(car(p
)); q
!= NIL
; q
= cdr(q
))
fprintf(uf
, "\t_n += %s(%s%s, 0, 0);\n",
pack_function(t
), ref
, name_of(car(q
)));
"\t_buf = Allocate(_n);\n\
for (p
= type
->t_args
; p
!= NIL
; p
= cdr(p
)) {
t
= (struct object
*) cdr(car(p
));
for (q
= car(car(p
)); q
!= NIL
; q
= cdr(q
))
fprintf(uf
, "\t_bp += %s(%s%s, _bp, 1);\n",
pack_function(t
), ref
, name_of(car(q
)));
"\tSendCallMessage(CourierProgram(\"%s\", _machine), %s, _n, _buf);\n",
program_name
, obj_rep(value
));
"\tSendCallMessage(_%sConnection, %s, _n, _buf);\n",
program_name
, obj_rep(value
));
fprintf(uf
, "\tDeallocate(_buf);\n");
"\t_bp = ReceiveReturnMessage(CourierProgram(\"%s\", _machine));\n",
"\t_bp = ReceiveReturnMessage(_%sConnection);\n",
unpack_function(result_type
), refstr(result_type
),
result_name
, result_name
);
* Program_name should have been set by now,
* but a little paranoia never hurt anyone.
if (! streq(name_of(prog
), program_name
)) {
yyerror("Internal error: conflicting program names %s and %s\n",
name_of(prog
), program_name
);
* Generate main loop for server program.
struct object
*t
, *proc
, *v
;
\tregister Unspecified *buf;\n\
\t\tbuf = ReceiveCallMessage(&procedure);\n\
\t\tswitch (procedure) {\n"
* Find all the procedures declared in the program.
for (p
= Types
; p
!= NIL
; p
= cdr(p
)) {
t
= (struct object
*) cdr(car(p
));
if (t
->t_constr
== C_PROCEDURE
) {
proc
= (struct object
*) car(car(p
));
v
= lookup(Values
, proc
);
obj_rep(v
), name_of(proc
));
\t\t\tNoSuchProcedureValue(\"%s\", procedure);\n\
* When implicit binding is used, this routine generates functions to
* bind the remote Courier program to a machine by setting the global
* connection variable for the program, and to remove the binding by
* closing the connection.
generate_binding_functions()
"\nint _%sConnection = -1;\n\
Bind%sToMachine(machine)\n\
\tclose(_%sConnection);\n\
\t_%sConnection = CourierActivate(\"%s\", machine);\n\
\tclose(_%sConnection);\n\
program_name
, program_name
, program_name
, program_name
,
program_name
, program_name
, program_name
, program_name
);