~ubuntu-branches/ubuntu/jaunty/graphviz/jaunty

« back to all changes in this revision

Viewing changes to lefty/display.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    This software may only be used by you under license from AT&T Corp.
 
3
    ("AT&T").  A copy of AT&T's Source Code Agreement is available at
 
4
    AT&T's Internet website having the URL:
 
5
    <http://www.research.att.com/sw/tools/graphviz/license/source.html>
 
6
    If you received this software without first entering into a license
 
7
    with AT&T, you have an infringing copy of this software and cannot use
 
8
    it without violating AT&T's intellectual property rights.
 
9
*/
 
10
 
 
11
#pragma prototyped
 
12
/* Lefteris Koutsofios - AT&T Bell Laboratories */
 
13
 
 
14
#include "common.h"
 
15
#include "mem.h"
 
16
#include "code.h"
 
17
#include "tbl.h"
 
18
#include "str.h"
 
19
#include "display.h"
 
20
 
 
21
typedef struct dnode_t {
 
22
    Ttype_t ttype;
 
23
    Tobj ko, vo;
 
24
    char *path;
 
25
} dnode_t;
 
26
 
 
27
typedef struct seennode_t {
 
28
    Tobj vo;
 
29
    char *path;
 
30
} seennode_t;
 
31
static seennode_t *seenp;
 
32
static int seeni, seenn;
 
33
#define SEENINCR 100
 
34
#define SEENSIZE sizeof (seennode_t)
 
35
 
 
36
static int indent, afternl;
 
37
 
 
38
static void update (dnode_t *);
 
39
static int cmp (const void *, const void *);
 
40
static seennode_t *findseen (dnode_t *);
 
41
static void add2seen (dnode_t *);
 
42
static void pr (char *);
 
43
 
 
44
void Dinit (void) {
 
45
    seenp = Marrayalloc ((long) SEENINCR * SEENSIZE);
 
46
    seeni = 0;
 
47
    seenn = SEENINCR;
 
48
}
 
49
 
 
50
void Dterm (void) {
 
51
    Marrayfree (seenp);
 
52
    seeni = seenn = 0;
 
53
}
 
54
 
 
55
void Dtrace (Tobj to, int offset) {
 
56
    dnode_t dnode;
 
57
    char *s;
 
58
    int i;
 
59
 
 
60
    indent = offset - 2;
 
61
    afternl = TRUE;
 
62
    if (Tgettype (to) != T_TABLE) {
 
63
        pr ((s = Ssfull (NULL, to))), free (s);
 
64
        return;
 
65
    }
 
66
 
 
67
    seeni = 0;
 
68
    dnode.vo = to;
 
69
    dnode.path = "";
 
70
    update (&dnode);
 
71
    for (i = 0; i < seeni; i++)
 
72
        free (seenp[i].path), seenp[i].path = NULL;
 
73
}
 
74
 
 
75
static void update (dnode_t *pnode) {
 
76
    Tkvindex_t tkvi;
 
77
    dnode_t *list, *cnode;
 
78
    seennode_t *seennode;
 
79
    char *s;
 
80
    long i, n;
 
81
 
 
82
    indent += 2;
 
83
    n = ((Ttable_t *) pnode->vo)->n;
 
84
    if (!(list = malloc (n * sizeof (dnode_t))))
 
85
        panic (POS, "update", "list malloc failed");
 
86
    for (cnode = &list[0], Tgetfirst (pnode->vo, &tkvi); tkvi.kvp;
 
87
            cnode++, Tgetnext (&tkvi)) {
 
88
        cnode->ko = tkvi.kvp->ko;
 
89
        cnode->vo = tkvi.kvp->vo;
 
90
        cnode->ttype = Tgettype (cnode->vo);
 
91
    }
 
92
    qsort ((char *) list, n, sizeof (dnode_t), cmp);
 
93
    for (i = 0, cnode = &list[0]; i < n; i++, cnode++) {
 
94
        cnode->path = Spath (pnode->path, cnode->ko);
 
95
        seennode = findseen (cnode);
 
96
        if (seennode) {
 
97
            pr ((s = Sseen (cnode->ko, seennode->path))), free (s);
 
98
        } else {
 
99
            add2seen (cnode);
 
100
            if (cnode->ttype == T_TABLE) {
 
101
                pr ((s = Stfull (cnode->ko))), free (s);
 
102
                update (cnode);
 
103
                pr ("];");
 
104
            } else {
 
105
                pr ((s = Ssfull (cnode->ko, cnode->vo))), free (s);
 
106
            }
 
107
        }
 
108
    }
 
109
    free (list);
 
110
    indent -= 2;
 
111
}
 
112
 
 
113
static int cmp (const void *a, const void *b) {
 
114
    Ttype_t atype, btype;
 
115
    dnode_t *anode, *bnode;
 
116
    double d1, d2;
 
117
 
 
118
    anode = (dnode_t *) a, bnode = (dnode_t *) b;
 
119
    atype = Tgettype (anode->ko), btype = Tgettype (bnode->ko);
 
120
    if (atype != btype)
 
121
        return (atype - btype);
 
122
    if (atype == T_STRING)
 
123
        return Strcmp (Tgetstring (anode->ko), Tgetstring (bnode->ko));
 
124
    if (atype == T_INTEGER)
 
125
        d1 = Tgetinteger (anode->ko), d2 = Tgetinteger (bnode->ko);
 
126
    else if (atype == T_REAL)
 
127
        d1 = Tgetreal (anode->ko), d2 = Tgetreal (bnode->ko);
 
128
    if (d1 < d2)
 
129
        return -1;
 
130
    else if (d1 > d2)
 
131
        return 1;
 
132
    else
 
133
        return 0; /* but this should never happen since keys are unique */
 
134
}
 
135
 
 
136
static seennode_t *findseen (dnode_t *cnode) {
 
137
    int i;
 
138
 
 
139
    for (i = 0; i < seeni; i++)
 
140
        if (seenp[i].vo == cnode->vo)
 
141
            return &seenp[i];
 
142
    return NULL;
 
143
}
 
144
 
 
145
static void add2seen (dnode_t *cnode) {
 
146
    if (seeni >= seenn) {
 
147
        seenp = Marraygrow (seenp, (long) (seenn + SEENINCR) * SEENSIZE);
 
148
        seenn += SEENINCR;
 
149
    }
 
150
    seenp[seeni].vo = cnode->vo;
 
151
    seenp[seeni++].path = cnode->path;
 
152
}
 
153
 
 
154
static void pr (char *s) {
 
155
    char *s1;
 
156
    int i;
 
157
 
 
158
    for (s1 = s; *s1; s1++) {
 
159
        if (afternl) {
 
160
            for (i = 0; i < indent; i++)
 
161
                putchar (' ');
 
162
            afternl = FALSE;
 
163
        }
 
164
        if (*s1 == '\n')
 
165
            afternl = TRUE;
 
166
        putchar ((*s1)); /* HACK: to keep proto happy */
 
167
    }
 
168
    putchar ('\n');
 
169
    afternl = TRUE;
 
170
}