Graphviz  2.41.20170921.2350
apply.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 /* The following functions take a graph and a template (node/edge/graph)
17  * and return the object representing the template within the local graph.
18  */
19 static Agobj_t *subnode_search(Agraph_t * sub, Agobj_t * n)
20 {
21  if (agraphof(n) == sub)
22  return n;
23  return (Agobj_t *) agsubnode(sub, (Agnode_t *) n, FALSE);
24 }
25 
26 static Agobj_t *subedge_search(Agraph_t * sub, Agobj_t * e)
27 {
28  if (agraphof(e) == sub)
29  return e;
30  return (Agobj_t *) agsubedge(sub, (Agedge_t *) e, FALSE);
31 }
32 
33 static Agobj_t *subgraph_search(Agraph_t * sub, Agobj_t * g)
34 {
35  NOTUSED(g);
36  return (Agobj_t *) sub;
37 }
38 
39 /* recursively apply objfn within the hierarchy of a graph.
40  * if obj is a node or edge, it and its images in every subg are visited.
41  * if obj is a graph, then it and its subgs are visited.
42  */
43 static void rec_apply(Agraph_t * g, Agobj_t * obj, agobjfn_t fn, void *arg,
44  agobjsearchfn_t objsearch, int preorder)
45 {
46  Agraph_t *sub;
47  Agobj_t *subobj;
48 
49  if (preorder)
50  fn(g, obj, arg);
51  for (sub = agfstsubg(g); sub; sub = agnxtsubg(sub)) {
52  if ((subobj = objsearch(sub, obj)))
53  rec_apply(sub, subobj, fn, arg, objsearch, preorder);
54  }
55  if (NOT(preorder))
56  fn(g, obj, arg);
57 }
58 
59 /* external entry point (this seems to be one of those ineffective
60  * comments censured in books on programming style) */
61 int agapply(Agraph_t * g, Agobj_t * obj, agobjfn_t fn, void *arg,
62  int preorder)
63 {
64  Agobj_t *subobj;
65 
66  agobjsearchfn_t objsearch;
67  switch (AGTYPE(obj)) {
68  case AGRAPH:
69  objsearch = subgraph_search;
70  break;
71  case AGNODE:
72  objsearch = subnode_search;
73  break;
74  case AGOUTEDGE:
75  case AGINEDGE:
76  objsearch = subedge_search;
77  break;
78  default:
79  agerr(AGERR, "agapply: unknown object type %d\n", AGTYPE(obj));
80  return FAILURE;
81  break;
82  }
83  if ((subobj = objsearch(g, obj))) {
84  rec_apply(g, subobj, fn, arg, objsearch, preorder);
85  return SUCCESS;
86  } else
87  return FAILURE;
88 }
Definition: cgraph.h:388
#define SUCCESS
Definition: cghdr.h:62
Agobj_t *(* agobjsearchfn_t)(Agraph_t *g, Agobj_t *obj)
Definition: cghdr.h:73
#define NOTUSED(var)
Definition: cghdr.h:54
int agerr(agerrlevel_t level, const char *fmt,...)
Definition: agerror.c:141
CGRAPH_API Agraph_t * agfstsubg(Agraph_t *g)
Definition: subg.c:72
#define AGOUTEDGE
Definition: cgraph.h:102
#define AGTYPE(obj)
Definition: cgraph.h:113
CGRAPH_API Agraph_t * agraphof(void *obj)
Definition: obj.c:185
CGRAPH_API Agraph_t * agnxtsubg(Agraph_t *subg)
Definition: subg.c:77
#define FAILURE
Definition: cghdr.h:63
CGRAPH_API Agedge_t * agsubedge(Agraph_t *g, Agedge_t *e, int createflag)
Definition: edge.c:378
#define AGNODE
Definition: cgraph.h:101
#define sub(h, i)
Definition: closest.c:75
#define NOT(x)
Definition: cgraph.h:41
#define AGINEDGE
Definition: cgraph.h:103
int agapply(Agraph_t *g, Agobj_t *obj, agobjfn_t fn, void *arg, int preorder)
Definition: apply.c:61
#define FALSE
Definition: cgraph.h:35
CGRAPH_API Agnode_t * agsubnode(Agraph_t *g, Agnode_t *n, int createflag)
Definition: node.c:254
void(* agobjfn_t)(Agraph_t *g, Agobj_t *obj, void *arg)
Definition: cgraph.h:210
#define AGRAPH
Definition: cgraph.h:100