From 82a12023cdc81c3a4768ac8339b28f3a561272de Mon Sep 17 00:00:00 2001 From: werner Date: Tue, 27 Apr 2010 01:02:24 +0000 Subject: [PATCH] I thought there was a bug in frame ordering, but it turns out that it works fine. Anyway, here's a new debug construct (%frame) and a bunch of new regression tests. - fpd.y, fpd.l, README: added new directive %frame to link frames also to other frames than the current one (like in the GUI) - gui_tool.h, gui_tool.c: export is_parent_of - test/frame_ref: regression tests to ensure that frame order remains valid, even if we reference late from early frames git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5945 99fdad57-331a-0410-800a-d7fa5415bdb3 --- README | 6 +++ fpd.l | 2 + fpd.y | 81 +++++++++++++++++++++++++++- gui_tool.c | 2 +- gui_tool.h | 2 + test/frame_ref | 143 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 233 insertions(+), 3 deletions(-) create mode 100755 test/frame_ref diff --git a/README b/README index 83b62d2..df0437b 100644 --- a/README +++ b/README @@ -590,6 +590,7 @@ most of which mimick the effect of GUI operations: %del %move [] +%frame %print %dump %exit @@ -610,6 +611,11 @@ anchor index vec/frame line/rect/pad arc measurement 1 - second point end of arc high point 2 - - start of arc - +%frame creates a frame reference. Unlike "frame", the destination frame +can be different from the current frame. E.g., "%frame foo bar.a" would +add a reference to frame "foo" in frame "bar", rooted at vector "a". The +parent frame's origin can be references as "@". + %dump writes the footprint definition in the fped language to standard output. %exit immediately exits fped, without invoking the GUI. diff --git a/fpd.l b/fpd.l index 9d5624d..fa6a488 100644 --- a/fpd.l +++ b/fpd.l @@ -127,6 +127,8 @@ SP [\t ]* return TOK_DBG_DEL; } "%move" { BEGIN(NOKEYWORD); return TOK_DBG_MOVE; } +"%frame" { BEGIN(NOKEYWORD); + return TOK_DBG_FRAME; } "%print" { BEGIN(NOKEYWORD); return TOK_DBG_PRINT; } "%dump" { BEGIN(NOKEYWORD); diff --git a/fpd.y b/fpd.y index 1ef0eb8..43446ee 100644 --- a/fpd.y +++ b/fpd.y @@ -234,6 +234,38 @@ static int dbg_move(const char *name, int anchor, const char *dest) } +/* + * @@@ This is very similar to what we do in rule "obj". Consider merging. + */ + +static int dbg_link_frame(const char *frame_name, + struct frame *base_frame, struct vec *base_vec) +{ + struct frame *frame; + struct obj *obj; + + frame = find_frame(frame_name); + if (!frame) { + yyerrorf("unknown frame \"%s\"", frame_name); + return 0; + } + /* this can only fail in %frame */ + if (is_parent_of(frame, base_frame)) { + yyerrorf("frame \"%s\" is a parent of \"%s\"", + frame->name, base_frame->name); + return 0; + } + obj = new_obj(ot_frame); + obj->base = base_vec; + obj->frame = base_frame; + obj->u.frame.ref = frame; + connect_obj(base_frame, obj); + if (!frame->active_ref) + frame->active_ref = obj; + return 1; +} + + static int dbg_print(const struct expr *expr) { const char *s; @@ -283,6 +315,10 @@ static void append_root_frame(void) int inverted; int max; } mo; + struct { + struct frame *frame; + struct vec *vec; + } qvec; }; @@ -291,8 +327,8 @@ static void append_root_frame(void) %token TOK_PAD TOK_RPAD TOK_HOLE 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 TOK_DBG_TSORT +%token TOK_DBG_DEL TOK_DBG_MOVE TOK_DBG_FRAME TOK_DBG_PRINT +%token TOK_DBG_DUMP TOK_DBG_EXIT TOK_DBG_TSORT %token NUMBER %token STRING @@ -306,10 +342,12 @@ static void append_root_frame(void) %type object obj meas %type expr opt_expr add_expr mult_expr unary_expr primary_expr %type opt_num +%type frame_qualifier %type opt_string %type pad_type %type meas_type %type meas_op +%type qualified_base %% @@ -468,6 +506,11 @@ frame_item: if (!dbg_move($2, $3.n, $4)) YYABORT; } + | TOK_DBG_FRAME ID qualified_base + { + if (!dbg_link_frame($2, $3.frame, $3.vec)) + YYABORT; + } | TOK_DBG_PRINT expr { if (!dbg_print($2)) @@ -672,6 +715,40 @@ base: } ; +qualified_base: + base + { + $$.frame = curr_frame; + $$.vec = $1; + } + | frame_qualifier '@' + { + $$.frame = $1; + $$.vec = NULL; + } + | frame_qualifier ID + { + $$.frame = $1; + $$.vec = find_vec($1, $2); + if (!$$.vec) { + yyerrorf("unknown vector \"%s.%s\"", + $1->name, $2); + YYABORT; + } + } + ; + +frame_qualifier: + ID '.' + { + $$ = find_frame($1); + if (!$$) { + yyerrorf("unknown frame \"%s\"", $1); + YYABORT; + } + } + ; + object: obj { diff --git a/gui_tool.c b/gui_tool.c index e81f13e..799d16d 100644 --- a/gui_tool.c +++ b/gui_tool.c @@ -603,7 +603,7 @@ static struct tool_ops circ_ops = { /* ----- frame helper ------------------------------------------------------ */ -static int is_parent_of(const struct frame *p, const struct frame *c) +int is_parent_of(const struct frame *p, const struct frame *c) { const struct obj *obj; diff --git a/gui_tool.h b/gui_tool.h index 0dac3e5..39b3509 100644 --- a/gui_tool.h +++ b/gui_tool.h @@ -62,6 +62,8 @@ void tool_redraw(void); struct obj *new_obj_unconnected(enum obj_type type, struct inst *base); void connect_obj(struct frame *frame, struct obj *obj); +int is_parent_of(const struct frame *p, const struct frame *c); + struct pix_buf *draw_move_line_common(struct inst *inst, struct coord end, struct coord pos, int i); struct pix_buf *drag_new_line(struct inst *from, struct coord to); diff --git a/test/frame_ref b/test/frame_ref new file mode 100755 index 0000000..5316c77 --- /dev/null +++ b/test/frame_ref @@ -0,0 +1,143 @@ +#!/bin/sh +. ./Common + +############################################################################### + +fped_dump "frame reference: with \"frame\" (origin)" <