Commit 39194ef6 authored by Dick Hollenbeck's avatar Dick Hollenbeck
Browse files

more free software, Format()ing works now, only a few more items to Parse()

parent 16e9ddc2
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ REVS="rev1 rev5 rev10"


REFERENCE="
    (reference U
    (reference U?
        (effects (at 12 13 180)(font (size .7 1))(visible yes))
    )"

@@ -71,7 +71,7 @@ for C in ${CATEGORIES}; do

    for P in ${PARTS};  do
        for R in ${REVS}; do
            echo "(part $C/$P (value 22)(footprint SM0805)(model Airplane)
            echo "(part $C/$P (value 22)(footprint SM0805)(model Airplane)(datasheet http://favorite.pdf)
                $REFERENCE
                $LINE
                $RECT
@@ -86,7 +86,7 @@ for C in ${CATEGORIES}; do
                )" > $BASEDIR/$C/$P.part.$R
        done
        # also make the part without a rev:
        echo "(part $C/$P (value 22)(footprint SM0805)(model Airplane)
        echo "(part $C/$P (value 22)(footprint SM0805)(model Airplane)(datasheet http://favorite.pdf)
            $REFERENCE
            $LINE
            $RECT
+340 −9
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <sch_sweet_parser.h>
#include <sch_lpid.h>
#include <sch_lib_table.h>
#include <macros.h>
//#include <richio.h>

using namespace SCH;
@@ -38,16 +39,21 @@ PART::PART( LIB* aOwner, const STRING& aPartNameAndRev ) :
    contains( 0 ),
    partNameAndRev( aPartNameAndRev ),
    extends( 0 ),
    base( 0 ),
    base( 0 )
/*
    reference(  this, wxT( "reference " ) ),
    value(      this, wxT( "value" ) ),
    footprint(  this, wxT( "footprint" ) ),
    model(      this, wxT( "model" ) ),
    datasheet(  this, wxT( "datasheet" ) )
*/
{
    // Our goal is to have class LIB only instantiate what is needed, so print here
    // what it is doing. It is the only class where PART can be instantiated.
    D(printf("PART::PART(%s)\n", aPartNameAndRev.c_str() );)

    for( int i=REFERENCE;  i<END;  ++i )
        mandatory[i] = 0;
}


@@ -69,7 +75,7 @@ void PART::clear()
        delete *it;
    pins.clear();

    // delete non-mandatory properties I own, since their container will not destroy them:
    // delete properties I own, since their container will not destroy them:
    for( PROPERTIES::iterator it = properties.begin();  it != properties.end();  ++it )
        delete *it;
    properties.clear();
@@ -78,7 +84,54 @@ void PART::clear()

    contains = 0;

    // @todo clear the mandatory fields
    // clear the mandatory fields
    for( int ndx = REFERENCE;  ndx < END;  ++ndx )
    {
        delete mandatory[ndx];
        mandatory[ndx] = 0;
    }
}


PROPERTY* PART::FieldLookup( PROP_ID aPropertyId )
{
    wxASSERT( unsigned(aPropertyId) < unsigned(END) );

    PROPERTY* p = mandatory[aPropertyId];

    if( !p )
    {
        switch( aPropertyId )
        {
        case REFERENCE:
            p = new PROPERTY( this, wxT( "reference" ) );
            p->text = wxT( "U?" );
            break;

        case VALUE:
            p = new PROPERTY( this, wxT( "value" ) );
            break;

        case FOOTPRINT:
            p = new PROPERTY(  this, wxT( "footprint" ) );
            break;

        case DATASHEET:
            p = new PROPERTY( this, wxT( "datasheet" ) );
            break;

        case MODEL:
            p = new PROPERTY( this, wxT( "model" ) );
            break;

        default:
            ;
        }

        mandatory[aPropertyId] = p;
    }

    return p;
}


@@ -151,7 +204,8 @@ PROPERTIES::iterator PART::propertyFind( const wxString& aPropertyName )
}


