1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
/**
* @file
* @brief implementation of subgraphs
* @ingroup cgraph_subgraph
* @ingroup cgraph_core
*/
/*************************************************************************
* Copyright (c) 2011 AT&T Intellectual Property
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors: Details at https://graphviz.org
*************************************************************************/
#include "config.h"
#include <cgraph/cghdr.h>
#include <stdbool.h>
#include <stddef.h>
#include <util/alloc.h>
static Agraph_t *agfindsubg_by_id(Agraph_t * g, IDTYPE id)
{
Agraph_t template;
agdtdisc(g, g->g_id, &Ag_subgraph_id_disc);
AGID(&template) = id;
return dtsearch(g->g_id, &template);
}
static Agraph_t *localsubg(Agraph_t * g, IDTYPE id)
{
Agraph_t *subg;
subg = agfindsubg_by_id(g, id);
if (subg)
return subg;
subg = gv_alloc(sizeof(Agraph_t));
subg->clos = g->clos;
subg->desc = g->desc;
subg->desc.maingraph = false;
subg->parent = g;
subg->root = g->root;
AGID(subg) = id;
return agopen1(subg);
}
Agraph_t *agidsubg(Agraph_t *g, IDTYPE id) {
return agfindsubg_by_id(g, id);
}
Agraph_t *agsubg(Agraph_t * g, char *name, int cflag)
{
IDTYPE id;
Agraph_t *subg;
if (name && agmapnametoid(g, AGRAPH, name, &id, false)) {
/* might already exist */
if ((subg = agfindsubg_by_id(g, id)))
return subg;
}
if (cflag && agmapnametoid(g, AGRAPH, name, &id, true)) { /* reserve id */
subg = localsubg(g, id);
agregister(g, AGRAPH, subg);
return subg;
}
return NULL;
}
Agraph_t *agfstsubg(Agraph_t * g)
{
return dtfirst(g->g_seq);
}
Agraph_t *agnxtsubg(Agraph_t * subg)
{
Agraph_t *g;
g = agparent(subg);
return g? dtnext(g->g_seq, subg) : 0;
}
Agraph_t *agparent(Agraph_t * g)
{
return g->parent;
}
/* this function is only responsible for deleting the entry
* in the parent's subg dict. the rest is done in agclose().
*/
int agdelsubg(Agraph_t * g, Agraph_t * subg)
{
return dtdelete(g->g_seq, subg) != NULL && dtdelete(g->g_id, subg) != NULL;
}
|