~ubuntu-branches/ubuntu/precise/graphviz/precise-security

« back to all changes in this revision

Viewing changes to .pc/3_fix_dot_output/lib/common/output.c

  • Committer: Bazaar Package Importer
  • Author(s): David Claughton
  • Date: 2010-03-24 22:45:18 UTC
  • mfrom: (1.2.7 upstream) (6.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100324224518-do441tthbqjaqjzd
Tags: 2.26.3-4
Add patch to fix segfault in circo. Backported from upstream snapshot
release.  Thanks to Francis Russell for his work on this.
(Closes: #575255)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: output.c,v 1.71 2009/10/15 17:28:19 erg Exp $ $Revision: 1.71 $ */
 
2
/* vim:set shiftwidth=4 ts=8: */
 
3
 
 
4
/**********************************************************
 
5
*      This software is part of the graphviz package      *
 
6
*                http://www.graphviz.org/                 *
 
7
*                                                         *
 
8
*            Copyright (c) 1994-2004 AT&T Corp.           *
 
9
*                and is licensed under the                *
 
10
*            Common Public License, Version 1.0           *
 
11
*                      by AT&T Corp.                      *
 
12
*                                                         *
 
13
*        Information and Software Systems Research        *
 
14
*              AT&T Research, Florham Park NJ             *
 
15
**********************************************************/
 
16
 
 
17
#include "render.h"
 
18
#include "agxbuf.h"
 
19
#include <stdarg.h>
 
20
#include <string.h>
 
21
 
 
22
#define YDIR(y) (Y_invert ? (Y_off - (y)) : (y))
 
23
#define YFDIR(y) (Y_invert ? (YF_off - (y)) : (y))
 
24
 
 
25
int Y_off;           /* ymin + ymax */
 
26
double YF_off;       /* Y_off in inches */
 
27
 
 
28
#ifdef WITH_CGRAPH
 
29
static int (*putstr) (void *chan, const char *str);
 
30
 
 
31
static void agputs (const char* s, FILE* fp)
 
32
{
 
33
    putstr ((void*)fp, s);
 
34
}
 
35
static void agputc (int c, FILE* fp)
 
36
{
 
37
    static char buf[2] = {'\0','\0'};
 
38
    buf[0] = c;
 
39
    putstr ((void*)fp, buf);
 
40
}
 
41
 
 
42
#endif
 
43
 
 
44
static void printstring(FILE * f, char *prefix, char *s)
 
45
{
 
46
    if (prefix) agputs(prefix, f);
 
47
    agputs(s, f);
 
48
}
 
49
 
 
50
static void printint(FILE * f, char *prefix, int i)
 
51
{
 
52
    char buf[BUFSIZ];
 
53
    
 
54
    if (prefix) agputs(prefix, f);
 
55
    sprintf(buf, "%d", i);
 
56
    agputs(buf, f);
 
57
}
 
58
 
 
59
static void printdouble(FILE * f, char *prefix, double v)
 
60
{
 
61
    char buf[BUFSIZ];
 
62
    
 
63
    if (prefix) agputs(prefix, f);
 
64
    sprintf(buf, "%.5g", v);
 
65
    agputs(buf, f);
 
66
}
 
67
 
 
68
static void printpoint(FILE * f, pointf p)
 
69
{
 
70
    printdouble(f, " ", PS2INCH(p.x));
 
71
    printdouble(f, " ", PS2INCH(YDIR(p.y)));
 
72
}
 
73
 
 
74
/* setYInvert:
 
75
 * Set parameters used to flip coordinate system (y=0 at top).
 
76
 * Values do not need to be unset, since if Y_invert is set, it's
 
77
 * set for * all graphs during current run, so each will 
 
78
 * reinitialize the values for its bbox.
 
79
 */
 
80
static void setYInvert(graph_t * g)
 
81
{
 
82
    if (Y_invert) {
 
83
        Y_off = ROUND(GD_bb(g).UR.y + GD_bb(g).LL.y);
 
84
        YF_off = PS2INCH(Y_off);
 
85
    }
 
86
}
 
87
 
 
88
/* canon:
 
89
 * Canonicalize a string which may not have been allocated using agstrdup.
 
90
 */
 
91
static char* canon (graph_t *g, char* s)
 
92
{
 
93
#ifndef WITH_CGRAPH
 
94
    char* ns = agstrdup (s);
 
95
    char* cs = agcanonStr (ns);
 
96
    agstrfree (ns);
 
97
#else
 
98
    char* ns = agstrdup (g, s);
 
99
    char* cs = agcanonStr (ns);
 
100
    agstrfree (g, ns);
 
101
#endif
 
102
    return cs;
 
103
}
 
104
 
 
105
static void writenodeandport(FILE * f, node_t * node, char *port)
 
106
{
 
107
    char *name;
 
108
    if (IS_CLUST_NODE(node))
 
109
        name = canon (agraphof(node), strchr(agnameof(node), ':') + 1);
 
110
    else
 
111
        name = agcanonStr (agnameof(node));
 
112
    printstring(f, " ", name); /* slimey i know */
 
113
    if (port && *port)
 
114
        printstring(f, ":", agcanonStr(port));
 
115
}
 
116
 
 
117
/* _write_plain:
 
118
 */
 
119
void write_plain(GVJ_t * job, graph_t * g, FILE * f, boolean extend)
 
120
{
 
121
    int i, j, splinePoints;
 
122
    char *tport, *hport;
 
123
    node_t *n;
 
124
    edge_t *e;
 
125
    bezier bz;
 
126
    pointf pt;
 
127
    char *lbl;
 
128
 
 
129
#ifdef WITH_CGRAPH
 
130
    putstr = g->clos->disc.io->putstr;
 
131
#endif
 
132
//    setup_graph(job, g);
 
133
    setYInvert(g);
 
134
    pt = GD_bb(g).UR;
 
135
    printdouble(f, "graph ", job->zoom);
 
136
    printdouble(f, " ", PS2INCH(pt.x));
 
137
    printdouble(f, " ", PS2INCH(pt.y));
 
138
    agputc('\n', f);
 
139
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
 
140
        if (IS_CLUST_NODE(n))
 
141
            continue;
 
142
        printstring(f, "node ", agcanonStr(agnameof(n)));
 
143
        printpoint(f, ND_coord(n));
 
144
        if (ND_label(n)->html)   /* if html, get original text */
 
145
#ifndef WITH_CGRAPH
 
146
            lbl = agcanonStr (agxget(n, N_label->index));
 
147
#else
 
148
            lbl = agcanonStr (agxget(n, N_label));
 
149
#endif
 
150
        else
 
151
            lbl = canon(agraphof(n),ND_label(n)->text);
 
152
        printdouble(f, " ", ND_width(n));
 
153
        printdouble(f, " ", ND_height(n));
 
154
        printstring(f, " ", lbl);
 
155
        printstring(f, " ", late_nnstring(n, N_style, "solid"));
 
156
        printstring(f, " ", ND_shape(n)->name);
 
157
        printstring(f, " ", late_nnstring(n, N_color, DEFAULT_COLOR));
 
158
        printstring(f, " ", late_nnstring(n, N_fillcolor, DEFAULT_FILL));
 
159
        agputc('\n', f);
 
160
    }
 
161
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
 
162
        for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
 
163
 
 
164
#ifndef WITH_CGRAPH
 
165
/* FIXME - there must be a proper way to get port info - these are 
 
166
 * supposed to be private to libgraph - from libgraph.h */
 
167
#define TAILX 1
 
168
#define HEADX 2
 
169
 
 
170
            if (extend && e->attr) {
 
171
                tport = e->attr[TAILX];
 
172
                hport = e->attr[HEADX];
 
173
            }
 
174
#else /* WITH_CGRAPH */
 
175
            if (extend) {               //assuming these two attrs have already been created by cgraph
 
176
                if (!(tport = agget(e,"tailport")))
 
177
                    tport = "";
 
178
                if (!(hport = agget(e,"headport")))
 
179
                    hport = "";
 
180
            }
 
181
#endif /* WITH_CGRAPH */
 
182
            else
 
183
                tport = hport = "";
 
184
            if (ED_spl(e)) {
 
185
                splinePoints = 0;
 
186
                for (i = 0; i < ED_spl(e)->size; i++) {
 
187
                    bz = ED_spl(e)->list[i];
 
188
                    splinePoints += bz.size;
 
189
                }
 
190
                printstring(f, NULL, "edge");
 
191
                writenodeandport(f, agtail(e), tport);
 
192
                writenodeandport(f, aghead(e), hport);
 
193
                printint(f, " ", splinePoints);
 
194
                for (i = 0; i < ED_spl(e)->size; i++) {
 
195
                    bz = ED_spl(e)->list[i];
 
196
                    for (j = 0; j < bz.size; j++)
 
197
                        printpoint(f, bz.list[j]);
 
198
                }
 
199
            }
 
200
            if (ED_label(e)) {
 
201
                printstring(f, " ", canon(agraphof(agtail(e)),ED_label(e)->text));
 
202
                printpoint(f, ED_label(e)->pos);
 
203
            }
 
204
            printstring(f, " ", late_nnstring(e, E_style, "solid"));
 
205
            printstring(f, " ", late_nnstring(e, E_color, DEFAULT_COLOR));
 
206
            agputc('\n', f);
 
207
        }
 
208
    }
 
