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: }

Defined functions

generate_server defined in line 205; used 1 times
proc_functions defined in line 10; used 1 times
program defined in line 187; used 1 times

Defined variables

sccsid defined in line 2; never used
Last modified: 1983-07-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1319
Valid CSS Valid XHTML 1.0 Strict