/* * This file is part of DGD, http://dgd-osr.sourceforge.net/ * Copyright (C) 1993-2010 Dworkin B.V. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ # define INCLUDE_FILE_IO # include "comp.h" # include "str.h" # include "array.h" # include "object.h" # include "xfloat.h" # include "interpret.h" # include "data.h" # include "path.h" # include "hash.h" # include "swap.h" # include "comm.h" # include "editor.h" # include "call_out.h" # include "node.h" # include "codegen.h" # include "compile.h" # include "csupport.h" static int size; /* current size of the dumped line */ /* * NAME: dump_int() * DESCRIPTION: output a number */ static void dump_int(n) int n; { if (size == 16) { putchar('\n'); size = 0; } printf("%d, ", n); size++; } /* * NAME: dump_chars() * DESCRIPTION: output a range of characters */ static void dump_chars(p, n) register char *p; register unsigned int n; { while (n > 0) { dump_int(*p++); --n; } } /* * NAME: dump_inherits() * DESCRIPTION: output the inherited objects */ static void dump_inherits(ctrl) register control *ctrl; { register int i; printf("\nstatic pcinherit inherits[] = {\n"); for (i = 0; i < ctrl->ninherits; i++) { printf("{ \"%s\", %u, %u, %u, %d },\n", OBJ(ctrl->inherits[i].oindex)->chain.name, ctrl->inherits[i].progoffset, ctrl->inherits[i].funcoffset, ctrl->inherits[i].varoffset, ctrl->inherits[i].priv); } printf("};\n"); } /* * NAME: dump_imap() * DESCRIPTION: output imap table */ static void dump_imap(ctrl) register control *ctrl; { register int i; printf("\nstatic char imap[] = {\n"); size = 0; for (i = 0; i < ctrl->imapsz; i++) { dump_int(ctrl->imap[i]); } printf("\n};\n"); } /* * NAME: dump_program() * DESCRIPTION: output the program */ static void dump_program(ctrl) control *ctrl; { if (ctrl->progsize != 0) { printf("\nstatic char program[] = {\n"); size = 0; dump_chars(ctrl->prog, ctrl->progsize); printf("\n};\n"); } } /* * NAME: dump_strings() * DESCRIPTION: output the strings */ static void dump_strings(ctrl) register control *ctrl; { register int i; register long len; if (ctrl->nstrings != 0) { printf("\nstatic dstrconst sstrings[] = {\n"); len = 0; for (i = 0; i < ctrl->nstrings; i++) { printf("{ %ld, %u },\n", len, ctrl->strings[i]->len); len += ctrl->strings[i]->len; } printf("};\n\nstatic char stext[] = {\n"); size = 0; for (i = 0; i < ctrl->nstrings; i++) { dump_chars(ctrl->strings[i]->text, ctrl->strings[i]->len); } printf("\n};\n"); } } /* * NAME: dump_funcdefs() * DESCRIPTION: output the function definitions */ static void dump_funcdefs(ctrl) register control *ctrl; { register int i; if (ctrl->nfuncdefs != 0) { printf("\nstatic dfuncdef funcdefs[] = {\n"); for (i = 0; i < ctrl->nfuncdefs; i++) { printf("{ %d, %d, %u, %u },\n", ctrl->funcdefs[i].class, ctrl->funcdefs[i].inherit, ctrl->funcdefs[i].index, ctrl->funcdefs[i].offset); } printf("};\n"); } } /* * NAME: dump_vardefs() * DESCRIPTION: output the variable definitions */ static void dump_vardefs(ctrl) register control *ctrl; { register int i; if (ctrl->nvardefs != 0) { printf("\nstatic dvardef vardefs[] = {\n"); for (i = 0; i < ctrl->nvardefs; i++) { printf("{ %d, %d, %u, %u },\n", ctrl->vardefs[i].class, ctrl->vardefs[i].inherit, ctrl->vardefs[i].index, ctrl->vardefs[i].type); } printf("};\n"); if (ctrl->nclassvars != 0) { printf("\nstatic char classvars[] = {\n"); size = 0; dump_chars(ctrl->classvars, ctrl->nclassvars * 3); printf("\n};\n"); } } } /* * NAME: dump_funcalls() * DESCRIPTION: output the function call table */ static void dump_funcalls(ctrl) register control *ctrl; { if (ctrl->nfuncalls > 0) { printf("\nstatic char funcalls[] = {\n"); size = 0; dump_chars(ctrl->funcalls, ctrl->nfuncalls << 1); printf("\n};\n"); } } /* * NAME: dump_symbols() * DESCRIPTION: output the symbol table */ static void dump_symbols(ctrl) register control *ctrl; { register uindex i; if (ctrl->nsymbols != 0) { printf("\nstatic dsymbol symbols[] = {\n"); for (i = 0; i < ctrl->nsymbols; i++) { printf("{ %d, %d, %u },\n", ctrl->symbols[i].inherit, ctrl->symbols[i].index, ctrl->symbols[i].next); } printf("};\n"); } } /* * NAME: dump_vtypes() * DESCRIPTION: output the variable types */ static void dump_vtypes(ctrl) register control *ctrl; { if (ctrl->nvariables > ctrl->nvardefs) { printf("\nstatic char vtypes[] = {\n"); size = 0; dump_chars(ctrl->vtypes, ctrl->nvariables - ctrl->nvardefs); printf("\n};\n"); } } /* * NAME: dgd_main() * DESCRIPTION: main routine of the precompiler */ int dgd_main(argc, argv) int argc; char *argv[]; { char buf[STRINGSZ], tag[9]; register unsigned int len; register control *ctrl; register char *file; int nfuncs; sector fragment; file = argv[2]; if ((argc != 3 && argc != 4) || (len=strlen(file)) < 2 || file[len - 2] != '.' || file[len - 1] != 'c') { P_message("usage: precomp config_file lpc_file [c_file]\012"); /* LF */ return 2; } /* open output file */ if (argc == 4 && freopen(argv[3], "w", stdout) == (FILE *) NULL) { P_message("cannot open output file\012"); /* LF */ return 2; } /* initialize */ if (!conf_init(argv[1], (char *) NULL, &fragment)) { P_message("Initialization failed\012"); /* LF */ return 2; } len = strlen(file = path_resolve(buf, file)); file[len - 2] = '\0'; sprintf(tag, "T%03x%04x", hashstr(file, len) & 0xfff, (unsigned short) P_random()); printf("/*\n * This file was compiled from LPC with the DGD precompiler."); printf("\n * DGD is Copyright by Dworkin B.V. and is released under the\n"); printf(" * terms of the GNU Affero General Public License.\n *\n"); printf(" * File: \"/%s.c\"\n */\n", file); printf("\n# ifdef TAG\nTAG(%s)\n# else\n", tag); printf("# include \"dgd.h\"\n# include \"str.h\"\n"); printf("# include \"array.h\"\n# include \"object.h\"\n"); printf("# include \"interpret.h\"\n# include \"data.h\"\n"); printf("# include \"xfloat.h\"\n# include \"csupport.h\"\n"); if (ec_push((ec_ftn) NULL)) { message("Failed to compile \"%s.c\"\012", file); /* LF */ printf("\n# error Error while compiling\n"); fclose(stdout); if (argc == 4) { /* remove output file: may fail if path is not absolute */ unlink(argv[3]); } return 1; } /* compile file */ ctrl = c_compile(cframe, file, (object *) NULL, (string **) NULL, 0, FALSE)->ctrl; nfuncs = cg_nfuncs(); ec_pop(); /* dump tables */ dump_inherits(ctrl); dump_imap(ctrl); dump_program(ctrl); dump_strings(ctrl); dump_funcdefs(ctrl); dump_vardefs(ctrl); dump_funcalls(ctrl); dump_symbols(ctrl); dump_vtypes(ctrl); printf("\nprecomp %s = {\nUINDEX_MAX,\n%d, inherits,\n", tag, ctrl->ninherits); printf("%u, imap,\n", ctrl->imapsz); printf("%ldL,\n", (long) ctrl->compiled); if (ctrl->progsize == 0) { printf("0, 0,\n"); } else { printf("%u, program,\n", ctrl->progsize); } if (ctrl->nstrings == 0) { printf("0, 0, 0, 0,\n"); } else { printf("%u, sstrings, stext, %luL,\n", ctrl->nstrings, (unsigned long) ctrl->strsize); } if (nfuncs == 0) { printf("0, 0,\n"); } else { printf("%u, functions,\n", nfuncs); } if (ctrl->nfuncdefs == 0) { printf("0, 0,\n"); } else { printf("%u, funcdefs,\n", ctrl->nfuncdefs); } if (ctrl->nvardefs == 0) { printf("0, 0, 0, 0,\n"); } else { printf("%u, %u, vardefs, ", ctrl->nvardefs, ctrl->nclassvars); if (ctrl->nclassvars == 0) { printf("0,\n"); } else { printf("classvars,\n"); } } if (ctrl->nfuncalls == 0) { printf("0, 0,\n"); } else { printf("%u, funcalls,\n", ctrl->nfuncalls); } if (ctrl->nsymbols == 0) { printf("0, 0,\n"); } else { printf("%u, symbols,\n", ctrl->nsymbols); } printf("%u,\n", ctrl->nvariables); if (ctrl->nvariables > ctrl->nvardefs) { printf("vtypes,\n"); } else { printf("0,\n"); } printf("%d\n", conf_typechecking()); printf("};\n# endif\n"); return 0; } /* * "Dummy" routines. */ /* * NAME: call_driver_object() * DESCRIPTION: pretend to call a function in the driver object */ bool call_driver_object(f, func, narg) register frame *f; char *func; int narg; { i_pop(f, narg); (--f->sp)->type = T_INT; f->sp->u.number = 0; return FALSE; } /* * NAME: errhandler() * DESCRIPTION: pretend to have a default error handler */ void errhandler(f, depth) frame *f; Int depth; { } /* * NAME: interrupt() * DESCRIPTION: pretend to register an interrupt */ void interrupt() { } /* * NAME: endthread() * DESCRIPTION: pretend to clean up after a thread has terminated */ void endthread() { } # ifndef PRECOMPILER_PRECOMPILED pcfunc *pcfunctions; /* dummy */ /* * NAME: pc_preload() * DESCRIPTION: pretend to preload compiled objects */ bool pc_preload(auto_name, driver_name) char *auto_name, *driver_name; { return TRUE; } /* * NAME: pc_list() * DESCRIPTION: pretend to return a list of precompiled objects */ array *pc_list(data) dataspace *data; { return (array *) NULL; } /* * NAME: pc_control() * DESCRIPTION: pretend to initialize the control block of a compiled object */ void pc_control(ctrl, obj) control *ctrl; object *obj; { } bool pc_dump(fd) int fd; { return TRUE; } void pc_restore(fd, conv) int fd, conv; { } # endif /* PRECOMPILER_PRECOMPILED */ /* * NAME: swap->init() * DESCRIPTION: pretend to initialize the swap device */ void sw_init(file, total, cache, secsize) char *file; unsigned int total, cache, secsize; { } /* * NAME: swap->finish() * DESCRIPTION: pretend to finish swapping */ void sw_finish() { } /* * NAME: swap->newv() * DESCRIPTION: pretend to create a new vector of sectors */ void sw_newv(vec, size) sector *vec; unsigned int size; { } /* * NAME: swap->wipev() * DESCRIPTION: pretend to wipe a vector of sectors */ void sw_wipev(vec, size) sector *vec; unsigned int size; { } /* * NAME: swap->delv() * DESCRIPTION: pretend to delete a vector of sectors */ void sw_delv(vec, size) sector *vec; unsigned int size; { } /* * NAME: swap->readv() * DESCRIPTION: pretend to read bytes from a vector of sectors */ void sw_readv(m, vec, size, idx) char *m; sector *vec; Uint size, idx; { } /* * NAME: swap->writev() * DESCRIPTION: pretend to write bytes to a vector of sectors */ void sw_writev(m, vec, size, idx) char *m; sector *vec; Uint size, idx; { } /* * NAME: swap->creadv() * DESCRIPTION: pretend to read bytes from a vector of sectors in the dump file */ void sw_creadv(m, vec, size, idx) char *m; sector *vec; Uint size, idx; { } /* * NAME: swap->dreadv() * DESCRIPTION: pretend to read bytes from a vector of sectors in the dump file */ void sw_dreadv(m, vec, size, idx) char *m; sector *vec; Uint size, idx; { } /* * NAME: swap->conv() * DESCRIPTION: pretend to read bytes from a vector of sectors in the dump file */ void sw_conv(m, vec, size, idx) char *m; sector *vec; Uint size, idx; { } /* * NAME: swap->mapsize() * DESCRIPTION: pretend to count the number of sectors required for size bytes */ sector sw_mapsize(size) Uint size; { return 0; } /* * NAME: swap->count() * DESCRIPTION: pretend to return the number of sectors presently in use */ sector sw_count() { return 0; } /* * NAME: swap->copy() * DESCRIPTION: pretend to copy a vector of sectors to a dump file */ bool sw_copy(time) Uint time; { return FALSE; } /* * NAME: swap->dump() * DESCRIPTION: pretend to dump swap file */ int sw_dump(dumpfile) char *dumpfile; { return 0; } /* * NAME: swap->restore() * DESCRIPTION: pretend to restore swap file */ void sw_restore(fd, secsize) int fd; unsigned int secsize; { } /* * NAME: comm->init() * DESCRIPTION: pretend to initialize communications */ #ifndef NETWORK_EXTENSION bool comm_init(n, thosts, bhosts, tports, bports, ntelnet, nbinary) int n, ntelnet, nbinary; #else bool comm_init(n, p, thosts, bhosts, tports, bports, ntelnet, nbinary) int n, p, ntelnet, nbinary; #endif char **thosts, **bhosts; unsigned short *tports, *bports; { return TRUE; } /* * NAME: comm->finish() * DESCRIPTION: pretend to terminate connections */ void comm_finish() { } /* * NAME: comm->finish() * DESCRIPTION: pretend to set the datagram challenge */ void comm_challenge(obj, str) object *obj; string *str; { } /* * NAME: comm->listen() * DESCRIPTION: pretend to start listening on telnet port and binary port */ void comm_listen() { } /* * NAME: comm->send() * DESCRIPTION: pretend to send a message to a user */ int comm_send(obj, str) object *obj; string *str; { return 0; } /* * NAME: comm->udpsend() * DESCRIPTION: pretend to send a message on the UDP channel of a connection */ int comm_udpsend(obj, str) object *obj; string *str; { return 0; } /* * NAME: comm->echo() * DESCRIPTION: pretend to turn on/off input echoing for a user */ bool comm_echo(obj, echo) object *obj; int echo; { return FALSE; } /* * NAME: comm->flush() * DESCRIPTION: pretend to flush output to all users */ void comm_flush() { } /* * NAME: comm->block() * DESCRIPTION: pretend to suspend or release input from a user */ void comm_block(obj, flag) object *obj; int flag; { } /* * NAME: comm->ip_number() * DESCRIPTION: pretend to return the ip number of a user (as a string) */ string *comm_ip_number(obj) object *obj; { return (string *) NULL; } /* * NAME: comm->ip_name() * DESCRIPTION: pretend to return the ip name of a user */ string *comm_ip_name(obj) object *obj; { return (string *) NULL; } /* * NAME: comm->close() * DESCRIPTION: pretend to remove a user */ void comm_close(f, obj) frame *f; object *obj; { } /* * NAME: comm->user() * DESCRIPTION: pretend to return the current user */ object *comm_user() { return (object *) NULL; } /* * NAME: comm->users() * DESCRIPTION: pretend to return an array with all user objects */ #ifndef NETWORK_EXTENSION array *comm_users(data) dataspace *data; { return (array *) NULL; } #else array *comm_users(data, ports) dataspace *data; bool ports; { return (array *) NULL; } /* * NAME: comm->is_connection() * DESCRIPTION: pretend to test if an object is a connection */ bool comm_is_connection(obj) object *obj; { return FALSE; } void comm_openport(f, obj, protocol, portnr) frame *f; object *obj; unsigned char protocol; unsigned short portnr; { } void comm_connect(f, obj, addr, protocol, port) frame *f; object *obj; char *addr; unsigned char protocol; unsigned short port; { } int comm_senddatagram(obj, str, ip, port) object * obj; string * str; string * ip; int port; { return 0; } #endif /* * NAME: ed->init() * DESCRIPTION: pretend to initialize editor handling */ void ed_init(tmp, num) char *tmp; int num; { } /* * NAME: ed->finish() * DESCRIPTION: pretend to terminate all editor sessions */ void ed_finish() { } /* * NAME: ed->new() * DESCRIPTION: pretend to start a new editor */ void ed_new(obj) object *obj; { } /* * NAME: ed->del() * DESCRIPTION: pretend to delete an editor instance */ void ed_del(obj) object *obj; { } /* * NAME: ed->command() * DESCRIPTION: pretend to handle an editor command */ string *ed_command(obj, cmd) object *obj; char *cmd; { return (string *) NULL; } /* * NAME: ed->status() * DESCRIPTION: pretend to return the editor status of an object */ char *ed_status(obj) object *obj; { return (char *) NULL; } /* * NAME: call_out->init() * DESCRIPTION: pretend to initialize callout handling */ bool co_init(max) unsigned int max; { return TRUE; } /* * NAME: call_out->check() * DESCRIPTION: pretend to check a new callout */ Uint co_check(n, delay, mdelay, tp, mp, qp) unsigned int n, mdelay; Int delay; Uint *tp; unsigned short *mp; cbuf **qp; { return 0; } /* * NAME: call_out->new() * DESCRIPTION: pretend to add a new callout */ void co_new(oindex, handle, t, m, q) unsigned int oindex, handle, m; Uint t; cbuf *q; { } /* * NAME: call_out->del() * DESCRIPTION: pretend to remove a callout */ void co_del(oindex, handle, t, m) unsigned int oindex, handle, m; Uint t; { } /* * NAME: call_out->remaining() * DESCRIPTION: pretend to return the time remaining before a callout expires */ Int co_remaining(t, m) Uint t; unsigned short *m; { return 0; } /* * NAME: call_out->list() * DESCRIPTION: pretend to adjust callout delays in an array */ void co_list(a) array *a; { } /* * NAME: call_out->call() * DESCRIPTION: pretend to call expired callouts */ void co_call(f) frame *f; { } /* * NAME: call_out->info() * DESCRIPTION: pretend to return information about callouts */ void co_info(n1, n2) uindex *n1, *n2; { } /* * NAME: call_out->decode() * DESCRIPTION: pretend to decode a callout time */ Uint co_decode(time, mtime) Uint time; unsigned short *mtime; { return 0; } /* * NAME: call_out->time() * DESCRIPTION: pretend to return the current time */ Uint co_time(mtime) unsigned short *mtime; { return 0; } /* * NAME: call_out->swaprate1() * DESCRIPTION: pretend to return the number of objects swapped out per minute */ long co_swaprate1() { return 0; } /* * NAME: call_out->swaprate5() * DESCRIPTION: pretend to return the number of objects swapped out per 5 mins */ long co_swaprate5() { return 0; } /* * NAME: call_out->dump() * DESCRIPTION: pretend to dump callout table */ bool co_dump(fd) int fd; { return FALSE; } /* * NAME: call_out->restore() * DESCRIPTION: pretend to restore callout table */ void co_restore(fd, t, conv) int fd, conv; Uint t; { }