Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
refstr.c
Go to the documentation of this file.
1
6/*************************************************************************
7 * Copyright (c) 2011 AT&T Intellectual Property
8 * All rights reserved. This program and the accompanying materials
9 * are made available under the terms of the Eclipse Public License v1.0
10 * which accompanies this distribution, and is available at
11 * https://www.eclipse.org/legal/epl-v10.html
12 *
13 * Contributors: Details at https://graphviz.org
14 *************************************************************************/
15
16#include <cgraph/cghdr.h>
17#include <stdbool.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <util/alloc.h>
21
22/*
23 * reference counted strings.
24 */
25
26typedef struct {
28 uint64_t refcnt: sizeof(uint64_t) * 8 - 1;
29 uint64_t is_html: 1;
30 char *s;
31 char store[1]; /* this is actually a dynamic array */
32} refstr_t;
33
35 offsetof(refstr_t, s), /* key */
36 -1, /* size */
37 0, /* link offset */
38 NULL,
39 free,
40 NULL,
41};
42
44
45/* refdict:
46 * Return the string dictionary associated with g.
47 * If necessary, create it.
48 * As a side-effect, set html masks. This assumes 8-bit bytes.
49 */
51{
52 Dict_t **dictref;
53
54 if (g)
55 dictref = &(g->clos->strdict);
56 else
57 dictref = &Refdict_default;
58 if (*dictref == NULL) {
59 *dictref = agdtopen(g, &Refstrdisc, Dttree);
60 }
61 return *dictref;
62}
63
65{
66 return agdtclose(g, refdict(g));
67}
68
69static refstr_t *refsymbind(Dict_t * strdict, const char *s)
70{
71 refstr_t key, *r;
72// Suppress Clang/GCC -Wcast-qual warning. Casting away const here is acceptable
73// as dtsearch does not modify its input key.
74#ifdef __GNUC__
75#pragma GCC diagnostic push
76#pragma GCC diagnostic ignored "-Wcast-qual"
77#endif
78 key.s = (char*)s;
79#ifdef __GNUC__
80#pragma GCC diagnostic pop
81#endif
82 r = dtsearch(strdict, &key);
83 return r;
84}
85
86static char *refstrbind(Dict_t * strdict, const char *s)
87{
88 refstr_t *r;
89 r = refsymbind(strdict, s);
90 if (r)
91 return r->s;
92 else
93 return NULL;
94}
95
96char *agstrbind(Agraph_t * g, const char *s)
97{
98 return refstrbind(refdict(g), s);
99}
100
101static char *agstrdup_internal(Agraph_t *g, const char *s, bool is_html) {
102 refstr_t *r;
103 Dict_t *strdict;
104 size_t sz;
105
106 if (s == NULL)
107 return NULL;
108 strdict = refdict(g);
109 r = refsymbind(strdict, s);
110 if (r)
111 r->refcnt++;
112 else {
113 sz = sizeof(refstr_t) + strlen(s);
114 if (g)
115 r = gv_calloc(sz, sizeof(char));
116 else {
117 r = malloc(sz);
118 if (sz > 0 && r == NULL) {
119 return NULL;
120 }
121 }
122 r->refcnt = 1;
123 r->is_html = is_html;
124 strcpy(r->store, s);
125 r->s = r->store;
126 dtinsert(strdict, r);
127 }
128 return r->s;
129}
130
131char *agstrdup(Agraph_t *g, const char *s) {
132 return agstrdup_internal(g, s, false);
133}
134
135char *agstrdup_html(Agraph_t *g, const char *s) {
136 return agstrdup_internal(g, s, true);
137}
138
139int agstrfree(Agraph_t * g, const char *s)
140{
141 refstr_t *r;
142 Dict_t *strdict;
143
144 if (s == NULL)
145 return FAILURE;
146
147 strdict = refdict(g);
148 r = refsymbind(strdict, s);
149 if (r && r->s == s) {
150 r->refcnt--;
151 if (r->refcnt == 0) {
152 agdtdelete(g, strdict, r);
153 }
154 }
155 if (r == NULL)
156 return FAILURE;
157 return SUCCESS;
158}
159
160/* aghtmlstr:
161 * Return true if s is an HTML string.
162 * We assume s points to the datafield store[0] of a refstr.
163 */
164int aghtmlstr(const char *s)
165{
166 const refstr_t *key;
167
168 if (s == NULL)
169 return 0;
170 key = (const refstr_t *) (s - offsetof(refstr_t, store[0]));
171 return key->is_html;
172}
173
174void agmarkhtmlstr(char *s)
175{
176 refstr_t *key;
177
178 if (s == NULL)
179 return;
180 key = (refstr_t *) (s - offsetof(refstr_t, store[0]));
181 key->is_html = 1;
182}
183
184#ifdef DEBUG
185static int refstrprint(void *ptr, void *user) {
186 refstr_t *r = ptr;
187 (void)user;
188 fprintf(stderr, "%s\n", r->s);
189 return 0;
190}
191
192void agrefstrdump(Agraph_t * g)
193{
194 dtwalk(refdict(g), refstrprint, 0);
195}
196#endif
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
CDT_API int dtwalk(Dt_t *, int(*)(void *, void *), void *)
Definition dtwalk.c:9
#define dtsearch(d, o)
Definition cdt.h:183
#define dtinsert(d, o)
Definition cdt.h:185
CDT_API Dtmethod_t * Dttree
Definition dttree.c:308
cgraph.h additions
Dict_t * agdtopen(Agraph_t *g, Dtdisc_t *disc, Dtmethod_t *method)
Definition utils.c:21
int agdtdelete(Agraph_t *g, Dict_t *dict, void *obj)
Definition utils.c:26
#define FAILURE
Definition cghdr.h:45
#define SUCCESS
Definition cghdr.h:44
int agdtclose(Agraph_t *g, Dict_t *dict)
Definition utils.c:32
void * malloc(YYSIZE_T)
void free(void *)
node NULL
Definition grammar.y:163
int aghtmlstr(const char *s)
Definition refstr.c:164
int agstrfree(Agraph_t *g, const char *s)
Definition refstr.c:139
char * agstrdup(Agraph_t *g, const char *s)
returns a pointer to a reference-counted copy of the argument string, creating one if necessary
Definition refstr.c:131
char * agstrbind(Agraph_t *g, const char *s)
Definition refstr.c:96
char * agstrdup_html(Agraph_t *g, const char *s)
Definition refstr.c:135
static int store(segment_t *seg, int first, pointf *pts)
Definition partition.c:115
int agstrclose(Agraph_t *g)
Definition refstr.c:64
static refstr_t * refsymbind(Dict_t *strdict, const char *s)
Definition refstr.c:69
static Dtdisc_t Refstrdisc
Definition refstr.c:34
static Dict_t * refdict(Agraph_t *g)
Definition refstr.c:50
static char * agstrdup_internal(Agraph_t *g, const char *s, bool is_html)
Definition refstr.c:101
static Dict_t * Refdict_default
Definition refstr.c:43
static char * refstrbind(Dict_t *strdict, const char *s)
Definition refstr.c:86
void agmarkhtmlstr(char *s)
Definition refstr.c:174
Dict_t * strdict
Definition cgraph.h:414
graph or subgraph
Definition cgraph.h:425
Agclos_t * clos
shared resources
Definition cgraph.h:435
Definition cdt.h:100
uint64_t refcnt
Definition refstr.c:28
char * s
Definition refstr.c:30
Dtlink_t link
Definition refstr.c:27
char store[1]
Definition refstr.c:31
uint64_t is_html
Definition refstr.c:29
Definition grammar.c:93