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 | /* FIXME |
15 | * This is an ugly mess. |
16 | * |
17 | * Args should be made independent of layout engine and arg values |
18 | * should be stored in gvc or gvc->job. All globals should be eliminated. |
19 | * |
20 | * Needs to be fixed before layout engines can be plugins. |
21 | */ |
22 | |
23 | #include <ctype.h> |
24 | #include "render.h" |
25 | #include "tlayout.h" |
26 | #include "gvc.h" |
27 | #include "fdp.h" |
28 | |
29 | /* neato_extra_args: |
30 | * Handle special neato arguments. |
31 | * Return number of unprocessed arguments; return < 0 on error. |
32 | */ |
33 | static int |
34 | (GVC_t *gvc, int argc, char** argv) |
35 | { |
36 | char** p = argv+1; |
37 | int i; |
38 | char* arg; |
39 | int cnt = 1; |
40 | |
41 | for (i = 1; i < argc; i++) { |
42 | arg = argv[i]; |
43 | if (arg && *arg == '-') { |
44 | switch (arg[1]) { |
45 | case 'x' : Reduce = TRUE; break; |
46 | case 'n': |
47 | if (arg[2]) { |
48 | Nop = atoi(arg+2); |
49 | if (Nop <= 0) { |
50 | agerr (AGERR, "Invalid parameter \"%s\" for -n flag\n" , arg+2); |
51 | dotneato_usage (1); |
52 | return -1; |
53 | } |
54 | } |
55 | else Nop = 1; |
56 | break; |
57 | default : |
58 | cnt++; |
59 | if (*p != arg) *p = arg; |
60 | p++; |
61 | break; |
62 | } |
63 | } |
64 | else { |
65 | cnt++; |
66 | if (*p != arg) *p = arg; |
67 | p++; |
68 | } |
69 | } |
70 | *p = 0; |
71 | return cnt; |
72 | } |
73 | |
74 | /* memtest_extra_args: |
75 | * Handle special memtest arguments. |
76 | * Return number of unprocessed arguments; return < 0 on error. |
77 | */ |
78 | static int |
79 | (GVC_t *gvc, int argc, char** argv) |
80 | { |
81 | char** p = argv+1; |
82 | int i; |
83 | char* arg; |
84 | int cnt = 1; |
85 | |
86 | for (i = 1; i < argc; i++) { |
87 | arg = argv[i]; |
88 | if (arg && *arg == '-') { |
89 | switch (arg[1]) { |
90 | case 'm' : |
91 | if (arg[2]) { |
92 | MemTest = atoi(arg+2); |
93 | if (MemTest <= 0) { |
94 | agerr (AGERR, "Invalid parameter \"%s\" for -m flag\n" , arg+2); |
95 | dotneato_usage (1); |
96 | return -1; |
97 | } |
98 | } |
99 | else MemTest = -1; |
100 | break; |
101 | default : |
102 | cnt++; |
103 | if (*p != arg) *p = arg; |
104 | p++; |
105 | break; |
106 | } |
107 | } |
108 | else { |
109 | cnt++; |
110 | if (*p != arg) *p = arg; |
111 | p++; |
112 | } |
113 | } |
114 | *p = 0; |
115 | return cnt; |
116 | } |
117 | |
118 | /* config_extra_args: |
119 | * Handle special config arguments. |
120 | * Return number of unprocessed arguments; return < 0 on error. |
121 | */ |
122 | static int |
123 | (GVC_t *gvc, int argc, char** argv) |
124 | { |
125 | char** p = argv+1; |
126 | int i; |
127 | char* arg; |
128 | int cnt = 1; |
129 | |
130 | for (i = 1; i < argc; i++) { |
131 | arg = argv[i]; |
132 | if (arg && *arg == '-') { |
133 | switch (arg[1]) { |
134 | case 'v': |
135 | gvc->common.verbose = 1; |
136 | if (isdigit(arg[2])) |
137 | gvc->common.verbose = atoi(&arg[2]); |
138 | break; |
139 | case 'O' : |
140 | gvc->common.auto_outfile_names = TRUE; |
141 | break; |
142 | case 'c' : |
143 | gvc->common.config = TRUE; |
144 | break; |
145 | default : |
146 | cnt++; |
147 | if (*p != arg) *p = arg; |
148 | p++; |
149 | break; |
150 | } |
151 | } |
152 | else { |
153 | cnt++; |
154 | if (*p != arg) *p = arg; |
155 | p++; |
156 | } |
157 | } |
158 | *p = 0; |
159 | return cnt; |
160 | } |
161 | |
162 | /* setDouble: |
163 | * If arg is an double, value is stored in v |
164 | * and functions returns 0; otherwise, returns 1. |
165 | */ |
166 | static int |
167 | setDouble (double* v, char* arg) |
168 | { |
169 | char* p; |
170 | double d; |
171 | |
172 | d = strtod(arg,&p); |
173 | if (p == arg) { |
174 | agerr (AGERR, "bad value in flag -L%s - ignored\n" , arg-1); |
175 | return 1; |
176 | } |
177 | *v = d; |
178 | return 0; |
179 | } |
180 | |
181 | /* setInt: |
182 | * If arg is an integer, value is stored in v |
183 | * and functions returns 0; otherwise, returns 1. |
184 | */ |
185 | static int |
186 | setInt (int* v, char* arg) |
187 | { |
188 | char* p; |
189 | int i; |
190 | |
191 | i = (int)strtol(arg,&p,10); |
192 | if (p == arg) { |
193 | agerr (AGERR, "bad value in flag -L%s - ignored\n" , arg-1); |
194 | return 1; |
195 | } |
196 | *v = i; |
197 | return 0; |
198 | } |
199 | |
200 | /* setFDPAttr: |
201 | * Actions for fdp specific flags |
202 | */ |
203 | static int |
204 | setFDPAttr (char* arg) |
205 | { |
206 | switch (*arg++) { |
207 | case 'g' : |
208 | fdp_parms->useGrid = 0; |
209 | break; |
210 | case 'O' : |
211 | fdp_parms->useNew = 0; |
212 | break; |
213 | case 'n' : |
214 | if (setInt (&fdp_parms->numIters, arg)) return 1; |
215 | break; |
216 | case 'U' : |
217 | if (setInt (&fdp_parms->unscaled, arg)) return 1; |
218 | break; |
219 | case 'C' : |
220 | if (setDouble (&fdp_parms->C, arg)) return 1; |
221 | break; |
222 | case 'T' : |
223 | if (*arg == '*') { |
224 | if (setDouble (&fdp_parms->Tfact, arg+1)) return 1; |
225 | } |
226 | else { |
227 | if (setDouble (&fdp_parms->T0, arg)) return 1; |
228 | } |
229 | break; |
230 | default : |
231 | agerr (AGWARN, "unknown flag -L%s - ignored\n" , arg-1); |
232 | break; |
233 | } |
234 | return 0; |
235 | } |
236 | |
237 | /* fdp_extra_args: |
238 | * Handle fdp specific arguments. |
239 | * These have the form -L<name>=<value>. |
240 | * Return number of unprocessed arguments; return < 0 on error. |
241 | */ |
242 | static int |
243 | (GVC_t *gvc, int argc, char** argv) |
244 | { |
245 | char** p = argv+1; |
246 | int i; |
247 | char* arg; |
248 | int cnt = 1; |
249 | |
250 | for (i = 1; i < argc; i++) { |
251 | arg = argv[i]; |
252 | if (arg && (*arg == '-') && (*(arg+1) == 'L')) { |
253 | if (setFDPAttr (arg+2)) { |
254 | dotneato_usage(1); |
255 | return -1; |
256 | } |
257 | } |
258 | else { |
259 | cnt++; |
260 | if (*p != arg) *p = arg; |
261 | p++; |
262 | } |
263 | } |
264 | *p = 0; |
265 | return cnt; |
266 | } |
267 | |
268 | /* gvParseArgs: |
269 | * Return 0 on success. |
270 | * Return x if calling function should call exit(x-1). |
271 | */ |
272 | int gvParseArgs(GVC_t *gvc, int argc, char** argv) |
273 | { |
274 | int rv; |
275 | if ((argc = neato_extra_args(gvc, argc, argv)) < 0) |
276 | return (1-argc); |
277 | if ((argc = fdp_extra_args(gvc, argc, argv)) < 0) |
278 | return (1-argc); |
279 | if ((argc = memtest_extra_args(gvc, argc, argv)) < 0) |
280 | return (1-argc); |
281 | if ((argc = config_extra_args(gvc, argc, argv)) < 0) |
282 | return (1-argc); |
283 | if ((rv = dotneato_args_initialize(gvc, argc, argv))) |
284 | return rv; |
285 | if (Verbose) |
286 | gvplugin_write_status(gvc); |
287 | return 0; |
288 | } |
289 | |