44#define DFLT_GVPRPATH "."
54 " [-o <ofile>] [-a <args>] ([-f <prog>] | 'prog') [files]\n\
55 -c - use source graph for output\n\
56 -f <pfile> - find program in file <pfile>\n\
57 -i - create node induced subgraph\n\
58 -a <args> - string arguments available as ARGV[0..]\n\
59 -o <ofile> - write output to <ofile>; stdout by default\n\
60 -n - no read-ahead of input graphs\n\
61 -q - turn off warning messages\n\
62 -V - print version info\n\
63 -? - print usage info\n\
64If no files are specified, stdin is used\n";
81 FILE *outs = fopen(name,
"w");
109 if ((c = *rs) ==
'\0')
114 }
else if (!q && ((c ==
'"') || (c ==
'\''))) {
116 }
else if (c ==
'\\') {
123 "backslash in argument followed by no character - ignored");
161 "at most %d arguments allowed per -a flag - ignoring rest",
171 av =
gv_recalloc(*argv, (
size_t)oldcnt, (
size_t)argc,
sizeof(
char*));
172 for (i = 0; i <
cnt; i++)
180#if defined(_WIN32) && !defined(__MINGW32__)
214 path = getenv(
"GVPRPATH");
216 path = getenv(
"GPRPATH");
228 fprintf (stderr,
"PATH: %s\n",
path);
238 sz = (size_t) (cp -
path);
248 if (access(
s, R_OK) == 0) {
259 fprintf (stderr,
"file %s resolved to %s\n", arg,
fname);
264getOptarg (
int c,
char** argp,
int* argip,
int argc,
char** argv)
275 else if (argi < argc) {
300 while ((c = *arg++)) {
321 if ((optarg =
getOptarg(c, &arg, &argi, argc, argv))) {
337 fprintf(stderr,
"%s version %s (%s)\n",
Info[0],
Info[1],
Info[2]);
341 if (optopt ==
'\0' || optopt ==
'?')
342 fprintf(stderr,
"Usage: gvpr%s",
usage);
358 fclose(
opts.outFile);
362 for (
int i = 0; i <
opts.argc; i++)
374 opts.cmdName = argv[0];
382 for (
int i = 1; i < argc; i++)
383 if (argv[i] && argv[i][0] !=
'-')
385 char** input_filenames =
gv_calloc(nfiles + 1,
sizeof(
char*));
389 for (
int i = 1; i < argc; ) {
398 input_filenames[nfiles++] = arg;
402 if (
opts.useFile == 0) {
405 "No program supplied via argument or -f option");
408 opts.program = input_filenames[0];
409 for (
size_t i = 1; i <= nfiles; i++)
410 input_filenames[i-1] = input_filenames[i];
416 free (input_filenames);
420 opts.inFiles = input_filenames;
423 opts.outFile = stdout;
426 if (
opts.state <= 0) {
429 free (input_filenames);
441 for (
size_t i = 0; i < xprog->
n_estmts; i++) {
454 return state->curobj;
463 for (
size_t i = 0; i < xprog->
n_nstmts; i++) {
476 return (
state->curobj);
492 state->flags &= ~GV_NEXT_SET;
493 }
else if (nodes->
prev) {
501#define MARKED(x) (((x)->iu.integer)&1)
502#define MARK(x) (((x)->iu.integer) = 1)
503#define ONSTACK(x) (((x)->iu.integer)&2)
504#define PUSH(x,e) (((x)->iu.integer)|=2,(x)->ine=(e))
505#define POP(x) (((x)->iu.integer)&=(~2))
558 state->tvedge = nd->ine;
560 for (cure =
agfstedge(g, n); cure; cure = nxte) {
580 gv_stack_t stk = {0};
599 state->tvedge = cure = 0;
611 if (entry ==
agopp(cure))
627 state->tvedge = entry = cure;
642 if (entry == &(
seed.out))
645 state->tvedge = entry;
677 for (e =
agfstout(g, n); e; e = nexte) {
695 for (e =
agfstout(g, n); e; e = nexte) {
722 if (!
state->target) {
726 if (
state->name_used) {
730 target =
state->tgtname;
741 if (!
state->outgraph)
744 switch (
state->tvt) {
872 const char *fmt, ...) {
877 && handle) ? *((
char **) handle) : (
char *) handle, level, fmt, ap);
958 if ((rv = setjmp (
jbuf))) {
963 bool incoreGraphs = uopts && uopts->
ingraphs;
966 fprintf(stderr,
"Parse/compile/init: %.2f secs.\n",
gvelapsed_sec());
1037 fprintf(stderr,
"Read graph: %.2f secs.\n",
gvelapsed_sec());
1061 int rv =
gvpr_core(argc, argv, uopts, &gvpr_state);
Agobj_t * cloneO(Agraph_t *g, Agobj_t *obj)
int sfioWrite(Agraph_t *g, FILE *fp)
double gvelapsed_sec(void)
static void agxbfree(agxbuf *xb)
free any malloced resources
static size_t agxbput(agxbuf *xb, const char *s)
append string s into xb
static size_t agxbput_n(agxbuf *xb, const char *s, size_t ssz)
append string s of length ssz into xb
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
static char * agxbuse(agxbuf *xb)
static char * agxbdisown(agxbuf *xb)
Memory allocation wrappers that exit on failure.
static void * gv_recalloc(void *ptr, size_t old_nmemb, size_t new_nmemb, size_t size)
static char * gv_strdup(const char *original)
static void * gv_calloc(size_t nmemb, size_t size)
abstract graph C library, Cgraph API
Agraph_t * openSubg(Agraph_t *g, char *name)
int walksGraph(comp_block *p)
void freeCompileProg(comp_prog *p)
int usesGraph(comp_prog *p)
Agraph_t * readG(FILE *fp)
comp_prog * compileProg(parse_prog *inp, Gpr_t *state, int flags)
void error(int level, const char *s,...)
void setTraceLevel(int i)
void errorv(const char *id, int level, const char *s, va_list ap)
void setErrorId(char *id)
void setErrorErrors(int errors)
Extype_t exeval(Expr_t *ex, Exnode_t *exnode, void *env)
static NORETURN void graphviz_exit(int status)
static void cleanup(void)
void initGPRState(Gpr_t *state)
void addBindings(Gpr_t *state, gvprbinding *bindings)
Gpr_t * openGPRState(gpr_info *info)
void closeGPRState(Gpr_t *state)
static int cnt(Dict_t *d, Dtlink_t **set)
int agnnodes(Agraph_t *g)
#define agopp(e)
opposite edge: flip Agedgepair_s.out ⇄ Agedgepair_s.in/*#end#*/
Agedge_t * agsubedge(Agraph_t *g, Agedge_t *e, int createflag)
Agedge_t * agnxtin(Agraph_t *g, Agedge_t *e)
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Agedge_t * agnxtedge(Agraph_t *g, Agedge_t *e, Agnode_t *n)
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Agedge_t * agfstedge(Agraph_t *g, Agnode_t *n)
Agedge_t * agfstin(Agraph_t *g, Agnode_t *n)
int agclose(Agraph_t *g)
deletes a graph, freeing its associated storage
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Agnode_t * agfstnode(Agraph_t *g)
Agnode_t * agsubnode(Agraph_t *g, Agnode_t *n, int createflag)
int agdelete(Agraph_t *g, void *obj)
deletes object. Equivalent to agclose, agdelnode, and agdeledge for obj being a graph,...
Agraph_t * agroot(void *obj)
Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
replacements for ctype.h functions
static bool gv_isspace(int c)
static void freeOpts(options opts)
static char * concat(char *pfx, char *sfx)
static char * resolve(char *arg, int verbose)
static Agobj_t * evalNode(Gpr_t *state, Expr_t *prog, comp_block *xprog, Agnode_t *n)
int gvpr(int argc, char *argv[], gvpropts *uopts)
static void chkClose(Agraph_t *g)
static void travNodes(Gpr_t *state, Expr_t *prog, comp_block *xprog)
static void doCleanup(Agraph_t *g)
static char * gettok(char **sp)
static FILE * openOut(char *name)
static bool traverse(Gpr_t *state, Expr_t *prog, comp_block *bp, bool cleanup)
static Agedge_t * agnxtin_(Agraph_t *g, Agedge_t *e, Agnode_t *ignored)
agnxtin wrapper to tweak calling convention
Agedge_t *(* nxttedgefn_t)(Agraph_t *, Agedge_t *, Agnode_t *)
static options scanArgs(int argc, char **argv)
static void travDFS(Gpr_t *state, Expr_t *prog, comp_block *xprog, trav_fns *fns)
static void travBFS(Gpr_t *state, Expr_t *prog, comp_block *xprog)
static void travFlat(Gpr_t *state, Expr_t *prog, comp_block *xprog)
static void travEdges(Gpr_t *state, Expr_t *prog, comp_block *xprog)
static void gvexitf(Expr_t *handle, Exdisc_t *discipline, int v)
static Agnode_t * nextNode(Gpr_t *state, nodestream *nodes)
static void addOutputGraph(Gpr_t *state, gvpropts *uopts)
static int gvpr_core(int argc, char *argv[], gvpropts *uopts, gvpr_state_t *gs)
static int doFlags(char *arg, int argi, int argc, char **argv, options *opts)
static void gverrorf(Expr_t *handle, Exdisc_t *discipline, int level, const char *fmt,...)
Agedge_t *(* fstedgefn_t)(Agraph_t *, Agnode_t *)
static Agedge_t * agnxtout_(Agraph_t *g, Agedge_t *e, Agnode_t *ignored)
agnxtout wrapper to tweak calling convention
static Agraph_t * ing_read(void *fp)
static const char * usage
static Agobj_t * evalEdge(Gpr_t *state, Expr_t *prog, comp_block *xprog, Agedge_t *e)
static int parseArgs(char *s, int argc, char ***argv)
static char * getOptarg(int c, char **argp, int *argip, int argc, char **argv)
graph pattern scanning and processing language API, main function gvpr
char * fileName(ingraph_state *sp)
Return name of current file being processed.
void closeIngraph(ingraph_state *sp)
Agraph_t * nextGraph(ingraph_state *sp)
ingraph_state * newIng(ingraph_state *sp, char **files, Agraph_t *(*readf)(void *))
ingraph_state * newIngGraphs(ingraph_state *sp, Agraph_t **graphs, Agraph_t *(*readf)(void *))
supports user-supplied data
void freeParseProg(parse_prog *prog)
parse_prog * parseProg(char *input, int isFile)
generic first-in-first-out buffer (queue)
static void queue_free(queue_t *q)
static void queue_push(queue_t *q, void *item)
static void * queue_pop(queue_t *q)
Implementation of a dynamically expanding stack data structure.
static void stack_push(gv_stack_t *stack, void *item)
static void * stack_pop(gv_stack_t *stack)
static void stack_reset(gv_stack_t *stack)
static bool stack_is_empty(const gv_stack_t *stack)
a generic header of Agraph_s, Agnode_s and Agedge_s
collective managed state used in gvpr_core
size_t n_outgraphs
if GV_USE_OUTGRAPH set, output graphs