1/* $Id$ $Revision$ */
2/* vim:set shiftwidth=4 ts=8: */
3
4/*************************************************************************
5 * Copyright (c) 2011 AT&T Intellectual Property
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Eclipse Public License v1.0
8 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *
11 * Contributors: See CVS logs. Details at http://www.graphviz.org/
12 *************************************************************************/
13
14#include <stdio.h>
15#include <cghdr.h>
16
17/* a default ID allocator that works off the shared string lib */
18
19static void *idopen(Agraph_t * g, Agdisc_t* disc)
20{
21 return g;
22}
23
24static long idmap(void *state, int objtype, char *str, IDTYPE *id,
25 int createflag)
26{
27 char *s;
28 static IDTYPE ctr = 1;
29
30 NOTUSED(objtype);
31 if (str) {
32 Agraph_t *g;
33 g = state;
34 if (createflag)
35 s = agstrdup(g, str);
36 else
37 s = agstrbind(g, str);
38 *id = (IDTYPE) s;
39 } else {
40 *id = ctr;
41 ctr += 2;
42 }
43 return TRUE;
44}
45
46 /* we don't allow users to explicitly set IDs, either */
47static long idalloc(void *state, int objtype, IDTYPE request)
48{
49 NOTUSED(state);
50 NOTUSED(objtype);
51 NOTUSED(request);
52 return FALSE;
53}
54
55static void idfree(void *state, int objtype, IDTYPE id)
56{
57 NOTUSED(objtype);
58 if (id % 2 == 0)
59 agstrfree((Agraph_t *) state, (char *) id);
60}
61
62static char *idprint(void *state, int objtype, IDTYPE id)
63{
64 NOTUSED(state);
65 NOTUSED(objtype);
66 if (id % 2 == 0)
67 return (char *) id;
68 else
69 return NILstr;
70}
71
72static void idclose(void *state)
73{
74 NOTUSED(state);
75}
76
77static void idregister(void *state, int objtype, void *obj)
78{
79 NOTUSED(state);
80 NOTUSED(objtype);
81 NOTUSED(obj);
82}
83
84Agiddisc_t AgIdDisc = {
85 idopen,
86 idmap,
87 idalloc,
88 idfree,
89 idprint,
90 idclose,
91 idregister
92};
93
94/* aux functions incl. support for disciplines with anonymous IDs */
95
96int agmapnametoid(Agraph_t * g, int objtype, char *str,
97 IDTYPE *result, int createflag)
98{
99 int rv;
100
101 if (str && (str[0] != LOCALNAMEPREFIX)) {
102 rv = AGDISC(g, id)->map(AGCLOS(g, id), objtype, str, result,
103 createflag);
104 if (rv)
105 return rv;
106 }
107
108 /* either an internal ID, or disc. can't map strings */
109 if (str) {
110 rv = aginternalmaplookup(g, objtype, str, result);
111 if (rv)
112 return rv;
113 } else
114 rv = 0;
115
116 if (createflag) {
117 /* get a new anonymous ID, and store in the internal map */
118 rv = AGDISC(g, id)->map(AGCLOS(g, id), objtype, NILstr, result,
119 createflag);
120 if (rv && str)
121 aginternalmapinsert(g, objtype, str, *result);
122 }
123 return rv;
124}
125
126int agallocid(Agraph_t * g, int objtype, IDTYPE request)
127{
128 return AGDISC(g, id)->alloc(AGCLOS(g, id), objtype, request);
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
137/* agnameof:
138 * Return string representation of object.
139 * In general, returns the name of node or graph,
140 * and the key of an edge. If edge is anonymous, returns NULL.
141 * Uses static buffer for anonymous graphs.
142 */
143char *agnameof(void *obj)
144{
145 Agraph_t *g;
146 char *rv;
147 static char buf[32];
148
149 /* perform internal lookup first */
150 g = agraphof(obj);
151 if ((rv = aginternalmapprint(g, AGTYPE(obj), AGID(obj))))
152 return rv;
153
154 if (AGDISC(g, id)->print) {
155 if ((rv =
156 AGDISC(g, id)->print(AGCLOS(g, id), AGTYPE(obj), AGID(obj))))
157 return rv;
158 }
159 if (AGTYPE(obj) != AGEDGE) {
160 sprintf(buf, "%c%ld", LOCALNAMEPREFIX, AGID(obj));
161 rv = buf;
162 }
163 else
164 rv = 0;
165 return rv;
166}
167
168/* register a graph object in an external namespace */
169void agregister(Agraph_t * g, int objtype, void *obj)
170{
171 AGDISC(g, id)->idregister(AGCLOS(g, id), objtype, obj);
172}
173