void PART::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const throw( IO_ERROR )
void PART::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
    throw( IO_ERROR )
{
    out->Print( indent, "(part %s", partNameAndRev.c_str() );

@@ -160,12 +214,13 @@ void PART::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const throw( IO_E

    out->Print( 0, "\n" );

/*
    @todo
    for( int i=0; i<MANDATORY_FIELDS;  ++i )
    for( int i = REFERENCE;  i < END;  ++i )
    {
        PROPERTY* prop = Field( PROP_ID( i ) );
        if( prop )
            prop->Format( out, indent+1, ctl );
    }
*/

    for( PROPERTIES::const_iterator it = properties.begin();  it != properties.end();  ++it )
    {
        (*it)->Format( out, indent+1, ctl );
@@ -178,6 +233,14 @@ void PART::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const throw( IO_E
            InternalToLogical( anchor.y ) );
    }

    if( keywords.size() )
    {
        out->Print( indent+1, "(keywords" );
        for( KEYWORDS::iterator it = keywords.begin();  it != keywords.end();  ++it )
            out->Print( 0, " %s", out->Quotew( *it ).c_str() );
        out->Print( 0, ")\n" );
    }

    for( GRAPHICS::const_iterator it = graphics.begin();  it != graphics.end();  ++it )
    {
        (*it)->Format( out, indent+1, ctl );
@@ -187,6 +250,274 @@ void PART::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const throw( IO_E
    {
        (*it)->Format( out, indent+1, ctl );
    }

    out->Print( indent, ")\n" );
}


//-----< PART objects  >------------------------------------------------------


void PROPERTY::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
    throw( IO_ERROR )
{
    wxASSERT( owner );      // all PROPERTYs should have an owner.

    int i;
    for( i = PART::REFERENCE;  i < PART::END;  ++i )
    {
        if( owner->Field( PART::PROP_ID(i) ) == this )
            break;
    }

    if( i < PART::END )   // is a field not a property
        out->Print( indent, "(%s", TO_UTF8( name ) );
    else
        out->Print( indent, "(property %s", out->Quotew( name ).c_str() );

    if( effects )
    {
        out->Print( 0, " %s\n", out->Quotew( text ).c_str() );
        effects->Format( out, indent+1, ctl | CTL_OMIT_NL );
        out->Print( 0, ")\n" );
    }
    else
    {
        out->Print( 0, " %s)\n", out->Quotew( text ).c_str() );
    }
}


TEXT_EFFECTS* PROPERTY::EffectsLookup()
{
    if( !effects )
    {
        effects = new TEXT_EFFECTS();
    }

    return effects;
}


void TEXT_EFFECTS::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
    throw( IO_ERROR )
{
    if( propName.IsEmpty() )
        out->Print( indent, "(effects " );
    else
        out->Print( indent, "(effects %s ",  out->Quotew( propName ).c_str() );

    out->Print( 0, "(at %.6g %.6g", InternalToLogical( pos.x ), InternalToLogical( pos.y ) );

    if( angle )
        out->Print( 0, " %.6g)", double( angle ) );
    else
        out->Print( 0, ")" );

    font.Format( out, 0, ctl | CTL_OMIT_NL );

    out->Print( 0, "(visible %s))%s",
            isVisible ? "yes" : "no",
            ctl & CTL_OMIT_NL ? "" : "\n" );
}


void FONT::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
    throw( IO_ERROR )
{
    if( name.IsEmpty() )
        out->Print( indent, "(font " );
    else
        out->Print( indent, "(font %s ", out->Quotew( name ).c_str() );

    out->Print( 0, "(size %.6g %.6g)",
            InternalToLogical( size.GetHeight() ),
            InternalToLogical( size.GetWidth() ) );

    if( italic )
        out->Print( 0, " italic" );

    if( bold )
        out->Print( 0, " bold" );

    out->Print( 0, ")%s", (ctl & CTL_OMIT_NL) ? "" : "\n" );
}


void PIN::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
    throw( IO_ERROR )
{
    out->Print( indent, "(pin %s %s ", ShowType(), ShowShape() );

    if( angle )
        out->Print( 0, "(at %.6g %.6g %.6g)", InternalToLogical( pos.x ), InternalToLogical( pos.y ), double(angle) );
    else
        out->Print( 0, "(at %.6g %.6g)", InternalToLogical( pos.x ), InternalToLogical( pos.y ) );

    out->Print( 0, "(length %.6g)", InternalToLogical( length ) );

    out->Print( 0, "(visible %s)\n", isVisible ? "yes" : "no" );

    signal.Format(  out, "signal",  indent+1, 0 );
    padname.Format( out, "padname", indent+1, CTL_OMIT_NL );
    out->Print( 0, ")\n" );
}


void PINTEXT::Format( OUTPUTFORMATTER* out, const char* aElement, int indent, int ctl ) const
    throw( IO_ERROR )
{
    out->Print( indent, "(%s %s ", aElement, out->Quotew( text ).c_str() );
    font.Format( out, 0, CTL_OMIT_NL );
    out->Print( 0, "(visible %s))%s",
        isVisible ? "yes" : "no",
        ctl & CTL_OMIT_NL ? "" : "\n" );
}


void POLY_LINE::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
    throw( IO_ERROR )
{
    out->Print( indent, "(%s ",  pts.size() == 2 ? "line" : "polyline" );
    formatContents( out, indent, ctl );
}


void POLY_LINE::formatContents(  OUTPUTFORMATTER* out, int indent, int ctl ) const
    throw( IO_ERROR )
{
    out->Print( 0, "(line_width %.6g)", lineWidth ); // @todo use logical units?

    if( fillType != PR::T_none )
        out->Print( 0, "(fill %s)", ShowFill( fillType ) );

    out->Print( 0, "\n" );

    if( pts.size() )
    {
        const int   maxLength = 75;
        int         len = 10;

        len += out->Print( indent+1, "(pts " );

        for( POINTS::const_iterator it = pts.begin();  it != pts.end();  ++it )
        {
            if( len > maxLength )
            {
                len = 10;
                out->Print( 0, "\n" );
                out->Print( indent+2, "(xy %.6g %.6g)",
                    InternalToLogical( it->x ), InternalToLogical( it->y ) );
            }
            else
                out->Print( 0, "(xy %.6g %.6g)",
                    InternalToLogical( it->x ), InternalToLogical( it->y ) );
        }

        out->Print( 0, ")" );
    }

    out->Print( 0, ")\n" );
}


void BEZIER::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
    throw( IO_ERROR )
{
    out->Print( indent, "(bezier " );
    formatContents( out, indent, ctl );     // inherited from POLY_LINE
}


void RECTANGLE::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
    throw( IO_ERROR )
{
    // (rectangle (start X Y) (end X Y) (line_width WIDTH) (fill FILL_TYPE))

    out->Print( indent, "(rectangle (start %.6g %.6g)(end %.6g %.6g)(line_width %.6g)",
        InternalToLogical( start.x ), InternalToLogical( start.y ),
        InternalToLogical( end.x ), InternalToLogical( end.y ),
        lineWidth );

    if( fillType != PR::T_none )
        out->Print( 0, "(fill %s)", ShowFill( fillType ) );

    out->Print( 0, ")\n" );
}


void CIRCLE::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
    throw( IO_ERROR )
{
    /*
        (circle (center X Y)(radius LENGTH)(line_width WIDTH)(fill FILL_TYPE))
    */

    out->Print( indent, "(circle (center %.6g %.6g)(radius %.6g)(line_width %.6g)",
        InternalToLogical( center.x ), InternalToLogical( center.y ),
        InternalToLogical( radius),
        lineWidth );

    if( fillType != PR::T_none )
        out->Print( 0, "(fill %s)", ShowFill( fillType ) );

    out->Print( 0, ")\n" );
}


void ARC::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
    throw( IO_ERROR )
{
    /*
        (arc (pos X Y)(radius RADIUS)(start X Y)(end X Y)(line_width WIDTH)(fill FILL_TYPE))
    */

    out->Print( indent, "(arc (pos %.6g %.6g)(radius %.6g)(start %.6g %.6g)(end %.6g %.6g)(line_width %.6g)",
        InternalToLogical( pos.x ), InternalToLogical( pos.y ),
        InternalToLogical( radius),
        InternalToLogical( start.x ), InternalToLogical( start.y ),
        InternalToLogical( end.x ),   InternalToLogical( end.y ),
        lineWidth );

    if( fillType != PR::T_none )
        out->Print( 0, "(fill %s)", ShowFill( fillType ) );

    out->Print( 0, ")\n" );
}


void GR_TEXT::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
    throw( IO_ERROR )
{
    /*
        (text "This is the text that gets drawn."
            (at X Y [ANGLE])

            # Valid horizontal justification values are center, right, and left.  Valid
            # vertical justification values are center, top, bottom.
            (justify HORIZONTAL_JUSTIFY VERTICAL_JUSTIFY)
            (font [FONT] (size HEIGHT WIDTH) [italic] [bold])
            (visible YES)
            (fill FILL_TYPE)
        )
    */

    out->Print( indent, "(text %s\n", out->Quotew( text ).c_str() );

    if( angle )
        out->Print( indent+1, "(at %.6g %.6g %.6g)",  InternalToLogical( pos.x ), InternalToLogical( pos.y ), double( angle ) );
    else
        out->Print( indent+1, "(at %.6g %.6g)",  InternalToLogical( pos.x ), InternalToLogical( pos.y ) );

    out->Print( 0, "(justify %s %s)(visible %s)",
            ShowJustify( hjustify ), ShowJustify( vjustify ),
            isVisible ? "yes" : "no" );

    if( fillType != PR::T_none )
        out->Print( 0, "(fill %s)", ShowFill( fillType ) );

    out->Print( 0, "\n" );
    font.Format( out, indent+1, CTL_OMIT_NL );
    out->Print( 0, ")\n" );
}
+258 −92
Original line number Diff line number Diff line
@@ -29,6 +29,32 @@
#include <sch_lib.h>


#define INTERNAL_PER_LOGICAL        10000   ///< no. internal units per logical unit


/**
 * Function InternalToLogical
 * converts an internal coordinate to a logical coordinate.  Logical coordinates
 * are defined as the standard distance between pins being equal to one.
 * Internal coordinates are currently INTERNAL_PER_LOGICAL times that.
 */
static inline double InternalToLogical( int aCoord )
{
    return double( aCoord ) / INTERNAL_PER_LOGICAL;
}


/**
 * Function LogicalToInternal
 * converts a logical coordinate to an internal coordinate.  Logical coordinates
 * are defined as the standard distance between pins being equal to one.
 * Internal coordinates are currently INTERNAL_PER_LOGICAL times that.
 */
static inline int LogicalToInternal( double aCoord )
{
    return int( aCoord * INTERNAL_PER_LOGICAL );
}

//-----<temporary home for PART sub objects, move after stable>------------------

#include <wx/gdicmn.h>
@@ -39,6 +65,9 @@

class OUTPUTFORMATTER;

/// Control Bits for Format() functions
#define CTL_OMIT_NL     (1<<0)          ///< omit new line in Format()s.

namespace SCH {

class PART;
@@ -81,6 +110,9 @@ public:
        italic( false ),
        bold( false )
    {}

    void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
        throw( IO_ERROR );
};


@@ -99,6 +131,9 @@ struct TEXT_EFFECTS
        isVisible( false ),
        property( 0 )
    {}

    void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
        throw( IO_ERROR );
};


@@ -117,7 +152,16 @@ public:

    virtual ~BASE_GRAPHIC() {}

    virtual void Format( OUTPUTFORMATTER* aOutputFormatter, int aNestLevel, int aControlBits ) const
    static const char* ShowFill( int aFillType )
    {
        return SWEET_LEXER::TokenName( PR::T( aFillType ) );
    }

    /**
     * Function Format
     * outputs this object to @a aFormatter in s-expression form.
     */
    virtual void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
        throw( IO_ERROR )
    {}
};
@@ -134,10 +178,19 @@ protected:
    int         fillType;       // T_none, T_filled, or T_transparent
    POINTS      pts;

    void formatContents( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
        throw( IO_ERROR );

public:
    POLY_LINE( PART* aOwner ) :
        BASE_GRAPHIC( aOwner )
    {}
        BASE_GRAPHIC( aOwner ),
        lineWidth( 1 ),
        fillType( PR::T_none )
    {
    }

    void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
        throw( IO_ERROR );
};

class BEZIER : public POLY_LINE
@@ -148,7 +201,13 @@ class BEZIER : public POLY_LINE
public:
    BEZIER( PART* aOwner ) :
        POLY_LINE( aOwner )
    {}
    {
        lineWidth = 1;
        fillType  = PR::T_none;
    }

    void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
        throw( IO_ERROR );
};

