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