209
    agputs("stop\n", f);
 
210
}
 
211
 
 
212
static void set_record_rects(node_t * n, field_t * f, agxbuf * xb)
 
213
{
 
214
    int i;
 
215
    char buf[BUFSIZ];
 
216
 
 
217
    if (f->n_flds == 0) {
 
218
        sprintf(buf, "%.5g,%.5g,%.5g,%.5g ",
 
219
                f->b.LL.x + ND_coord(n).x,
 
220
                YFDIR(f->b.LL.y + ND_coord(n).y),
 
221
                f->b.UR.x + ND_coord(n).x,
 
222
                YFDIR(f->b.UR.y + ND_coord(n).y));
 
223
        agxbput(xb, buf);
 
224
    }
 
225
    for (i = 0; i < f->n_flds; i++)
 
226
        set_record_rects(n, f->fld[i], xb);
 
227
}
 
228
 
 
229
static void rec_attach_bb(graph_t * g, Agsym_t* bbsym)
 
230
{
 
231
    int c;
 
232
    char buf[BUFSIZ];
 
233
    pointf pt;
 
234
 
 
235
    sprintf(buf, "%.5g,%.5g,%.5g,%.5g", GD_bb(g).LL.x, YFDIR(GD_bb(g).LL.y),
 
236
            GD_bb(g).UR.x, YFDIR(GD_bb(g).UR.y));
 
237
#ifndef WITH_CGRAPH
 
238
    agxset(g, bbsym->index, buf);
 
239
#else
 
240
    agxset(g, bbsym, buf);
 
241
#endif
 
242
    if (GD_label(g) && GD_label(g)->text[0]) {
 
243
        pt = GD_label(g)->pos;
 
244
        sprintf(buf, "%.5g,%.5g", pt.x, YFDIR(pt.y));
 
245
        agset(g, "lp", buf);
 
246
    }
 
247
    for (c = 1; c <= GD_n_cluster(g); c++)
 
248
        rec_attach_bb(GD_clust(g)[c], bbsym);
 
249
}
 
