/* * sch.c - Parse Eeschema .sch file * * Written 2016 by Werner Almesberger * Copyright 2016 by Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include #include #include #include "style.h" #include "fig.h" #include "lib.h" #include "sch.h" static enum fig_shape do_decode_shape(const char *s) { if (!strcmp(s, "UnSpc")) return fig_unspec; if (!strcmp(s, "Input")) return fig_in; if (!strcmp(s, "Output")) return fig_out; if (!strcmp(s, "3State")) return fig_tri; fprintf(stderr, "unknown shape: \"%s\"\n", s); exit(1); } static enum fig_shape decode_shape(const char *s) { enum fig_shape res; res = do_decode_shape(s); free((void *) s); return res; } static void draw_text(int x, int y, const char *s, int dir, int dim, enum fig_shape shape) { fig_text(x, y, s, dim, text_min, 0, COLOR_TEXT, LAYER_TEXT); } bool sch_parse(struct sch_ctx *ctx, const char *line) { int n = 0; int x, y, ex, ey; char *s; int m[4]; ctx->lineno++; switch (ctx->state) { case sch_basic: if (sscanf(line, "$Comp%n", &n) == 0 && n) { ctx->state = sch_comp; return 1; } if (sscanf(line, "$Sheet%n", &n) == 0 && n) { ctx->state = sch_sheet; return 1; } /* Text */ if (sscanf(line, "Text Notes %d %d %d %d", &ctx->x, &ctx->y, &ctx->dir, &ctx->dim) == 4) { ctx->state = sch_text; ctx->text = draw_text; return 1; } if (sscanf(line, "Text GLabel %d %d %d %d %ms", &ctx->x, &ctx->y, &ctx->dir, &ctx->dim, &s) == 5) { ctx->state = sch_text; ctx->shape = decode_shape(s); ctx->text = fig_glabel; return 1; } if (sscanf(line, "Text HLabel %d %d %d %d %ms", &ctx->x, &ctx->y, &ctx->dir, &ctx->dim, &s) == 5) { ctx->state = sch_text; abort(); return 1; } if (sscanf(line, "Text Label%n", &n) == 0 && n) { ctx->state = sch_text; abort(); return 1; } /* Connection */ if (sscanf(line, "Connection ~ %d %d", &x, &y) == 2) { fig_junction(x, y); return 1; } /* Wire */ if (sscanf(line, "Wire Wire Line%n", &n) == 0 && n) { ctx->state = sch_wire; ctx->wire = fig_wire; return 1; } if (sscanf(line, "Wire Bus Line%n", &n) == 0 && n) { ctx->state = sch_wire; abort(); return 1; } if (sscanf(line, "Wire Notes Line%n", &n) == 0 && n) { ctx->state = sch_wire; ctx->wire = fig_line; return 1; } if (sscanf(line, "Wire Wire Bus%n", &n) == 0 && n) { ctx->state = sch_wire; abort(); return 1; } if (sscanf(line, "Wire Bus Bus%n", &n) == 0 && n) { ctx->state = sch_wire; abort(); return 1; } /* EndSCHEMATC */ if (sscanf(line, "$EndSCHEMATC%n", &n) == 0 && n) return 0; break; case sch_descr: if (sscanf(line, "$EndDescr%n", &n) || !n) return 1; ctx->state = sch_basic; return 1; case sch_comp: if (sscanf(line, "$EndComp%n", &n) == 0 && n) { ctx->state = sch_basic; free(ctx->comp); ctx->comp = NULL; return 1; } if (sscanf(line, "L %ms", &ctx->comp) == 1) return 1; if (sscanf(line, "U %u", &ctx->unit) == 1) return 1; if (sscanf(line, "P %d %d", &ctx->x, &ctx->y) == 2) return 1; if (sscanf(line, "F%d", &n) == 1) return 1; // @@@ n = sscanf(line, " %d %d %d %d", m + 1, m + 2, m + 4, m + 5); if (n == 3) return 1; if (n == 4) { m[0] = ctx->x; m[3] = ctx->y; lib_exec(ctx->comp, ctx->unit, m); return 1; } break; case sch_sheet: if (sscanf(line, "$EndSheet%n", &n) || !n) return 1; ctx->state = sch_basic; return 1; case sch_text: ctx->state = sch_basic; ctx->text(ctx->x, ctx->y, line, ctx->dir, ctx->dim, ctx->shape); return 1; case sch_wire: if (sscanf(line, "%d %d %d %d", &x, &y, &ex, &ey) != 4) break; ctx->wire(x, y, ex, ey); ctx->state = sch_basic; return 1; default: abort(); } fprintf(stderr, "%u: cannot parse\n\"%s\"\n", ctx->lineno, line); exit(1); } void sch_init(struct sch_ctx *ctx) { ctx->state = sch_descr; ctx->lineno++; }