class RECTANGLE : public BASE_GRAPHIC
@@ -164,8 +223,14 @@ protected:

public:
    RECTANGLE( PART* aOwner ) :
        BASE_GRAPHIC( aOwner )
    {}
        BASE_GRAPHIC( aOwner ),
        lineWidth( 1 ),
        fillType( PR::T_none )
    {
    }

    void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
        throw( IO_ERROR );
};


@@ -182,8 +247,15 @@ protected:

public:
    CIRCLE( PART* aOwner ) :
        BASE_GRAPHIC( aOwner )
    {}
        BASE_GRAPHIC( aOwner ),
        radius( LogicalToInternal( 0.5 ) ),
        lineWidth( 1 ),
        fillType( PR::T_none )
    {
    }

    void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
        throw( IO_ERROR );
};


@@ -202,8 +274,15 @@ protected:

public:
    ARC( PART* aOwner ) :
        BASE_GRAPHIC( aOwner )
    {}
        BASE_GRAPHIC( aOwner ),
        lineWidth( 1 ),
        fillType( PR::T_none ),
        radius( LogicalToInternal( 0.5 ) )
    {
    }

    void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
        throw( IO_ERROR );
};


@@ -233,6 +312,14 @@ public:
        vjustify( PR::T_bottom ),
        isVisible( true )
    {}

    static const char* ShowJustify( int aJustify )
    {
        return SWEET_LEXER::TokenName( PR::T( aJustify ) );
    }

    void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
        throw( IO_ERROR );
};


