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 "config.h"
15
16#include "gml2gv.h"
17#include <stdlib.h>
18#include <string.h>
19#ifdef HAVE_UNISTD_H
20#include <unistd.h>
21#endif
22
23#include <getopt.h>
24
25#define N_NEW(n,t) (t*)malloc((n)*sizeof(t))
26
27static int Verbose;
28static char* gname = "";
29static FILE *outFile;
30static char *CmdName;
31static char **Files;
32
33static FILE *getFile(void)
34{
35 FILE *rv = NULL;
36 static FILE *savef = NULL;
37 static int cnt = 0;
38
39 if (Files == NULL) {
40 if (cnt++ == 0) {
41 rv = stdin;
42 }
43 } else {
44 if (savef)
45 fclose(savef);
46 while (Files[cnt]) {
47 if ((rv = fopen(Files[cnt++], "r")) != 0)
48 break;
49 else
50 fprintf(stderr, "Can't open %s\n", Files[cnt - 1]);
51 }
52 }
53 savef = rv;
54 return rv;
55}
56
57static FILE *openFile(char *name, char *mode)
58{
59 FILE *fp;
60 char *modestr;
61
62 fp = fopen(name, mode);
63 if (!fp) {
64 if (*mode == 'r')
65 modestr = "reading";
66 else
67 modestr = "writing";
68 fprintf(stderr, "%s: could not open file %s for %s\n",
69 CmdName, name, modestr);
70 perror(name);
71 exit(1);
72 }
73 return fp;
74}
75
76
77static char *useString = "Usage: %s [-v?] [-g<name>] [-o<file>] <files>\n\
78 -g<name> : use <name> as template for graph names\n\
79 -v : verbose mode\n\
80 -o<file> : output to <file> (stdout)\n\
81 -? : print usage\n\
82If no files are specified, stdin is used\n";
83
84static void usage(int v)
85{
86 printf(useString, CmdName);
87 exit(v);
88}
89
90static char *cmdName(char *path)
91{
92 char *sp;
93
94 sp = strrchr(path, '/');
95 if (sp)
96 sp++;
97 else
98 sp = path;
99 return sp;
100}
101
102static void initargs(int argc, char **argv)
103{
104 int c;
105
106 CmdName = cmdName(argv[0]);
107 opterr = 0;
108 while ((c = getopt(argc, argv, ":g:vo:")) != -1) {
109 switch (c) {
110 case 'g':
111 gname = optarg;
112 break;
113 case 'v':
114 Verbose = 1;
115 break;
116 case 'o':
117 outFile = openFile(optarg, "w");
118 break;
119 case ':':
120 fprintf(stderr, "%s: option -%c missing argument\n", CmdName, optopt);
121 usage(1);
122 break;
123 case '?':
124 if (optopt == '?')
125 usage(0);
126 else {
127 fprintf(stderr, "%s: option -%c unrecognized\n", CmdName,
128 optopt);
129 usage(1);
130 }
131 }
132 }
133
134 argv += optind;
135 argc -= optind;
136
137 if (argc)
138 Files = argv;
139 if (!outFile)
140 outFile = stdout;
141}
142
143static char*
144nameOf (char* name, int cnt)
145{
146 static char* buf = 0;
147
148 if (*name == '\0')
149 return name;
150 if (cnt) {
151 if (!buf)
152 buf = N_NEW (strlen(name)+32,char); /* 32 to handle any integer plus null byte */
153 sprintf (buf, "%s%d", name, cnt);
154 return buf;
155 }
156 else
157 return name;
158}
159
160int main(int argc, char **argv)
161{
162 Agraph_t *G;
163 Agraph_t *prev = 0;
164 FILE *inFile;
165 int gcnt, cnt, rv;
166
167 rv = 0;
168 gcnt = 0;
169 initargs(argc, argv);
170 while ((inFile = getFile())) {
171 cnt = 0;
172 while ((G = gml_to_gv(nameOf(gname, gcnt), inFile, cnt, &rv))) {
173 cnt++;
174 gcnt++;
175 if (prev)
176 agclose(prev);
177 prev = G;
178 if (Verbose)
179 fprintf (stderr, "%s: %d nodes %d edges\n",
180 agnameof (G), agnnodes(G), agnedges(G));
181 agwrite(G, outFile);
182 fflush(outFile);
183 }
184 }
185 exit(rv);
186}
187
188