mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-12-22 23:41:10 +02:00
Added debugging directives to the fped language. They're describe at the end
of README. - fpd.l, fpd.y, README: added debugging directives %del, %move, %print, %dump, and %exit - obj.h, fpd.y (find_obj, find_label, new_obj): objects can now be labeled - obj.c (obj_anchors), inst.c (inst_anchors): gathering the list of anchors is now a per-object function, not an instance "method". inst_anchors implements the vector vs. object switch. - inst.h, inst.c: removed all *_op_anchors functions - expr.c (str_unit): in the past, we returned a malloc'ed string, but these times are long gone. Thus, don't stralloc(""). git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5919 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
parent
e302162a70
commit
6374b3a61a
31
README
31
README
@ -555,3 +555,34 @@ b: vec @(1mm, 0mm)
|
||||
measx "width = " a >> b 0mm
|
||||
|
||||
would print "width = 1mm"
|
||||
|
||||
|
||||
Experimental: debugging directives
|
||||
----------------------------------
|
||||
|
||||
For debugging and regression tests, fped supports the following commands
|
||||
that mimick the effect of GUI operations:
|
||||
|
||||
%del <identifier>
|
||||
%move <identifier> [<number>] <identifier>
|
||||
%print <expression>
|
||||
%dump
|
||||
%exit
|
||||
|
||||
%del and %move take as their first argument the name of the vector or
|
||||
object to manipulate. For this purpose, also objects can be labeled.
|
||||
|
||||
Object labels behave like vector labels and share the same name space.
|
||||
They are not shown anywhere in the GUI.
|
||||
|
||||
%move sets an anchor point to the vector named as its last argument.
|
||||
The anchor point is identified by index as follows:
|
||||
|
||||
anchor index vec/frame line/rect/pad arc measurement
|
||||
-------------- --------- ------------- ------------ -----------
|
||||
0 (or omitted) base first point center low point
|
||||
1 - second point end of arc high point
|
||||
2 - - start of arc -
|
||||
|
||||
%dump writes the footprint definition in the fped language to standard
|
||||
output. %exit immediately exits fped, without invoking the GUI.
|
||||
|
9
dump.c
9
dump.c
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* dump.c - Dump objects in the native FPD format
|
||||
*
|
||||
* Written 2009 by Werner Almesberger
|
||||
* Copyright 2009 by Werner Almesberger
|
||||
* Written 2009, 2010 by Werner Almesberger
|
||||
* Copyright 2009, 2010 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
|
||||
@ -484,8 +484,11 @@ static void dump_frame(FILE *file, struct frame *frame, const char *indent)
|
||||
order = order_frame(frame);
|
||||
for (item = order; item->vec || item->obj; item++) {
|
||||
if (item->obj) {
|
||||
fprintf(file, "%s", indent);
|
||||
if (item->obj->name)
|
||||
fprintf(file, "%s: ", item->obj->name);
|
||||
s = print_obj(item->obj, item->vec);
|
||||
fprintf(file, "%s%s\n", indent, s);
|
||||
fprintf(file, "%s\n", s);
|
||||
} else {
|
||||
s1 = print_label(item->vec);
|
||||
s = print_vec(item->vec);
|
||||
|
2
expr.c
2
expr.c
@ -55,7 +55,7 @@ const char *str_unit(struct num n)
|
||||
char buf[20]; /* @@@ plenty */
|
||||
|
||||
if (n.exponent == 0)
|
||||
return stralloc("");
|
||||
return "";
|
||||
switch (n.type) {
|
||||
case nt_mm:
|
||||
unit = "mm";
|
||||
|
11
fpd.l
11
fpd.l
@ -121,6 +121,17 @@ SP [\t ]*
|
||||
<INITIAL>"unit" { BEGIN(NOKEYWORD);
|
||||
return TOK_UNIT; }
|
||||
|
||||
<INITIAL>"%del" { BEGIN(NOKEYWORD);
|
||||
return TOK_DBG_DEL; }
|
||||
<INITIAL>"%move" { BEGIN(NOKEYWORD);
|
||||
return TOK_DBG_MOVE; }
|
||||
<INITIAL>"%print" { BEGIN(NOKEYWORD);
|
||||
return TOK_DBG_PRINT; }
|
||||
<INITIAL>"%dump" { BEGIN(NOKEYWORD);
|
||||
return TOK_DBG_DUMP; }
|
||||
<INITIAL>"%exit" { BEGIN(NOKEYWORD);
|
||||
return TOK_DBG_EXIT; }
|
||||
|
||||
<INITIAL>[a-zA-Z_][a-zA-Z_0-9]*: { *strchr(yytext, ':') = 0;
|
||||
yylval.id = unique(yytext);
|
||||
return LABEL; }
|
||||
|
161
fpd.y
161
fpd.y
@ -21,6 +21,7 @@
|
||||
#include "obj.h"
|
||||
#include "meas.h"
|
||||
#include "gui_status.h"
|
||||
#include "dump.h"
|
||||
#include "fpd.h"
|
||||
|
||||
|
||||
@ -68,6 +69,27 @@ static struct vec *find_vec(const struct frame *frame, const char *name)
|
||||
}
|
||||
|
||||
|
||||
static struct obj *find_obj(const struct frame *frame, const char *name)
|
||||
{
|
||||
struct obj *obj;
|
||||
|
||||
for (obj = frame->objs; obj; obj = obj->next)
|
||||
if (obj->name == name)
|
||||
return obj;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int find_label(const struct frame *frame, const char *name)
|
||||
{
|
||||
if (find_vec(frame, name))
|
||||
return 1;
|
||||
if (find_obj(frame, name))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct var *find_var(const struct frame *frame, const char *name)
|
||||
{
|
||||
const struct table *table;
|
||||
@ -145,6 +167,7 @@ static struct obj *new_obj(enum obj_type type)
|
||||
|
||||
obj = alloc_type(struct obj);
|
||||
obj->type = type;
|
||||
obj->name = NULL;
|
||||
obj->frame = curr_frame;
|
||||
obj->next = NULL;
|
||||
obj->lineno = lineno;
|
||||
@ -152,6 +175,80 @@ static struct obj *new_obj(enum obj_type type)
|
||||
}
|
||||
|
||||
|
||||
static int dbg_delete(const char *name)
|
||||
{
|
||||
struct vec *vec;
|
||||
struct obj *obj;
|
||||
|
||||
vec = find_vec(curr_frame, name);
|
||||
if (vec) {
|
||||
delete_vec(vec);
|
||||
return 1;
|
||||
}
|
||||
obj = find_obj(curr_frame, name);
|
||||
if (obj) {
|
||||
delete_obj(obj);
|
||||
return 1;
|
||||
}
|
||||
yyerrorf("unknown item \"%s\"", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int dbg_move(const char *name, int anchor, const char *dest)
|
||||
{
|
||||
struct vec *to, *vec;
|
||||
struct obj *obj;
|
||||
struct vec **anchors[3];
|
||||
int n_anchors;
|
||||
|
||||
to = find_vec(curr_frame, dest);
|
||||
if (!to) {
|
||||
yyerrorf("unknown vector \"%s\"", dest);
|
||||
return 0;
|
||||
}
|
||||
vec = find_vec(curr_frame, name);
|
||||
if (vec) {
|
||||
if (anchor) {
|
||||
yyerrorf("invalid anchor (%d > 0)", anchor);
|
||||
return 0;
|
||||
}
|
||||
vec->base = to;
|
||||
return 1;
|
||||
}
|
||||
obj = find_obj(curr_frame, name);
|
||||
if (!obj) {
|
||||
yyerrorf("unknown item \"%s\"", name);
|
||||
return 0;
|
||||
}
|
||||
n_anchors = obj_anchors(obj, anchors);
|
||||
if (anchor >= n_anchors) {
|
||||
yyerrorf("invalid anchor (%d > %d)", anchor, n_anchors-1);
|
||||
return 0;
|
||||
}
|
||||
*anchors[anchor] = to;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int dbg_print(const struct expr *expr)
|
||||
{
|
||||
const char *s;
|
||||
struct num num;
|
||||
|
||||
s = eval_str(expr, curr_frame);
|
||||
if (s) {
|
||||
printf("%s\n", s);
|
||||
return 1;
|
||||
}
|
||||
num = eval_num(expr, curr_frame);
|
||||
if (is_undef(num))
|
||||
return 0;
|
||||
printf("%lg%s\n", num.n, str_unit(num));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
%}
|
||||
|
||||
|
||||
@ -181,6 +278,8 @@ static struct obj *new_obj(enum obj_type type)
|
||||
%token TOK_PAD TOK_RPAD TOK_RECT TOK_LINE TOK_CIRC TOK_ARC
|
||||
%token TOK_MEAS TOK_MEASX TOK_MEASY TOK_UNIT
|
||||
%token TOK_NEXT TOK_NEXT_INVERTED TOK_MAX TOK_MAX_INVERTED
|
||||
%token TOK_DBG_DEL TOK_DBG_MOVE TOK_DBG_PRINT TOK_DBG_DUMP
|
||||
%token TOK_DBG_EXIT
|
||||
|
||||
%token <num> NUMBER
|
||||
%token <str> STRING
|
||||
@ -191,8 +290,9 @@ static struct obj *new_obj(enum obj_type type)
|
||||
%type <row> rows
|
||||
%type <value> row value opt_value_list
|
||||
%type <vec> vec base qbase
|
||||
%type <obj> obj meas
|
||||
%type <obj> object obj meas
|
||||
%type <expr> expr opt_expr add_expr mult_expr unary_expr primary_expr
|
||||
%type <num> opt_num
|
||||
%type <str> opt_string
|
||||
%type <pt> pad_type
|
||||
%type <mt> meas_type
|
||||
@ -323,16 +423,46 @@ frame_item:
|
||||
| vec
|
||||
| LABEL vec
|
||||
{
|
||||
if (find_vec(curr_frame, $1)) {
|
||||
yyerrorf("duplicate vector \"%s\"", $1);
|
||||
if (find_label(curr_frame, $1)) {
|
||||
yyerrorf("duplicate label \"%s\"", $1);
|
||||
YYABORT;
|
||||
}
|
||||
$2->name = $1;
|
||||
}
|
||||
| obj
|
||||
| object
|
||||
| LABEL object
|
||||
{
|
||||
*next_obj = $1;
|
||||
next_obj = &$1->next;
|
||||
if (find_label(curr_frame, $1)) {
|
||||
yyerrorf("duplicate label \"%s\"", $1);
|
||||
YYABORT;
|
||||
}
|
||||
$2->name = $1;
|
||||
}
|
||||
| TOK_DBG_DEL ID
|
||||
{
|
||||
if (!dbg_delete($2))
|
||||
YYABORT;
|
||||
}
|
||||
| TOK_DBG_MOVE ID opt_num ID
|
||||
{
|
||||
if (!dbg_move($2, $3.n, $4))
|
||||
YYABORT;
|
||||
}
|
||||
| TOK_DBG_PRINT expr
|
||||
{
|
||||
if (!dbg_print($2))
|
||||
YYABORT;
|
||||
}
|
||||
| TOK_DBG_DUMP
|
||||
{
|
||||
if (!dump(stdout)) {
|
||||
perror("stdout");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
| TOK_DBG_EXIT
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
;
|
||||
|
||||
@ -478,6 +608,15 @@ base:
|
||||
}
|
||||
;
|
||||
|
||||
object:
|
||||
obj
|
||||
{
|
||||
$$ = $1;
|
||||
*next_obj = $1;
|
||||
next_obj = &$1->next;
|
||||
}
|
||||
;
|
||||
|
||||
obj:
|
||||
TOK_PAD STRING base base pad_type
|
||||
{
|
||||
@ -650,6 +789,16 @@ meas_op:
|
||||
}
|
||||
;
|
||||
|
||||
opt_num:
|
||||
{
|
||||
$$.n = 0;
|
||||
}
|
||||
| NUMBER
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
opt_string:
|
||||
{
|
||||
$$ = NULL;
|
||||
|
73
inst.c
73
inst.c
@ -421,7 +421,11 @@ struct vec *inst_get_vec(const struct inst *inst)
|
||||
|
||||
int inst_anchors(struct inst *inst, struct vec ***anchors)
|
||||
{
|
||||
return inst->ops->anchors ? inst->ops->anchors(inst, anchors) : 0;
|
||||
if (inst->vec) {
|
||||
anchors[0] = &inst->vec->base;
|
||||
return 1;
|
||||
}
|
||||
return obj_anchors(inst->obj, anchors);
|
||||
}
|
||||
|
||||
|
||||
@ -658,13 +662,6 @@ static struct inst *find_point_vec(struct inst *self, struct coord pos)
|
||||
}
|
||||
|
||||
|
||||
static int vec_op_anchors(struct inst *inst, struct vec ***anchors)
|
||||
{
|
||||
anchors[0] = &inst->vec->base;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* When instantiating and when dumping, we assume that bases appear in the
|
||||
* frame->vecs list before vectors using them. A move may change this order.
|
||||
@ -729,7 +726,6 @@ static struct inst_ops vec_ops = {
|
||||
.distance = gui_dist_vec,
|
||||
.select = vec_op_select,
|
||||
.find_point = find_point_vec,
|
||||
.anchors = vec_op_anchors,
|
||||
.draw_move = draw_move_vec,
|
||||
.do_move_to = do_move_to_vec,
|
||||
};
|
||||
@ -765,21 +761,10 @@ static void line_op_select(struct inst *self)
|
||||
}
|
||||
|
||||
|
||||
static int line_op_anchors(struct inst *inst, struct vec ***anchors)
|
||||
{
|
||||
struct obj *obj = inst->obj;
|
||||
|
||||
anchors[0] = &obj->base;
|
||||
anchors[1] = &obj->u.rect.other;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
static struct inst_ops line_ops = {
|
||||
.draw = gui_draw_line,
|
||||
.distance = gui_dist_line,
|
||||
.select = line_op_select,
|
||||
.anchors = line_op_anchors,
|
||||
.draw_move = draw_move_line,
|
||||
};
|
||||
|
||||
@ -820,7 +805,6 @@ static struct inst_ops rect_ops = {
|
||||
.draw = gui_draw_rect,
|
||||
.distance = gui_dist_rect,
|
||||
.select = rect_op_select,
|
||||
.anchors = line_op_anchors,
|
||||
.draw_move = draw_move_rect,
|
||||
};
|
||||
|
||||
@ -874,21 +858,10 @@ static void pad_op_select(struct inst *self)
|
||||
}
|
||||
|
||||
|
||||
static int pad_op_anchors(struct inst *inst, struct vec ***anchors)
|
||||
{
|
||||
struct obj *obj = inst->obj;
|
||||
|
||||
anchors[0] = &obj->base;
|
||||
anchors[1] = &obj->u.pad.other;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
static struct inst_ops pad_ops = {
|
||||
.draw = gui_draw_pad,
|
||||
.distance = gui_dist_pad,
|
||||
.select = pad_op_select,
|
||||
.anchors = pad_op_anchors,
|
||||
.draw_move = draw_move_pad,
|
||||
};
|
||||
|
||||
@ -906,7 +879,6 @@ static struct inst_ops rpad_ops = {
|
||||
.draw = gui_draw_rpad,
|
||||
.distance = gui_dist_pad, /* @@@ */
|
||||
.select = rpad_op_select,
|
||||
.anchors = pad_op_anchors,
|
||||
.draw_move = draw_move_rpad,
|
||||
};
|
||||
|
||||
@ -951,26 +923,10 @@ static void arc_op_select(struct inst *self)
|
||||
}
|
||||
|
||||
|
||||
static int arc_op_anchors(struct inst *inst, struct vec ***anchors)
|
||||
{
|
||||
struct obj *obj = inst->obj;
|
||||
|
||||
/*
|
||||
* Put end point first so that this is what we grab if dragging a
|
||||
* circle (thereby turning it into an arc).
|
||||
*/
|
||||
anchors[0] = &obj->base;
|
||||
anchors[1] = &obj->u.arc.end;
|
||||
anchors[2] = &obj->u.arc.start;
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
static struct inst_ops arc_ops = {
|
||||
.draw = gui_draw_arc,
|
||||
.distance = gui_dist_arc,
|
||||
.select = arc_op_select,
|
||||
.anchors = arc_op_anchors,
|
||||
.draw_move = draw_move_arc,
|
||||
.do_move_to = do_move_to_arc,
|
||||
};
|
||||
@ -1022,21 +978,10 @@ static void meas_op_select(struct inst *self)
|
||||
}
|
||||
|
||||
|
||||
static int meas_op_anchors(struct inst *inst, struct vec ***anchors)
|
||||
{
|
||||
struct obj *obj = inst->obj;
|
||||
|
||||
anchors[0] = &obj->base;
|
||||
anchors[1] = &obj->u.meas.high;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
static struct inst_ops meas_ops = {
|
||||
.draw = gui_draw_meas,
|
||||
.distance = gui_dist_meas,
|
||||
.select = meas_op_select,
|
||||
.anchors = meas_op_anchors,
|
||||
.begin_drag_move= begin_drag_move_meas,
|
||||
.find_point = find_point_meas_move,
|
||||
.draw_move = draw_move_meas,
|
||||
@ -1146,19 +1091,11 @@ static void frame_op_select(struct inst *self)
|
||||
}
|
||||
|
||||
|
||||
static int frame_op_anchors(struct inst *inst, struct vec ***anchors)
|
||||
{
|
||||
anchors[0] = &inst->obj->base;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static struct inst_ops frame_ops = {
|
||||
.draw = gui_draw_frame,
|
||||
.hover = gui_hover_frame,
|
||||
.distance = gui_dist_frame,
|
||||
.select = frame_op_select,
|
||||
.anchors = frame_op_anchors,
|
||||
.draw_move = draw_move_frame,
|
||||
};
|
||||
|
||||
|
1
inst.h
1
inst.h
@ -61,7 +61,6 @@ struct inst_ops {
|
||||
unit_type (*distance)(struct inst *self, struct coord pos,
|
||||
unit_type scale);
|
||||
void (*select)(struct inst *self);
|
||||
int (*anchors)(struct inst *self, struct vec ***anchors);
|
||||
void (*begin_drag_move)(struct inst *from, int i);
|
||||
struct inst *(*find_point)(struct inst *self, struct coord pos);
|
||||
struct pix_buf *(*draw_move)(struct inst *inst,
|
||||
|
33
obj.c
33
obj.c
@ -96,6 +96,39 @@ void search_inst(const struct inst *inst)
|
||||
}
|
||||
|
||||
|
||||
/* ----- Get the list of anchors of an object ------------------------------ */
|
||||
|
||||
|
||||
int obj_anchors(struct obj *obj, struct vec ***anchors)
|
||||
{
|
||||
anchors[0] = &obj->base;
|
||||
switch (obj->type) {
|
||||
case ot_frame:
|
||||
return 1;
|
||||
case ot_rect:
|
||||
case ot_line:
|
||||
anchors[1] = &obj->u.rect.other;
|
||||
return 2;
|
||||
case ot_pad:
|
||||
anchors[1] = &obj->u.pad.other;
|
||||
return 2;
|
||||
case ot_meas:
|
||||
anchors[1] = &obj->u.meas.high;
|
||||
return 2;
|
||||
case ot_arc:
|
||||
/*
|
||||
* Put end point first so that this is what we grab if dragging
|
||||
* a circle (thereby turning it into an arc).
|
||||
*/
|
||||
anchors[1] = &obj->u.arc.end;
|
||||
anchors[2] = &obj->u.arc.start;
|
||||
return 3;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ----- Instantiation ----------------------------------------------------- */
|
||||
|
||||
|
||||
|
3
obj.h
3
obj.h
@ -205,6 +205,7 @@ struct arc {
|
||||
|
||||
struct obj {
|
||||
enum obj_type type;
|
||||
const char *name; /* NULL if anonymous */
|
||||
union {
|
||||
struct frame_ref frame;
|
||||
struct rect rect;
|
||||
@ -251,6 +252,8 @@ void find_inst(const struct inst *inst);
|
||||
|
||||
void search_inst(const struct inst *inst);
|
||||
|
||||
int obj_anchors(struct obj *obj, struct vec ***anchors);
|
||||
|
||||
int instantiate(void);
|
||||
void obj_cleanup(void);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user