~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to agraph/refstr.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
#include <aghdr.h>
 
13
 
 
14
#ifdef DMALLOC
 
15
#include "dmalloc.h"
 
16
#endif
 
17
 
 
18
/*
 
19
 * reference counted strings.
 
20
 */
 
21
 
 
22
typedef struct refstr_t {
 
23
        Dtlink_t                link;
 
24
        unsigned long   refcnt;
 
25
        char                    *s;
 
26
        char                    store[1];               /* this is actually a dynamic array */
 
27
} refstr_t;
 
28
 
 
29
static Dtdisc_t Refstrdisc = {
 
30
        offsetof(refstr_t,s),   /* key */
 
31
        -1,                                             /* size */
 
32
        0,                                              /* link offset */
 
33
        NIL(Dtmake_f),
 
34
        agdictobjfree,
 
35
        NIL(Dtcompar_f),
 
36
        NIL(Dthash_f),
 
37
        agdictobjmem,
 
38
        NIL(Dtevent_f)
 
39
};
 
40
 
 
41
static Dict_t *Refdict_default;
 
42
 
 
43
static Dict_t *refdict(Agraph_t *g)
 
44
{
 
45
        Dict_t  **dictref;
 
46
 
 
47
        if (g) dictref = &(g->clos->strdict);
 
48
        else dictref = &Refdict_default;
 
49
        if (*dictref == NIL(Dict_t*))
 
50
                *dictref = agdtopen(g,&Refstrdisc,Dttree);
 
51
        return *dictref;
 
52
}
 
53
 
 
54
void agstrclose(Agraph_t *g)
 
55
{
 
56
        agdtclose(g,refdict(g));
 
57
}
 
58
 
 
59
static refstr_t *refsymbind(Dict_t *strdict, char *s)
 
60
{
 
61
        refstr_t                key,*r;
 
62
        key.s = s;
 
63
        r = (refstr_t*) dtsearch(strdict,&key);
 
64
        return r;
 
65
}
 
66
 
 
67
static char *refstrbind(Dict_t *strdict, char *s)
 
68
{
 
69
        refstr_t        *r;
 
70
        r = refsymbind(strdict, s);
 
71
        if (r) return r->s;
 
72
        else return NIL(char*);
 
73
}
 
74
 
 
75
char *agstrbind(Agraph_t *g, char *s)
 
76
{
 
77
        return refstrbind(refdict(g),s);
 
78
}
 
79
 
 
80
char *agstrdup(Agraph_t *g, char *s)
 
81
{
 
82
        refstr_t                *r;
 
83
        Dict_t                  *strdict;
 
84
        size_t                  sz;
 
85
 
 
86
        if (s == NIL(char*)) return NIL(char*);
 
87
        strdict = refdict(g);
 
88
        r = refsymbind(strdict,s);
 
89
        if (r) r->refcnt++;
 
90
        else {
 
91
                sz = sizeof(refstr_t)+strlen(s);
 
92
                if (g) r = (refstr_t*) agalloc(g,sz);
 
93
                else r = (refstr_t*)malloc(sz);
 
94
                r->refcnt = 1;
 
95
                strcpy(r->store,s);
 
96
                r->s = r->store;
 
97
                dtinsert(strdict,r);
 
98
        }
 
99
        return r->s;
 
100
}
 
101
 
 
102
int agstrfree(Agraph_t *g, char *s)
 
103
{
 
104
        refstr_t                *r;
 
105
        Dict_t                  *strdict;
 
106
 
 
107
        if (s == NIL(char*))
 
108
                return FAILURE;
 
109
 
 
110
        strdict = refdict(g);
 
111
        r = refsymbind(strdict,s);
 
112
        if (r && (r->s == s)) {
 
113
                r->refcnt--;
 
114
                if (r->refcnt <= 0) {
 
115
                        agdtdelete(g,strdict,r);
 
116
                        /*
 
117
                        if (g) agfree(g,r);
 
118
                        else free(r);
 
119
                        */
 
120
                }
 
121
        }
 
122
        if (r == NIL(refstr_t*)) return FAILURE;
 
123
        return SUCCESS;
 
124
}
 
125
 
 
126
#ifdef DEBUG
 
127
static int refstrprint(Dict_t *dict, void *ptr, void *user)
 
128
{
 
129
        refstr_t *r;
 
130
 
 
131
        NOTUSED(dict);
 
132
        r = ptr;
 
133
        NOTUSED(user);
 
134
        write(2,r->s,strlen(r->s));
 
135
        write(2,"\n",1);
 
136
        return 0;
 
137
}
 
138
 
 
139
void agrefstrdump(Agraph_t *g)
 
140
{
 
141
        dtwalk(Refdict_default,refstrprint,0);
 
142
}
 
143
#endif