mirror of
git://projects.qi-hardware.com/eda-tools.git
synced 2024-11-26 08:50:37 +02:00
sch2fig/: eeschema to FIG converter (WIP)
This commit is contained in:
parent
006940d58b
commit
1cff10b824
19
sch2fig/Makefile
Normal file
19
sch2fig/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
NAME = sch2fig
|
||||
OBJS = main.o sch.o lib.o fig.o
|
||||
|
||||
CFLAGS = -g -Wall -Wextra -Wno-unused-parameter
|
||||
|
||||
include ../../anelok/common/Makefile.c-common
|
||||
|
||||
.PHONY: test
|
||||
|
||||
all:: $(NAME)
|
||||
|
||||
$(NAME): $(OBJS)
|
||||
$(CC) -o $(NAME) $(OBJS)
|
||||
|
||||
NEO900_HW = ../../../n9/ee/hw/
|
||||
|
||||
test: $(NAME)
|
||||
$(NAME) $(NEO900_HW)/neo900.lib $(NEO900_HW)neo900_SS_1.sch \
|
||||
>out.fig
|
144
sch2fig/fig.c
Normal file
144
sch2fig/fig.c
Normal file
@ -0,0 +1,144 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "fig.h"
|
||||
|
||||
|
||||
#define COLOR_BLACK 0
|
||||
#define COLOR_BLUE 1
|
||||
#define COLOR_GREEN4 12
|
||||
#define COLOR_RED4 18
|
||||
#define COLOR_RED3 19
|
||||
|
||||
#define FONT_HELVETICA_BOLD 18
|
||||
|
||||
#define LAYER_TEXT 30
|
||||
#define LAYER_WIRES 50
|
||||
#define LAYER_LINES 60
|
||||
#define LAYER_COMP_DWG 70
|
||||
|
||||
#define WIDTH_WIRE 2
|
||||
#define WIDTH_LINE 2
|
||||
#define WIDTH_COMP_DWG 2
|
||||
|
||||
#define JUNCTION_R 50
|
||||
|
||||
|
||||
/*
|
||||
* FIG works with 1/1200 in
|
||||
* KiCad works with mil
|
||||
* 1 point = 1/72 in
|
||||
*/
|
||||
|
||||
|
||||
static inline int cx(int x)
|
||||
{
|
||||
return x * 1200 / 1000;
|
||||
}
|
||||
|
||||
|
||||
static inline int cy(int y)
|
||||
{
|
||||
return y * 1200 / 1000;
|
||||
}
|
||||
|
||||
|
||||
static inline int pt(int x)
|
||||
{
|
||||
return cx(x) * 72 * 1.5 / 1200;
|
||||
}
|
||||
|
||||
|
||||
void fig_rect(int sx, int sy, int ex, int ey)
|
||||
{
|
||||
// Type Thick Depth StyleV Rad
|
||||
// SubTy Color Pen Join FwdAr
|
||||
// Style FillCol AreaFil Cap BwdAr
|
||||
printf("2 2 0 %d %d 7 %d -1 -1 0.0 1 1 -1 0 0 5\n",
|
||||
WIDTH_COMP_DWG, COLOR_RED4, LAYER_COMP_DWG);
|
||||
printf("\t%d %d %d %d %d %d %d %d %d %d\n",
|
||||
cx(sx), cy(sy), cx(ex), cy(sy), cx(ex), cy(ey), cx(sx), cy(ey),
|
||||
cx(sx), cy(sy));
|
||||
}
|
||||
|
||||
|
||||
void fig_poly(int points, int x[points], int y[points])
|
||||
{
|
||||
int i;
|
||||
char ch = '\t';
|
||||
|
||||
// Type Thick Depth StyleV Rad
|
||||
// SubTy Color Pen Join FwdAr
|
||||
// Style FillCol AreaFil Cap BwdAr
|
||||
printf("2 1 0 %d %d 7 %d -1 -1 0.0 1 1 -1 0 0 %d\n",
|
||||
WIDTH_COMP_DWG, COLOR_RED4, LAYER_COMP_DWG, points);
|
||||
for (i = 0; i != points; i++) {
|
||||
printf("%c%d %d", ch, cx(x[i]), cy(y[i]));
|
||||
ch = ' ';
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
void fig_text(int x, int y, const char *s, int dir, int dim,
|
||||
enum fig_shape shape)
|
||||
{
|
||||
// Type Depth FontSiz Height
|
||||
// Just Pen Angle Length
|
||||
// Color Font Flags X Y
|
||||
printf("4 0 %d %d -1 %d %d %d 4 0.0 0.0 %d %d %s\\001\n",
|
||||
COLOR_BLACK, LAYER_TEXT, FONT_HELVETICA_BOLD,
|
||||
pt(dim), 0, cx(x), cy(y), s);
|
||||
}
|
||||
|
||||
|
||||
void fig_glabel(int x, int y, const char *s, int dir, int dim,
|
||||
enum fig_shape shape)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void fig_junction(int x, int y)
|
||||
{
|
||||
// Type Thick Depth StyleV Cx Rx Sx Ex
|
||||
// SubTy Color Pen Dir Cy Ry Sy Ey
|
||||
// Style FillCol AreaFil Angle
|
||||
printf("1 3 0 0 -1 %d %d -1 20 0.0 1 0.0 %d %d %d %d %d %d %d %d\n",
|
||||
COLOR_GREEN4, LAYER_WIRES, cx(x), cy(y), JUNCTION_R, JUNCTION_R,
|
||||
cx(x), cy(y), cx(x) + JUNCTION_R, cy(y));
|
||||
}
|
||||
|
||||
|
||||
void fig_wire(int sx, int sy, int ex, int ey)
|
||||
{
|
||||
// TypeStyle FillCol AreaFil Cap FwdAr
|
||||
// SubTy Color Pen StyleV Rad BwdAr
|
||||
// Thick Depth Join Points
|
||||
printf("2 1 0 %d %d 7 %d -1 -1 0.0 1 1 -1 0 0 2\n",
|
||||
WIDTH_WIRE, COLOR_GREEN4, LAYER_WIRES);
|
||||
printf("\t%d %d %d %d\n", cx(sx), cy(sy), cx(ex), cy(ey));
|
||||
}
|
||||
|
||||
|
||||
void fig_line(int sx, int sy, int ex, int ey)
|
||||
{
|
||||
// TypeStyle FillCol AreaFil Cap FwdAr
|
||||
// SubTy Color Pen StyleV Rad BwdAr
|
||||
// Thick Depth Join Points
|
||||
printf("2 1 0 %d %d 7 %d -1 -1 0.0 1 1 -1 0 0 2\n",
|
||||
WIDTH_LINE, COLOR_BLUE, LAYER_LINES);
|
||||
printf("\t%d %d %d %d\n", cx(sx), cy(sy), cx(ex), cy(ey));
|
||||
}
|
||||
|
||||
|
||||
void fig_init(void)
|
||||
{
|
||||
printf("#FIG 3.2\n");
|
||||
printf("Landscape\n");
|
||||
printf("Center\n");
|
||||
printf("Metric\n");
|
||||
printf("A4\n");
|
||||
printf("10.00\n");
|
||||
printf("Single\n");
|
||||
printf("-2\n");
|
||||
printf("1200 2\n");
|
||||
}
|
33
sch2fig/fig.h
Normal file
33
sch2fig/fig.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef FIG_H
|
||||
#define FIG_H
|
||||
|
||||
enum fig_shape {
|
||||
fig_unspec, // UnSpc
|
||||
fig_in, // Input
|
||||
fig_out, // Output
|
||||
fig_tri, // 3State
|
||||
};
|
||||
|
||||
|
||||
/* libraries */
|
||||
|
||||
void fig_rect(int sx, int sy, int ex, int ey);
|
||||
void fig_poly(int points, int x[points], int y[points]);
|
||||
|
||||
/* schematics */
|
||||
|
||||
void fig_text(int x, int y, const char *s, int dir, int dim,
|
||||
enum fig_shape shape);
|
||||
void fig_glabel(int x, int y, const char *s, int dir, int dim,
|
||||
enum fig_shape shape);
|
||||
|
||||
void fig_junction(int x, int y);
|
||||
|
||||
void fig_wire(int sx, int sy, int ex, int ey);
|
||||
void fig_line(int sx, int sy, int ex, int ey);
|
||||
|
||||
/* inititalization */
|
||||
|
||||
void fig_init(void);
|
||||
|
||||
#endif /* !FIG_H */
|
264
sch2fig/lib.c
Normal file
264
sch2fig/lib.c
Normal file
@ -0,0 +1,264 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "fig.h"
|
||||
#include "lib.h"
|
||||
|
||||
|
||||
struct obj {
|
||||
enum obj_type {
|
||||
obj_poly,
|
||||
obj_rect,
|
||||
obj_circ,
|
||||
obj_arc,
|
||||
obj_text,
|
||||
obj_pin,
|
||||
} type;
|
||||
unsigned unit;
|
||||
unsigned convert;
|
||||
union {
|
||||
struct poly {
|
||||
int thick;
|
||||
char fill;
|
||||
int points;
|
||||
int *x;
|
||||
int *y;
|
||||
} poly;
|
||||
struct {
|
||||
int thick;
|
||||
char fill;
|
||||
int sx, sy;
|
||||
int ex, ey;
|
||||
} rect;
|
||||
struct {
|
||||
int x, y;
|
||||
int r;
|
||||
int thick;
|
||||
char fill;
|
||||
} circ;
|
||||
struct {
|
||||
char orient;
|
||||
int x, y;
|
||||
int dim;
|
||||
char *s;
|
||||
} text;
|
||||
struct {
|
||||
char *name;
|
||||
char *number;
|
||||
int x, y;
|
||||
int length;
|
||||
char orient;
|
||||
int number_size;
|
||||
int name_size;
|
||||
char etype;
|
||||
// @@@ shape
|
||||
} pin;
|
||||
} u;
|
||||
struct obj *next;
|
||||
};
|
||||
|
||||
|
||||
struct comp {
|
||||
const char *name;
|
||||
struct obj *objs;
|
||||
struct comp *next;
|
||||
};
|
||||
|
||||
|
||||
static struct comp *comps = NULL;
|
||||
static struct comp **next_comp = &comps;
|
||||
static struct obj **next_obj;
|
||||
|
||||
|
||||
static inline int mx(int x, int y, int m[6])
|
||||
{
|
||||
return m[0] + x * m[1] + y * m[2];
|
||||
}
|
||||
|
||||
|
||||
static inline int my(int x, int y, int m[6])
|
||||
{
|
||||
return m[3] + x * m[4] + y * m[5];
|
||||
}
|
||||
|
||||
|
||||
static void draw_poly(const struct poly *poly, int m[6])
|
||||
{
|
||||
int n = poly->points;
|
||||
int x[n];
|
||||
int y[n];
|
||||
int i;
|
||||
|
||||
for (i = 0; i != n; i++) {
|
||||
x[i] = mx(poly->x[i], poly->y[i], m);
|
||||
y[i] = my(poly->x[i], poly->y[i], m);
|
||||
}
|
||||
fig_poly(n, x, y);
|
||||
}
|
||||
|
||||
|
||||
static void draw(const struct obj *obj, int m[6])
|
||||
{
|
||||
switch (obj->type) {
|
||||
case obj_poly:
|
||||
draw_poly(&obj->u.poly, m);
|
||||
break;
|
||||
case obj_rect:
|
||||
fig_rect(mx(obj->u.rect.sx, obj->u.rect.sy, m),
|
||||
my(obj->u.rect.sx, obj->u.rect.sy, m),
|
||||
mx(obj->u.rect.ex, obj->u.rect.ey, m),
|
||||
my(obj->u.rect.ex, obj->u.rect.ey, m));
|
||||
// @@@
|
||||
break;
|
||||
case obj_circ:
|
||||
break;
|
||||
case obj_text:
|
||||
break;
|
||||
case obj_pin:
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void lib_exec(const char *name, unsigned unit, int m[4])
|
||||
{
|
||||
const struct comp *comp;
|
||||
const struct obj *obj;
|
||||
|
||||
for (comp = comps; comp; comp = comp->next)
|
||||
if (!strcmp(comp->name, name))
|
||||
goto found;
|
||||
fprintf(stderr, "\"%s\" not found\n", name);
|
||||
exit(1);
|
||||
|
||||
found:
|
||||
for (obj = comp->objs; obj; obj = obj->next) {
|
||||
if (obj->unit && obj->unit != unit)
|
||||
continue;
|
||||
draw(obj, m);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static bool parse_poly(struct obj *obj, const char *line, int points)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
obj->u.poly.points = points;
|
||||
obj->u.poly.x = malloc(sizeof(int) * points);
|
||||
obj->u.poly.y = malloc(sizeof(int) * points);
|
||||
for (i = 0; i != points; i++) {
|
||||
if (sscanf(line, "%d %d %n",
|
||||
obj->u.poly.x + i, obj->u.poly.y + i, &n) != 2)
|
||||
return 0;
|
||||
line += n;
|
||||
}
|
||||
if (sscanf(line, "%c", &obj->u.poly.fill) != 1)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
bool lib_parse(struct lib_ctx *ctx, const char *line)
|
||||
{
|
||||
int n = 0;
|
||||
char *s;
|
||||
unsigned points;
|
||||
struct comp *comp;
|
||||
struct obj *obj;
|
||||
|
||||
ctx->lineno++;
|
||||
|
||||
switch (ctx->state) {
|
||||
case lib_skip:
|
||||
if (sscanf(line, "DEF %ms", &s) == 1) {
|
||||
ctx->state = lib_def;
|
||||
comp = malloc(sizeof(struct comp));
|
||||
if (*s == '~')
|
||||
s++;
|
||||
comp->name = s;
|
||||
comp->objs = NULL;
|
||||
comp->next = NULL;
|
||||
*next_comp = comp;
|
||||
next_comp = &comp->next;
|
||||
next_obj = &comp->objs;
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
case lib_def:
|
||||
if (sscanf(line, "DRAW%n", &n) == 0 && n) {
|
||||
ctx->state = lib_draw;
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
case lib_draw:
|
||||
if (sscanf(line, "ENDDRAW%n", &n) == 0 && n) {
|
||||
ctx->state = lib_skip;
|
||||
return 1;
|
||||
}
|
||||
|
||||
obj = malloc(sizeof(struct obj));
|
||||
obj->next = NULL;
|
||||
*next_obj = obj;
|
||||
next_obj = &obj->next;
|
||||
|
||||
if (sscanf(line, "P %u %u %u %u %n",
|
||||
&points, &obj->unit, &obj->convert, &obj->u.poly.thick,
|
||||
&n) == 4) {
|
||||
obj->type = obj_poly;
|
||||
if (parse_poly(obj, line + n, points))
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
if (sscanf(line, "S %d %d %d %d %u %u %d %c",
|
||||
&obj->u.rect.sx, &obj->u.rect.sy, &obj->u.rect.ex,
|
||||
&obj->u.rect.ey, &obj->unit, &obj->convert,
|
||||
&obj->u.rect.thick, &obj->u.rect.fill) == 8) {
|
||||
obj->type = obj_rect;
|
||||
return 1;
|
||||
}
|
||||
if (sscanf(line, "C %d %d %d %u %u %d %c",
|
||||
&obj->u.circ.x, &obj->u.circ.y, &obj->u.circ.r,
|
||||
&obj->unit, &obj->convert, &obj->u.circ.thick,
|
||||
&obj->u.circ.fill) == 7) {
|
||||
obj->type = obj_circ;
|
||||
return 1;
|
||||
}
|
||||
if (sscanf(line, "A %n", &n) == 0 && n) {
|
||||
obj->type = obj_arc;
|
||||
return 1; // @@@
|
||||
}
|
||||
if (sscanf(line, "T %c %d %d %d %u %u %ms",
|
||||
&obj->u.text.orient, &obj->u.text.x, &obj->u.text.y,
|
||||
&obj->u.text.dim, &obj->unit, &obj->convert,
|
||||
&obj->u.text.s) == 7) {
|
||||
obj->type = obj_text;
|
||||
return 1;
|
||||
}
|
||||
if (sscanf(line, "X %ms %ms %d %d %d %c %d %d %u %u %c",
|
||||
&obj->u.pin.name, &obj->u.pin.number,
|
||||
&obj->u.pin.x, &obj->u.pin.y, &obj->u.pin.length,
|
||||
&obj->u.pin.orient,
|
||||
&obj->u.pin.number_size, &obj->u.pin.name_size,
|
||||
&obj->unit, &obj->convert, &obj->u.pin.etype) == 11) {
|
||||
obj->type = obj_pin;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
fprintf(stderr, "%u: cannot parse\n\"%s\"\n", ctx->lineno, line);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void lib_init(struct lib_ctx *ctx)
|
||||
{
|
||||
ctx->state = lib_skip;
|
||||
ctx->lineno++;
|
||||
}
|
24
sch2fig/lib.h
Normal file
24
sch2fig/lib.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef LIB_H
|
||||
#define LIB_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
enum lib_state {
|
||||
lib_skip, /* before a definition */
|
||||
lib_def, /* in definition */
|
||||
lib_draw, /* in drawings */
|
||||
};
|
||||
|
||||
struct lib_ctx {
|
||||
enum lib_state state;
|
||||
unsigned lineno;
|
||||
};
|
||||
|
||||
|
||||
void lib_exec(const char *name, unsigned unit, int m[6]);
|
||||
|
||||
bool lib_parse(struct lib_ctx *ctx, const char *line);
|
||||
void lib_init(struct lib_ctx *ctx);
|
||||
|
||||
#endif /* !LIB_H */
|
69
sch2fig/main.c
Normal file
69
sch2fig/main.c
Normal file
@ -0,0 +1,69 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fig.h"
|
||||
#include "lib.h"
|
||||
#include "sch.h"
|
||||
|
||||
|
||||
static bool do_sch_parse(void *ctx, const char *line)
|
||||
{
|
||||
return sch_parse(ctx, line);
|
||||
}
|
||||
|
||||
|
||||
static bool do_lib_parse(void *ctx, const char *line)
|
||||
{
|
||||
return lib_parse(ctx, line);
|
||||
}
|
||||
|
||||
|
||||
static void read_file(const char *name, void *ctx,
|
||||
bool (*parse)(void *ctx, const char *line))
|
||||
{
|
||||
FILE *file;
|
||||
char buf[1000];
|
||||
char *nl;
|
||||
|
||||
file = fopen(name, "r");
|
||||
while (fgets(buf, sizeof(buf), file)) {
|
||||
nl = strchr(buf, '\n');
|
||||
if (nl)
|
||||
*nl = 0;
|
||||
if (!parse(ctx, buf))
|
||||
break;
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
|
||||
static void usage(const char *name)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [file.lib ...] file.sch\n", name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int arg;
|
||||
|
||||
if (argc < 2)
|
||||
usage(*argv);
|
||||
|
||||
fig_init();
|
||||
for (arg = 1; arg != argc; arg++) {
|
||||
if (arg == argc - 1) {
|
||||
struct sch_ctx ctx;
|
||||
|
||||
sch_init(&ctx);
|
||||
read_file(argv[arg], &ctx, do_sch_parse);
|
||||
} else {
|
||||
struct lib_ctx ctx;
|
||||
|
||||
lib_init(&ctx);
|
||||
read_file(argv[arg], &ctx, do_lib_parse);
|
||||
}
|
||||
}
|
||||
}
|
181
sch2fig/sch.c
Normal file
181
sch2fig/sch.c
Normal file
@ -0,0 +1,181 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.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;
|
||||
}
|
||||
|
||||
|
||||
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 = fig_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++;
|
||||
}
|
45
sch2fig/sch.h
Normal file
45
sch2fig/sch.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef SCH_H
|
||||
#define SCH_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
enum sch_state {
|
||||
sch_basic, /* basic state */
|
||||
sch_descr, /* prelude and description */
|
||||
sch_comp, /* component */
|
||||
sch_sheet, /* sub-sheet */
|
||||
sch_text, /* text or label */
|
||||
sch_wire, /* wire */
|
||||
};
|
||||
|
||||
struct sch_ctx {
|
||||
enum sch_state state;
|
||||
void (*wire)(int sx, int sy, int ex, int ey);
|
||||
|
||||
/* text and component */
|
||||
|
||||
int x, y; /* saved coordinates */
|
||||
|
||||
/* text */
|
||||
|
||||
void (*text)(int x, int y, const char *s, int dir, int dim,
|
||||
enum fig_shape shape);
|
||||
int dir; /* orientation */
|
||||
int dim; /* dimension */
|
||||
enum fig_shape shape;
|
||||
|
||||
/* component */
|
||||
|
||||
char *comp; /* current component */
|
||||
unsigned unit; /* unit of current component */
|
||||
|
||||
|
||||
unsigned lineno;
|
||||
};
|
||||
|
||||
|
||||
bool sch_parse(struct sch_ctx *ctx, const char *line);
|
||||
void sch_init(struct sch_ctx *ctx);
|
||||
|
||||
#endif /* !SCH_H */
|
Loading…
Reference in New Issue
Block a user