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 | |
27 | static int Verbose; |
28 | static char* gname = "" ; |
29 | static FILE *outFile; |
30 | static char *CmdName; |
31 | static char **Files; |
32 | |
33 | static 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 | |
57 | static 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 | |
77 | static 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\ |
82 | If no files are specified, stdin is used\n" ; |
83 | |
84 | static void usage(int v) |
85 | { |
86 | printf(useString, CmdName); |
87 | exit(v); |
88 | } |
89 | |
90 | static 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 | |
102 | static 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 | |
143 | static char* |
144 | nameOf (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 | |
160 | int 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 | |