Graphviz  2.41.20170921.2350
imap.c
Go to the documentation of this file.
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 <cghdr.h>
15 
16 typedef struct IMapEntry_s {
20  char *str;
21 } IMapEntry_t;
22 
23 static int idcmpf(Dict_t * d, void *arg_p0, void *arg_p1, Dtdisc_t * disc)
24 {
25  IMapEntry_t *p0, *p1;
26 
27  NOTUSED(d);
28  p0 = arg_p0;
29  p1 = arg_p1;
30  NOTUSED(disc);
31  if (p0->id > p1->id)
32  {
33  return 1;
34  }
35  else if (p0->id < p1->id)
36  {
37  return -1;
38  }
39  else
40  {
41  return 0;
42  }
43 }
44 
45 /* note, OK to compare pointers into shared string pool
46  * but can't probe with an arbitrary string pointer
47  */
48 static int namecmpf(Dict_t * d, void *arg_p0, void *arg_p1,
49  Dtdisc_t * disc)
50 {
51  IMapEntry_t *p0, *p1;
52 
53  NOTUSED(d);
54  p0 = arg_p0;
55  p1 = arg_p1;
56  NOTUSED(disc);
57  if (p0->str > p1->str)
58  {
59  return 1;
60  }
61  else if (p0->str < p1->str)
62  {
63  return -1;
64  }
65  else
66  {
67  return 0;
68  }
69 }
70 
71 static Dtdisc_t LookupByName = {
72  0, /* object ptr is passed as key */
73  0, /* size (ignored) */
74  offsetof(IMapEntry_t, namedict_link),
75  NIL(Dtmake_f),
76  NIL(Dtfree_f),
77  namecmpf,
78  NIL(Dthash_f),
80  NIL(Dtevent_f)
81 };
82 
83 static Dtdisc_t LookupById = {
84  0, /* object ptr is passed as key */
85  0, /* size (ignored) */
86  offsetof(IMapEntry_t, iddict_link),
87  NIL(Dtmake_f),
88  NIL(Dtfree_f),
89  idcmpf,
90  NIL(Dthash_f),
92  NIL(Dtevent_f)
93 };
94 
95 int aginternalmaplookup(Agraph_t * g, int objtype, char *str,
96  IDTYPE *result)
97 {
98  Dict_t *d;
99  IMapEntry_t *sym, template;
100  char *search_str;
101 
102  if (objtype == AGINEDGE)
103  objtype = AGEDGE;
104  if ((d = g->clos->lookup_by_name[objtype])) {
105  if ((search_str = agstrbind(g, str))) {
106  template.str = search_str;
107  sym = (IMapEntry_t *) dtsearch(d, &template);
108  if (sym) {
109  *result = sym->id;
110  return TRUE;
111  }
112  }
113  }
114  return FALSE;
115 }
116 
117 /* caller GUARANTEES that this is a new entry */
118 void aginternalmapinsert(Agraph_t * g, int objtype, char *str,
119  IDTYPE id)
120 {
121  IMapEntry_t *ent;
122  Dict_t *d_name_to_id, *d_id_to_name;
123 
124  ent = AGNEW(g, IMapEntry_t);
125  ent->id = id;
126  ent->str = agstrdup(g, str);
127 
128  if (objtype == AGINEDGE)
129  objtype = AGEDGE;
130  if ((d_name_to_id = g->clos->lookup_by_name[objtype]) == NIL(Dict_t *))
131  d_name_to_id = g->clos->lookup_by_name[objtype] =
132  agdtopen(g, &LookupByName, Dttree);
133  if ((d_id_to_name = g->clos->lookup_by_id[objtype]) == NIL(Dict_t *))
134  d_id_to_name = g->clos->lookup_by_id[objtype] =
135  agdtopen(g, &LookupById, Dttree);
136  dtinsert(d_name_to_id, ent);
137  dtinsert(d_id_to_name, ent);
138 }
139 
140 static IMapEntry_t *find_isym(Agraph_t * g, int objtype, IDTYPE id)
141 {
142  Dict_t *d;
143  IMapEntry_t *isym, itemplate;
144 
145  if (objtype == AGINEDGE)
146  objtype = AGEDGE;
147  if ((d = g->clos->lookup_by_id[objtype])) {
148  itemplate.id = id;
149  isym = (IMapEntry_t *) dtsearch(d, &itemplate);
150  } else
151  isym = NIL(IMapEntry_t *);
152  return isym;
153 }
154 
155 char *aginternalmapprint(Agraph_t * g, int objtype, IDTYPE id)
156 {
157  IMapEntry_t *isym;
158 
159  if ((isym = find_isym(g, objtype, id)))
160  return isym->str;
161  return NILstr;
162 }
163 
164 
165 int aginternalmapdelete(Agraph_t * g, int objtype, IDTYPE id)
166 {
167  IMapEntry_t *isym;
168 
169  if (objtype == AGINEDGE)
170  objtype = AGEDGE;
171  if ((isym = find_isym(g, objtype, id))) {
172  dtdelete(g->clos->lookup_by_name[objtype], isym);
173  dtdelete(g->clos->lookup_by_id[objtype], isym);
174  agstrfree(g, isym->str);
175  agfree(g, isym);
176  return TRUE;
177  }
178  return FALSE;
179 }
180 
182 {
183  int i;
184  IMapEntry_t *sym, *nxt;
185  Dict_t **d_name;
186  /* Dict_t **d_id; */
187 
188  Ag_G_global = g;
189  d_name = g->clos->lookup_by_name;
190  /* d_id = g->clos->lookup_by_id; */
191  for (i = 0; i < 3; i++) {
192  if (d_name[i]) {
193  for (sym = dtfirst(d_name[i]); sym; sym = nxt) {
194  nxt = dtnext(d_name[i], sym);
195  if (sym->str[0] == LOCALNAMEPREFIX)
196  aginternalmapdelete(g, i, sym->id);
197  }
198  }
199  }
200 }
201 
202 static void closeit(Dict_t ** d)
203 {
204  int i;
205 
206  for (i = 0; i < 3; i++) {
207  if (d[i]) {
208  dtclose(d[i]);
209  d[i] = NIL(Dict_t *);
210  }
211  }
212 }
213 
215 {
216  Ag_G_global = g;
217  closeit(g->clos->lookup_by_name);
218  closeit(g->clos->lookup_by_id);
219 }
void aginternalmapinsert(Agraph_t *g, int objtype, char *str, IDTYPE result)
Definition: imap.c:118
unsigned int(* Dthash_f)(Dt_t *, void *, Dtdisc_t *)
Definition: cdt.h:41
CDT_API int dtclose(Dt_t *)
struct IMapEntry_s IMapEntry_t
Dtlink_t iddict_link
Definition: imap.c:18
void *(* Dtmake_f)(Dt_t *, void *, Dtdisc_t *)
Definition: cdt.h:38
Dict_t * lookup_by_id[3]
Definition: cgraph.h:236
#define LOCALNAMEPREFIX
Definition: cghdr.h:64
#define dtdelete(d, o)
Definition: cdt.h:264
#define NOTUSED(var)
Definition: cghdr.h:54
Definition: cdt.h:80
#define dtfirst(d)
Definition: cdt.h:254
Dtlink_t namedict_link
Definition: imap.c:17
CGRAPH_API void agfree(Agraph_t *g, void *ptr)
Definition: mem.c:89
#define AGNEW(g, t)
Definition: cghdr.h:68
#define NILstr
Definition: cghdr.h:60
char * aginternalmapprint(Agraph_t *g, int objtype, IDTYPE id)
Definition: imap.c:155
uint64_t IDTYPE
Definition: cgraph.h:51
#define NIL(t)
Definition: dthdr.h:13
#define dtsearch(d, o)
Definition: cdt.h:260
Dict_t * lookup_by_name[3]
Definition: cgraph.h:235
#define dtnext(d, o)
Definition: cdt.h:255
IDTYPE id
Definition: imap.c:19
int aginternalmaplookup(Agraph_t *g, int objtype, char *str, IDTYPE *result)
Definition: imap.c:95
CGRAPH_API int agstrfree(Agraph_t *, char *)
Definition: refstr.c:149
CGRAPH_API char * agstrdup(Agraph_t *, char *)
Definition: refstr.c:97
void aginternalmapclose(Agraph_t *g)
Definition: imap.c:214
EXTERN Agraph_t * Ag_G_global
Definition: cghdr.h:78
char * str
Definition: imap.c:20
int aginternalmapdelete(Agraph_t *g, int objtype, IDTYPE id)
Definition: imap.c:165
#define dtinsert(d, o)
Definition: cdt.h:262
Dict_t * agdtopen(Agraph_t *g, Dtdisc_t *disc, Dtmethod_t *method)
Definition: utils.c:53
CDT_API Dtmethod_t * Dttree
Definition: cdt.h:176
CGRAPH_API void aginternalmapclearlocalnames(Agraph_t *g)
Definition: imap.c:181
void * agdictobjmem(Dict_t *dict, void *p, size_t size, Dtdisc_t *disc)
Definition: utils.c:19
int(* Dtevent_f)(Dt_t *, int, void *, Dtdisc_t *)
Definition: cdt.h:42
void(* Dtfree_f)(Dt_t *, void *, Dtdisc_t *)
Definition: cdt.h:39
#define AGINEDGE
Definition: cgraph.h:103
Definition: cdt.h:99
agxbuf * str
Definition: htmlparse.c:85
Agclos_t * clos
Definition: cgraph.h:248
CGRAPH_API char * agstrbind(Agraph_t *g, char *)
Definition: refstr.c:92
#define AGEDGE
Definition: cgraph.h:104
#define FALSE
Definition: cgraph.h:35
#define TRUE
Definition: cgraph.h:38