Graphviz 14.1.2~dev.20260118.1035
Loading...
Searching...
No Matches
id.c
Go to the documentation of this file.
1
5/*************************************************************************
6 * Copyright (c) 2011 AT&T Intellectual Property
7 * All rights reserved. This program and the accompanying materials
8 * are made available under the terms of the Eclipse Public License v1.0
9 * which accompanies this distribution, and is available at
10 * https://www.eclipse.org/legal/epl-v10.html
11 *
12 * Contributors: Details at https://graphviz.org
13 *************************************************************************/
14
15#include "config.h"
16
17#include <assert.h>
18#include <stdbool.h>
19#include <stdio.h>
20#include <cgraph/cghdr.h>
21#include <inttypes.h>
22#include <stdint.h>
23#include <stdlib.h>
24#include <util/alloc.h>
25
26/* a default ID allocator that works off the shared string lib */
27
29typedef struct {
32} state_t;
33
34static void *idopen(Agraph_t * g, Agdisc_t* disc)
35{
36 (void)disc;
37
38 state_t *s = gv_alloc(sizeof(state_t));
39 *s = (state_t){.g = g};
40 return s;
41}
42
43static long idmap(void *state, int objtype, char *str, IDTYPE *id,
44 int createflag)
45{
46 char *s;
47 state_t *st = state;
48
49 (void)objtype;
50 if (str) {
51 if (createflag)
52 s = agstrdup(st->g, str);
53 else
54 s = agstrbind(st->g, str);
55 // The scheme of using pointers as the IDs of named objects and odd
56 // numbers as the IDs of unnamed objects relies on heap pointers being
57 // even, to avoid collisions. So the low bit had better be unset.
58 assert((uintptr_t)s % 2 == 0 &&
59 "heap pointer with low bit set will collide with anonymous IDs");
60 *id = (IDTYPE)(uintptr_t)s;
61 } else {
62 *id = st->counter * 2 + 1;
63 ++st->counter;
64 }
65 return 1;
66}
67
68static void idfree(void *state, int objtype, IDTYPE id)
69{
70 (void)objtype;
71 state_t *st = state;
72 if (id % 2 == 0)
73 agstrfree(st->g, (char *)(uintptr_t)id, false);
74}
75
76static char *idprint(void *state, int objtype, IDTYPE id)
77{
78 (void)state;
79 (void)objtype;
80 if (id % 2 == 0)
81 return (char *)(uintptr_t)id;
82 else
83 return NULL;
84}
85
86static void idregister(void *state, int objtype, void *obj)
87{
88 (void)state;
89 (void)objtype;
90 (void)obj;
91}
92
94 idopen,
95 idmap,
96 idfree,
97 idprint,
98 free,
100};
101
102/* aux functions incl. support for disciplines with anonymous IDs */
103
104int agmapnametoid(Agraph_t * g, int objtype, char *str,
105 IDTYPE *result, bool createflag) {
106 int rv;
107
108 if (str && str[0] != LOCALNAMEPREFIX) {
109 rv = (int) AGDISC(g, id)->map(AGCLOS(g, id), objtype, str, result,
110 createflag);
111 if (rv)
112 return rv;
113 }
114
115 /* either an internal ID, or disc. can't map strings */
116 if (str) {
117 rv = aginternalmaplookup(g, objtype, str, result);
118 if (rv)
119 return rv;
120 } else
121 rv = 0;
122
123 if (createflag) {
124 /* get a new anonymous ID, and store in the internal map */
125 rv = (int) AGDISC(g, id)->map(AGCLOS(g, id), objtype, NULL, result,
126 createflag);
127 if (rv && str)
128 aginternalmapinsert(g, objtype, str, *result);
129 }
130 return rv;
131}
132
133void agfreeid(Agraph_t * g, int objtype, IDTYPE id)
134{
135 (void) aginternalmapdelete(g, objtype, id);
136 (AGDISC(g, id)->free) (AGCLOS(g, id), objtype, id);
137}
138
145char *agnameof(void *obj)
146{
147 Agraph_t *g;
148 char *rv;
149
150 /* perform internal lookup first */
151 g = agraphof(obj);
152 rv = aginternalmapprint(g, AGTYPE(obj), AGID(obj));
153 if (rv != NULL)
154 return rv;
155
156 if (AGDISC(g, id)->print) {
157 rv = AGDISC(g, id)->print(AGCLOS(g, id), AGTYPE(obj), AGID(obj));
158 if (rv != NULL)
159 return rv;
160 }
161 if (AGTYPE(obj) != AGEDGE) {
162 static char buf[32];
163 snprintf(buf, sizeof(buf), "%c%" PRIu64, LOCALNAMEPREFIX, AGID(obj));
164 rv = buf;
165 }
166 else
167 rv = 0;
168 return rv;
169}
170
171/* register a graph object in an external namespace */
172void agregister(Agraph_t * g, int objtype, void *obj)
173{
174 AGDISC(g, id)->idregister(AGCLOS(g, id), objtype, obj);
175}
Memory allocation wrappers that exit on failure.
static void * gv_alloc(size_t size)
Definition alloc.h:47
cgraph.h additions
int aginternalmapdelete(Agraph_t *g, int objtype, IDTYPE id)
Definition imap.c:151
void aginternalmapinsert(Agraph_t *g, int objtype, char *str, IDTYPE result)
Definition imap.c:105
char * aginternalmapprint(Agraph_t *g, int objtype, IDTYPE id)
Definition imap.c:141
bool aginternalmaplookup(Agraph_t *g, int objtype, char *str, IDTYPE *result)
Definition imap.c:84
#define AGDISC(g, d)
Definition cghdr.h:48
#define LOCALNAMEPREFIX
Definition cghdr.h:46
#define AGCLOS(g, d)
Definition cghdr.h:49
static void print(Excc_t *cc, Exnode_t *exnode)
Definition excc.c:109
static Dtdisc_t disc
Definition exparse.y:209
void free(void *)
node NULL
Definition grammar.y:181
Agiddisc_t AgIdDisc
Definition id.c:93
Agraph_t * agraphof(void *obj)
Definition obj.c:187
char * agnameof(void *obj)
returns a string descriptor for the object.
Definition id.c:145
#define AGID(obj)
returns the unique integer ID associated with the object
Definition cgraph.h:221
uint64_t IDTYPE
unique per main graph ID
Definition cgraph.h:73
#define AGTYPE(obj)
returns AGRAPH, AGNODE, or AGEDGE depending on the type of the object
Definition cgraph.h:216
@ AGEDGE
Definition cgraph.h:207
int agstrfree(Agraph_t *, const char *, bool is_html)
Definition refstr.c:417
char * agstrdup(Agraph_t *, const char *)
returns a pointer to a reference-counted copy of the argument string, creating one if necessary
Definition refstr.c:401
char * agstrbind(Agraph_t *g, const char *)
Definition refstr.c:341
static uint64_t id
Definition gv2gml.c:42
textitem scanner parser str
Definition htmlparse.y:218
void agfreeid(Agraph_t *g, int objtype, IDTYPE id)
Definition id.c:133
static void * idopen(Agraph_t *g, Agdisc_t *disc)
Definition id.c:34
int agmapnametoid(Agraph_t *g, int objtype, char *str, IDTYPE *result, bool createflag)
Definition id.c:104
void agregister(Agraph_t *g, int objtype, void *obj)
Definition id.c:172
static char * idprint(void *state, int objtype, IDTYPE id)
Definition id.c:76
static void idfree(void *state, int objtype, IDTYPE id)
Definition id.c:68
static void idregister(void *state, int objtype, void *obj)
Definition id.c:86
static long idmap(void *state, int objtype, char *str, IDTYPE *id, int createflag)
Definition id.c:43
user's discipline
Definition cgraph.h:336
object ID allocator discipline
Definition cgraph.h:316
long(* map)(void *state, int objtype, char *str, IDTYPE *id, int createflag)
Definition cgraph.h:318
graph or subgraph
Definition cgraph.h:424
information the ID allocator needs to do its job
Definition id.c:29
Agraph_t * g
graph in use
Definition id.c:31
IDTYPE counter
base to derive next identifier from
Definition id.c:30
Definition grammar.c:90