250
 
 
251
void attach_attrs_and_arrows(graph_t* g, int* sp, int* ep)
 
252
{
 
253
    int e_arrows;               /* graph has edges with end arrows */
 
254
    int s_arrows;               /* graph has edges with start arrows */
 
255
    int i, j, sides;
 
256
    char buf[BUFSIZ];           /* Used only for small strings */
 
257
    unsigned char xbuffer[BUFSIZ];      /* Initial buffer for xb */
 
258
    agxbuf xb;
 
259
    node_t *n;
 
260
    edge_t *e;
 
261
    pointf ptf;
 
262
    int dim3 = (GD_odim(g) >= 3);
 
263
    Agsym_t* bbsym;
 
264
 
 
265
    gv_fixLocale (1);
 
266
    e_arrows = s_arrows = 0;
 
267
    setYInvert(g);
 
268
    agxbinit(&xb, BUFSIZ, xbuffer);
 
269
#ifndef WITH_CGRAPH
 
270
    safe_dcl(g, g->proto->n, "pos", "", agnodeattr);
 
271
    safe_dcl(g, g->proto->n, "rects", "", agnodeattr);
 
272
    N_width = safe_dcl(g, g->proto->n, "width", "", agnodeattr);
 
273
    N_height = safe_dcl(g, g->proto->n, "height", "", agnodeattr);
 
274
    safe_dcl(g, g->proto->e, "pos", "", agedgeattr);
 
275
    if (GD_has_labels(g) & NODE_XLABEL)
 
276
        safe_dcl(g, g->proto->n, "xlp", "", agnodeattr);
 
277
    if (GD_has_labels(g) & EDGE_LABEL)
 
278
        safe_dcl(g, g->proto->e, "lp", "", agedgeattr);
 
279
    if (GD_has_labels(g) & EDGE_XLABEL)
 
280
        safe_dcl(g, g->proto->e, "xlp", "", agedgeattr);
 
281
    if (GD_has_labels(g) & HEAD_LABEL)
 
282
        safe_dcl(g, g->proto->e, "head_lp", "", agedgeattr);
 
283
    if (GD_has_labels(g) & TAIL_LABEL)
 
284
        safe_dcl(g, g->proto->e, "tail_lp", "", agedgeattr);
 
285
    if (GD_label(g)) {
 
286
        safe_dcl(g, g, "lp", "", agraphattr);
 
287
        if (GD_label(g)->text[0]) {
 
288
            ptf = GD_label(g)->pos;
 
289
            sprintf(buf, "%.5g,%.5g", ptf.x, YFDIR(ptf.y));
 
290
            agset(g, "lp", buf);
 
291
        }
 
292
    }
 
293
    bbsym = safe_dcl(g, g, "bb", "", agraphattr);
 
294
#else
 
295
    safe_dcl(g, AGNODE, "pos", "");
 
296
    safe_dcl(g, AGNODE, "rects", "");
 
297
    N_width = safe_dcl(g, AGNODE, "width", "");
 
298
    N_height = safe_dcl(g, AGNODE, "height", "");
 
299
    safe_dcl(g, AGEDGE, "pos", "");
 
300
    if (GD_has_labels(g) & NODE_XLABEL)
 
301
        safe_dcl(g, AGNODE, "xlp", "");
 
302
    if (GD_has_labels(g) & EDGE_LABEL)
 
303
        safe_dcl(g, AGEDGE, "lp", "");
 
304
    if (GD_has_labels(g) & EDGE_XLABEL)
 
305
        safe_dcl(g, AGEDGE, "xlp", "");
 
306
    if (GD_has_labels(g) & HEAD_LABEL)
 
307
        safe_dcl(g, AGEDGE, "head_lp", "");
 
308
    if (GD_has_labels(g) & TAIL_LABEL)
 
309
        safe_dcl(g, AGEDGE, "tail_lp", "");
 
310
    if (GD_label(g)) {
 
311
        safe_dcl(g, AGRAPH, "lp", "");
 
312
        if (GD_label(g)->text[0]) {
 
313
            ptf = GD_label(g)->pos;
 
314
            sprintf(buf, "%.5g,%.5g", ptf.x, YFDIR(ptf.y));
 
315
            agset(g, "lp", buf);
 
316
        }
 
317
    }
 
318
    bbsym = safe_dcl(g, AGRAPH, "bb", "");
 
319
#endif
 
320
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
 
321
        if (dim3) {
 
322
            sprintf(buf, "%.5g,%.5g,%.5g", ND_coord(n).x, YDIR(ND_coord(n).y), POINTS_PER_INCH*(ND_pos(n)[2]));
 
323
        } else {
 
324
            sprintf(buf, "%.5g,%.5g", ND_coord(n).x, YDIR(ND_coord(n).y));
 
325
        }
 
326
        agset(n, "pos", buf);
 
327
        sprintf(buf, "%.5g", PS2INCH(ND_ht(n)));
 
328
#ifndef WITH_CGRAPH
 
329
        agxset(n, N_height->index, buf);
 
330
        sprintf(buf, "%.5g", PS2INCH(ND_lw(n) + ND_rw(n)));
 
331
        agxset(n, N_width->index, buf);
 
332
#else
 
333
        agxset(n, N_height, buf);
 
334
        sprintf(buf, "%.5g", PS2INCH(ND_lw(n) + ND_rw(n)));
 
335
        agxset(n, N_width, buf);
 
336
#endif
 
337
        if (ND_xlabel(n)) {
 
338
            ptf = ND_xlabel(n)->pos;
 
339
            sprintf(buf, "%.5g,%.5g", ptf.x, YFDIR(ptf.y));
 
340
            agset(n, "xlp", buf);
 
341
        }
 
342
        if (strcmp(ND_shape(n)->name, "record") == 0) {
 
343
            set_record_rects(n, ND_shape_info(n), &xb);
 
344
            agxbpop(&xb);       /* get rid of last space */
 
345
            agset(n, "rects", agxbuse(&xb));
 
346
        } else {
 
347
            polygon_t *poly;
 
348
            int i;
 
349
            if (N_vertices && isPolygon(n)) {
 
350
                poly = (polygon_t *) ND_shape_info(n);
 
351
                sides = poly->sides;
 
352
                if (sides < 3) {
 
353
                    char *p = agget(n, "samplepoints");
 
354
                    if (p)
 
355
                        sides = atoi(p);
 
356
                    else
 
357
                        sides = 8;
 
358
                    if (sides < 3)
 
359
                        sides = 8;
 
360
                }
 
361
                for (i = 0; i < sides; i++) {
 
362
                    if (i > 0)
 
363
                        agxbputc(&xb, ' ');
 
364
                    if (poly->sides >= 3)
 
365
                        sprintf(buf, "%.5g %.5g",
 
366
                                PS2INCH(poly->vertices[i].x),
 
367
                                YFDIR(PS2INCH(poly->vertices[i].y)));
 
368
                    else
 
369
                        sprintf(buf, "%.5g %.5g",
 
370
                                ND_width(n) / 2.0 * cos(i / (double) sides * M_PI * 2.0),
 
371
                                YFDIR(ND_height(n) / 2.0 * sin(i / (double) sides * M_PI * 2.0)));
 
372
                    agxbput(&xb, buf);
 
373
                }
 
374
#ifndef WITH_CGRAPH
 
375
                agxset(n, N_vertices->index, agxbuse(&xb));
 
376
#else /* WITH_CGRAPH */
 
377
                agxset(n, N_vertices, agxbuse(&xb));
 
378
#endif /* WITH_CGRAPH */
 
379
            }
 
380
        }
 
381
        if (State >= GVSPLINES) {
 
382
            for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
 
383
                if (ED_edge_type(e) == IGNORED)
 
384
                    continue;
 
385
                if (ED_spl(e) == NULL)
 
386
                    continue;   /* reported in postproc */
 
387
                for (i = 0; i < ED_spl(e)->size; i++) {
 
388
                    if (i > 0)
 
389
                        agxbputc(&xb, ';');
 
390
                    if (ED_spl(e)->list[i].sflag) {
 
391
                        s_arrows = 1;
 
392
                        sprintf(buf, "s,%.5g,%.5g ",
 
393
                                ED_spl(e)->list[i].sp.x,
 
394
                                YFDIR(ED_spl(e)->list[i].sp.y));
 
395
                        agxbput(&xb, buf);
 
396
                    }
 
397
                    if (ED_spl(e)->list[i].eflag) {
 
398
                        e_arrows = 1;
 
399
                        sprintf(buf, "e,%.5g,%.5g ",
 
400
                                ED_spl(e)->list[i].ep.x,
 
401
                                YFDIR(ED_spl(e)->list[i].ep.y));
 
402
                        agxbput(&xb, buf);
 
403
                    }
 
404
                    for (j = 0; j < ED_spl(e)->list[i].size; j++) {
 
405
                        if (j > 0)
 
406
                            agxbputc(&xb, ' ');
 
407
                        ptf = ED_spl(e)->list[i].list[j];
 
408
                        sprintf(buf, "%.5g,%.5g", ptf.x, YFDIR(ptf.y));
 
409
                        agxbput(&xb, buf);
 
410
                    }
 
411
                }
 
412
                agset(e, "pos", agxbuse(&xb));
 
413
                if (ED_label(e)) {
 
414
                    ptf = ED_label(e)->pos;
 
415
                    sprintf(buf, "%.5g,%.5g", ptf.x, YFDIR(ptf.y));
 
416
                    agset(e, "lp", buf);
 
417
                }
 
418
                if (ED_xlabel(e)) {
 
419
                    ptf = ED_xlabel(e)->pos;
 
420
                    sprintf(buf, "%.5g,%.5g", ptf.x, YFDIR(ptf.y));
 
421
                    agset(e, "xlp", buf);
 
422
                }
 
423
                if (ED_head_label(e)) {
 
424
                    ptf = ED_head_label(e)->pos;
 
425
                    sprintf(buf, "%.5g,%.5g", ptf.x, YFDIR(ptf.y));
 
426
                    agset(e, "head_lp", buf);
 
427
                }
 
428
                if (ED_tail_label(e)) {
 
429
                    ptf = ED_tail_label(e)->pos;
 
430
                    sprintf(buf, "%.5g,%.5g", ptf.x, YDIR(ptf.y));
 
431
                    agset(e, "tail_lp", buf);
 
432
                }
 
433
            }
 
434
        }
 
435
    }
 
436
    rec_attach_bb(g, bbsym);
 
437
    agxbfree(&xb);
 
438
 
 
439
    if (HAS_CLUST_EDGE(g))
 
440
        undoClusterEdges(g);
 
441
    
 
442
    *sp = s_arrows;
 
443
    *ep = e_arrows;
 
444
    gv_fixLocale (0);
 
445
}
 
446
 
 
447
void attach_attrs(graph_t * g)
 
448
{
 
449
    int e, s;
 
450
    attach_attrs_and_arrows (g, &s, &e);
 
451
}
 
452
 
 
453
void output_point(agxbuf *xbuf, pointf p)
 
454
{
 
455
    char buf[BUFSIZ];
 
456
    sprintf(buf, "%d %d ", ROUND(p.x), YDIR(ROUND(p.y)));
 
457
    agxbput(xbuf, buf);
 
458
}
 
459