| 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 | |