@@ -245,14 +332,45 @@ protected:
    PART*           birthplace;     ///< at which PART in inheritance chain was this PROPERTY added
    wxString        name;
    wxString        text;
    TEXT_EFFECTS    effects;
    TEXT_EFFECTS*   effects;

    void clear()
    {
        delete effects;
        effects = 0;

        name = wxEmptyString;
        text = wxEmptyString;
    }

public:
    PROPERTY( PART* aOwner, const wxChar* aName = wxT( "" ) ) :
        BASE_GRAPHIC( aOwner ),
        birthplace( aOwner ),
        name( aName )
        name( aName ),
        effects( 0 )
    {}

    ~PROPERTY()
    {
        clear();
    }

    /**
     * Function Effects
     * returns a pointer to the TEXT_EFFECTS object for this PROPERTY, and optionally
     * will lazily allocate one if it did not exist previously.
     * @param doAlloc if true, means do an allocation of a new TEXT_EFFECTS if one
     * currently does not exist, otherwise return NULL if non-existent.
     */
    TEXT_EFFECTS*   EffectsLookup();
    TEXT_EFFECTS*   Effects() const
    {
        return effects;
    }

    void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
        throw( IO_ERROR );
};


@@ -265,6 +383,9 @@ struct PINTEXT
    PINTEXT() :
        isVisible( true )
    {}

    void Format( OUTPUTFORMATTER* aFormatter, const char* aElement, int aNestLevel, int aControlBits ) const
        throw( IO_ERROR );
};


