--- /dev/null
+.TH LIBXDOT 3 "31 JULY 2009"
+.SH NAME
+\fBlibxdot\fR \- parsing and deparsing of xdot operations
+.SH SYNOPSIS
+.ta .75i 1.5i 2.25i 3i 3.75i 4.5i 5.25i 6i
+.PP
+.nf
+\f5
+#include <graphviz/xdot.h>
+
+typedef enum {
+ xd_left, xd_center, xd_right
+} xdot_align;
+
+typedef struct {
+ double x, y, z;
+} xdot_point;
+
+typedef struct {
+ double x, y, w, h;
+} xdot_rect;
+
+typedef struct {
+ int cnt;
+ xdot_point* pts;
+} xdot_polyline;
+
+typedef struct {
+ double x, y;
+ xdot_align align;
+ double width;
+ char* text;
+} xdot_text;
+
+typedef struct {
+ xdot_rect pos;
+ char* name;
+} xdot_image;
+
+typedef struct {
+ double size;
+ char* name;
+} xdot_font;
+
+typedef enum {
+ xd_filled_ellipse, xd_unfilled_ellipse,
+ xd_filled_polygon, xd_unfilled_polygon,
+ xd_filled_bezier, xd_unfilled_bezier,
+ xd_polyline, xd_text,
+ xd_fill_color, xd_pen_color, xd_font, xd_style, xd_image
+} xdot_kind;
+
+typedef enum {
+ xop_ellipse,
+ xop_polygon,
+ xop_bezier,
+ xop_polyline, xop_text,
+ xop_fill_color, xop_pen_color, xop_font, xop_style, xop_image
+} xop_kind;
+
+typedef struct _xdot_op xdot_op;
+typedef void (*drawfunc_t)(xdot_op*, int);
+typedef void (*freefunc_t)(xdot_op*);
+
+struct _xdot_op {
+ xdot_kind kind;
+ union {
+ xdot_rect ellipse; /* xd_filled_ellipse, xd_unfilled_ellipse */
+ xdot_polyline polygon; /* xd_filled_polygon, xd_unfilled_polygon */
+ xdot_polyline polyline; /* xd_polyline */
+ xdot_polyline bezier; /* xd_filled_bezier, xd_unfilled_bezier */
+ xdot_text text; /* xd_text */
+ xdot_image image; /* xd_image */
+ char* color; /* xd_fill_color, xd_pen_color */
+ xdot_font font; /* xd_font */
+ char* style; /* xd_style */
+ } u;
+ drawfunc_t drawfunc;
+};
+
+#define XDOT_PARSE_ERROR 1
+
+typedef struct {
+ int cnt;
+ int sz;
+ xdot_op* ops;
+ freefunc_t freefunc;
+ int flags;
+} xdot;
+
+xdot* parseXDotF (char*, drawfunc_t opfns[], int sz);
+xdot* parseXDot (char*);
+char* sprintXDot (xdot*);
+void fprintXDot (FILE*, xdot*);
+void freeXDot (xdot*);
+\fP
+.fi
+.SH DESCRIPTION
+\fIlibxdot\fP provides support for parsing and deparsing
+graphical operations specificed by the \fIxdot\fP language.
+.SS "Types"
+.PP
+.SS " xdot"
+This encapsulates a series of \fIcnt\fP xdot operations, stored
+in the array pointed to by \fIops\fP. The \fIsz\fP indicates
+the size of each item stored in \fIops\fP. If the user sets
+the \fIfreefunc\fP field, this function will be called on each
+item in \fIops\fP during \fIfreeXDot\fP before the library does
+its own clean up of the item. This allows the user to free any
+resources stored in the item by using an expansion of the \fIxdot_op\fP
+structure.
+.PP
+.SS " xdot_op"
+A value of this type represents one xdot operation. The operation
+is specified by the \fIkind\fP field. The corresponding data is
+stored in the union \fIu\fP, with the subfield associated with
+a given \fIkind\fP indicated by the comments.
+.PP
+The \fIdrawfunc\fP field allows the user to attach a drawing-specific
+function to the operation, providing an object-based interface. These
+functions can be automatically attached during parsing by providing a
+non-NULL second argument to \fIparseXDotF\fP.
+.PP
+.SS " xop_kind"
+This type provides an enumeration of the allowed xdot operations.
+See
+.br
+ http://www.graphviz.org/doc/info/output.html#d:xdot
+.br
+for the specific semantics associated with each operation.
+.PP
+.SS " xdot_rect"
+This represents a rectangle. For ellipses,
+the \fIx\fP and \fIx\fP fields represent the center of the rectangle,
+and \fIw\fP and \fIh\fP give the half-width and half-height, respectively.
+For images, (\fIx\fP,\fIy\fP) gives the lower left corner of the
+rectangle, and \fIw\fP and \fIh\fP give the width and height, respectively.
+.PP
+.SS " xdot_polyline"
+This type encapsulates a series of \fIcnt\fP points.
+.PP
+.SS " xdot_text"
+A value of this type corresponds to printing the string \fItext\fP
+using the baseline point (\fIx\fP,\fIy\fP).
+The \fIwidth\fP field gives an approximation of how wide the printed
+string will be using the current font and font size.
+The \fIalign\fP field indicates how the text should be horizontally
+aligned with the point (\fIx\fP,\fIy\fP).
+.PP
+.SS " xdot_image"
+This denotes the insertion of an image. The image source is
+given by \fIname\fP. The images is to be placed into the rectangle
+\fIpos\fP.
+.PP
+.SS " xdot_font"
+The fields give the name and size, in points, of a font.
+.PP
+.SS " xdot_align"
+This enumeration type corresponds to the xdot alignment values
+-1, 0 and 1 used with the text operator, or '\\l', '\\n' and '\\r'
+used in dot text.
+.SS "Functions"
+.PP
+.SS " xdot* parseXDotF (char *str, drawfunc_t* opfns, int sz)"
+Parses the string \fIstr\fP as a sequence of xdot operations
+and returns a pointer to the resulting \fIxdot\fP structure.
+The function parses as many xdot operations as it can. If some
+unknown or incorrect input was encountered in \fIstr\fP,
+the \fIops\fP and \fIcnt\fP fields will reflect the operations
+parsed before the error, and
+the \fIXDOT_PARSE_ERROR\fP bit will be set in the \fIflags\fP field.
+The function returns NULL if it cannot parse anything.
+.PP
+If \fIsz\fP is non-zero, it is assumed to be the size of some
+structure type containing \fIxdot_op\fP as a prefix. In this case,
+the elements in the array pointed to by \fIops\fP will each have
+size \fIsz\fP.
+.PP
+If \fIopfns\fP is non-zero, it is taken to be any array of functions
+indexed by \fIxop_kind\fP. During parsing, the \fIdrawfunc\fP member
+of \fIxop_op\fP will be set to the corresponding function in \fIopfns\fP.
+.PP
+.SS " xdot* parseXDot (char *str)"
+This is equivalent to \fIparseXDotF(str, 0, 0)\fP .
+.PP
+.SS " void freeXDot (xdot* xp)"
+This frees the resources associated with the argument.
+If \fIxp\fP is NULL, nothing happens.
+.PP
+.SS " extern char* sprintXDot (xdot* xp)"
+.SS " extern void fprintXDot (FILE* fp, xdot* xp)"
+These two functions deparse the argument xdot structure, producing
+a string representation. \fIfprintXDot\fP writes the output onto
+the open stream \fIfp\fP; \fIsprintXDot\fP returns a heap-allocated
+string.
+
+.SH BUGS
+Although some small checking is done on the \fIsz\fP argument to
+\fIparseXDotF\fP, it is assumed it is a valid value from \fIsizeof\fP
+applied to some structure type containing \fIxdot_op\fP as its first
+field. There can be no validation of the \fIopfns\fP argument.
+.SH AUTHORS
+Emden R. Gansner (erg@research.att.com).
* AT&T Research, Florham Park NJ *
**********************************************************/
-
#include <xdot.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <memory.h>
-#include <time.h>
-static char*
-parseReal (char* s, double* fp)
+#define NEW(t) (t*)malloc(sizeof(t))
+#define N_NEW(n,t) (t*)malloc((n)*sizeof(t))
+
+/* the parse functions should return NULL on error */
+static char *parseReal(char *s, double *fp)
{
- char* p;
- double d;
+ char *p;
+ double d;
d = strtod(s, &p);
- assert (p != s);
+ if (p == s) return 0;
+
*fp = d;
return (p);
}
-static char*
-parseInt (char* s, int* ip)
+static char *parseInt(char *s, int *ip)
{
int r, sz;
r = sscanf(s, "%d%n", ip, &sz);
- assert (r == 1);
- return (s+sz);
+ if (r != 1) return 0;
+ else return (s + sz);
}
-static char*
-parsePoint (char* s, xdot_point* pp)
+static char *parsePoint(char *s, xdot_point * pp)
{
int r, sz;
r = sscanf(s, "%lf %lf%n", &(pp->x), &(pp->y), &sz);
- assert (r == 2);
- pp->z = 0;
- return (s+sz);
+ if (r != 2) return 0;
+ pp->z = 0;
+ return (s + sz);
}
-static char*
-parseRect (char* s, xdot_rect* rp)
+static char *parseRect(char *s, xdot_rect * rp)
{
int r, sz;
- r = sscanf(s, "%lf %lf %lf %lf%n", &(rp->x), &(rp->y), &(rp->w), &(rp->h), &sz);
- assert (r == 4);
- return (s+sz);
+ r = sscanf(s, "%lf %lf %lf %lf%n", &(rp->x), &(rp->y), &(rp->w),
+ &(rp->h), &sz);
+ if (r != 4) return 0;
+ else return (s + sz);
}
-static char*
-parsePolyline (char* s, xdot_polyline* pp)
+static char *parsePolyline(char *s, xdot_polyline * pp)
{
int i;
- xdot_point* pts;
+ xdot_point *pts;
- s = parseInt (s, &i);
+ s = parseInt(s, &i);
+ if (!s) return s;
pts = N_NEW(i, xdot_point);
pp->cnt = i;
- for (i = 0; i < pp->cnt; i++)
- s = parsePoint (s, pts+i);
+ for (i = 0; i < pp->cnt; i++) {
+ s = parsePoint(s, pts + i);
+ if (!s) {
+ free (pts);
+ return 0;
+ }
+ }
pp->pts = pts;
return s;
}
-static char*
-parseString (char* s, char** sp)
+static char *parseString(char *s, char **sp)
{
int i;
- char* c;
- s = parseInt (s, &i);
- c = N_NEW(i+1, char);
- while (*s++ != '-');
- memcpy (c, s, i);
- c[i] = '\0';
+ char *c;
+ char *p;
+ s = parseInt(s, &i);
+ if (!s || (i <= 0)) return 0;
+ while (*s && (*s != '-')) s++;
+ if (*s) s++;
+ else {
+ return 0;
+ }
+ c = N_NEW(i + 1, char);
+ p = c;
+ while ((i > 0) && *s) {
+ *p++ = *s++;
+ i--;
+ }
+ if (i > 0) {
+ free (c);
+ return 0;
+ }
+
+ *p = '\0';
*sp = c;
- return (s+i);
+ return s;
}
-static char*
-parseAlign (char* s, xdot_align* ap)
+static char *parseAlign(char *s, xdot_align * ap)
{
int i;
- s = parseInt (s, &i);
- if (i < 0) *ap = xd_left;
- else if (i > 0) *ap = xd_right;
- else *ap = xd_center;
+ s = parseInt(s, &i);
+
+ if (i < 0)
+ *ap = xd_left;
+ else if (i > 0)
+ *ap = xd_right;
+ else
+ *ap = xd_center;
return s;
}
-static char*
-parseOp (xdot_op* op, char* s, drawfunc_t ops[])
+#define CHK(s) if(!s){*error=1;return 0;}
+
+static char *parseOp(xdot_op * op, char *s, drawfunc_t ops[], int* error)
{
- while (isspace(*s)) s++;
+ *error = 0;
+ while (isspace(*s))
+ s++;
switch (*s++) {
- case 'E' :
+ case 'E':
op->kind = xd_filled_ellipse;
- s = parseRect (s, &op->u.ellipse);
- if (ops) op->drawfunc=ops[xop_ellipse];
+ s = parseRect(s, &op->u.ellipse);
+ CHK(s);
+ if (ops)
+ op->drawfunc = ops[xop_ellipse];
break;
- case 'e' :
+ case 'e':
op->kind = xd_unfilled_ellipse;
- s = parseRect (s, &op->u.ellipse);
- if (ops) op->drawfunc=ops[xop_ellipse];
+ s = parseRect(s, &op->u.ellipse);
+ CHK(s);
+ if (ops)
+ op->drawfunc = ops[xop_ellipse];
break;
- case 'P' :
+ case 'P':
op->kind = xd_filled_polygon;
- s = parsePolyline (s, &op->u.polygon);
- if (ops) op->drawfunc=ops[xop_polygon];
+ s = parsePolyline(s, &op->u.polygon);
+ CHK(s);
+ if (ops)
+ op->drawfunc = ops[xop_polygon];
break;
- case 'p' :
+ case 'p':
op->kind = xd_unfilled_polygon;
- s = parsePolyline (s, &op->u.polygon);
- if (ops) op->drawfunc=ops[xop_polygon];
+ s = parsePolyline(s, &op->u.polygon);
+ CHK(s);
+ if (ops)
+ op->drawfunc = ops[xop_polygon];
break;
- case 'b' :
+ case 'b':
op->kind = xd_filled_bezier;
- s = parsePolyline (s, &op->u.bezier);
- if (ops) op->drawfunc=ops[xop_bezier];
+ s = parsePolyline(s, &op->u.bezier);
+ CHK(s);
+ if (ops)
+ op->drawfunc = ops[xop_bezier];
break;
-
- case 'B' :
+
+ case 'B':
op->kind = xd_unfilled_bezier;
- s = parsePolyline (s, &op->u.bezier);
- if (ops) op->drawfunc=ops[xop_bezier];
+ s = parsePolyline(s, &op->u.bezier);
+ CHK(s);
+ if (ops)
+ op->drawfunc = ops[xop_bezier];
break;
-
- case 'c' :
+
+ case 'c':
op->kind = xd_pen_color;
- s = parseString (s, &op->u.color);
- if (ops) op->drawfunc=ops[xop_pen_color];
+ s = parseString(s, &op->u.color);
+ CHK(s);
+ if (ops)
+ op->drawfunc = ops[xop_pen_color];
break;
-
- case 'C' :
+
+ case 'C':
op->kind = xd_fill_color;
- s = parseString (s, &op->u.color);
- if (ops) op->drawfunc=ops[xop_fill_color];
+ s = parseString(s, &op->u.color);
+ CHK(s);
+ if (ops)
+ op->drawfunc = ops[xop_fill_color];
break;
-
- case 'L' :
+
+ case 'L':
op->kind = xd_polyline;
- s = parsePolyline (s, &op->u.polyline);
- if (ops) op->drawfunc=ops[xop_polyline];
+ s = parsePolyline(s, &op->u.polyline);
+ CHK(s);
+ if (ops)
+ op->drawfunc = ops[xop_polyline];
break;
-
- case 'T' :
+
+ case 'T':
op->kind = xd_text;
- s = parseReal (s, &op->u.text.x);
- s = parseReal (s, &op->u.text.y);
- s = parseAlign (s, &op->u.text.align);
- s = parseReal (s, &op->u.text.width);
- s = parseString (s, &op->u.text.text);
- if (ops) op->drawfunc=ops[xop_text];
- break;
-
- case 'F' :
+ s = parseReal(s, &op->u.text.x);
+ CHK(s);
+ s = parseReal(s, &op->u.text.y);
+ CHK(s);
+ s = parseAlign(s, &op->u.text.align);
+ CHK(s);
+ s = parseReal(s, &op->u.text.width);
+ CHK(s);
+ s = parseString(s, &op->u.text.text);
+ CHK(s);
+ if (ops)
+ op->drawfunc = ops[xop_text];
+ break;
+
+ case 'F':
op->kind = xd_font;
- s = parseReal (s, &op->u.font.size);
- s = parseString (s, &op->u.font.name);
- if (ops) op->drawfunc=ops[xop_font];
+ s = parseReal(s, &op->u.font.size);
+ CHK(s);
+ s = parseString(s, &op->u.font.name);
+ CHK(s);
+ if (ops)
+ op->drawfunc = ops[xop_font];
break;
-
- case 'S' :
+
+ case 'S':
op->kind = xd_style;
- s = parseString (s, &op->u.style);
- if (ops) op->drawfunc=ops[xop_style];
+ s = parseString(s, &op->u.style);
+ CHK(s);
+ if (ops)
+ op->drawfunc = ops[xop_style];
break;
-
- case 'I' :
+
+ case 'I':
op->kind = xd_image;
- s = parseRect (s, &op->u.image.pos);
- s = parseString (s, &op->u.image.name);
- if (ops) op->drawfunc=ops[xop_image];
+ s = parseRect(s, &op->u.image.pos);
+ CHK(s);
+ s = parseString(s, &op->u.image.name);
+ CHK(s);
+ if (ops)
+ op->drawfunc = ops[xop_image];
+ break;
+
+
+ case '\0':
+ s = 0;
break;
-
- default :
+
+ default:
+ *error = 1;
s = 0;
break;
}
#define XDBSIZE 100
-xdot*
-parseXDotF (char* s, drawfunc_t fns[], int sz)
+xdot *parseXDotF(char *s, drawfunc_t fns[], int sz)
{
- xdot* x;
+ xdot *x;
xdot_op op;
- char* ops;
- int bufsz = XDBSIZE;
- if (!s) return NULL;
+ char *ops;
+ int oldsz, bufsz = XDBSIZE;
+ int error;
+
+ if (!s)
+ return NULL;
x = NEW(xdot);
- if (sz <= 0) sz = sizeof(xdot_op);
- ops = (char*)gmalloc(XDBSIZE*sz);
+ if (sz <= sizeof(xdot_op))
+ sz = sizeof(xdot_op);
+ ops = (char *) calloc(XDBSIZE, sz);
x->cnt = 0;
+ x->flags = 0;
+ x->freefunc = 0;
x->sz = sz;
- while ((s = parseOp (&op, s, fns)))
- {
- if (x->cnt == bufsz)
- {
- bufsz += XDBSIZE;
- ops = (char*)grealloc (ops, bufsz*sz);
- }
- *(xdot_op*)(ops + (x->cnt*sz)) = op;
- x->cnt++;
+ while ((s = parseOp(&op, s, fns, &error))) {
+ if (x->cnt == bufsz) {
+ oldsz = bufsz;
+ bufsz *= 2;
+ ops = (char *) realloc(ops, bufsz * sz);
+ memset(ops + (oldsz*sz), '\0', (bufsz - oldsz)*sz);
+ }
+ *(xdot_op *) (ops + (x->cnt * sz)) = op;
+ x->cnt++;
}
- if (x->cnt)
- x->ops = (xdot_op*)grealloc (ops, x->cnt*sz);
- else
- {
- free (x);
- x = 0;
+ if (x->cnt) {
+ x->ops = (xdot_op *) realloc(ops, x->cnt * sz);
+ if (error)
+ x->flags |= XDOT_PARSE_ERROR;
+ }
+ else {
+ free(x);
+ x = 0;
}
return x;
}
-xdot*
-parseXDot (char* s)
+xdot *parseXDot(char *s)
{
- return parseXDotF (s, 0, 0);
+ return parseXDotF(s, 0, 0);
}
-typedef void (*pf)(char*, void*);
+typedef void (*pf) (char *, void *);
-static void
-printRect (xdot_rect* r, pf print, void* info)
+static void printRect(xdot_rect * r, pf print, void *info)
{
char buf[128];
- sprintf (buf, " %.06f %.06f %.06f %.06f", r->x, r->y, r->w, r->h);
- print (buf, info);
+ sprintf(buf, " %.06f %.06f %.06f %.06f", r->x, r->y, r->w, r->h);
+ print(buf, info);
}
-static void
-printPolyline (xdot_polyline* p, pf print, void* info)
+static void printPolyline(xdot_polyline * p, pf print, void *info)
{
int i;
char buf[512];
- sprintf (buf, " %d", p->cnt);
- print (buf, info);
- for (i = 0; i< p->cnt; i++) {
- sprintf (buf, " %.06f %.06f", p->pts[i].x, p->pts[i].y);
- print (buf, info);
+ sprintf(buf, " %d", p->cnt);
+ print(buf, info);
+ for (i = 0; i < p->cnt; i++) {
+ sprintf(buf, " %.06f %.06f", p->pts[i].x, p->pts[i].y);
+ print(buf, info);
}
}
-static void
-printString (char* p, pf print, void* info)
+static void printString(char *p, pf print, void *info)
{
char buf[30];
- sprintf (buf, " %d -", (int)strlen(p));
- print (buf, info);
- print (p, info);
+ sprintf(buf, " %d -", (int) strlen(p));
+ print(buf, info);
+ print(p, info);
}
-static void
-printInt (int i, pf print, void* info)
+static void printInt(int i, pf print, void *info)
{
char buf[30];
- sprintf (buf, " %d", i);
- print (buf, info);
+ sprintf(buf, " %d", i);
+ print(buf, info);
}
-static void
-printFloat (float f, pf print, void* info)
+static void printFloat(float f, pf print, void *info)
{
char buf[128];
- sprintf (buf, " %f", f);
- print (buf, info);
+ sprintf(buf, " %f", f);
+ print(buf, info);
}
-static void
-printAlign (xdot_align a, pf print, void* info)
+static void printAlign(xdot_align a, pf print, void *info)
{
switch (a) {
- case xd_left :
- print (" -1", info);
+ case xd_left:
+ print(" -1", info);
break;
- case xd_right :
- print (" 1", info);
+ case xd_right:
+ print(" 1", info);
break;
- case xd_center :
- print (" 0", info);
+ case xd_center:
+ print(" 0", info);
break;
}
}
-static void
-printXDot_Op (xdot_op* op, pf print, void* info)
+static void printXDot_Op(xdot_op * op, pf print, void *info)
{
switch (op->kind) {
- case xd_filled_ellipse :
- print ("E", info);
- printRect (&op->u.ellipse, print, info);
+ case xd_filled_ellipse:
+ print("E", info);
+ printRect(&op->u.ellipse, print, info);
break;
- case xd_unfilled_ellipse :
- print ("e", info);
- printRect (&op->u.ellipse, print, info);
+ case xd_unfilled_ellipse:
+ print("e", info);
+ printRect(&op->u.ellipse, print, info);
break;
- case xd_filled_polygon :
- print ("P", info);
- printPolyline (&op->u.polygon, print, info);
+ case xd_filled_polygon:
+ print("P", info);
+ printPolyline(&op->u.polygon, print, info);
break;
- case xd_unfilled_polygon :
- print ("p", info);
- printPolyline (&op->u.polygon, print, info);
+ case xd_unfilled_polygon:
+ print("p", info);
+ printPolyline(&op->u.polygon, print, info);
break;
- case xd_filled_bezier :
- print ("b", info);
+ case xd_filled_bezier:
+ print("b", info);
op->kind = xd_filled_bezier;
- printPolyline (&op->u.bezier, print, info);
- break;
- case xd_unfilled_bezier :
- print ("B", info);
- printPolyline (&op->u.bezier, print, info);
- break;
- case xd_pen_color :
- print ("c", info);
- printString (op->u.color, print, info);
- break;
- case xd_fill_color :
- print ("C", info);
- printString (op->u.color, print, info);
- break;
- case xd_polyline :
- print ("L", info);
- printPolyline (&op->u.polyline, print, info);
- break;
- case xd_text :
- print ("T", info);
- printInt (op->u.text.x, print, info);
- printInt (op->u.text.y, print, info);
- printAlign (op->u.text.align, print, info);
- printInt (op->u.text.width, print, info);
- printString (op->u.text.text, print, info);
- break;
- case xd_font :
- print ("F", info);
+ printPolyline(&op->u.bezier, print, info);
+ break;
+ case xd_unfilled_bezier:
+ print("B", info);
+ printPolyline(&op->u.bezier, print, info);
+ break;
+ case xd_pen_color:
+ print("c", info);
+ printString(op->u.color, print, info);
+ break;
+ case xd_fill_color:
+ print("C", info);
+ printString(op->u.color, print, info);
+ break;
+ case xd_polyline:
+ print("L", info);
+ printPolyline(&op->u.polyline, print, info);
+ break;
+ case xd_text:
+ print("T", info);
+ printInt(op->u.text.x, print, info);
+ printInt(op->u.text.y, print, info);
+ printAlign(op->u.text.align, print, info);
+ printInt(op->u.text.width, print, info);
+ printString(op->u.text.text, print, info);
+ break;
+ case xd_font:
+ print("F", info);
op->kind = xd_font;
- printFloat (op->u.font.size, print, info);
- printString (op->u.font.name, print, info);
+ printFloat(op->u.font.size, print, info);
+ printString(op->u.font.name, print, info);
break;
- case xd_style :
- print ("S", info);
- printString (op->u.style, print, info);
+ case xd_style:
+ print("S", info);
+ printString(op->u.style, print, info);
break;
- case xd_image :
- print ("I", info);
- printRect (&op->u.image.pos, print, info);
- printString (op->u.image.name, print, info);
+ case xd_image:
+ print("I", info);
+ printRect(&op->u.image.pos, print, info);
+ printString(op->u.image.name, print, info);
break;
}
}
-static void
-_printXDot (xdot* x, pf print, void* info)
+static void _printXDot(xdot * x, pf print, void *info)
{
int i;
- xdot_op* op;
- char* base = (char*)(x->ops);
+ xdot_op *op;
+ char *base = (char *) (x->ops);
for (i = 0; i < x->cnt; i++) {
- op = (xdot_op*)(base + i*x->sz);
- printXDot_Op (op, print, info);
- if (i < x->cnt-1) print (" ", info);
+ op = (xdot_op *) (base + i * x->sz);
+ printXDot_Op(op, print, info);
+ if (i < x->cnt - 1)
+ print(" ", info);
}
}
-
+
typedef struct {
- unsigned char *buf; /* start of buffer */
- unsigned char *ptr; /* next place to write */
+ unsigned char *buf; /* start of buffer */
+ unsigned char *ptr; /* next place to write */
unsigned char *eptr; /* end of buffer */
- int dyna; /* true if buffer is malloc'ed */
+ int dyna; /* true if buffer is malloc'ed */
} agxbuf;
#define agxbputc(X,C) ((((X)->ptr >= (X)->eptr) ? agxbmore(X,1) : 0), \
(int)(*(X)->ptr++ = ((unsigned char)C)))
#define agxbuse(X) (agxbputc(X,'\0'),(char*)((X)->ptr = (X)->buf))
-static void
-agxbinit(agxbuf * xb, unsigned int hint, unsigned char *init)
+static void agxbinit(agxbuf * xb, unsigned int hint, unsigned char *init)
{
if (init) {
xb->buf = init;
xb->ptr = xb->buf;
*xb->ptr = '\0';
}
-static int
-agxbmore(agxbuf * xb, unsigned int ssz)
+static int agxbmore(agxbuf * xb, unsigned int ssz)
{
int cnt; /* current no. of characters in buffer */
int size; /* current buffer size */
return 0;
}
-static int
-agxbput(char* s, agxbuf * xb)
+static int agxbput(char *s, agxbuf * xb)
{
- unsigned int ssz = strlen (s);
+ unsigned int ssz = strlen(s);
if (xb->ptr + ssz > xb->eptr)
agxbmore(xb, ssz);
memcpy(xb->ptr, s, ssz);
/* agxbfree:
* Free any malloced resources.
*/
-static void
-agxbfree(agxbuf * xb)
+static void agxbfree(agxbuf * xb)
{
if (xb->dyna)
free(xb->buf);
}
-char*
-sprintXDot (xdot* x)
+char *sprintXDot(xdot * x)
{
- char* s;
+ char *s;
unsigned char buf[BUFSIZ];
agxbuf xb;
- agxbinit (&xb, BUFSIZ, buf);
- _printXDot (x, (pf)agxbput, &xb);
- s = strdup(agxbuse (&xb));
- agxbfree (&xb);
+ agxbinit(&xb, BUFSIZ, buf);
+ _printXDot(x, (pf) agxbput, &xb);
+ s = strdup(agxbuse(&xb));
+ agxbfree(&xb);
return s;
}
-void
-fprintXDot (FILE* fp, xdot* x)
+void fprintXDot(FILE * fp, xdot * x)
{
- _printXDot (x, (pf)fputs, fp);
+ _printXDot(x, (pf) fputs, fp);
}
-static void
-freeXOpData (xdot_op* x)
+static void freeXOpData(xdot_op * x)
{
switch (x->kind) {
- case xd_filled_polygon :
- case xd_unfilled_polygon :
- free (x->u.polyline.pts);
+ case xd_filled_polygon:
+ case xd_unfilled_polygon:
+ free(x->u.polyline.pts);
break;
- case xd_filled_bezier :
- case xd_unfilled_bezier :
- free (x->u.polyline.pts);
+ case xd_filled_bezier:
+ case xd_unfilled_bezier:
+ free(x->u.polyline.pts);
break;
- case xd_polyline :
- free (x->u.polyline.pts);
+ case xd_polyline:
+ free(x->u.polyline.pts);
break;
- case xd_text :
- free (x->u.text.text);
+ case xd_text:
+ free(x->u.text.text);
break;
- case xd_fill_color :
- case xd_pen_color :
- free (x->u.color);
+ case xd_fill_color:
+ case xd_pen_color:
+ free(x->u.color);
break;
- case xd_font :
- free (x->u.font.name);
+ case xd_font:
+ free(x->u.font.name);
break;
- case xd_style :
- free (x->u.style);
+ case xd_style:
+ free(x->u.style);
break;
- case xd_image :
- free (x->u.image.name);
+ case xd_image:
+ free(x->u.image.name);
break;
- default :
+ default:
break;
}
}
-void
-freeXDot (xdot* x)
+void freeXDot (xdot * x)
{
int i;
- xdot_op* op;
- char* base = (char*)(x->ops);
+ xdot_op *op;
+ char *base;
+ freefunc_t ff = x->freefunc;
+
+ if (!x) return;
+ base = (char *) (x->ops);
for (i = 0; i < x->cnt; i++) {
- op = (xdot_op*)(base + i*x->sz);
- freeXOpData (op);
+ op = (xdot_op *) (base + i * x->sz);
+ if (ff) ff (op);
+ freeXOpData(op);
}
- free (base);
- free (x);
+ free(base);
+ free(x);
}
#if 0
-static void
-execOp (xdot_op* op,int param)
+static void execOp(xdot_op * op, int param)
{
- op->drawfunc(op,param);
+ op->drawfunc(op, param);
}
#endif