Changeset 5967


Ignore:
Timestamp:
05/29/10 23:13:48 (3 years ago)
Author:
werner
Message:

The mechanism for selecting points for measurements reaches its limits when
using frames to encapsulate building blocks, e.g., like macros or functions in
a programming language. Since measurements only know about the frame containing
a vector but not the frames containing that frame, invocations of this frame
from different places can only be distinguished within the min/next/max scheme.
(See the example in README.)

To eliminate this limitation, one needs a way to tell fped to consider a point
only if it has been instantiated through a certain path, e.g., by requiring
some other frames to be visited in its instantiation. This increases the number
of distinct points available for measurements.

The mechanism chosen is to qualify a measurement point with frames that lead to
it. This list of outer frames does not have to include all frames. Without
qualifying, the old behaviour results.

Note that this doesn't cover all possible ways in which a point can appear in
different roles. Multiple frame references can also result from repeating the
same frame reference in the same parent frame. The current qualification
mechanism does not allow such paths to be distinguished. However, one can
always introduce intermediate frames for this purpose.

Furthermore, repetitions create multiple instances of a point, although in what
should be considered the same role.

  • fpd.l: make scanner support free-format a little better by switching back to keyword mode after frame braces. This way, one can write a simple frame in a single line, which is useful for regression tests.
  • fpd.l, fpd.y, README, test/dbg_meas: added %meas directive to print the result of a measurement
  • fpd.y, README: measurements can now be labeled. Note that, due to limitations of the grammar, the first measurement cannot be labeled.
  • error.h, error.c (yywarn): new function for non-fatal diagnostics that always get reported to standard error
  • bitset.h, bitset.c: functions to manipulate variable-size bit sets
  • meas.h, fpd.y, README, test/meas_qual: added the means to specify qualifiers for points used in measurements
  • dump.c (print_meas_base, print_meas): dump qualifiers
  • delete.c (delete_references, test/del_frame): delete measurements that reference a frame being deleted in their qualifiers
  • obj.h, obj.c (enumerate_frames, instantiate): enumerate all frames so that we have an index into the bit vector of visited frames
  • meas.h, meas.c (reset_samples, meas_post), obj.c (generate_vecs, generate_frame, instantiate): record the set of frames visited for each sample
  • meas.c (meas_post): only treat two instances of a point as equivalent if the set of frames visited of one of them is a superset of set of the other. In this case, keep the union of the two sets.
  • meas.h, meas.c (meas_find_min, meas_find_next, meas_find_max), test/meas_qual: instantiate_meas_pkg only select points for which all frames in the qualification have been visited
  • gui_meas.c (is_min, is_next, is_max, is_a_next): updated for above change
  • inst.h, inst.c (curr_frame, propagate_bbox, add_inst, inst_begin_frame, inst_end_frame, inst_start): renamed curr_frame to frame_instantiating to avoid clash with curr_frame in fpd.y
  • inst.h, inst.c (find_meas_hint): make global
  • test/structure, test/del_vec, test/del_frame: fped now warns if a measurement is in an unlinked frame. Changed regressions tests to avoid this warning.
  • test/Common: new function expect_grep to compare only part of the output