@@ -284,10 +405,18 @@ public:
        isVisible( true )
    {}

/*
    void Format( OUTPUTFORMATTER* aOutputFormatter, int aNestLevel, int aControlBits ) const
    const char* ShowType() const
    {
        return SWEET_LEXER::TokenName( PR::T( connectionType ) );
    }

    const char* ShowShape() const
    {
        return SWEET_LEXER::TokenName( PR::T( shape ) );
    }

    void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
        throw( IO_ERROR );
*/

protected:
    PART*       birthplace;         ///< at which PART in inheritance chain was this PIN added
@@ -340,86 +469,22 @@ class PART
    friend class LIB;           // is the owner of all PARTS, afterall
    friend class SWEET_PARSER;

protected:      // not likely to have C++ descendants, but protected none-the-less.

    /// a protected constructor, only a LIB can instantiate a PART.
    PART( LIB* aOwner, const STRING& aPartNameAndRev );

    /**
     * Function destroy
     * clears out this object, deleting all graphics, all fields, all properties,
     * etc.
     */
    void clear();

    /**
     * Function inherit
     * is a specialized assignment function that copies a specific subset, enough
     * to fulfill the requirements of the Sweet s-expression language.
     */
    void inherit( const PART& aBasePart );

    /**
     * Function propertyFind
     * searches for aPropertyName and returns a PROPERTIES::iterator which
     * is the found item or properties.end() if not found.
     */
    PROPERTIES::iterator propertyFind( const wxString& aPropertyName );


    POINT           anchor;

    //PART( LIB* aOwner );

    LIB*            owner;      ///< which LIB am I a part of (pun if you want)
    int             contains;   ///< has bits from Enum PartParts

    STRING          partNameAndRev;   ///< example "passives/R[/revN..]", immutable.

    LPID*           extends;    ///< of base part, NULL if none, otherwise I own it.
    PART*           base;       ///< which PART am I extending, if any.  no ownership.

    /// encapsulate the old version deletion, take ownership of @a aLPID
    void setExtends( LPID* aLPID );

    /// s-expression text for the part, initially empty, and read in as this part
    /// actually becomes cached in RAM.
    STRING          body;

    // mandatory properties
    PROPERTY        reference;      ///< prefix only, only components have full references
    PROPERTY        value;
    PROPERTY        footprint;
    PROPERTY        model;
    PROPERTY        datasheet;

    // separate lists for speed:

    /**
     * Member properties
     * holds the non-mandatory properties.
     */
    PROPERTIES      properties;
