Graphviz 12.0.1~dev.20240715.2254
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 <stddef.h>
18#include <stdbool.h>
19#include <stdio.h>
20
21/*
22 * reference counted strings.
23 */
24
25typedef struct {
27 uint64_t refcnt: sizeof(uint64_t) * 8 - 1;
28 uint64_t is_html: 1;
29 char *s;
30 char store[1]; /* this is actually a dynamic array */
31} refstr_t;
32
34 offsetof(refstr_t, s), /* key */
35 -1, /* size */
36 0, /* link offset */
37 NULL,
39 NULL,
40};
41
43
44/* refdict:
45 * Return the string dictionary associated with g.
46 * If necessary, create it.
47 * As a side-effect, set html masks. This assumes 8-bit bytes.
48 */
50{
51 Dict_t **dictref;
52
53 if (g)
54 dictref = &(g->clos->strdict);
55 else
56 dictref = &Refdict_default;
57 if (*dictref == NULL) {
58 *dictref = agdtopen(g, &Refstrdisc, Dttree);
59 }
60 return *dictref;
61}
62
64{
65 return agdtclose(g, refdict(g));
66}
67
68static refstr_t *refsymbind(Dict_t * strdict, const char *s)
69{
70 refstr_t key, *r;
71// Suppress Clang/GCC -Wcast-qual warning. Casting away const here is acceptable
72// as dtsearch does not modify its input key.
73#ifdef __GNUC__
74#pragma GCC diagnostic push
75#pragma GCC diagnostic ignored "-Wcast-qual"
76#endif
77 key.s = (char*)s;
78#ifdef __GNUC__
79#pragma GCC diagnostic pop
80#endif
81 r = dtsearch(strdict, &key);
82 return r;
83}
84
85static char *refstrbind(Dict_t * strdict, const char *s)
86{
87 refstr_t *r;
88 r = refsymbind(strdict, s);
89 if (r)
90 return r->s;
91 else
92 return NULL;
93}
94
95char *agstrbind(Agraph_t * g, const char *s)
96{
97 return refstrbind(refdict(g), s);
98}
99
100static char *agstrdup_internal(Agraph_t *g, const char *s, bool is_html) {
101 refstr_t *r;
102 Dict_t *strdict;
103 size_t sz;
104
105 if (s == NULL)
106 return NULL;
107 strdict = refdict(g);
108 r = refsymbind(strdict, s);
109 if (r)
110 r->refcnt++;
111 else {
112 sz = sizeof(refstr_t) + strlen(s);
113 if (g)
114 r = agalloc(g, sz);
115 else {
116 r = malloc(sz);
117 if (sz > 0 && r == NULL) {
118 return NULL;
119 }
120 }
121 r->refcnt = 1;
122 r->is_html = is_html;
123 strcpy(r->store, s);
124 r->s = r->store;
125 dtinsert(strdict, r);
126 }
127 return r->s;
128}
129
130char *agstrdup(Agraph_t *g, const char *s) {
131 return agstrdup_internal(g, s, false);
132}
133
134char *agstrdup_html(Agraph_t *g, const char *s) {
135 return agstrdup_internal(g, s, true);
136}
137
138int agstrfree(Agraph_t * g, const char *s)
139{
140 refstr_t *r;
141 Dict_t *strdict;
142
143 if (s == NULL)
144 return FAILURE;
145
146 strdict = refdict(g);
147 r = refsymbind(strdict, s);
148 if (r && r->s == s) {
149 r->refcnt--;
150 if (r->refcnt == 0) {
151 agdtdelete(g, strdict, r);
152 }
153 }
154 if (r == NULL)
155 return FAILURE;
156 return SUCCESS;
157}
158
159/* aghtmlstr:
160 * Return true if s is an HTML string.
161 * We assume s points to the datafield store[0] of a refstr.
162 */
163int aghtmlstr(const char *s)
164{
165 const refstr_t *key;
166
167 if (s == NULL)
168 return 0;
169 key = (const refstr_t *) (s - offsetof(refstr_t, store[0]));
170 return key->is_html;
171}
172
173void agmarkhtmlstr(char *s)
174{
175 refstr_t *key;
176
177 if (s == NULL)
178 return;
179 key = (refstr_t *) (s - offsetof(refstr_t, store[0]));
180 key->is_html = 1;
181}
182
183#ifdef DEBUG
184static int refstrprint(void *ptr, void *user) {
185 refstr_t *r = ptr;
186 (void)user;
187 fprintf(stderr, "%s\n", r->s);
188 return 0;
189}
190
191void agrefstrdump(Agraph_t * g)
192{
193 dtwalk(refdict(g), refstrprint, 0);
194}
195#endif
CDT_API int dtwalk(Dt_t *, int(*)(void *, void *), void *)
Definition dtwalk.c:9
#define dtsearch(d, o)
Definition cdt.h:191
#define dtinsert(d, o)
Definition cdt.h:193
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:29
int agdtdelete(Agraph_t *g, Dict_t *dict, void *obj)
Definition utils.c:39
#define FAILURE
Definition cghdr.h:44
#define SUCCESS
Definition cghdr.h:43
void agdictobjfree(void *p)
Definition utils.c:21
int agdtclose(Agraph_t *g, Dict_t *dict)
Definition utils.c:45
disc key
Definition exparse.y:214
void * malloc(YYSIZE_T)
node NULL
Definition grammar.y:149
void * agalloc(Agraph_t *g, size_t size)
Definition mem.c:19
int aghtmlstr(const char *s)
Definition refstr.c:163
int agstrfree(Agraph_t *g, const char *s)
Definition refstr.c:138
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:130
char * agstrbind(Agraph_t *g, const char *s)
Definition refstr.c:95
char * agstrdup_html(Agraph_t *g, const char *s)
Definition refstr.c:134
static int store(segment_t *seg, int first, pointf *pts)
Definition partition.c:115
int agstrclose(Agraph_t *g)
Definition refstr.c:63
static refstr_t * refsymbind(Dict_t *strdict, const char *s)
Definition refstr.c:68
static Dtdisc_t Refstrdisc
Definition refstr.c:33
static Dict_t * refdict(Agraph_t *g)
Definition refstr.c:49
static char * agstrdup_internal(Agraph_t *g, const char *s, bool is_html)
Definition refstr.c:100
static Dict_t * Refdict_default
Definition refstr.c:42
static char * refstrbind(Dict_t *strdict, const char *s)
Definition refstr.c:85
void agmarkhtmlstr(char *s)
Definition refstr.c:173
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:104
uint64_t refcnt
Definition refstr.c:27
char * s
Definition refstr.c:29
Dtlink_t link
Definition refstr.c:26
char store[1]
Definition refstr.c:30
uint64_t is_html
Definition refstr.c:28
Definition grammar.c:93