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 
agfindsubg_by_id(Agraph_t * g,IDTYPE id)16 static 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 
localsubg(Agraph_t * g,IDTYPE id)25 static 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 
agidsubg(Agraph_t * g,IDTYPE id,int cflag)43 Agraph_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 
agsubg(Agraph_t * g,char * name,int cflag)52 Agraph_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 
agfstsubg(Agraph_t * g)72 Agraph_t *agfstsubg(Agraph_t * g)
73 {
74     return (Agraph_t *) dtfirst(g->g_dict);
75 }
76 
agnxtsubg(Agraph_t * subg)77 Agraph_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 
agparent(Agraph_t * g)85 Agraph_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  */
agdelsubg(Agraph_t * g,Agraph_t * subg)93 long agdelsubg(Agraph_t * g, Agraph_t * subg)
94 {
95     return (long) dtdelete(g->g_dict, subg);
96 }
97