Graphviz 13.0.0~dev.20250121.0651
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 <assert.h>
16#include <stdbool.h>
17#include <stdio.h>
18#include <cgraph/cghdr.h>
19#include <inttypes.h>
20#include <stdint.h>
21#include <stdlib.h>
22#include <util/alloc.h>
23
24/* a default ID allocator that works off the shared string lib */
25
27typedef struct {
30} state_t;
31
32static void *idopen(Agraph_t * g, Agdisc_t* disc)
33{
34 (void)disc;
35
36 state_t *s = gv_alloc(sizeof(state_t));
37 *s = (state_t){.g = g};
38 return s;
39}
40
41static long idmap(void *state, int objtype, char *str, IDTYPE *id,
42 int createflag)
43{
44 char *s;
45 state_t *st = state;
46
47 (void)objtype;
48 if (str) {
49 if (createflag)
50 s = agstrdup(st->g, str);
51 else
52 s = agstrbind(st->g, str);
53 // The scheme of using pointers as the IDs of named objects and odd
54 // numbers as the IDs of unnamed objects relies on heap pointers being
55 // even, to avoid collisions. So the low bit had better be unset.
56 assert((uintptr_t)s % 2 == 0 &&
57 "heap pointer with low bit set will collide with anonymous IDs");
58 *id = (IDTYPE)(uintptr_t)s;
59 } else {
60 *id = st->counter * 2 + 1;
61 ++st->counter;
62 }
63 return 1;
64}
65
66static void idfree(void *state, int objtype, IDTYPE id)
67{
68 (void)objtype;
69 state_t *st = state;
70 if (id % 2 == 0)
71 agstrfree(st->g, (char *)(uintptr_t)id, false);
72}
73
74static char *idprint(void *state, int objtype, IDTYPE id)
75{
76 (void)state;
77 (void)objtype;
78 if (id % 2 == 0)
79 return (char *)(uintptr_t)id;
80 else
81 return NULL;
82}
83
84static void idregister(void *state, int objtype, void *obj)
85{
86 (void)state;
87 (void)objtype;
88 (void)obj;
89}
90
92 idopen,
93 idmap,
94 idfree,
95 idprint,
96 free,
98};
99
100/* aux functions incl. support for disciplines with anonymous IDs */
101
102int agmapnametoid(Agraph_t * g, int objtype, char *str,
103 IDTYPE *result, bool createflag) {
104 int rv;
105
106 if (str && str[0] != LOCALNAMEPREFIX) {
107 rv = (int) AGDISC(g, id)->map(AGCLOS(g, id), objtype, str, result,
108 createflag);
109 if (rv)
110 return rv;
111 }
112
113 /* either an internal ID, or disc. can't map strings */
114 if (str) {
115 rv = aginternalmaplookup(g, objtype, str, result);
116 if (rv)
117 return rv;
118 } else
119 rv = 0;
120
121 if (createflag) {
122 /* get a new anonymous ID, and store in the internal map */
123 rv = (int) AGDISC(g, id)->map(AGCLOS(g, id), objtype, NULL, result,
124 createflag);
125 if (rv && str)
126 aginternalmapinsert(g, objtype, str, *result);
127 }
128 return rv;
129}
130
131void agfreeid(Agraph_t * g, int objtype, IDTYPE id)
132{
133 (void) aginternalmapdelete(g, objtype, id);
134 (AGDISC(g, id)->free) (AGCLOS(g, id), objtype, id);
135}
136
143char *agnameof(void *obj)
144{
145 Agraph_t *g;
146 char *rv;
147
148 /* perform internal lookup first */
149 g = agraphof(obj);
150 rv = aginternalmapprint(g, AGTYPE(obj), AGID(obj));
151 if (rv != NULL)
152 return rv;
153
154 if (AGDISC(g, id)->print) {
155 rv = AGDISC(g, id)->print(AGCLOS(g, id), AGTYPE(obj), AGID(obj));
156 if (rv != NULL)
157 return rv;
158 }
159 if (AGTYPE(obj) != AGEDGE) {
160 static char buf[32];
161 snprintf(buf, sizeof(buf), "%c%" PRIu64, LOCALNAMEPREFIX, AGID(obj));
162 rv = buf;
163 }
164 else
165 rv = 0;
166 return rv;
167}
168
169/* register a graph object in an external namespace */
170void agregister(Agraph_t * g, int objtype, void *obj)
171{
172 AGDISC(g, id)->idregister(AGCLOS(g, id), objtype, obj);
173}
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:149
void aginternalmapinsert(Agraph_t *g, int objtype, char *str, IDTYPE result)
Definition imap.c:103
char * aginternalmapprint(Agraph_t *g, int objtype, IDTYPE id)
Definition imap.c:139
bool aginternalmaplookup(Agraph_t *g, int objtype, char *str, IDTYPE *result)
Definition imap.c:82
#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:107
static Dtdisc_t disc
Definition exparse.y:209
void free(void *)
node NULL
Definition grammar.y:163
Agiddisc_t AgIdDisc
Definition id.c:91
Agraph_t * agraphof(void *obj)
Definition obj.c:185
char * agnameof(void *obj)
returns a string descriptor for the object.
Definition id.c:143
#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:378
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:370
char * agstrbind(Agraph_t *g, const char *)
Definition refstr.c:337
static uint64_t id
Definition gv2gml.c:42
textitem scanner parser str
Definition htmlparse.y:224
void agfreeid(Agraph_t *g, int objtype, IDTYPE id)
Definition id.c:131
static void * idopen(Agraph_t *g, Agdisc_t *disc)
Definition id.c:32
int agmapnametoid(Agraph_t *g, int objtype, char *str, IDTYPE *result, bool createflag)
Definition id.c:102
void agregister(Agraph_t *g, int objtype, void *obj)
Definition id.c:170
static char * idprint(void *state, int objtype, IDTYPE id)
Definition id.c:74
static void idfree(void *state, int objtype, IDTYPE id)
Definition id.c:66
static void idregister(void *state, int objtype, void *obj)
Definition id.c:84
static long idmap(void *state, int objtype, char *str, IDTYPE *id, int createflag)
Definition id.c:41
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:27
Agraph_t * g
graph in use
Definition id.c:29
IDTYPE counter
base to derive next identifier from
Definition id.c:28
Definition grammar.c:93