args.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /// @file
  2. /// @ingroup common_utils
  3. /*************************************************************************
  4. * Copyright (c) 2011 AT&T Intellectual Property
  5. * All rights reserved. This program and the accompanying materials
  6. * are made available under the terms of the Eclipse Public License v1.0
  7. * which accompanies this distribution, and is available at
  8. * https://www.eclipse.org/legal/epl-v10.html
  9. *
  10. * Contributors: Details at https://graphviz.org
  11. *************************************************************************/
  12. /* FIXME
  13. * This is an ugly mess.
  14. *
  15. * Args should be made independent of layout engine and arg values
  16. * should be stored in gvc or gvc->job. All globals should be eliminated.
  17. *
  18. * Needs to be fixed before layout engines can be plugins.
  19. */
  20. #include <assert.h>
  21. #include <cgraph/gv_ctype.h>
  22. #include <common/render.h>
  23. #include <fdpgen/tlayout.h>
  24. #include <gvc/gvc.h>
  25. #include <fdpgen/fdp.h>
  26. #include <stdbool.h>
  27. /* Handle special neato arguments.
  28. * Return number of unprocessed arguments; return < 0 on error.
  29. */
  30. static int neato_extra_args(int argc, char** argv) {
  31. char** p = argv+1;
  32. int i;
  33. char* arg;
  34. int cnt = 1;
  35. for (i = 1; i < argc; i++) {
  36. arg = argv[i];
  37. assert(arg != NULL);
  38. if (arg[0] == '-') {
  39. switch (arg[1]) {
  40. case 'x' : Reduce = true; break;
  41. case 'n':
  42. if (arg[2]) {
  43. Nop = atoi(arg+2);
  44. if (Nop <= 0) {
  45. agerrorf("Invalid parameter \"%s\" for -n flag\n", arg+2);
  46. dotneato_usage(argv[0], 1);
  47. return -1;
  48. }
  49. }
  50. else Nop = 1;
  51. break;
  52. default :
  53. cnt++;
  54. if (*p != arg) *p = arg;
  55. p++;
  56. break;
  57. }
  58. }
  59. else {
  60. cnt++;
  61. if (*p != arg) *p = arg;
  62. p++;
  63. }
  64. }
  65. *p = 0;
  66. return cnt;
  67. }
  68. /* Handle special config arguments.
  69. * Return number of unprocessed arguments; return < 0 on error.
  70. */
  71. static int
  72. config_extra_args(GVC_t *gvc, int argc, char** argv)
  73. {
  74. char** p = argv+1;
  75. int i;
  76. char* arg;
  77. int cnt = 1;
  78. for (i = 1; i < argc; i++) {
  79. arg = argv[i];
  80. assert(arg != NULL);
  81. if (arg[0] == '-') {
  82. switch (arg[1]) {
  83. case 'v':
  84. gvc->common.verbose = 1;
  85. if (gv_isdigit(arg[2]))
  86. gvc->common.verbose = atoi(&arg[2]);
  87. break;
  88. case 'O' :
  89. gvc->common.auto_outfile_names = true;
  90. break;
  91. case 'c' :
  92. gvc->common.config = true;
  93. break;
  94. default :
  95. cnt++;
  96. if (*p != arg) *p = arg;
  97. p++;
  98. break;
  99. }
  100. }
  101. else {
  102. cnt++;
  103. if (*p != arg) *p = arg;
  104. p++;
  105. }
  106. }
  107. *p = 0;
  108. return cnt;
  109. }
  110. /* If arg is an double, value is stored in v
  111. * and functions returns 0; otherwise, returns 1.
  112. */
  113. static int
  114. setDouble (double* v, char* arg)
  115. {
  116. char* p;
  117. double d;
  118. d = strtod(arg,&p);
  119. if (p == arg) {
  120. agerrorf("bad value in flag -L%s - ignored\n", arg-1);
  121. return 1;
  122. }
  123. *v = d;
  124. return 0;
  125. }
  126. /* If arg is an integer, value is stored in v
  127. * and functions returns 0; otherwise, returns 1.
  128. */
  129. static int
  130. setInt (int* v, char* arg)
  131. {
  132. char* p;
  133. int i;
  134. i = (int)strtol(arg,&p,10);
  135. if (p == arg) {
  136. agerrorf("bad value in flag -L%s - ignored\n", arg-1);
  137. return 1;
  138. }
  139. *v = i;
  140. return 0;
  141. }
  142. /// Actions for fdp specific flags
  143. static int
  144. setFDPAttr (char* arg)
  145. {
  146. switch (*arg++) {
  147. case 'g' :
  148. fdp_parms->useGrid = 0;
  149. break;
  150. case 'O' :
  151. fdp_parms->useNew = 0;
  152. break;
  153. case 'n' :
  154. if (setInt (&fdp_parms->numIters, arg)) return 1;
  155. break;
  156. case 'U' :
  157. if (setInt (&fdp_parms->unscaled, arg)) return 1;
  158. break;
  159. case 'C' :
  160. if (setDouble (&fdp_parms->C, arg)) return 1;
  161. break;
  162. case 'T' :
  163. if (*arg == '*') {
  164. if (setDouble (&fdp_parms->Tfact, arg+1)) return 1;
  165. }
  166. else {
  167. if (setDouble (&fdp_parms->T0, arg)) return 1;
  168. }
  169. break;
  170. default :
  171. agwarningf("unknown flag -L%s - ignored\n", arg-1);
  172. break;
  173. }
  174. return 0;
  175. }
  176. /* Handle fdp specific arguments.
  177. * These have the form -L<name>=<value>.
  178. * Return number of unprocessed arguments; return < 0 on error.
  179. */
  180. static int fdp_extra_args(int argc, char** argv) {
  181. char** p = argv+1;
  182. int i;
  183. char* arg;
  184. int cnt = 1;
  185. for (i = 1; i < argc; i++) {
  186. arg = argv[i];
  187. assert(arg != NULL);
  188. if (arg[0] == '-' && arg[1] == 'L') {
  189. if (setFDPAttr (arg+2)) {
  190. dotneato_usage(argv[0], 1);
  191. return -1;
  192. }
  193. }
  194. else {
  195. cnt++;
  196. if (*p != arg) *p = arg;
  197. p++;
  198. }
  199. }
  200. *p = 0;
  201. return cnt;
  202. }
  203. /* Return 0 on success.
  204. * Return x if calling function should call exit(x-1).
  205. */
  206. int gvParseArgs(GVC_t *gvc, int argc, char** argv)
  207. {
  208. int rv;
  209. if ((argc = neato_extra_args(argc, argv)) < 0)
  210. return (1-argc);
  211. if ((argc = fdp_extra_args(argc, argv)) < 0)
  212. return (1-argc);
  213. if ((argc = config_extra_args(gvc, argc, argv)) < 0)
  214. return (1-argc);
  215. if ((rv = dotneato_args_initialize(gvc, argc, argv)))
  216. return rv;
  217. if (Verbose)
  218. gvplugin_write_status(gvc);
  219. return 0;
  220. }