2
This software may only be used by you under license from AT&T Corp.
3
("AT&T"). A copy of AT&T's Source Code Agreement is available at
4
AT&T's Internet website having the URL:
5
<http://www.research.att.com/sw/tools/graphviz/license/source.html>
6
If you received this software without first entering into a license
7
with AT&T, you have an infringing copy of this software and cannot use
8
it without violating AT&T's intellectual property rights.
12
* gpr: graph pattern recognizer
14
* Written by Emden Gansner
30
static const char* usage =
31
": gpr [-o <ofile>] ([-f <prog>] | 'prog') [files]\n\
32
-c - use source graph for output\n\
33
-f <pfile> - find program in file <pfile>\n\
34
-i - create node induced subgraph\n\
35
-o <ofile> - write output to <ofile>; stdout by default\n\
36
If no files are specified, stdin is used\n";
40
FILE* outFile; /* output stream; stdout default */
42
int useFile; /* true if program comes from a file */
52
outs = fopen(name,"w");
54
error (3|ERROR_SYSTEM, "could not open %s for writing", name);
60
* Parse command line options.
63
scanArgs(int argc,char **argv)
68
options.cmdName = argv[0];
71
error_info.id = options.cmdName;
73
while ((c = getopt(argc, argv, ":?cif:o:")) != -1) {
76
options.compflags |= SRCOUT;
80
options.program = optarg;
83
options.compflags |= INDUCE;
90
error(ERROR_USAGE, "%s", usage);
94
error(2, "option -%c unrecognized\n", optopt);
98
error(2, "missing argument for option -%c", optopt);
105
/* Handle additional semantics */
106
if (options.useFile == 0) {
108
error(2, "No program supplied via argument or -f option");
109
error_info.errors = 1;
112
options.program = *argv++;
116
if (argc == 0) options.inFiles = 0;
117
else options.inFiles = argv;
118
if (outname) options.outFile = openOut (outname);
119
else options.outFile = stdout;
121
if (error_info.errors)
122
error(ERROR_USAGE|4, "%s", usage);
126
evalEdge (Gpr_t* state, comp_prog* xprog, Agedge_t* e)
132
state->curobj = (Agobj_t*)e;
133
for (i = 0; i < xprog->n_estmts; i++) {
134
cs = xprog->edge_stmts+i;
136
okay = (exeval (xprog->prog, cs->guard, state)).integer;
139
if (cs->action) exeval (xprog->prog, cs->action, state);
140
else agsubedge (state->target, e, TRUE);
146
evalNode (Gpr_t* state, comp_prog* xprog, Agnode_t* n)
152
state->curobj = (Agobj_t*)n;
153
for (i = 0; i < xprog->n_nstmts; i++) {
154
cs = xprog->node_stmts+i;
155
if (cs->guard) okay = (exeval (xprog->prog, cs->guard, state)).integer;
158
if (cs->action) exeval (xprog->prog, cs->action, state);
159
else agsubnode (state->target, n, TRUE);
164
#define nData(n) ((ndata*)(aggetrec(n,UDATA,0)))
165
#define MARKED(x) (((x)->iu.integer)&1)
166
#define MARK(x) (((x)->iu.integer) = 1)
167
#define ONSTACK(x) (((x)->iu.integer)&2)
168
#define PUSH(x) (((x)->iu.integer)|=2)
169
#define POP(x) (((x)->iu.integer)&=(~2))
172
travDFS (Gpr_t* state, comp_prog* xprog)
184
for (n = agfstnode(state->curgraph); n; n = agnxtnode(n)) {
186
if (MARKED(nd)) continue;
194
evalNode (state, xprog, n);
197
if (cure) cure = agnxtedge (cure,curn);
198
else cure = agfstedge (curn);
200
if (entry == agopp(cure)) continue;
201
nd = nData(cure->node);
204
evalEdge (state, xprog, cure);
207
evalEdge (state, xprog, cure);
212
evalNode (state, xprog, curn);
221
entry = (Agedge_t*)pull(stk);
222
if (entry) curn = entry->node;
230
travFlat (Gpr_t* state, comp_prog* xprog)
235
for (n = agfstnode(state->curgraph); n; n = agnxtnode(n)) {
236
evalNode (state, xprog, n);
237
if (xprog->n_estmts > 0) {
238
for (e = agfstout(n); e; e = agnxtout(e)) {
239
evalEdge (state, xprog, e);
246
traverse (Gpr_t* state, comp_prog* xprog)
250
if (state->name_used) {
251
sfprintf (state->tmp, "%s%d", state->tgtname, state->name_used);
252
target = sfstruse (state->tmp);
254
else target = state->tgtname;
256
state->target = agsubg(state->curgraph,target,TRUE);
257
state->outgraph = state->target;
259
if (state->tvt == TV_dfs)
260
travDFS (state, xprog);
262
travFlat (state, xprog);
272
aginit(g,AGRAPH,UDATA,sizeof(gdata),0);
273
aginit(g,AGNODE,UDATA,sizeof(ndata),0);
274
aginit(g,AGEDGE,UDATA,sizeof(edata),0);
280
main (int argc, char* argv[])
289
prog = parseProg (options.program, options.useFile);
290
state = openGPRState ();
291
xprog = compileProg (prog, state, options.compflags);
292
initGPRState (state,xprog->prog->vm,options.outFile);
295
if (xprog->begin_stmt)
296
exeval (xprog->prog, xprog->begin_stmt, state);
298
/* if program is not null */
299
if (usesGraph(xprog)) {
300
ing = newIngraph (0, options.inFiles, readG);
301
while (state->curgraph = nextGraph(ing)) {
303
if (xprog->begg_stmt)
304
exeval (xprog->prog, xprog->begg_stmt, state);
307
if (walksGraph(xprog))
308
traverse (state, xprog);
311
if (xprog->endg_stmt)
312
exeval (xprog->prog, xprog->endg_stmt, state);
314
/* if $O == $G and $T is empty, delete $T */
315
if ((state->outgraph == state->curgraph) &&
316
(state->target) && !agnnodes(state->target))
317
agdelete (state->curgraph, state->target);
319
/* output graph, if necessary */
320
if (state->outgraph && agnnodes(state->outgraph))
321
agwrite (state->outgraph, options.outFile);
323
agclose (state->curgraph);
333
exeval (xprog->prog, xprog->end_stmt, state);