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
16static Agraph_t *agfindsubg_by_id(Agraph_t * g, IDTYPE id)
17{
18 Agraph_t template;
19
20 agdtdisc(g, g->g_dict, &Ag_subgraph_id_disc);
21 AGID(&template) = id;
22 return (Agraph_t *) dtsearch(g->g_dict, &template);
23}
24
25static Agraph_t *localsubg(Agraph_t * g, IDTYPE id)
26{
27 Agraph_t *subg;
28
29 subg = agfindsubg_by_id(g, id);
30 if (subg)
31 return subg;
32
33 subg = agalloc(g, sizeof(Agraph_t));
34 subg->clos = g->clos;
35 subg->desc = g->desc;
36 subg->desc.maingraph = FALSE;
37 subg->parent = g;
38 subg->root = g->root;
39 AGID(subg) = id;
40 return agopen1(subg);
41}
42
43Agraph_t *agidsubg(Agraph_t * g, IDTYPE id, int cflag)
44{
45 Agraph_t *subg;
46 subg = agfindsubg_by_id(g, id);
47 if ((subg == NILgraph) && cflag && agallocid(g, AGRAPH, id))
48 subg = localsubg(g, id);
49 return subg;
50}
51
52Agraph_t *agsubg(Agraph_t * g, char *name, int cflag)
53{
54 IDTYPE id;
55 Agraph_t *subg;
56
57 if (name && agmapnametoid(g, AGRAPH, name, &id, FALSE)) {
58 /* might already exist */
59 if ((subg = agfindsubg_by_id(g, id)))
60 return subg;
61 }
62
63 if (cflag && agmapnametoid(g, AGRAPH, name, &id, TRUE)) { /* reserve id */
64 subg = localsubg(g, id);
65 agregister(g, AGRAPH, subg);
66 return subg;
67 }
68
69 return NILgraph;
70}
71
72Agraph_t *agfstsubg(Agraph_t * g)
73{
74 return (Agraph_t *) dtfirst(g->g_dict);
75}
76
77Agraph_t *agnxtsubg(Agraph_t * subg)
78{
79 Agraph_t *g;
80
81 g = agparent(subg);
82 return g? (Agraph_t *) dtnext(g->g_dict, subg) : 0;
83}
84
85Agraph_t *agparent(Agraph_t * g)
86{
87 return g->parent;
88}
89
90/* this function is only responsible for deleting the entry
91 * in the parent's subg dict. the rest is done in agclose().
92 */
93long agdelsubg(Agraph_t * g, Agraph_t * subg)
94{
95 return (long) dtdelete(g->g_dict, subg);
96}
97