public:

    /**
     * Member graphics
     * owns : POLY_LINE, RECTANGLE, CIRCLE, ARC, BEZIER, and GR_TEXT objects.
     * Enum PROP_ID
     * is the set of "mandatory" properties within a PART.  These are used by
     * class PART as array indices into PART::mandatory[].
     */
    GRAPHICS        graphics;

    /**
     * Member pins
     * owns all the PINs in pins.
     */
    PINS            pins;

    /// Alternate body forms.
    //ALTERNATES  alternates;

    KEYWORDS        keywords;


public:
    enum  PROP_ID
    {
        REFERENCE,      ///< reference prefix, a template for instantiation at COMPONENT level
        VALUE,          ///< value, e.g. "3.3K"
        FOOTPRINT,      ///< name of PCB module, e.g. "16DIP300"
        DATASHEET,      ///< URI of datasheet
        MODEL,          ///< spice model name
        END             ///< array sentinel, not a valid index
    };

    virtual ~PART();

@@ -457,6 +522,24 @@ public:

    void PropertyDelete( const wxString& aPropertyName ) throw( IO_ERROR );

    /**
     * Function Field
     * returns a pointer to one of the mandatory properties, or NULL
     * if non-existent.  Use FieldLookup() to potentially allocate it.
     */
    PROPERTY*   Field( PROP_ID aPropertyId ) const
    {
        wxASSERT( unsigned(aPropertyId) < unsigned(END) );
        return mandatory[aPropertyId];
    }

    /**
     * Function FieldLookup
     * returns a pointer to one of the mandatory properties, which is lazily
     * constructed by this function if need be.
     * @param aPropertyId tells which field.
     */
    PROPERTY*   FieldLookup( PROP_ID aPropertyId );


/*
@@ -494,6 +577,89 @@ public:
        body = aSExpression;
    }
*/


protected:      // not likely to have C++ descendants, but protected none-the-less.

    /// a protected constructor, only a LIB can instantiate a PART.
    PART( LIB* aOwner, const STRING& aPartNameAndRev );

    /**
     * Function destroy
     * clears out this object, deleting everything that this PART owns and
     * initializing values back to a state as if the object was just constructed
     * empty.
     */
    void clear();

    /**
     * Function inherit
     * is a specialized assignment function that copies a specific subset, enough
     * to fulfill the requirements of the Sweet s-expression language.
     */
    void inherit( const PART& aBasePart );

    /**
     * Function propertyFind
     * searches for aPropertyName and returns a PROPERTIES::iterator which
     * is the found item or properties.end() if not found.
     */
    PROPERTIES::iterator propertyFind( const wxString& aPropertyName );

    POINT           anchor;

    //PART( LIB* aOwner );

    LIB*            owner;      ///< which LIB am I a part of (pun if you want)
    int             contains;   ///< has bits from Enum PartParts

    STRING          partNameAndRev;   ///< example "passives/R[/revN..]", immutable.

    LPID*           extends;    ///< of base part, NULL if none, otherwise I own it.
    PART*           base;       ///< which PART am I extending, if any.  no ownership.

    /// encapsulate the old version deletion, take ownership of @a aLPID
    void setExtends( LPID* aLPID );

    /// s-expression text for the part, initially empty, and read in as this part
    /// actually becomes cached in RAM.
    STRING          body;

    // mandatory properties
    PROPERTY*       mandatory[END];

/*
    PROPERTY        value;
    PROPERTY        footprint;
    PROPERTY        model;
    PROPERTY        datasheet;
*/

    // separate lists for speed:

    /**
     * Member properties
     * holds the non-mandatory properties.
     */
    PROPERTIES      properties;

    /**
     * Member graphics
     * owns : POLY_LINE, RECTANGLE, CIRCLE, ARC, BEZIER, and GR_TEXT objects.
     */
    GRAPHICS        graphics;

    /**
     * Member pins
     * owns all the PINs in pins.
     */
    PINS            pins;

    /// Alternate body forms.
    //ALTERNATES  alternates;

    KEYWORDS        keywords;

};

}   // namespace PART
+59 −127

File changed.

Preview size limit exceeded, changes collapsed.

+0 −9
Original line number Diff line number Diff line
@@ -29,15 +29,6 @@
#include <sweet_lexer.h>


#define INTERNAL_PER_LOGICAL        10000   ///< no. internal units per logical unit


static inline double InternalToLogical( int aCoord )
{
    return double( aCoord ) / INTERNAL_PER_LOGICAL;
}


class POINT;

namespace SCH {
Loading