fped.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * fped.c - Footprint editor, main function
  3. *
  4. * Written 2009-2012, 2015-2016 by Werner Almesberger
  5. * Copyright 2009-2012, 2015-2016 by Werner Almesberger
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. */
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <unistd.h>
  15. #include <string.h>
  16. #include <errno.h>
  17. #include "cpp.h"
  18. #include "util.h"
  19. #include "error.h"
  20. #include "obj.h"
  21. #include "inst.h"
  22. #include "file.h"
  23. #include "postscript.h"
  24. #include "dump.h"
  25. #include "gui.h"
  26. #include "delete.h"
  27. #include "fpd.h"
  28. #include "fped.h"
  29. char *save_file_name = NULL;
  30. int no_save = 0;
  31. static void load_file(const char *name)
  32. {
  33. FILE *file;
  34. char line[sizeof(MACHINE_GENERATED)];
  35. file = fopen(name, "r");
  36. if (file) {
  37. if (!fgets(line, sizeof(line), file)) {
  38. if (ferror(file)) {
  39. perror(name);
  40. exit(1);
  41. }
  42. *line = 0;
  43. }
  44. no_save = strcmp(line, MACHINE_GENERATED);
  45. fclose(file);
  46. reporter = report_parse_error;
  47. run_cpp_on_file(name);
  48. } else {
  49. if (errno != ENOENT) {
  50. perror(name);
  51. exit(1);
  52. }
  53. scan_empty();
  54. }
  55. (void) yyparse();
  56. }
  57. void reload(void)
  58. {
  59. struct frame *old_frames;
  60. /* @@@ this needs more work */
  61. purge();
  62. old_frames = frames;
  63. scan_file();
  64. load_file(save_file_name);
  65. if (!instantiate())
  66. frames = old_frames;
  67. change_world();
  68. }
  69. static void list_packages(void)
  70. {
  71. const struct pkg *pkg;
  72. for (pkg = pkgs; pkg; pkg = pkg->next)
  73. if (pkg->name)
  74. printf("%s\n", pkg->name);
  75. }
  76. static void usage(const char *name)
  77. {
  78. fprintf(stderr,
  79. "usage: %s [batch_mode] [cpp_option ...] [in_file [out_file]]\n\n"
  80. "Batch mode options:\n"
  81. " -g [-1 package]\n"
  82. " write gnuplot output, then exit\n"
  83. " -k write KiCad output, then exit\n"
  84. " -l list package names, then exit\n"
  85. " -p [-m] write Postscript output, then exit\n"
  86. " -P [-K] [-m] [-s scale] [-1 package]\n"
  87. " write Postscript output (full page), then exit\n"
  88. " -T test mode. Load file, then exit\n"
  89. " -T -T test mode. Load file, dump to stdout, then exit\n\n"
  90. "Common options:\n"
  91. " -1 name output only the specified package\n"
  92. " -K show the pad type key\n"
  93. " -m do not show measurements\n"
  94. " -s scale scale factor for -P (default: auto-scale)\n"
  95. " -s [width]x[height]\n"
  96. " auto-scale to fit within specified box. Dimensions in mm.\n"
  97. " cpp_option -Idir, -Dname[=value], or -Uname\n"
  98. , name);
  99. exit(1);
  100. }
  101. static int parse_scaling(const char *arg)
  102. {
  103. const char *x;
  104. char *end;
  105. x = strchr(arg, 'x');
  106. if (!x) {
  107. postscript_params.zoom = strtod(arg, &end);
  108. return !*end;
  109. }
  110. if (x != arg) {
  111. postscript_params.max_width = mm_to_units(strtod(arg, &end));
  112. if (*end != 'x')
  113. return 0;
  114. }
  115. if (x[1]) {
  116. postscript_params.max_height = mm_to_units(strtod(x+1, &end));
  117. if (*end)
  118. return 0;
  119. }
  120. return 1;
  121. }
  122. int main(int argc, char **argv)
  123. {
  124. enum {
  125. batch_none = 0,
  126. batch_kicad,
  127. batch_ps,
  128. batch_ps_fullpage,
  129. batch_gnuplot,
  130. batch_test,
  131. batch_list,
  132. } batch = batch_none;
  133. char *name = *argv;
  134. char **fake_argv;
  135. char *args[2];
  136. int fake_argc;
  137. char opt[] = "-?";
  138. int error;
  139. int test_mode = 0;
  140. const char *one = NULL;
  141. int c;
  142. while ((c = getopt(argc, argv, "1:gklmps:D:I:KPTU:")) != EOF)
  143. switch (c) {
  144. case '1':
  145. one = optarg;
  146. break;
  147. case 'g':
  148. if (batch)
  149. usage(*argv);
  150. batch = batch_gnuplot;
  151. break;
  152. case 'k':
  153. if (batch)
  154. usage(*argv);
  155. batch = batch_kicad;
  156. break;
  157. case 'l':
  158. if (batch)
  159. usage(*argv);
  160. batch = batch_list;
  161. break;
  162. case 'm':
  163. postscript_params.show_meas = 0;
  164. break;
  165. case 'p':
  166. if (batch)
  167. usage(*argv);
  168. batch = batch_ps;
  169. break;
  170. case 'P':
  171. if (batch)
  172. usage(*argv);
  173. batch = batch_ps_fullpage;
  174. break;
  175. case 'K':
  176. postscript_params.show_key = 1;
  177. break;
  178. case 's':
  179. if (batch != batch_ps_fullpage)
  180. usage(*argv);
  181. if (!parse_scaling(optarg))
  182. usage(*argv);
  183. break;
  184. case 'T':
  185. batch = batch_test;
  186. test_mode++;
  187. break;
  188. case 'D':
  189. case 'U':
  190. case 'I':
  191. opt[1] = c;
  192. add_cpp_arg(opt);
  193. add_cpp_arg(optarg);
  194. break;
  195. default:
  196. usage(name);
  197. }
  198. if (one && batch != batch_ps && batch != batch_ps_fullpage &&
  199. batch != batch_gnuplot)
  200. usage(name);
  201. if (postscript_params.show_key && batch != batch_ps_fullpage)
  202. usage(name);
  203. if (!batch) {
  204. args[0] = name;
  205. args[1] = NULL;
  206. fake_argc = 1;
  207. fake_argv = args;
  208. error = gui_init(&fake_argc, &fake_argv);
  209. if (error)
  210. return error;
  211. }
  212. switch (argc-optind) {
  213. case 0:
  214. scan_empty();
  215. (void) yyparse();
  216. break;
  217. case 1:
  218. load_file(argv[optind]);
  219. save_file_name = argv[optind];
  220. break;
  221. case 2:
  222. load_file(argv[optind]);
  223. save_file_name = argv[optind+1];
  224. if (!strcmp(save_file_name, "-"))
  225. save_file_name = NULL;
  226. break;
  227. default:
  228. usage(name);
  229. }
  230. if (!pkg_name)
  231. pkg_name = stralloc("_");
  232. reporter = report_to_stderr;
  233. if (!instantiate())
  234. return 1;
  235. switch (batch) {
  236. case batch_none:
  237. error = gui_main();
  238. if (error)
  239. return error;
  240. break;
  241. case batch_kicad:
  242. write_kicad();
  243. break;
  244. case batch_ps:
  245. write_ps(one);
  246. break;
  247. case batch_ps_fullpage:
  248. write_ps_fullpage(one);
  249. break;
  250. case batch_gnuplot:
  251. write_gnuplot(one);
  252. break;
  253. case batch_test:
  254. if (test_mode > 1)
  255. dump(stdout, NULL);
  256. break;
  257. case batch_list:
  258. list_packages();
  259. break;
  260. default:
  261. abort();
  262. }
  263. purge();
  264. inst_revert();
  265. obj_cleanup();
  266. unique_cleanup();
  267. return 0;
  268. }