--- /dev/null
+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';
+};
--- /dev/null
+/* $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
--- /dev/null
+.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 <expression>"
+.B <expression>
+is parsed and executed.
+.TP
+.B -el <num>
+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 <num>"
+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 <num>"
+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 <string>"
+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 <file>"
+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.
--- /dev/null
+/* $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 <gtk/gtk.h>
+#include <glib/gmain.h>
+#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 <sys/time.h>
+#ifdef HAVE_UNISTD_H
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+#ifdef STATS
+#include <sys/resource.h>
+#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
+}
--- /dev/null
+/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
--- /dev/null
+/* $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--;
+}
--- /dev/null
+/* $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
--- /dev/null
+/* $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;
+ }
+}
--- /dev/null
+/* $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
--- /dev/null
+*.la
+*.lo
+.deps
+.libs
+Makefile
+Makefile.in
--- /dev/null
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS = unix
+
+EXTRA_DIST = mswin32/lefty.mak mswin32/doinst mswin32/io.c