From: ellson Date: Thu, 6 Jan 2005 15:01:43 +0000 (+0000) Subject: add lefty, dotty, lneato to graphviz2 tree X-Git-Tag: LAST_LIBGRAPH~32^2~8134 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=80ceab2c670d0e19a4669fc56a3bfe81a3bcb56b;p=graphviz add lefty, dotty, lneato to graphviz2 tree --- diff --git a/cmd/lefty/examples/tree.lefty b/cmd/lefty/examples/tree.lefty new file mode 100644 index 000000000..92c299784 --- /dev/null +++ b/cmd/lefty/examples/tree.lefty @@ -0,0 +1,195 @@ +load ('def.lefty'); +definit (); +# +# initialize window data +# +canvas = defcanvas; +wrect = [0 = ['x' = -5; 'y' = 0;]; 1 = ['x' = 410; 'y' = 500;];]; +setwidgetattr (canvas, ['window' = wrect;]); +# +# data structures +# +nodearray = []; +nodenum = 0; +dist = ['x' = 40; 'y' = 40;]; +defsize = ['x' = 10; 'y' = 10;]; +fontname = 'fixed'; +fontsize = 18; +tree = null; + +# drawing functions +# +boxnode = function (node) { + local center; + box (canvas, node, node.rect, ['color' = 0; 'fill' = 'on';]); + box (canvas, node, node.rect); + center = [ + 'x' = (node.rect[0].x + node.rect[1].x) / 2; + 'y' = (node.rect[0].y + node.rect[1].y) / 2; + ]; + if (node.name) + text (canvas, node, center, node.name, fontname, fontsize, 'cc'); +}; +circlenode = function (node) { + local center, radius; + center = [ + 'x' = (node.rect[0].x + node.rect[1].x) / 2; + 'y' = (node.rect[0].y + node.rect[1].y) / 2; + ]; + radius = [ + 'x' = center.x - node.rect[0].x; + 'y' = center.y - node.rect[0].y; + ]; + arc (canvas, node, center, radius, ['color' = 0; 'fill' = 'on';]); + arc (canvas, node, center, radius); + if (node.name) + text (canvas, node, center, node.name, fontname, fontsize, 'cc'); +}; +drawnode = boxnode; +drawedge = function (node1, node2) { + line (canvas, null, + [ + 'x' = (node1.rect[1].x + node1.rect[0].x) / 2; + 'y' = node1.rect[0].y; + ], [ + 'x' = (node2.rect[1].x + node2.rect[0].x) / 2; + 'y' = node2.rect[1].y; + ]); +}; +drawtree = function (node) { + local i; + for (i in nodearray) + drawnode (nodearray[i]); + drawtreerec (node); +}; +drawtreerec = function (node) { + local i, n; + if ((n = tablesize (node.ch)) > 0) { + for (i = 0; i < n; i = i + 1) { + drawedge (node, node.ch[i]); + drawtreerec (node.ch[i]); + } + } +}; +redraw = function (c) { + if (tree) + drawtree (tree); +}; + +# layout functions +# +complayout = function () { + leafx = 0; + leafrank = 0; + dolayout (tree, wrect[1].y - 10); + remove ('leafx'); + remove ('leafrank'); +}; +dolayout = function (node, pary) { + local r, n, i, size, lchp, rchp; + size = nodesize (node); + if (node.chn > 0) { + for (i = 0; i < node.chn; i = i + 1) + dolayout (node.ch[i], pary - size.y - dist.y); + node.rank = (node.ch[0].rank + node.ch[node.chn - 1].rank) / 2; + lchp = node.ch[0].rect; + rchp = node.ch[node.chn - 1].rect; + r[0].x = lchp[0].x + ((rchp[1].x - lchp[0].x) - size.x) / 2; + r[0].y = pary - size.y; + r[1].x = r[0].x + size.x; + r[1].y = pary; + node.rect = r; + } else { + node.rank = leafrank; + r[0].x = leafx; + r[0].y = pary - size.y; + r[1].x = r[0].x + size.x; + r[1].y = pary; + leafrank = leafrank + 1; + leafx = r[1].x + dist.x; + node.rect = r; + } +}; + +# editing functions +# +inode = function (point, name) { + local i, nnum, size; + nnum = nodenum; + if (~name) + name = ask ('give name of node:'); + nodearray[nnum].ch = []; + nodearray[nnum].chn = 0; + nodearray[nnum].name = name; + size = nodesize (nodearray[nnum]); + nodearray[nnum].rect[0] = point; + nodearray[nnum].rect[1] = ['x' = point.x + size.x; 'y' = point.y + size.y;]; + nodenum = nodenum + 1; + if (~tree) { + tree = nodearray[nnum]; + tree.depth = 0; + complayout (); + drawtree (tree); + } else + drawtree (nodearray[nnum]); + return nodearray[nnum]; +}; +iedge = function (node1, node2) { + node1.ch[node1.chn] = node2; + node1.chn = node1.chn + 1; + node2.depth = node1.depth + 1; + complayout (); + clear (canvas); + drawtree (tree); +}; +fix = function (node, op, np) { + if (node.depth ~= 0) + dist.y = dist.y + (op.y - np.y) / node.depth; + if (node.rank ~= 0) + dist.x = dist.x + (np.x - op.x) / node.rank; + complayout (); + clear (canvas); + drawtree (tree); +}; +nodesize = function (node) { + local siz; + if (~(siz = textsize (canvas, node.name, fontname, fontsize))) + siz = defsize; + else { + siz.x = siz.x + 8; + siz.y = siz.y + 8; + } + return siz; +}; +changenode = function (nodestyle) { + drawnode = nodestyle; + clear (canvas); + drawtree (tree); +}; + +# user interface functions +# +leftdown = function (data) { + if (~data.obj) + inode (data.pos, null); +}; +leftup = function (data) { + if (data.pobj) + fix (data.pobj, data.ppos, data.pos); +}; +middleup = function (data) { + if (data.pobj & data.obj) + iedge (data.pobj, data.obj); +}; +dops = function () { + local s; + + s = ['x' = 8 * 300; 'y' = 10.5 * 300;]; + fontname = 'Times-Roman'; + canvas = createwidget (-1, ['type' = 'ps'; 'size' = s;]); + setwidgetattr (canvas, ['window' = wrect;]); + drawtree (tree); + destroywidget (canvas); + canvas=defcanvas; + fontname = 'fixed'; +}; diff --git a/cmd/lefty/io.h b/cmd/lefty/io.h new file mode 100644 index 000000000..cc940f38a --- /dev/null +++ b/cmd/lefty/io.h @@ -0,0 +1,81 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2004 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Lefteris Koutsofios - AT&T Bell Laboratories */ + +#ifndef _IO_H +#define _IO_H + + typedef enum { + IO_FILE, IO_PTY, IO_PIPE, IO_SOCKET, +#ifdef FEATURE_CS + IO_CS, +#endif + IO_SIZE + } iotype_t; + + typedef struct io_t { + int inuse, ismonitored; + iotype_t type; + FILE *ifp, *ofp; + int pid; + char *buf; + } io_t; + +#ifdef FEATURE_MS +#define IOmonitor(ioi, set) do { \ + iop[ioi].ismonitored = TRUE; \ +} while (0) +#define IOunmonitor(ioi, set) do { \ + iop[ioi].ismonitored = FALSE; \ +} while (0) +#else +#define IOmonitor(ioi, set) do { \ + iop[ioi].ismonitored = TRUE; \ + FD_SET (fileno (iop[ioi].ifp), &set); \ +} while (0) +#define IOunmonitor(ioi, set) do { \ + iop[ioi].ismonitored = FALSE; \ + FD_CLR (fileno (iop[ioi].ifp), &set); \ +} while (0) +#endif + +#define IOismonitored(ioi) (iop[ioi].ismonitored == TRUE) +#define IOINCR 5 +#define IOSIZE sizeof (io_t) +#define IOBUFSIZE 2048 + + extern io_t *iop; + extern int ion; + + void IOinit(void); + void IOterm(void); + int IOopen(char *, char *, char *, char *); + int IOclose(int, char *); + int IOreadline(int, char *, int); + int IOread(int, char *, int); + int IOwriteline(int, char *); + +#endif /* _IO_H */ + +#ifdef __cplusplus +} +#endif diff --git a/cmd/lefty/lefty.1 b/cmd/lefty/lefty.1 new file mode 100644 index 000000000..bf73d040e --- /dev/null +++ b/cmd/lefty/lefty.1 @@ -0,0 +1,120 @@ +.TH LEFTY 1 +.SH NAME +lefty \- A Programmable Graphics Editor +.SH SYNOPSIS +.B lefty +[ +.I options +] [ +.I file +] +.SH DESCRIPTION +.B lefty +is a two-view graphics editor for technical pictures. This editor has +no hardwired knowledge about specific picture layouts or editing operations. +Each picture is described by a program that contains functions to draw the +picture and functions to perform editing operations that are appropriate for +the specific picture. Primitive user actions, like mouse and keyboard events, +are also bound to functions in this program. Besides the graphical view of the +picture itself, the editor presents a textual view of the program that +describes the picture. Programmability and the two-view interface allow the +editor to handle a variety of pictures, but are particularly useful for +pictures used in technical contexts, e.g., graphs and trees. Also, +.B lefty +can communicate with other processes. This feature allows it to use existing +tools to compute specific picture layouts and allows external processes to use +the editor as a front end to display their data structures graphically. +.SH USAGE +The file name is optional. It may be +.BR - , +for reading from standard input. +.B lefty +uses two environment variables, +.B LEFTYPATH +and +.BR LEFTYOPTIONS . +.B LEFTYPATH +is a colon separated list of directories. When +.B lefty +tries to open a file, it searches that path for the file. When +.B lefty +tries to start up another process, it searches +.B LEFTYPATH +first, then the standard +.B PATH +variable. +.B LEFTYOPTIONS +can be used to set specific options. Options specified on the command line +override options set through this variable. +.SH OPTIONS +.TP +.B -x +Instructs the editor to exit after processing +.BR file . +.TP +.B "-e " +.B +is parsed and executed. +.TP +.B -el +Set error reporting level. The default value is +.BR 0 . +.B 0 +never prints any messages. +.B 1 +prints severe errors, such as trying to return from a non function. +.B 2 +is the most useful: it reports function calls that cannot be executed, either +because there is no function, or because of argument mismatches. +.B 3 +also warns about bad variable names. +.B 4,5 +warn about expressions that do not return a value. Only level +.B 1 +messages are real errors. The rest arise from legal +.B lefty +statements, but may be cased by some logic errors. +.TP +.B "-sd " +Specifies how much of the stack to show, when an error message is to be +printed. The defualt value is +.BR 2 . +With +.BR 0 , +no part of the stack is shown. With +.BR 1 , +only the top stack frame is printed. With +.BR 2 , +the full stack is printed. +.TP +.B "-sb " +Specifies how much of each function in the stack to show, when an error message +is to be printed. The default value is +.BR 2 . +With +.BR 0 , +no part of the function is shown. With +.BR 1 , +only the line around the error is printed. With +.BR 2 , +the full function body is printed. +.TP +.B "-df " +Sets the default font. This font is used whenever a requested font cannot be +found. The string must be a legal X font. If string is +.BR "''" , +.B lefty +will draw small boxes instead of text. +.TP +.B "-ps " +Specifies a default file name for postscript files. This name is used when no +name is specified in the +.B createwidget +call. The default file name is +.BR out.ps . +.TP +.B -V +Prints the version. +.SH SEE ALSO +.I lefty +user guide. diff --git a/cmd/lefty/lefty.c b/cmd/lefty/lefty.c new file mode 100644 index 000000000..51432f2e2 --- /dev/null +++ b/cmd/lefty/lefty.c @@ -0,0 +1,534 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2004 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + + +/* Lefteris Koutsofios - AT&T Bell Laboratories */ + +#ifdef FEATURE_GTK +#include +#include +#endif + +#include "common.h" +#include "g.h" +#include "code.h" +#include "io.h" +#include "mem.h" +#include "tbl.h" +#include "parse.h" +#include "exec.h" +#include "str.h" +#include "display.h" +#include "internal.h" +#include "txtview.h" +#include "gfxview.h" +#ifdef FEATURE_GMAP +#include "gmap.h" +#include "gmap2l.h" +#endif +#ifndef FEATURE_MS +#include +#ifdef HAVE_UNISTD_H +#include +#include +#endif +#ifdef STATS +#include +#endif +#endif + +/* the gnu way is to test for features explicitly */ +#ifdef HAVE_FILE_R +#define canread(fp) ((fp)->_r > 0) +#else +#ifdef HAVE_FILE_IO_READ_END +#define canread(fp) ((fp)->_IO_read_end > (fp)->_IO_read_ptr) +#else +#ifdef HAVE_FILE_CNT +#define canread(fp) ((fp)->_cnt > 0) +#else +#ifdef HAVE_FILE_NEXT +#define canread(fp) ((fp)->next < (fp)->endb) +#else +#ifdef HAVE___FREADABLE +#define canread(fp) (__freadable(fp)) + +/* the other way is to presume a feature based on OS */ +#else +#ifdef FEATURE_CS +#define canread(fp) ((fp)->next < (fp)->endb) +#else +#ifdef FEATURE_GNU +#define canread(fp) ((fp)->_IO_read_end > (fp)->_IO_read_ptr) +#else +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__Mac_OSX__) +#define canread(fp) ((fp)->_r > 0) +#endif +#endif +#endif +#endif + +#endif +#endif +#endif +#endif + +#ifdef FEATURE_GMAP +static int gmapon; +#endif + +static Grect_t txtcoords = { + {1, 1}, {449, 599}, +}; + +#ifdef STATS +static time_t stime; +#endif + +static int endflag = FALSE; + +static char *exprstr; +static FILE *fp; + +static int processinput(int); +static void processargs(int, char **); +static void processstr(char *); +static void printusage(void); + +#if defined(FEATURE_X11) || defined(FEATURE_NONE) || defined(FEATURE_GTK) + +int main(int argc, char **argv) +{ + Tobj co; + Psrc_t src; + +#ifdef MTRACE + extern int Mt_certify; + Mt_certify = 1; +#endif +#ifdef STATS + stime = time(NULL); +#endif + + idlerunmode = 0; + exprstr = NULL; + fp = NULL; + init(argv[0]); + Minit(GFXprune); + Ginit(); + FD_SET(Gxfd, &inputfds); + + Eerrlevel = 1; + Estackdepth = 2; + Eshowbody = 1; + Eshowcalls = 1; + + processstr(leftyoptions); + argv++, argc--; + processargs(argc, argv); + + if (setjmp(exitljbuf)) + goto eop; + + Cinit(); + IOinit(); + Tinit(); + Pinit(); + Einit(); + Sinit(); + Dinit(); + Iinit(); + TXTinit(txtcoords); + GFXinit(); +#ifdef FEATURE_GMAP + gmapon = TRUE, G2Linit(); +#endif + + if (exprstr) { + src.flag = CHARSRC, src.s = exprstr, src.fp = NULL; + src.tok = -1, src.lnum = 1; + while ((co = Punit(&src))) + Eunit(co); + } + if (fp) { + src.flag = FILESRC, src.s = NULL, src.fp = fp; + src.tok = -1, src.lnum = 1; + while ((co = Punit(&src))) + Eunit(co); + } + if (endflag) + goto eop; + + TXTupdate(); + + +#ifdef FEATURE_GTK + while (gtk_events_pending()) { + gtk_main_iteration(); + } + + Gneedredraw = FALSE; + while (TRUE) { + if (gtk_events_pending()) { + GdkEvent *eve; + + gtk_main_iteration(); + if (Gneedredraw) + GFXredraw(), Gneedredraw = FALSE; + if (Gbuttonsdown > 0) { + GFXmove(), Gprocessevents(FALSE, G_ONEEVENT); + processinput(FALSE); + } else { + if (Mcouldgc) { + if (!processinput(FALSE)) + Mdogc(M_GCINCR); + } else if (idlerunmode) { + if (!processinput(FALSE)) + GFXidle(); + } else + processinput(TRUE); + } +#ifdef FEATURE_GMAP + if (gmapon) + GMAPupdate(); +#endif + if (Erun) + TXTupdate(), Erun = FALSE; + } + } +#else + + Gneedredraw = FALSE; + for (;;) { + if (Gneedredraw) + GFXredraw(), Gneedredraw = FALSE; + if (Gbuttonsdown > 0) { + GFXmove(), Gprocessevents(FALSE, G_ONEEVENT); + processinput(FALSE); + } else { + if (Mcouldgc) { + if (!processinput(FALSE)) + Mdogc(M_GCINCR); + } + if (idlerunmode) { + if (!processinput(FALSE)) + GFXidle(); + } else + processinput(TRUE); + } +#ifdef FEATURE_GMAP + if (gmapon) + GMAPupdate(); +#endif + if (Erun) + TXTupdate(), Erun = FALSE; + } +#endif /* end of else part of FEATURE_GTK */ + + eop: +#ifdef PARANOID +#ifdef FEATURE_GMAP + if (gmapon) + G2Lterm(); +#endif + GFXterm(); + TXTterm(); + Iterm(); + Dterm(); + Sterm(); + Eterm(); + Pterm(); + Tterm(); + IOterm(); + Cterm(); + Gterm(); + Mterm(); + FD_CLR(Gxfd, &inputfds); + term(); +#endif + printusage(); + return 0; +} + +#else + +extern char **__argv; +extern int __argc; + +HANDLE hinstance, hprevinstance; + +int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, + LPSTR lpCmdLine, int nCmdShow) +{ + Tobj co; + Psrc_t src; + + hinstance = hInstance; + hprevinstance = hPrevInstance; + idlerunmode = 0; + exprstr = NULL; + fp = NULL; + init(NULL); + Ginit(); +#ifndef FEATURE_MS + FD_SET(Gxfd, &inputfds); +#endif + + Eerrlevel = 1; + Estackdepth = 2; + Eshowbody = 1; + Eshowcalls = 1; + + processstr(leftyoptions); + __argv++, __argc--; + processargs(__argc, __argv); + + if (setjmp(exitljbuf)) + goto eop; + + Cinit(); + IOinit(); + Minit(GFXprune); + Tinit(); + Pinit(); + Einit(); + Sinit(); + Dinit(); + Iinit(); + TXTinit(txtcoords); + GFXinit(); + + if (exprstr) { + src.flag = CHARSRC, src.s = exprstr, src.fp = NULL; + src.tok = -1, src.lnum = 1; + while ((co = Punit(&src))) + Eunit(co); + } + if (fp) { + src.flag = FILESRC, src.s = NULL, src.fp = fp; + src.tok = -1, src.lnum = 1; + while ((co = Punit(&src))) + Eunit(co); + } + if (endflag) + goto eop; + + TXTupdate(); + + Gneedredraw = FALSE; + for (;;) { + if (Gneedredraw) + GFXredraw(), Gneedredraw = FALSE; + if (Gbuttonsdown > 0) + GFXmove(), Gprocessevents(FALSE, G_ONEEVENT); + else { + if (Mcouldgc) { + if (!processinput(FALSE)) + Mdogc(M_GCINCR); + } else if (idlerunmode) { + if (!processinput(FALSE)) + GFXidle(); + } else + processinput(TRUE); + } + if (Erun) + TXTupdate(), Erun = FALSE; + } + + eop: +#ifdef PARANOID + GFXterm(); + TXTterm(); + Iterm(); + Dterm(); + Sterm(); + Eterm(); + Pterm(); + Tterm(); + Mterm(); + IOterm(); + Cterm(); + Gterm(); + term(); +#endif + printusage(); + exit(0); +} + +#endif + +#ifndef FEATURE_MS +static struct timeval longwait = { 1000, 0 }; +static struct timeval zerowait = { 0, 0 }; +#endif + +static int processinput(int waitflag) +{ + fd_set fdset; +#ifndef FEATURE_MS + struct timeval tz, *tzp; +#else + HANDLE evs[MAXIMUM_WAIT_OBJECTS]; + int evn; +#endif + int n, rtn; + int ioi; + + rtn = 0; + while (Gprocessevents(FALSE, G_MANYEVENTS)) + rtn = 1; +#ifndef FEATURE_MS + for (ioi = 0, n = 0; ioi < ion; ioi++) + if (iop[ioi].inuse && iop[ioi].ismonitored && + FD_ISSET(fileno(iop[ioi].ifp), &inputfds) && + canread(iop[ioi].ifp)) + GFXmonitorfile(ioi), n++; + if (n || rtn) + return 1; + if (Gneedredraw) + return 0; + tz = (waitflag && !rtn) ? longwait : zerowait; + tzp = &tz; + fdset = inputfds; + if ((n = select(FD_SETSIZE, &fdset, NULL, NULL, tzp)) <= 0) + return rtn; + rtn = 1; + if (FD_ISSET(Gxfd, &fdset)) + Gprocessevents(TRUE, G_MANYEVENTS), n--; + if (!n) + return rtn; + Gsync(); + for (ioi = 0; n > 0 && ioi < ion; ioi++) + if (iop[ioi].inuse && iop[ioi].ismonitored && + FD_ISSET(fileno(iop[ioi].ifp), &fdset)) + GFXmonitorfile(ioi), n--; +#else + for (ioi = 0, n = 0, evn = 0; ioi < ion; ioi++) { + if (!iop[ioi].inuse || !IOismonitored(ioi, inputfds)) + continue; + if ((iop[ioi].type == IO_FILE && canread(iop[ioi].ifp)) || + (iop[ioi].type == IO_PIPE && iop[ioi].buf[0])) + GFXmonitorfile(ioi), n++; + if (iop[ioi].type != IO_PIPE) + continue; + evs[evn++] = iop[ioi].ifp; + } + if (n) + return 1; + if (Gneedredraw) + return 0; + n = MsgWaitForMultipleObjects(evn, evs, FALSE, + (waitflag && !rtn) ? 1 : 0, QS_ALLINPUT); + if (n == WAIT_TIMEOUT || n < WAIT_OBJECT_0 || n > WAIT_OBJECT_0 + evn) + return rtn; + if (n == WAIT_OBJECT_0 + evn) + Gprocessevents(TRUE, G_MANYEVENTS); + Gsync(); + for (ioi = 0; ioi < ion; ioi++) + if (iop[ioi].inuse && IOismonitored(ioi) && + (iop[ioi].type == IO_FILE || (iop[ioi].type == IO_PIPE && + evs[n - WAIT_OBJECT_0] == + iop[ioi].ifp))) + GFXmonitorfile(ioi); +#endif + return rtn; +} + +static void processstr(char *buf) +{ + char *words[100]; + char *s, *s1; + int i; + + if (!(s = buf) || *s == 0) + return; + s = strdup(s); + for (i = 0, s1 = s; *s1;) { + for (; *s1 && *s1 == ' '; s1++); + if (!*s1) + break; + words[i++] = s1; + for (; *s1 && *s1 != ' '; s1++); + if (*s1) + *s1 = '\000', s1++; + } + words[i] = NULL; + processargs(i, words); + free(s); +} + +static void processargs(int argc, char *argv[]) +{ + while (argc) { + if (Strcmp(argv[0], "-x") == 0) + endflag = TRUE; + else if (Strcmp(argv[0], "-e") == 0) + exprstr = argv[1], argv++, argc--; + else if (Strcmp(argv[0], "-el") == 0) + Eerrlevel = atoi(argv[1]), argv++, argc--; + else if (Strcmp(argv[0], "-sd") == 0) + Estackdepth = atoi(argv[1]), argv++, argc--; + else if (Strcmp(argv[0], "-sb") == 0) + Eshowbody = atoi(argv[1]), argv++, argc--; + else if (Strcmp(argv[0], "-sc") == 0) + Eshowcalls = atoi(argv[1]), argv++, argc--; + else if (Strcmp(argv[0], "-df") == 0) + Gdefaultfont = argv[1], argv++, argc--; + else if (Strcmp(argv[0], "-w") == 0) + warnflag = TRUE; + else if (Strcmp(argv[0], "-ps") == 0) + Gpscanvasname = argv[1], argv++, argc--; + else if (Strcmp(argv[0], "-V") == 0) + fprintf(stderr, "lefty version %s (%s)\n", VERSION, BUILDDATE); + else if (Strcmp(argv[0], "-") == 0) + fp = stdin; + else { + if ((fp = fopen(argv[0], "r")) == NULL) + panic(POS, "main", "cannot open input file: %s", argv[0]); + } + argv++, argc--; + } + if (Eerrlevel > 1) + Gerrflag = TRUE; +} + +static void printusage(void) +{ +#ifdef STATS + struct rusage ru; + + getrusage(RUSAGE_SELF, &ru); + Mreport(); +#ifdef FEATURE_RUSAGE + printf("user time %13.3lf\n", + ru.ru_utime.tv_sec + ru.ru_utime.tv_nsec / 1000000000.0); + printf("system time %13.3lf\n", + ru.ru_stime.tv_sec + ru.ru_stime.tv_nsec / 1000000000.0); +#else + printf("user time %13.3lf\n", + ru.ru_utime.tv_sec + ru.ru_utime.tv_usec / 1000000.0); + printf("system time %13.3lf\n", + ru.ru_stime.tv_sec + ru.ru_stime.tv_usec / 1000000.0); +#endif + printf("resident size %10d\n", ru.ru_maxrss * getpagesize()); + printf("input %8d\n", ru.ru_inblock); + printf("output %8d\n", ru.ru_oublock); + printf("socket msgs sent %8d\n", ru.ru_msgsnd); + printf("socket msgs rcvd %8d\n", ru.ru_msgrcv); + printf("real time %8d\n", time(NULL) - stime); + fflush(stdout); +#endif +} diff --git a/cmd/lefty/lefty.psp b/cmd/lefty/lefty.psp new file mode 100644 index 000000000..c3c9b0138 --- /dev/null +++ b/cmd/lefty/lefty.psp @@ -0,0 +1,79 @@ +/BOX { + /boxy1 exch def /boxx1 exch def /boxy0 exch def /boxx0 exch def + boxx0 boxy0 moveto boxx1 boxy0 lineto + boxx1 boxy1 lineto boxx0 boxy1 lineto + closepath +} def +/SCP { stroke initclip newpath BOX clip newpath } def +/CL { stroke setrgbcolor } def +/DO { stroke } def +/NP { newpath } def +/FI { fill } def +/LI { moveto lineto } def +/CT { curveto } def +/AR { + /ang2 exch def /ang1 exch def + /radius exch def /y2x exch def /cy exch def /cx exch def + gsave + cx cy translate 1 y2x scale 0 0 radius ang1 ang2 arc stroke + grestore +} def +/ARF { + /ang2 exch def /ang1 exch def + /radius exch def /y2x exch def /cy exch def /cx exch def + gsave + cx cy translate 1 y2x scale 0 0 radius ang1 ang2 arc fill + grestore +} def +/TXT { + /texth exch def + /textf exch def + /textn exch def + /texts exch def + /textyj exch def /texty exch def + /textxj exch def /textx exch def + textf findfont texth scalefont dup setfont + /FontBBox get 1 get 1000 div texth mul /textbl exch def + /textth texth textn mul def /texttw 0 def + 0 1 textn 1 sub { + texts exch get 0 get stringwidth pop + dup texttw gt { /texttw exch def } { pop } ifelse + } for + textyj (d) eq { /ty texty textth add def } if + textyj (c) eq { /ty texty textth 2 div add def } if + textyj (u) eq { /ty texty def } if + /ty ty textbl sub def + textxj (l) eq { /tx textx def } if + textxj (c) eq { /tx textx texttw 2 div sub def } if + textxj (r) eq { /tx textx texttw sub def } if + 0 1 textn 1 sub { + /ty ty texth sub def + texts exch get dup 0 get /ts exch def 1 get /tj exch def + tj (l) eq { tx ty moveto ts show } if + tj (n) eq { + tx texttw ts stringwidth pop sub 2 div add ty moveto ts show + } if + tj (r) eq { + tx texttw ts stringwidth pop sub add ty moveto ts show + } if + } for +} def + +/colorimage where { + pop +} { + /bwproc { + rgbproc dup length 3 idiv string 0 3 0 5 -1 roll { + add 2 1 roll 1 sub dup 0 eq { + pop 3 idiv 3 -1 roll dup 4 -1 roll + dup 3 1 roll 5 -1 roll put 1 add 3 0 + } { + 2 1 roll + } ifelse + } forall + pop pop pop + } def + /colorimage { + pop pop /rgbproc exch def {bwproc} image + } bind def +} ifelse diff --git a/cmd/lefty/lex.c b/cmd/lefty/lex.c new file mode 100644 index 000000000..31c61a19c --- /dev/null +++ b/cmd/lefty/lex.c @@ -0,0 +1,293 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2004 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + + +/* Lefteris Koutsofios - AT&T Bell Laboratories */ + +#include "common.h" +#include "lex.h" + +Ltype_t Ltok; +char Lstrtok[MAXTOKEN]; + +Lname_t Lnames[] = { + /* L_SEMI */ ";", + /* L_ASSIGN */ "=", + /* L_OR */ "|", + /* L_AND */ "&", + /* L_EQ */ "==", + /* L_NE */ "~=", + /* L_LT */ "<", + /* L_LE */ "<=", + /* L_GT */ ">", + /* L_GE */ ">=", + /* L_PLUS */ "+", + /* L_MINUS */ "-", + /* L_MUL */ "*", + /* L_DIV */ "/", + /* L_MOD */ "%", + /* L_NOT */ "~", + /* L_STRING */ "STRING", + /* L_NUMBER */ "NUMBER", + /* L_ID */ "IDENTIFIER", + /* L_DOT */ "DOT", + /* L_LB */ "LEFT BRACKET", + /* L_RB */ "RIGHT BRACKET", + /* L_FUNCTION */ "FUNCTION", + /* L_LP */ "LEFT PARENTHESIS", + /* L_RP */ "RIGHT PARENTHESIS", + /* L_LCB */ "LEFT CURLY BRACE", + /* L_RCB */ "RIGHT CURLY BRACE", + /* L_LOCAL */ "LOCAL", + /* L_COLON */ ":", + /* L_COMMA */ ",", + /* L_IF */ "IF", + /* L_ELSE */ "ELSE", + /* L_WHILE */ "WHILE", + /* L_FOR */ "FOR", + /* L_IN */ "IN", + /* L_BREAK */ "BREAK", + /* L_CONTINUE */ "CONTINUE", + /* L_RETURN */ "RETURN", + /* L_INTERNAL */ "INTERNAL", + /* L_EOF */ "EOF" +}; + +static char *unitp, *ucp; +static FILE *lfp; +static int lsrc, seeneof, linenum; + +#define MAXBUF 10000 +static char unitbuf[MAXBUF]; + +/* keyword mapping */ +static struct keyword { + char *str; + int tok; +} keywords[] = { + { + "function", L_FUNCTION}, { + "local", L_LOCAL}, { + "if", L_IF}, { + "else", L_ELSE}, { + "while", L_WHILE}, { + "for", L_FOR}, { + "in", L_IN}, { + "break", L_BREAK}, { + "continue", L_CONTINUE}, { + "return", L_RETURN}, { + "internal", L_INTERNAL}, { + NULL, 0} +}; + +/* single character token mapping */ +static struct keychar { + int chr, tok; +} keychars[] = { + { + ';', L_SEMI}, { + '|', L_OR}, { + '&', L_AND}, { + '+', L_PLUS}, { + '-', L_MINUS}, { + '*', L_MUL}, { + '/', L_DIV}, { + '%', L_MOD}, { + '.', L_DOT}, { + '[', L_LB}, { + ']', L_RB}, { + '(', L_LP}, { + ')', L_RP}, { + '{', L_LCB}, { + '}', L_RCB}, { + ':', L_COLON}, { + ',', L_COMMA}, { + '\000', 0} +}; + +static Ltype_t gtok(void); +static int sgetc(void); +static void sungetc(void); + +void Lsetsrc(int src, char *s, FILE * fp, int tok, int lnum) +{ + if (src == CHARSRC) + unitp = ucp = s; + else if (src == FILESRC) + unitp = ucp = unitbuf, unitbuf[0] = '\000', lfp = fp; + lsrc = src; + linenum = lnum; + seeneof = FALSE; + if (tok == -1 || tok == L_EOF) + Ltok = gtok(); + else + Ltok = (Ltype_t) tok; +} + +void Lgetsrc(int *srcp, char **sp, FILE ** fpp, int *tokp, int *lnump) +{ + *srcp = lsrc; + *sp = ucp; + *fpp = lfp; + *tokp = Ltok; + if (*ucp && *ucp == '\n') + linenum++; + *lnump = linenum; +} + +void Lprintpos(void) +{ + char *s1, *s2; + char c; + + printf("at line %d: ", linenum); + for (s1 = ucp; s1 > unitp && *s1 != '\n'; s1--); + for (s2 = ucp; *s2 && *s2 != '\n'; s2++); + c = *s2, *s2 = '\000'; + printf("%s\n", s1); + *s2 = c; +} + +void Lgtok(void) +{ + Ltok = gtok(); +} + +static Ltype_t gtok(void) +{ + struct keyword *kwp; + struct keychar *kcp; + int c, qc, nc; + char *p; + + while ((c = sgetc()) != EOF) { + if (c == '#') + while ((c = sgetc()) != '\n'); + if (c != ' ' && c != '\t' && c != '\n') + break; + } + if (c == EOF) + return L_EOF; + /* check for keywords and identifiers */ + if (isalpha(c) || c == '_') { + p = &Lstrtok[0], *p++ = c; + while (isalpha((c = sgetc())) || isdigit(c) || c == '_') + *p++ = c; + sungetc(); + *p = '\000'; + for (kwp = &keywords[0]; kwp->str; kwp++) + if (Strcmp(kwp->str, Lstrtok) == 0) + return (Ltype_t) (kwp->tok); + return L_ID; + } + /* check for number constant */ + if (isdigit(c)) { + p = &Lstrtok[0], *p++ = c; + while (isdigit((c = sgetc()))) + *p++ = c; + if (c == '.') { + *p++ = c; + while (isdigit((c = sgetc()))) + *p++ = c; + } + sungetc(); + *p = '\000'; + return L_NUMBER; + } + /* check for string constants */ + if (c == '"' || c == '\'') { + p = &Lstrtok[0]; + qc = c; + while ((c = sgetc()) != EOF && c != qc) + *p++ = c; /* FIXME: deal with \'s */ + if (c == EOF) + return L_EOF; + *p = '\000'; + return L_STRING; + } + /* check for single letter keywords */ + for (kcp = &keychars[0]; kcp->chr; kcp++) + if (kcp->chr == c) + return (Ltype_t) (kcp->tok); + /* check for 2/1 letter keywords */ + if (c == '=' || c == '~' || c == '<' || c == '>') { + nc = sgetc(); + if (nc == '=') { + switch (c) { + case '=': + return L_EQ; + case '~': + return L_NE; + case '<': + return L_LE; + case '>': + return L_GE; + } + } else { + sungetc(); + switch (c) { + case '=': + return L_ASSIGN; + case '~': + return L_NOT; + case '<': + return L_LT; + case '>': + return L_GT; + } + } + } + return L_EOF; +} + +static int sgetc(void) +{ + if (seeneof) + return EOF; + if (*ucp == '\000') { + if (lsrc == CHARSRC) { + seeneof = TRUE; + linenum++; + return EOF; + } else if (lsrc == FILESRC) { + if (ucp != unitp) + *unitp = *(ucp - 1), ucp = unitp + 1; + else + ucp = unitp; + *ucp = '\000'; + if (!fgets(ucp, MAXBUF - (ucp - unitp), lfp)) { + seeneof = TRUE; + return EOF; + } + } + } + if (*ucp == '\n') + linenum++; + return *ucp++; +} + +static void sungetc(void) +{ + if (seeneof) { + seeneof = FALSE; + return; + } + if (ucp == unitp) + panic(POS, "sungetc", "unget before start of string"); + ucp--; + if (*ucp == '\n') + linenum--; +} diff --git a/cmd/lefty/lex.h b/cmd/lefty/lex.h new file mode 100644 index 000000000..d5e6a7277 --- /dev/null +++ b/cmd/lefty/lex.h @@ -0,0 +1,51 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2004 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Lefteris Koutsofios - AT&T Bell Laboratories */ + +#ifndef _LEX_H +#define _LEX_H + typedef enum { + L_SEMI, L_ASSIGN, L_OR, L_AND, L_EQ, L_NE, L_LT, L_LE, L_GT, L_GE, + L_PLUS, + L_MINUS, L_MUL, L_DIV, L_MOD, L_NOT, L_STRING, L_NUMBER, L_ID, + L_DOT, + L_LB, L_RB, L_FUNCTION, L_LP, L_RP, L_LCB, L_RCB, L_LOCAL, L_COLON, + L_COMMA, L_IF, L_ELSE, L_WHILE, L_FOR, L_IN, L_BREAK, L_CONTINUE, + L_RETURN, L_INTERNAL, L_EOF, L_SIZE + } Ltype_t; + +#define MAXTOKEN 1000 + typedef char *Lname_t; + + extern Ltype_t Ltok; + extern char Lstrtok[]; + extern Lname_t Lnames[]; + + void Lsetsrc(int, char *, FILE *, int, int); + void Lgetsrc(int *, char **, FILE **, int *, int *); + void Lprintpos(void); + void Lgtok(void); +#endif /* _LEX_H */ + +#ifdef __cplusplus +} +#endif diff --git a/cmd/lefty/mem.c b/cmd/lefty/mem.c new file mode 100644 index 000000000..de66eacaf --- /dev/null +++ b/cmd/lefty/mem.c @@ -0,0 +1,426 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2004 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + + +/* Lefteris Koutsofios - AT&T Bell Laboratories */ + +#include "common.h" +#include "mem.h" + +/* SHORTCUT: the following are imported from tbl.c */ +extern void Tgchelper(void *), Tfreehelper(void *); + +#define M_MAXTYPES 6 + +int Mhaspointers[M_MAXTYPES]; +Mgcstate_t Mgcstate; +int Mcouldgc; + +typedef struct buffer_t { + void *data; + struct buffer_t *next; +} buffer_t; +#define BUFFERSIZE sizeof (buffer_t) +static buffer_t *bufferlist; + +typedef struct freeobj_t { + Mheader_t head; + void *next; +} freeobj_t; +#define FREEOBJSIZE sizeof (freeobj_t) +#define FREESIZE sizeof (void *) +static void **freearray; +static long freen; + +#define MARKSIZE sizeof (void *) +#define MARKINCR 100 +static void **markarray; +static long markn, marki; + +#define OTSIZE sizeof (void *) +#define OTINCR 1000 +static void **otarray[2]; +static long otn, oti, otj; +static char otarea[2]; + +static void (*cbfunc) (void); + +#define GCINCRSTEPS 4 +static int gcsteps = GCINCRSTEPS; + +#define NUMOFALLOCS 10 +static int numofallocs = 0; + +#define CALCNUM(size) ((size < 20) ? 1000 : ((size < 200) ? 100 : 1)) + +#ifdef STATS +static caddr_t origsbrk, finsbrk; +static long objnum, objsiz; +static long typenum[M_MAXTYPES], typesiz[M_MAXTYPES]; +#endif + +static void allocbuffer(long); + +void Minit(void (*func) (void)) +{ + +#ifdef STATS + int i; + + origsbrk = (caddr_t) sbrk(0); + for (i = 0; i < M_MAXTYPES; i++) + typenum[i] = typesiz[i] = 0; +#endif + + freearray = Marrayalloc((long) FREESIZE); + freen = 1; + freearray[0] = NULL; + markarray = Marrayalloc((long) MARKINCR * MARKSIZE); + markn = MARKINCR; + marki = 0; + otarray[0] = Marrayalloc((long) OTINCR * OTSIZE); + otarray[1] = Marrayalloc((long) OTINCR * OTSIZE); + otn = OTINCR; + oti = otj = 0; + otarea[0] = 1, otarea[1] = 2; + cbfunc = func; + Mcouldgc = FALSE; +} + +void Mterm(void) +{ + buffer_t *bp; + +#ifdef STATS + finsbrk = (caddr_t) sbrk(0); + printf("memory used by data: %ld\n", (long) (finsbrk - origsbrk)); +#endif + + Marrayfree(otarray[0]), Marrayfree(otarray[1]); + otarray[0] = otarray[1] = NULL; + otn = otj = oti = 0; + Marrayfree(freearray), freearray = NULL, freen = 0; + Marrayfree(markarray), markarray = NULL, markn = marki = 0; + for (bp = bufferlist; bp;) { + free(bp->data); + bufferlist = bp, bp = bp->next, free(bufferlist); + } + bufferlist = NULL; +} + +void *Mnew(long size, int type) +{ + freeobj_t *fp; + + size = (size < FREEOBJSIZE) ? + M_BYTE2SIZE(FREEOBJSIZE) : M_BYTE2SIZE(size); + if (size >= freen || !freearray[size]) { + allocbuffer(size), numofallocs++; + if (numofallocs == NUMOFALLOCS) + Mdogc(M_GCFULL), gcsteps <<= 1, numofallocs = 0; + else + Mdogc(M_GCINCR); + } else if (Mgcstate == M_GCON) + Mdogc(M_GCINCR); + fp = freearray[size], freearray[size] = fp->next; + fp->head.type = type; + Mmkcurr(fp); + Mcouldgc = TRUE; + +#ifdef STATS + objnum++, objsiz += size; + typenum[type]++, typesiz[type] += size; +#endif + + return fp; +} + +void *Mallocate(long size) +{ + freeobj_t *fp; + + size = (size < FREEOBJSIZE) ? + M_BYTE2SIZE(FREEOBJSIZE) : M_BYTE2SIZE(size); + if (size >= freen || !freearray[size]) + allocbuffer(size); + fp = freearray[size], freearray[size] = fp->next; + return fp; +} + +void Mfree(void *p, long size) +{ + freeobj_t *fp; + + fp = p; + fp->head.size = size; + fp->head.area = 0; + fp->head.type = 0; + fp->next = freearray[fp->head.size], freearray[fp->head.size] = fp; +} + +#ifndef FEATURE_MS + +void *Marrayalloc(long size) +{ + void *p; + + if (!(p = malloc(size))) + panic(POS, "Marrayallocate", "cannot allocate array"); + return p; +} + +void *Marraygrow(void *p, long size) +{ + if (!(p = realloc(p, size))) + panic(POS, "Marrayreallocate", "cannot re-allocate array"); + return p; +} + +void Marrayfree(void *p) +{ + free(p); +} + +#else + +static struct arraymap_t { + HGLOBAL k; + void *v; +} arraymap[100]; + +void *Marrayalloc(long size) +{ + int i; + + for (i = 0; i < 100; i++) + if (!arraymap[i].k) + break; + if (i == 100) + panic(POS, "Marrayalloc", "out of space in arraymap"); + if (!(arraymap[i].k = GlobalAlloc(GPTR, size))) + panic(POS, "Marrayallocate", "cannot allocate array"); + arraymap[i].v = GlobalLock(arraymap[i].k); + return arraymap[i].v; +} + +void *Marraygrow(void *p, long size) +{ + int i; + + for (i = 0; i < 100; i++) + if (arraymap[i].v == p) + break; + if (i == 100) + panic(POS, "Marraygrow", "cannot locate pointer"); + if (! + (arraymap[i].k = + GlobalReAlloc(arraymap[i].k, size, GMEM_MOVEABLE))) + panic(POS, "Marraygrow", "cannot re-allocate array"); + arraymap[i].v = GlobalLock(arraymap[i].k); + return arraymap[i].v; +} + +void Marrayfree(void *p) +{ + int i; + + for (i = 0; i < 100; i++) + if (arraymap[i].v == p) + break; + if (i == 100) + panic(POS, "Marrayfree", "cannot locate pointer"); + GlobalUnlock(arraymap[i].k); + GlobalFree(arraymap[i].k); + arraymap[i].k = 0; +} + +#endif + +long Mpushmark(void *p) +{ + if (marki == markn) { + markarray = Marraygrow(markarray, + (long) (markn + MARKINCR) * MARKSIZE); + markn += MARKINCR; + } + markarray[marki++] = p; + if (Mgcstate == M_GCON) + Mmkcurr(p); + return marki - 1; +} + +void Mpopmark(long m) +{ + marki = m; +} + +void Mresetmark(long m, void *p) +{ + markarray[m] = p; + if (Mgcstate == M_GCON) + Mmkcurr(p); +} + +void Mmkcurr(void *p) +{ + if (!p || M_AREAOF(p) == otarea[0]) + return; + if (oti >= otn) { + otarray[0] = + Marraygrow(otarray[0], (long) (otn + OTINCR) * OTSIZE); + otarray[1] = + Marraygrow(otarray[1], (long) (otn + OTINCR) * OTSIZE); + otn += OTINCR; + } + otarray[0][oti++] = p; + ((Mheader_t *) p)->area = otarea[0]; +} + +void Mdogc(Mgctype_t gctype) +{ + void *p; + long i; + char n; + static long prevoti; + + if (Mgcstate == M_GCOFF) { + Mgcstate = M_GCON; + p = otarray[0], otarray[0] = otarray[1], otarray[1] = p; + n = otarea[0], otarea[0] = otarea[1], otarea[1] = n; + prevoti = oti, oti = otj = 0; + for (i = 0; i < marki; i++) + Mmkcurr(markarray[i]); + } + if (gctype == M_GCFULL) { + while (otj != oti) { + p = otarray[0][otj]; + if (Mhaspointers[M_TYPEOF(p)]) + Tgchelper(p); + otj++; + } + } else { + for (i = 0; i < gcsteps && otj != oti; i++) { + p = otarray[0][otj]; + if (Mhaspointers[M_TYPEOF(p)]) + Tgchelper(p); + otj++; + } + if (otj < oti) + return; + } + for (i = 0; i < prevoti; i++) { + p = otarray[1][i]; + if (p && M_AREAOF(p) == otarea[1]) { + if (Mhaspointers[M_TYPEOF(p)]) + Tfreehelper(p); + Mfree(p, (long) ((Mheader_t *) p)->size); + } + } + if (gctype == M_GCINCR) { + if (numofallocs < NUMOFALLOCS / 2) { + int t = (gcsteps > GCINCRSTEPS) ? gcsteps >>= 1 : GCINCRSTEPS; + gcsteps = t; + numofallocs = 0; + } + } + if (cbfunc) + (*cbfunc) (); + Mgcstate = M_GCOFF; + Mcouldgc = FALSE; +} + +void Mreport(void) +{ + Mheader_t *p; + long num[M_MAXTYPES], siz[M_MAXTYPES]; + long i, n; + freeobj_t *fp; + + Mdogc(M_GCFULL); + Mdogc(M_GCFULL); + for (i = 0; i < M_MAXTYPES; i++) + num[i] = siz[i] = 0; + for (i = 0; i < oti; i++) { + p = otarray[0][i]; + siz[0] += p->size; + siz[M_TYPEOF(p)] += p->size; + num[M_TYPEOF(p)]++; + num[0]++; + } + fprintf(stderr, "live objects: %8ld (", num[0]); + for (i = 1; i < M_MAXTYPES; i++) + fprintf(stderr, "%8ld%s", num[i], + (i == M_MAXTYPES - 1) ? "" : ","); + fprintf(stderr, ")\n sizes: %8ld (", siz[0]); + for (i = 1; i < M_MAXTYPES; i++) + fprintf(stderr, "%8ld%s", siz[i], + (i == M_MAXTYPES - 1) ? "" : ","); + fprintf(stderr, ")\n"); + fprintf(stderr, "free lists: %ld\n", freen); + for (i = 0; i < freen; i++) { + for (n = 0, fp = freearray[i]; fp; fp = fp->next) + n++; + if (n > 0) + fprintf(stderr, "free list: %ld - %ld\n", i, n); + } +#ifdef STATS + printf("objects allocated: %8ld (", objnum); + for (i = 1; i < M_MAXTYPES; i++) + printf("%l8d%s", typenum[i], (i == M_MAXTYPES - 1) ? "" : ","); + printf(")\n sizes: %8ld (", objsiz); + for (i = 1; i < M_MAXTYPES; i++) + printf("%8ld%s", typesiz[i], (i == M_MAXTYPES - 1) ? "" : ","); + printf(")\n"); + finsbrk = (caddr_t) sbrk(0); + printf("memory used by data: %ld\n", (long) (finsbrk - origsbrk)); +#endif +} + +static void allocbuffer(long size) +{ + buffer_t *bp; + char *p; + long i, bytes, n; + + if (size >= freen) { + if (size > M_SIZEMAX) + panic(POS, "allocbuffer", "size is too big"); + freearray = Marraygrow(freearray, (long) (size + 1) * FREESIZE); + for (i = freen; i < size + 1; i++) + freearray[i] = NULL; + freen = size + 1; + } + n = CALCNUM(size); + if (!freearray[size]) { + if (!(bp = malloc(BUFFERSIZE))) + panic(POS, "allocbuffer", "cannot allocate buffer struct"); + if (!(bp->data = malloc(size * M_UNITSIZE * n))) + panic(POS, "allocbuffer", "cannot allocate buffer"); + bp->next = bufferlist, bufferlist = bp; + bytes = size * M_UNITSIZE; + for (i = 0, p = bp->data; i < n - 1; i++, p += bytes) { + ((freeobj_t *) p)->next = p + bytes; + ((freeobj_t *) p)->head.size = (Msize_t) size; + ((freeobj_t *) p)->head.area = 0; + ((freeobj_t *) p)->head.type = 0; + } + ((freeobj_t *) p)->next = NULL; + ((freeobj_t *) p)->head.size = (Msize_t) size; + ((freeobj_t *) p)->head.area = 0; + ((freeobj_t *) p)->head.type = 0; + freearray[size] = bp->data; + } +} diff --git a/cmd/lefty/mem.h b/cmd/lefty/mem.h new file mode 100644 index 000000000..17ba9f9d8 --- /dev/null +++ b/cmd/lefty/mem.h @@ -0,0 +1,76 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2004 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Lefteris Koutsofios - AT&T Bell Laboratories */ + +#ifndef _MEM_H +#define _MEM_H + +#ifdef FEATURE_MINTSIZE + typedef int Msize_t; +#define M_SIZEMAX INT_MAX +#else + typedef short Msize_t; +#define M_SIZEMAX SHRT_MAX +#endif + typedef struct Mheader_t { + char type; + char area; + Msize_t size; + } Mheader_t; +#define M_HEADERSIZE sizeof (Mheader_t) + + typedef enum { + M_GCOFF, M_GCON + } Mgcstate_t; + + typedef enum { + M_GCFULL, M_GCINCR + } Mgctype_t; + +#define M_UNITSIZE sizeof (long) +#define M_BYTE2SIZE(l) ((long) (((l + M_UNITSIZE - 1) / M_UNITSIZE))) +#define M_AREAOF(p) ((int) (((Mheader_t *) p)->area)) +#define M_TYPEOF(p) ((int) (((Mheader_t *) p)->type)) + + extern int Mhaspointers[]; + extern Mgcstate_t Mgcstate; + extern int Mcouldgc; + + void Minit(void (*)(void)); + void Mterm(void); + void *Mnew(long, int); + void *Mallocate(long); + void Mfree(void *, long); + void *Marrayalloc(long); + void *Marraygrow(void *, long); + void Marrayfree(void *); + long Mpushmark(void *); + void Mpopmark(long); + void Mresetmark(long, void *); + void Mmkcurr(void *); + void Mdogc(Mgctype_t); + void Mreport(void); +#endif /* _MEM_H */ + +#ifdef __cplusplus +} +#endif diff --git a/cmd/lefty/os/.cvsignore b/cmd/lefty/os/.cvsignore new file mode 100644 index 000000000..9fb985742 --- /dev/null +++ b/cmd/lefty/os/.cvsignore @@ -0,0 +1,6 @@ +*.la +*.lo +.deps +.libs +Makefile +Makefile.in diff --git a/cmd/lefty/os/Makefile.am b/cmd/lefty/os/Makefile.am new file mode 100644 index 000000000..08d53d02c --- /dev/null +++ b/cmd/lefty/os/Makefile.am @@ -0,0 +1,5 @@ +## Process this file with automake to produce Makefile.in + +SUBDIRS = unix + +EXTRA_DIST = mswin32/lefty.mak mswin32/doinst mswin32/io.c