1
0
mirror of git://projects.qi-hardware.com/eda-tools.git synced 2024-09-16 07:36:27 +03:00
eda-tools/sch2fig/sch.c

203 lines
4.1 KiB
C
Raw Normal View History

/*
* 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 <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#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++;
}