Location:
trunk/eda/fped
Files:
4 added
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/eda/fped/Makefile

    r5944 r5967  
    1717OBJS = fped.o expr.o coord.o obj.o delete.o inst.o util.o error.o \ 
    1818       unparse.o file.o dump.o kicad.o postscript.o meas.o \ 
    19        layer.o overlap.o hole.o tsort.o \ 
     19       layer.o overlap.o hole.o tsort.o bitset.o \ 
    2020       cpp.o lex.yy.o y.tab.o \ 
    2121       gui.o gui_util.o gui_style.o gui_inst.o gui_status.o gui_canvas.o \ 
  • trunk/eda/fped/README

    r5947 r5967  
    583583 
    584584 
     585Additional qualifiers 
     586- - - - - - - - - - - 
     587 
     588When using frames as reusable building blocks, similar to functions or 
     589macros in many programming languages, one may need finer control over 
     590the points that are selected for measurements. 
     591 
     592For example, let us consider a frame "square" that draws a square 
     593centered at the frame's origin and with a side length given by the 
     594variable "size". This variable be set in the frame referencing 
     595"square". 
     596 
     597    frame square { 
     598        a: vec @(-size/2, -size/2) 
     599        b: vec @(size/2, size/2) 
     600        rect a b 
     601    } 
     602 
     603    frame small { 
     604        set size = 2mm 
     605        frame square @ 
     606    } 
     607 
     608    frame big { 
     609        set size = 5mm 
     610        frame square @ 
     611    } 
     612 
     613    frame small @ 
     614    vec @(5mm, 0mm) 
     615    frame big . 
     616 
     617If we want to measure the size of each square, we could use 
     618 
     619measx square.a -> square.b 
     620 
     621Unfortunately, this only measures the small square. To reach the 
     622big frame, we need to tell fped to use only those points in "square" 
     623that have been placed when "square" was invoked from the big frame. 
     624 
     625This is accomplished by prefixing the points in question with the 
     626name(s) of the frames that need to be visited. The frame names are 
     627separated by slashes (/). 
     628 
     629measx big/square.a -> square.b 
     630 
     631For clarity, it's better to qualify both points, e.g., 
     632 
     633measx big/square.a -> big/square.b 
     634 
     635If multiple frame names are given, they must be in the order in 
     636which they are invoked. 
     637 
     638 
    585639Experimental: debugging directives 
    586640---------------------------------- 
     
    593647%frame <identifier> <qualified-base> 
    594648%print <expression> 
     649%meas <identifier> 
    595650%dump 
    596651%exit 
     
    623678output. %exit immediately exits fped, without invoking the GUI. 
    624679 
     680%print evaluates the expression and prints the result to standard output. 
     681%meas performs an instantiation and prints the value of the labeled 
     682measurement. 
     683 
    625684%tsort is used to test-drive the topological sort algorithm. The items 
    626685in the curly braces are declarations of nodes with (-<id>) or without 
  • trunk/eda/fped/delete.c

    r5948 r5967  
    522522 
    523523 
     524static int qual_ref(const struct frame_qual *qual, const struct frame *ref) 
     525{ 
     526        while (qual) { 
     527                if (qual->frame == ref) 
     528                        return 1; 
     529                qual = qual->next; 
     530        } 
     531        return 0; 
     532} 
     533 
     534 
    524535static void delete_references(const struct frame *ref) 
    525536{ 
     
    536547                        case ot_meas: 
    537548                                if (obj->base->frame == ref || 
    538                                     obj->u.meas.high->frame == ref) 
     549                                    obj->u.meas.high->frame == ref || 
     550                                    qual_ref(obj->u.meas.low_qual, ref) || 
     551                                    qual_ref(obj->u.meas.high_qual, ref)) 
    539552                                        do_delete_obj(obj); 
    540553                                break; 
  • trunk/eda/fped/dump.c

    r5948 r5967  
    1414#include <stdlib.h> 
    1515#include <stdio.h> 
     16#include <string.h> 
     17#include <sys/types.h> 
    1618 
    1719#include "util.h" 
     
    390392 
    391393 
    392 static char *print_meas_base(struct vec *base) 
     394static char *print_meas_base(struct vec *base, const struct frame_qual *qual) 
    393395{ 
    394396        const char *name; 
     397        size_t n; 
     398        const struct frame_qual *walk; 
     399        char *s, *p; 
    395400 
    396401        name = base_name(base, NULL); 
    397         if (base->frame == frames) 
    398                 return stralloc(name); 
    399         return stralloc_printf("%s.%s", base->frame->name, name); 
     402        n = strlen(name)+1; /* vec\0 */ 
     403        for (walk = qual; walk; walk = walk->next) 
     404                n += strlen(walk->frame->name)+1; /* frame/ */ 
     405        if (base->frame != frames) 
     406                n += strlen(base->frame->name)+1; /* frame. */ 
     407 
     408        s = p = alloc_size(n); 
     409        for (walk = qual; walk; walk = walk->next) { 
     410                n = strlen(walk->frame->name); 
     411                memcpy(p, walk->frame->name, n); 
     412                p[n] = '/'; 
     413                p += n+1; 
     414        } 
     415        if (base->frame != frames) { 
     416                n = strlen(base->frame->name); 
     417                memcpy(p, base->frame->name, n); 
     418                p[n] = '.'; 
     419                p += n+1; 
     420        } 
     421        strcpy(p, name); 
     422        return s; 
    400423} 
    401424 
     
    414437                s = t; 
    415438        } 
    416         s1 = print_meas_base(obj->base); 
     439        s1 = print_meas_base(obj->base, obj->u.meas.low_qual); 
    417440        s2 = stralloc_printf(" %s ", 
    418441                    obj->u.meas.type < 3 ? obj->u.meas.inverted ? "<-" : "->" : 
    419442                    obj->u.meas.inverted ? "<<" : ">>"); 
    420         s3 = print_meas_base(obj->u.meas.high); 
     443        s3 = print_meas_base(obj->u.meas.high, obj->u.meas.high_qual); 
    421444        t = stralloc_printf("%s%s%s%s", s, s1, s2, s3); 
    422445        free(s); 
  • trunk/eda/fped/error.c

    r5461 r5967  
    22 * error.c - Error reporting 
    33 * 
    4  * Written 2009 by Werner Almesberger 
    5  * Copyright 2009 by Werner Almesberger 
     4 * Written 2009, 2010 by Werner Almesberger 
     5 * Copyright 2009, 2010 by Werner Almesberger 
    66 * 
    77 * This program is free software; you can redistribute it and/or modify 
     
    2424int lineno = 1; 
    2525void (*reporter)(const char *s) = report_to_stderr; 
     26 
     27 
     28void yywarn(const char *s) 
     29{ 
     30        /* we use yywarn only when starting */ 
     31        fprintf(stderr, "%d: warning: %s near \"%s\"\n", lineno, s, yytext); 
     32} 
    2633 
    2734 
  • trunk/eda/fped/error.h

    r5461 r5967  
    22 * error.h - Error reporting 
    33 * 
    4  * Written 2009 by Werner Almesberger 
    5  * Copyright 2009 by Werner Almesberger 
     4 * Written 2009, 2010 by Werner Almesberger 
     5 * Copyright 2009, 2010 by Werner Almesberger 
    66 * 
    77 * This program is free software; you can redistribute it and/or modify 
     
    2121 
    2222 
     23void yywarn(const char *s); 
     24 
    2325void yyerrorf(const char *fmt, ...) 
    2426    __attribute__((format(printf, 1, 2))); 
  • trunk/eda/fped/fpd.l

    r5945 r5967  
    132132<INITIAL>"%print"               { BEGIN(NOKEYWORD); 
    133133                                  return TOK_DBG_PRINT; } 
     134<INITIAL>"%meas"                { BEGIN(NOKEYWORD); 
     135                                  return TOK_DBG_MEAS; } 
    134136<INITIAL>"%dump"                { BEGIN(NOKEYWORD); 
    135137                                  return TOK_DBG_DUMP; } 
     
    174176;                               BEGIN(INITIAL); 
    175177 
    176 "{"                             { BEGIN(NOKEYWORD); 
    177                                   disable_keywords = is_table; 
     178"{"                             { disable_keywords = is_table; 
     179                                  BEGIN(disable_keywords ? 
     180                                    NOKEYWORD : INITIAL); 
    178181                                  return '{'; } 
    179182"}"                             { disable_keywords = 0; 
     183                                  BEGIN(INITIAL); 
    180184                                  return '}'; } 
    181185 
  • trunk/eda/fped/fpd.y

    r5948 r5967  
    1818#include "util.h" 
    1919#include "error.h" 
     20#include "coord.h" 
    2021#include "expr.h" 
    2122#include "obj.h" 
    2223#include "meas.h" 
    2324#include "gui_status.h" 
     25#include "gui_inst.h" /* for %meas */ 
    2426#include "dump.h" 
    2527#include "tsort.h" 
    2628#include "fpd.h" 
     29 
     30#include "y.tab.h" 
    2731 
    2832 
     
    4852 
    4953static struct tsort *tsort; 
     54 
     55 
     56/* ----- lookup functions -------------------------------------------------- */ 
    5057 
    5158 
     
    108115        return NULL; 
    109116} 
     117 
     118 
     119/* ----- item creation ----------------------------------------------------- */ 
    110120 
    111121 
     
    178188 
    179189 
     190/* ---- frame qualifiers --------------------------------------------------- */ 
     191 
     192 
     193static int duplicate_qualifier(const struct frame_qual *a, 
     194    const struct frame_qual *b) 
     195{ 
     196        if (!b) 
     197                return 0; 
     198        if (a != b && a->frame == b->frame) { 
     199                yyerrorf("duplicate qualifier \"%s\"", a->frame->name); 
     200                return 1; 
     201        } 
     202        if (b && duplicate_qualifier(a, b->next)) 
     203                return 1; 
     204        return duplicate_qualifier(a->next, a->next); 
     205} 
     206 
     207 
     208static int can_reach(const struct frame *curr, const struct frame_qual *qual, 
     209    const struct frame *end) 
     210{ 
     211        const struct obj *obj; 
     212 
     213        if (curr == end) 
     214                return !qual; 
     215 
     216        /* 
     217         * Don't recurse for removing the qualifier alone. We require a frame 
     218         * reference step as well, so that things like foo.foo.foo.bar.vec 
     219         * aren't allowed. 
     220         * 
     221         * Since a duplicate qualifier can never work, we test for this error 
     222         * explicitly in "duplicate_qualifier". 
     223         */ 
     224        if (qual && curr == qual->frame) 
     225                qual = qual->next; 
     226 
     227        for (obj = curr->objs; obj; obj = obj->next) 
     228                if (obj->type == ot_frame) 
     229                        if (can_reach(obj->u.frame.ref, qual, end)) 
     230                                return 1; 
     231        return 0; 
     232} 
     233 
     234 
     235static int check_qbase(struct qbase *qbase) 
     236{ 
     237        if (duplicate_qualifier(qbase->qualifiers, qbase->qualifiers)) 
     238                return 0; 
     239 
     240        if (!can_reach(frames, qbase->qualifiers, qbase->vec->frame)) 
     241                yywarn("not all qualifiers can be reached"); 
     242        return 1; 
     243} 
     244 
     245 
     246/* ----- debugging directives ---------------------------------------------- */ 
     247 
     248 
    180249static int dbg_delete(const char *frame_name, const char *name) 
    181250{ 
     
    311380                return 0; 
    312381        printf("%lg%s\n", num.n, str_unit(num)); 
     382        return 1; 
     383} 
     384 
     385 
     386static int dbg_meas(const char *name) 
     387{ 
     388        const struct obj *obj; 
     389        const struct inst *inst; 
     390        struct coord a1, b1; 
     391        char *s; 
     392 
     393        obj = find_obj(frames, name); 
     394        if (!obj) { 
     395                yyerrorf("unknown object \"%s\"", name); 
     396                return 0; 
     397        } 
     398 
     399        /* from fped.c:main */ 
     400 
     401        if (!pkg_name) 
     402                pkg_name = stralloc("_"); 
     403        reporter = report_to_stderr; 
     404        if (!instantiate()) 
     405                return 0; 
     406 
     407        inst = find_meas_hint(obj); 
     408        if (!inst) { 
     409                yyerrorf("measurement \"%s\" was not instantiated", name); 
     410                return 0; 
     411        } 
     412 
     413        project_meas(inst, &a1, &b1); 
     414        s = format_len(obj->u.meas.label ? obj->u.meas.label : "", 
     415            dist_point(a1, b1), curr_unit); 
     416        printf("%s\n", s); 
     417        free(s); 
     418 
    313419        return 1; 
    314420} 
     
    340446                struct vec *vec; 
    341447        } qvec; 
     448        struct qbase { 
     449                struct vec *vec; 
     450                struct frame_qual *qualifiers; 
     451        } qbase; 
    342452}; 
    343453 
     
    349459%token          TOK_NEXT TOK_NEXT_INVERTED TOK_MAX TOK_MAX_INVERTED 
    350460%token          TOK_DBG_DEL TOK_DBG_MOVE TOK_DBG_FRAME TOK_DBG_PRINT 
    351 %token          TOK_DBG_DUMP TOK_DBG_EXIT TOK_DBG_TSORT 
     461%token          TOK_DBG_DUMP TOK_DBG_EXIT TOK_DBG_TSORT TOK_DBG_MEAS 
    352462 
    353463%token  <num>   NUMBER 
     
    359469%type   <row>   rows 
    360470%type   <value> row value opt_value_list 
    361 %type   <vec>   vec base qbase 
    362 %type   <obj>   object obj meas 
     471%type   <vec>   vec base 
     472%type   <obj>   object obj meas unlabeled_meas 
    363473%type   <expr>  expr opt_expr add_expr mult_expr unary_expr primary_expr 
    364474%type   <num>   opt_num 
     
    369479%type   <mo>    meas_op 
    370480%type   <qvec>  qualified_base 
     481%type   <qbase> qbase qbase_unchecked 
    371482 
    372483%% 
     
    537648                { 
    538649                        if (!dbg_print($2)) 
     650                                YYABORT; 
     651                } 
     652        | TOK_DBG_MEAS ID 
     653                { 
     654                        if (!dbg_meas($2)) 
    539655                                YYABORT; 
    540656                } 
     
    868984 
    869985measurements: 
    870         meas 
     986        unlabeled_meas  /* @@@ hack */ 
    871987                { 
    872988                        *next_obj = $1; 
     
    882998 
    883999meas: 
     1000        unlabeled_meas 
     1001                { 
     1002                        $$ = $1; 
     1003                } 
     1004        | LABEL unlabeled_meas 
     1005                { 
     1006                        $$ = $2; 
     1007                        if (find_label(curr_frame, $1)) { 
     1008                                yyerrorf("duplicate label \"%s\"", $1); 
     1009                                YYABORT; 
     1010                        } 
     1011                        $$->name = $1; 
     1012                } 
     1013        ; 
     1014 
     1015unlabeled_meas: 
    8841016        meas_type opt_string qbase meas_op qbase opt_expr 
    8851017                { 
     
    8901022                        meas->type = $4.max ? $1+3 : $1; 
    8911023                        meas->label = $2; 
    892                         $$->base = $3; 
     1024                        $$->base = $3.vec; 
     1025                        meas->low_qual = $3.qualifiers; 
    8931026                        meas->inverted = $4.inverted; 
    894                         meas->high = $5; 
     1027                        meas->high = $5.vec; 
     1028                        meas->high_qual = $5.qualifiers; 
    8951029                        meas->offset = $6; 
    8961030                        $$->next = NULL; 
     
    8991033 
    9001034qbase: 
     1035        qbase_unchecked 
     1036                { 
     1037                        $$ = $1; 
     1038                        if (!check_qbase(&$$)) 
     1039                                YYABORT; 
     1040                } 
     1041        ; 
     1042 
     1043qbase_unchecked: 
    9011044        ID 
    9021045                { 
    903                         $$ = find_vec(frames, $1); 
    904                         if (!$$) { 
     1046                        $$.vec = find_vec(frames, $1); 
     1047                        if (!$$.vec) { 
    9051048                                yyerrorf("unknown vector \"%s\"", $1); 
    9061049                                YYABORT; 
    9071050                        } 
     1051                        $$.qualifiers = NULL; 
    9081052                } 
    9091053        | ID '.' ID 
     
    9121056 
    9131057                        frame = find_frame($1); 
    914                         $$ = frame ? find_vec(frame, $3) : NULL; 
    915                         if (!$$) { 
     1058                        $$.vec = frame ? find_vec(frame, $3) : NULL; 
     1059                        if (!$$.vec) { 
    9161060                                yyerrorf("unknown vector \"%s.%s\"", $1, $3); 
    9171061                                YYABORT; 
     1062                        } 
     1063                        $$.qualifiers = NULL; 
     1064                } 
     1065        | ID '/' qbase 
     1066                { 
     1067                        const struct frame *frame; 
     1068                        struct frame_qual *qual; 
     1069 
     1070                        $$ = $3; 
     1071                        frame = find_frame($1); 
     1072                        if (!frame) { 
     1073                                yyerrorf("unknown frame \"%s\"", $1); 
     1074                                YYABORT; 
     1075                        } else { 
     1076                                qual = alloc_type(struct frame_qual); 
     1077                                qual->frame = frame; 
     1078                                qual->next = $$.qualifiers; 
     1079                                $$.qualifiers = qual; 
    9181080                        } 
    9191081                } 
  • trunk/eda/fped/gui_meas.c

    r5948 r5967  
    22 * gui_meas.c - GUI, measurements 
    33 * 
    4  * Written 2009 by Werner Almesberger 
    5  * Copyright 2009 by Werner Almesberger 
     4 * Written 2009, 2010 by Werner Almesberger 
     5* Copyright 2009, 2010 by Werner Almesberger 
    66 * 
    77 * This program is free software; you can redistribute it and/or modify 
     
    6262static int is_min(lt_op_type lt, const struct inst *inst) 
    6363{ 
    64         struct coord min; 
    65  
    66         min = meas_find_min(lt, active_pkg->samples[inst->vec->n]); 
    67         return coord_eq(inst->u.vec.end, min); 
     64        const struct sample *min; 
     65 
     66        min = meas_find_min(lt, active_pkg->samples[inst->vec->n], NULL); 
     67        return coord_eq(inst->u.vec.end, min->pos); 
    6868} 
    6969 
     
    7272    const struct inst *inst, const struct inst *ref) 
    7373{ 
    74         struct coord next; 
     74        const struct sample *next; 
    7575 
    7676        next = meas_find_next(lt, active_pkg->samples[inst->vec->n], 
    77             ref->u.vec.end); 
    78         return coord_eq(inst->u.vec.end, next); 
     77            ref->u.vec.end, NULL); 
     78        return coord_eq(inst->u.vec.end, next->pos); 
    7979} 
    8080 
     
    8282static int is_max(lt_op_type lt, const struct inst *inst) 
    8383{ 
    84         struct coord max; 
    85  
    86         max = meas_find_max(lt, active_pkg->samples[inst->vec->n]); 
    87         return coord_eq(inst->u.vec.end, max); 
     84        const struct sample *max; 
     85 
     86        max = meas_find_max(lt, active_pkg->samples[inst->vec->n], NULL); 
     87        return coord_eq(inst->u.vec.end, max->pos); 
    8888} 
    8989 
     
    9292{ 
    9393        struct inst *a; 
    94         struct coord min, next; 
     94        const struct sample *min, *next; 
    9595 
    9696        for (a = insts_ip_vec(); a; a = a->next) { 
    97                 min = meas_find_min(lt, active_pkg->samples[a->vec->n]); 
     97                min = meas_find_min(lt, active_pkg->samples[a->vec->n], NULL); 
    9898                next = meas_find_next(lt, active_pkg->samples[inst->vec->n], 
    99                     min); 
    100                 if (coord_eq(next, inst->u.vec.end)) 
     99                    min->pos, NULL); 
     100                if (coord_eq(next->pos, inst->u.vec.end)) 
    101101                        return 1; 
    102102        } 
     
    310310        meas->offset = NULL; 
    311311        meas_dsc = NULL; 
     312        /* we don't support qualifiers through the GUI yet */ 
     313        meas->low_qual = NULL; 
     314        meas->high_qual = NULL; 
    312315        return 1; 
    313316} 
  • trunk/eda/fped/inst.c

    r5948 r5967  
    3636struct bbox active_frame_bbox; 
    3737struct pkg *pkgs, *active_pkg, *curr_pkg; 
    38 struct inst *curr_frame = NULL; 
     38struct inst *frame_instantiating = NULL; 
    3939 
    4040static struct pkg *prev_pkgs; 
     
    575575static void propagate_bbox(const struct inst *inst) 
    576576{ 
    577         struct inst *frame = 
    578             curr_frame ? curr_frame : curr_pkg->insts[ip_frame]; 
     577        struct inst *frame = frame_instantiating ? 
     578            frame_instantiating : curr_pkg->insts[ip_frame]; 
    579579 
    580580        update_bbox(&frame->bbox, inst->bbox.min); 
     
    603603        inst->obj = NULL; 
    604604        inst->base = inst->bbox.min = inst->bbox.max = base; 
    605         inst->outer = curr_frame; 
     605        inst->outer = frame_instantiating; 
    606606        inst->active = IS_ACTIVE; 
    607607        inst->next = NULL; 
     
    10311031 
    10321032 
    1033 static struct inst *find_meas_hint(const struct obj *obj) 
     1033struct inst *find_meas_hint(const struct obj *obj) 
    10341034{ 
    10351035        struct inst *inst; 
     
    11521152        inst->active = active; 
    11531153        find_inst(inst); 
    1154         curr_frame = inst; 
     1154        frame_instantiating = inst; 
    11551155} 
    11561156 
     
    11581158void inst_end_frame(const struct frame *frame) 
    11591159{ 
    1160         struct inst *inst = curr_frame; 
    1161  
    1162         curr_frame = curr_frame->outer; 
    1163         if (curr_frame) 
     1160        struct inst *inst = frame_instantiating; 
     1161 
     1162        frame_instantiating = frame_instantiating->outer; 
     1163        if (frame_instantiating) 
    11641164                propagate_bbox(inst); 
    11651165        if (inst->u.frame.active && frame == active_frame) 
     
    12461246        inst_select_pkg(NULL); 
    12471247        curr_pkg = pkgs; 
    1248         curr_frame = NULL; 
     1248        frame_instantiating = NULL; 
    12491249} 
    12501250 
  • trunk/eda/fped/inst.h

    r5941 r5967  
    138138/* 
    139139 * frame being instantiated - we need to export this one for meas.c, so that 
    140  * measurement scan update the root frame's bounding box. 
     140 * measurements can update the root frame's bounding box. 
    141141 */ 
    142 extern struct inst *curr_frame; 
     142extern struct inst *frame_instantiating; 
    143143 
    144144/* 
     
    184184int inst_arc(struct obj *obj, struct coord center, struct coord start, 
    185185    struct coord stop, unit_type width); 
     186struct inst *find_meas_hint(const struct obj *obj); 
    186187int inst_meas(struct obj *obj, struct coord from, struct coord to); 
    187188void inst_meas_hint(struct obj *obj, unit_type offset); 
  • trunk/eda/fped/meas.c

    r5948 r5967  
    22 * meas.c - Measurements 
    33 * 
    4  * Written 2009 by Werner Almesberger 
    5  * Copyright 2009 by Werner Almesberger 
     4 * Written 2009, 2010 by Werner Almesberger 
     5 * Copyright 2009, 2010 by Werner Almesberger 
    66 * 
    77 * This program is free software; you can redistribute it and/or modify 
     
    3636                while (samples[i]) { 
    3737                        next = samples[i]->next; 
     38                        bitset_free(samples[i]->frame_set); 
    3839                        free(samples[i]); 
    3940                        samples[i] = next; 
     
    5455 
    5556 
    56 void meas_post(const struct vec *vec, struct coord pos) 
     57void meas_post(const struct vec *vec, struct coord pos, 
     58    const struct bitset *frame_set) 
    5759{ 
    5860        struct sample **walk, *new; 
     
    6567                if (pos.x < (*walk)->pos.x) 
    6668                        break; 
    67                 if (pos.x == (*walk)->pos.x) 
     69                if (pos.x != (*walk)->pos.x) 
     70                        continue; 
     71                if (bitset_ge((*walk)->frame_set, frame_set)) 
    6872                        return; 
     73                if (bitset_ge(frame_set, (*walk)->frame_set)) { 
     74                        bitset_or((*walk)->frame_set, frame_set); 
     75                        return; 
     76                } 
    6977        } 
    7078        new = alloc_type(struct sample); 
    7179        new->pos = pos; 
     80        new->frame_set = bitset_clone(frame_set); 
    7281        new->next = *walk; 
    7382        *walk = new; 
     
    178187 */ 
    179188 
    180 struct coord meas_find_min(lt_op_type lt, const struct sample *s) 
    181 { 
    182         struct coord min; 
    183  
    184         min = s->pos; 
     189const struct sample *meas_find_min(lt_op_type lt, const struct sample *s, 
     190    const struct bitset *qual) 
     191{ 
     192        const struct sample *min = NULL; 
     193 
    185194        while (s) { 
    186                 if (lt(s->pos, min) || 
    187                     (!lt(min, s->pos) && lt_xy(s->pos, min))) 
    188                         min = s->pos; 
     195                if (!qual || bitset_ge(s->frame_set, qual)) 
     196                        if (!min || lt(s->pos, min->pos) || 
     197                            (!lt(min->pos, s->pos) && lt_xy(s->pos, min->pos))) 
     198                                min = s; 
    189199                s = s->next; 
    190200        } 
     
    193203 
    194204 
    195 struct coord meas_find_next(lt_op_type lt, const struct sample *s, 
    196     struct coord ref) 
    197 { 
    198         struct coord next; 
    199  
    200         next = s->pos; 
     205const struct sample *meas_find_next(lt_op_type lt, const struct sample *s, 
     206    struct coord ref, const struct bitset *qual) 
     207{ 
     208        const struct sample *next = NULL; 
     209 
    201210        while (s) { 
    202                 if (better_next(lt, ref, next, s->pos)) 
    203                         next = s->pos; 
     211                if (!qual || bitset_ge(s->frame_set, qual)) 
     212                        if (!next || better_next(lt, ref, next->pos, s->pos)) 
     213                                next = s; 
    204214                s = s->next; 
    205215        } 
     
    208218 
    209219 
    210 struct coord meas_find_max(lt_op_type lt, const struct sample *s) 
    211 { 
    212         struct coord max; 
    213  
    214         max = s->pos; 
     220const struct sample *meas_find_max(lt_op_type lt, const struct sample *s, 
     221    const struct bitset *qual) 
     222{ 
     223        const struct sample *max = NULL; 
     224 
    215225        while (s) { 
    216                 if (lt(max, s->pos) || 
    217                     (!lt(s->pos, max) && lt_xy(max, s->pos))) 
    218                         max = s->pos; 
     226                if (!qual || bitset_ge(s->frame_set, qual)) 
     227                        if (!max || lt(max->pos, s->pos) || 
     228                            (!lt(s->pos, max->pos) && lt_xy(max->pos, s->pos))) 
     229                                max = s; 
    219230                s = s->next; 
    220231        } 
     
    226237 
    227238 
    228 static int instantiate_meas_pkg(void) 
     239static struct bitset *make_frame_set(struct frame_qual *qual, int n_frames) 
     240{ 
     241        struct bitset *set; 
     242 
     243        set = bitset_new(n_frames); 
     244        while (qual) { 
     245                bitset_set(set, qual->frame->n); 
     246                qual = qual->next; 
     247        } 
     248        return set; 
     249} 
     250 
     251 
     252static int instantiate_meas_pkg(int n_frames) 
    229253{ 
    230254        struct obj *obj; 
    231255        const struct meas *meas; 
    232         struct coord a0, b0; 
     256        struct bitset *set; 
     257        const struct sample *a0, *b0; 
    233258        lt_op_type lt; 
    234259 
     
    237262                        continue; 
    238263                meas = &obj->u.meas; 
     264 
     265                /* optimization. not really needed anymore. */ 
    239266                if (!curr_pkg->samples[obj->base->n] || 
    240267                    !curr_pkg->samples[meas->high->n]) 
     
    242269 
    243270                lt = lt_op[meas->type]; 
    244                 a0 = meas_find_min(lt, curr_pkg->samples[obj->base->n]); 
     271 
     272                set = make_frame_set(meas->low_qual, n_frames); 
     273                a0 = meas_find_min(lt, curr_pkg->samples[obj->base->n], set); 
     274                bitset_free(set); 
     275                if (!a0) 
     276                        continue; 
     277 
     278                set = make_frame_set(meas->high_qual, n_frames); 
    245279                if (is_next[meas->type]) 
    246280                        b0 = meas_find_next(lt, 
    247                             curr_pkg->samples[meas->high->n], a0); 
     281                            curr_pkg->samples[meas->high->n], a0->pos, set); 
    248282                else 
    249283                        b0 = meas_find_max(lt, 
    250                             curr_pkg->samples[meas->high->n]); 
     284                            curr_pkg->samples[meas->high->n], set); 
     285                bitset_free(set); 
     286                if (!b0) 
     287                        continue; 
    251288 
    252289                inst_meas(obj, 
    253                     meas->inverted ? b0 : a0, meas->inverted ? a0 : b0); 
     290                    meas->inverted ? b0->pos : a0->pos, 
     291                    meas->inverted ? a0->pos : b0->pos); 
    254292        } 
    255293        return 1; 
     
    257295 
    258296 
    259 int instantiate_meas(void) 
     297int instantiate_meas(int n_frames) 
    260298{ 
    261299        struct pkg *pkg; 
    262300 
    263         curr_frame = pkgs->insts[ip_frame]; 
     301        frame_instantiating = pkgs->insts[ip_frame]; 
    264302        for (pkg = pkgs; pkg; pkg = pkg->next) 
    265303                if (pkg->name) { 
    266304                        inst_select_pkg(pkg->name); 
    267                         if (!instantiate_meas_pkg()) 
     305                        if (!instantiate_meas_pkg(n_frames)) 
    268306                                return 0; 
    269307                } 
  • trunk/eda/fped/meas.h

    r5480 r5967  
    22 * meas.h - Measurements 
    33 * 
    4  * Written 2009 by Werner Almesberger 
    5  * Copyright 2009 by Werner Almesberger 
     4 * Written 2009, 2010 by Werner Almesberger 
     5 * Copyright 2009, 2010 by Werner Almesberger 
    66 * 
    77 * This program is free software; you can redistribute it and/or modify 
     
    1818#include "coord.h" 
    1919#include "expr.h" 
     20#include "bitset.h" 
    2021 
    2122 
     
    2425struct vec; 
    2526struct obj; 
     27 
     28struct frame_qual { 
     29        const struct frame *frame; 
     30        struct frame_qual *next; 
     31}; 
    2632 
    2733struct meas { 
     
    4046        struct vec *high; 
    4147        struct expr *offset; 
     48                 
     49        /* frame qualifiers */ 
     50        struct frame_qual *low_qual; 
     51        struct frame_qual *high_qual; 
    4252}; 
    4353 
    4454struct sample { 
    4555        struct coord pos; 
     56        struct bitset *frame_set; 
    4657        struct sample *next; 
    4758}; 
     
    5566int lt_xy(struct coord a, struct coord b); 
    5667 
    57 struct coord meas_find_min(lt_op_type lt, const struct sample *s); 
    58 struct coord meas_find_next(lt_op_type lt, const struct sample *s, 
    59     struct coord ref); 
    60 struct coord meas_find_max(lt_op_type lt, const struct sample *s); 
     68const struct sample *meas_find_min(lt_op_type lt, const struct sample *s, 
     69    const struct bitset *qual); 
     70const struct sample *meas_find_next(lt_op_type lt, const struct sample *s, 
     71    struct coord ref, const struct bitset *qual); 
     72const struct sample *meas_find_max(lt_op_type lt, const struct sample *s, 
     73    const struct bitset *qual); 
    6174 
    6275 
    6376void reset_samples(struct sample **samples, int n); 
    6477void meas_start(void); 
    65 void meas_post(const struct vec *vec, struct coord pos); 
    66 int instantiate_meas(void); 
     78void meas_post(const struct vec *vec, struct coord pos, 
     79    const struct bitset *frame_set); 
     80int instantiate_meas(int n_frames); 
    6781 
    6882#endif /* !MEAS_H */ 
  • trunk/eda/fped/obj.c

    r5948 r5967  
    1919#include "error.h" 
    2020#include "expr.h" 
     21#include "bitset.h" 
    2122#include "meas.h" 
    2223#include "inst.h" 
     
    3738struct frame *active_frame = NULL; 
    3839void *instantiation_error = NULL; 
     40 
     41 
     42static struct bitset *frame_set; /* frames visited in "call chain" */ 
    3943 
    4044 
     
    182186                if (!inst_vec(vec, vec_base)) 
    183187                        goto error; 
    184                 meas_post(vec, vec->pos); 
     188                meas_post(vec, vec->pos, frame_set); 
    185189        } 
    186190        return 1; 
     
    400404            active && parent == active_frame, 
    401405            active && frame == active_frame); 
     406        bitset_set(frame_set, frame->n); 
    402407        frame->curr_parent = parent; 
    403408        ok = iterate_tables(frame, frame->tables, base, active); 
    404409        inst_end_frame(frame); 
     410        bitset_clear(frame_set, frame->n); 
    405411        frame->curr_parent = NULL; 
    406412        return ok; 
     
    459465 
    460466 
     467static int enumerate_frames(void) 
     468{ 
     469        struct frame *frame; 
     470        int n = 0; 
     471 
     472        for (frame = frames; frame; frame = frame->next) 
     473                frame->n = n++; 
     474        return n; 
     475} 
     476 
     477 
    461478int instantiate(void) 
    462479{ 
    463480        struct coord zero = { 0, 0 }; 
     481        int n_frames; 
    464482        int ok; 
    465483 
    466484        meas_start(); 
    467485        inst_start(); 
     486        n_frames = enumerate_frames(); 
     487        frame_set = bitset_new(n_frames); 
    468488        instantiation_error = NULL; 
    469489        reset_all_loops(); 
     
    481501                ok = refine_layers(); 
    482502        if (ok) 
    483                 ok = instantiate_meas(); 
     503                ok = instantiate_meas(n_frames); 
    484504        if (ok) 
    485505                inst_commit(); 
    486506        else 
    487507                inst_revert(); 
     508        bitset_free(frame_set); 
    488509        return ok; 
    489510} 
  • trunk/eda/fped/obj.h

    r5948 r5967  
    164164        struct obj *active_ref; 
    165165 
    166         /* For searching */ 
     166        /* for searching */ 
    167167        struct obj *found_ref;  /* NULL if not found yet */ 
     168 
     169        /* index into bit vector in samples */ 
     170        int n; 
    168171 
    169172        /* for dumping */ 
  • trunk/eda/fped/test/Common

    r5944 r5967  
    6363 
    6464 
     65expect_grep() 
     66{ 
     67        grep "$1" <_out >_tmp || exit 1 
     68        mv _tmp _out 
     69        shift 
     70        expect "$@" 
     71} 
     72 
     73 
    6574if [ ! -z "$CWD_PREFIX" -a ! -z "$FPED" -a "$FPED" = "${FPED#/}" ]; then 
    6675    FPED="$CWD_PREFIX/$FPED" 
  • trunk/eda/fped/test/del_frame

    r5947 r5967  
    5454} 
    5555 
     56frame f @ 
    5657meas f.v -> f.v 
    5758 
     
    6566EOF 
    6667 
     68#------------------------------------------------------------------------------ 
     69 
     70fped_dump "delete frame: measurements with qualifiers disappear" <<EOF 
     71frame f { 
     72        v: vec @(0mm, 0mm) 
     73} 
     74 
     75frame g { frame f @ } 
     76 
     77frame g @ 
     78meas g/f.v -> f.v 
     79 
     80%del g 
     81EOF 
     82expect <<EOF 
     83/* MACHINE-GENERATED ! */ 
     84 
     85frame f { 
     86        v: vec @(0mm, 0mm) 
     87} 
     88 
     89package "_" 
     90unit mm 
     91EOF 
     92 
    6793############################################################################### 
  • trunk/eda/fped/test/del_vec

    r5947 r5967  
    4949        v: vec @(0mm, 0mm) 
    5050} 
     51frame f @ 
    5152meas f.v -> f.v 
    5253%del f.v 
     
    6061package "_" 
    6162unit mm 
     63frame f @ 
    6264EOF 
    6365 
  • trunk/eda/fped/test/structure

    r5944 r5967  
    7373        b: vec @(1mm, 1mm) 
    7474} 
     75frame f @ 
    7576meas f.a -> f.b 
    7677EOF 
     
    8586package "_" 
    8687unit mm 
     88frame f @ 
    8789meas f.a -> f.b 
    8890EOF 
Note: See TracChangeset for help on using the changeset viewer.