Root/eeshow/main.c

Source at commit 1a4c62da314be46691f6f4ff1ab8ea33ba81ef16 created 7 years 4 months ago.
By Werner Almesberger, eshow/main.c: support using project file as leader (instead of top sheet)
1/*
2 * main.c - Visualize and convert Eeschema schematics
3 *
4 * Written 2016 by Werner Almesberger
5 * Copyright 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
13
14#include <stdbool.h>
15#include <stdlib.h>
16#include <stdio.h>
17#include <unistd.h>
18#include <string.h>
19
20#include <gtk/gtk.h>
21
22#include "misc/util.h"
23#include "misc/diag.h"
24#include "gfx/fig.h"
25#include "gfx/cro.h"
26#include "gfx/diff.h"
27#include "gfx/gfx.h"
28#include "file/file.h"
29#include "kicad/ext.h"
30#include "kicad/sexpr.h"
31#include "kicad/pl.h"
32#include "kicad/lib.h"
33#include "kicad/sch.h"
34#include "kicad/pro.h"
35#include "gui/fmt-pango.h"
36#include "file/git-hist.h"
37#include "gui/gui.h"
38#include "version.h"
39#include "main.h"
40
41
42static struct gfx_ops const *ops_list[] = {
43    &fig_ops,
44    &cro_png_ops,
45    &cro_pdf_ops,
46    &diff_ops,
47};
48
49
50static void sexpr(void)
51{
52    struct sexpr_ctx *parser = sexpr_new();
53    struct expr *expr;
54    char *buf = NULL;
55    size_t n = 0;
56
57    while (getline(&buf, &n, stdin) > 0)
58        sexpr_parse(parser, buf);
59    if (sexpr_finish(parser, &expr))
60        dump_expr(expr);
61    else
62        exit(1);
63}
64
65
66void usage(const char *name)
67{
68    fprintf(stderr,
69"usage: %s [gtk_flags] [-r] [-N n] kicad_file ...\n"
70" %s [-r] [-v ...] kicad_file ...\n"
71" %*s[-- driver_spec]\n"
72" %s [-v ...] -C [rev:]file\n"
73" %s [-v ...] -H path_into_repo\n"
74" %s -S\n"
75" %s -V\n"
76" %s gdb ...\n"
77"\n"
78" kicad_file [rev:]file.ext\n"
79" ext .pro, .lib, .sch, or .kicad_wks\n"
80" rev git revision\n"
81"\n"
82" -r recurse into sub-sheets\n"
83" -v increase verbosity of diagnostic output\n"
84" -C 'cat' the file to standard output\n"
85" -H show history of repository on standard output\n"
86" -N n limit history to n revisions (unlimited if omitted or 0)\n"
87" -S parse S-expressions from stdin and dump to stdout\n"
88" -V print revision (version) number and exit\n"
89" gdb run eeshow under gdb\n"
90"\n"
91"No driver spec: enter GUI\n"
92"\n"
93"FIG driver spec:\n"
94" fig [-t template.fig] [var=value ...]\n"
95"\n"
96" var=value substitute \"<var>\" with \"value\" in template\n"
97" -t template.fig merge this file with generated output\n"
98"\n"
99"Cairo PNG driver spec:\n"
100" png [-o output.png] [-s scale]\n"
101"\n"
102" -o output.png write PNG to specified file (default; standard output)\n"
103" -s scale scale by indicated factor (default: 1.0)\n"
104"\n"
105"Cairo PDF driver spec:\n"
106" pdf [-o output.pdf] [-s scale] [-T]\n"
107"\n"
108" see PNG for -o and -s\n"
109" -T do not add table of contents\n"
110"\n"
111"Diff driver spec:\n"
112" diff [-o output.pdf] [-s scale] [file.lib ...] file.sch\n"
113"\n"
114" see PNG\n"
115    , name, name, (int) strlen(name) + 1, "", name, name, name, name, name);
116    exit(1);
117}
118
119
120int main(int argc, char **argv)
121{
122    struct lib lib;
123    struct sch_ctx sch_ctx;
124    struct file pro_file, sch_file;
125    bool recurse = 0;
126    const char *cat = NULL;
127    const char *history = NULL;
128    const char *fmt = NULL;
129    struct pl_ctx *pl = NULL;
130    int limit = 0;
131    char c;
132    int dashdash;
133    unsigned i;
134    bool have_dashdash = 0;
135    struct file_names file_names;
136    struct file_names *fn = &file_names;
137    int gfx_argc;
138    char **gfx_argv;
139    const struct gfx_ops **ops = ops_list;
140
141    if (argc > 1 && !strcmp(argv[1], "gdb")) {
142        char **args;
143
144        args = alloc_type_n(char *, argc + 2);
145        args[0] = "gdb";
146        args[1] = "--args";
147        args[2] = *argv;
148        memcpy(args + 3, argv + 2, sizeof(char *) * (argc - 1));
149        execvp("gdb", args);
150        perror(*argv);
151        return 1;
152    }
153
154    for (dashdash = 1; dashdash != argc; dashdash++)
155        if (!strcmp(argv[dashdash], "--")) {
156            have_dashdash = 1;
157            break;
158        }
159
160    if (!have_dashdash)
161        gtk_init(&argc, &argv);
162
163    while ((c = getopt(dashdash, argv, "rvC:F:H:N:SV")) != EOF)
164        switch (c) {
165        case 'r':
166            recurse = 1;
167            break;
168        case 'v':
169            verbose++;
170            break;
171        case 'C':
172            cat = optarg;
173            break;
174        case 'F':
175            fmt = optarg;
176            break;
177        case 'H':
178            history = optarg;
179            break;
180        case 'N':
181            limit = atoi(optarg);
182            break;
183        case 'S':
184            sexpr();
185            return 0;
186        case 'V':
187            fprintf(stderr, "%s\n", version);
188            return 1;
189        default:
190            usage(*argv);
191        }
192
193    if (cat) {
194        struct file file;
195
196        if (argc != optind)
197            usage(*argv);
198        if (!file_open(&file, cat, NULL))
199            return 1;
200        if (!file_read(&file, file_cat, NULL))
201            return 1;
202        file_close(&file);
203        return 0;
204    }
205
206    if (history) {
207        struct hist *h;
208
209        h = vcs_git_hist(history);
210        dump_hist(h);
211        return 0;
212    }
213
214    if (fmt) {
215        char *buf;
216
217        buf = fmt_pango(fmt, argv[optind]);
218        printf("\"%s\"\n", buf);
219        return 0;
220    }
221
222    if (dashdash - optind < 1)
223        usage(*argv);
224
225    classify_files(&file_names, argv + optind, dashdash - optind);
226    if (!file_names.pro && !file_names.sch)
227        fatal("project or top sheet name required");
228
229    if (!have_dashdash) {
230        optind = 0; /* reset getopt */
231        return gui(&file_names, recurse, limit);
232    }
233
234    if (file_names.pro) {
235        if (!file_open(&pro_file, file_names.pro, NULL))
236            return 1;
237        fn = pro_parse_file(&pro_file, &file_names);
238    }
239
240    sch_init(&sch_ctx, recurse);
241    if (!file_open(&sch_file, fn->sch, file_names.pro ? &pro_file : NULL))
242        return 1;
243
244    lib_init(&lib);
245    for (i = 0; i != fn->n_libs; i++)
246        if (!lib_parse(&lib, fn->libs[i], &sch_file))
247            return 1;
248
249    if (fn->pl) {
250        struct file file;
251
252        if (!file_open(&file, fn->pl, &sch_file))
253            return 1;
254        pl = pl_parse(&file);
255        file_close(&file);
256        if (!pl)
257            return 1;
258    }
259
260    if (dashdash == argc) {
261        gfx_argc = 1;
262        gfx_argv = alloc_type_n(char *, 2);
263        gfx_argv[0] = (char *) (*ops)->name;
264        gfx_argv[1] = NULL;
265    } else {
266        gfx_argc = argc - dashdash - 1;
267        if (!gfx_argc)
268            usage(*argv);
269        gfx_argv = alloc_type_n(char *, gfx_argc + 1);
270        memcpy(gfx_argv, argv + dashdash + 1,
271            sizeof(const char *) * (gfx_argc + 1));
272
273        for (ops = ops_list; ops != ARRAY_END(ops_list); ops++)
274            if (!strcmp((*ops)->name, *gfx_argv))
275                goto found;
276        fatal("graphics backend \"%s\" not found\n", *gfx_argv);
277found:
278        ;
279    }
280
281    optind = 0; /* reset getopt */
282
283    if (!sch_parse(&sch_ctx, &sch_file, &lib, NULL))
284        return 1;
285    file_close(&sch_file);
286
287    gfx_init(*ops, gfx_argc, gfx_argv);
288    if (recurse) {
289        const struct sheet *sheet;
290
291        if (!gfx_multi_sheet())
292            fatal("graphics backend only supports single sheet\n");
293        for (sheet = sch_ctx.sheets; sheet; sheet = sheet->next) {
294            gfx_sheet_name(sheet->title);
295            sch_render(sheet);
296            if (pl)
297                pl_render(pl, sch_ctx.sheets, sheet);
298            if (sheet->next)
299                gfx_new_sheet();
300        }
301    } else {
302        sch_render(sch_ctx.sheets);
303        if (pl)
304            pl_render(pl, sch_ctx.sheets, sch_ctx.sheets);
305    }
306    gfx_end();
307
308    sch_free(&sch_ctx);
309    lib_free(&lib);
310
311    return 0;
312}
313

Archive Download this file

Branches:
master



interactive