Root/eeshow/main.c

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

Archive Download this file

Branches:
master



interactive