more free software, Format()ing works now, only a few more items to Parse()
This commit is contained in:
parent
16e9ddc27a
commit
39194ef669
|
@ -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
|
||||
|
|
349
new/sch_part.cpp
349
new/sch_part.cpp
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -119,7 +172,7 @@ PART& PART::operator=( const PART& other )
|
|||
}
|
||||
|
||||
|
||||
void PART::Parse( SWEET_PARSER* aParser, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_ERROR )
|
||||
void PART::Parse( SWEET_PARSER* aParser , LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_ERROR )
|
||||
{
|
||||
aParser->Parse( this, aTable );
|
||||
}
|
||||
|
@ -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" );
|
||||
}
|
||||
|
||||
|
|
354
new/sch_part.h
354
new/sch_part.h
|
@ -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,87 +469,23 @@ 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Enum PROP_ID
|
||||
* is the set of "mandatory" properties within a PART. These are used by
|
||||
* class PART as array indices into PART::mandatory[].
|
||||
*/
|
||||
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();
|
||||
|
||||
PART& operator = ( const PART& other );
|
||||
|
@ -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
|
||||
|
|
|
@ -36,20 +36,9 @@ using namespace PR;
|
|||
#define MAX_INHERITANCE_NESTING 6 ///< max depth of inheritance, no problem going larger
|
||||
|
||||
|
||||
/**
|
||||
* Function log2int
|
||||
* 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 log2int( double aCoord )
|
||||
{
|
||||
return int( aCoord * INTERNAL_PER_LOGICAL );
|
||||
}
|
||||
|
||||
static inline int internal( const STRING& aCoord )
|
||||
{
|
||||
return log2int( strtod( aCoord.c_str(), NULL ) );
|
||||
return LogicalToInternal( strtod( aCoord.c_str(), NULL ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,15 +50,15 @@ static inline int internal( const STRING& aCoord )
|
|||
*/
|
||||
enum PartBit
|
||||
{
|
||||
PARSED, ///< have parsed this part already, otherwise 'body' text must be parsed
|
||||
EXTENDS, ///< saw "extends" keyword, inheriting from another PART
|
||||
VALUE,
|
||||
ANCHOR,
|
||||
REFERENCE,
|
||||
FOOTPRINT,
|
||||
DATASHEET,
|
||||
MODEL,
|
||||
KEYWORDS,
|
||||
parsed, ///< have parsed this part already, otherwise 'body' text must be parsed
|
||||
extends, ///< saw "extends" keyword, inheriting from another PART
|
||||
value,
|
||||
anchor,
|
||||
reference,
|
||||
footprint,
|
||||
datasheet,
|
||||
model,
|
||||
keywords,
|
||||
};
|
||||
|
||||
|
||||
|
@ -86,7 +75,7 @@ void SWEET_PARSER::parseExtends( PART* me )
|
|||
PART* base;
|
||||
int offset;
|
||||
|
||||
if( contains & PB(EXTENDS) )
|
||||
if( contains & PB(extends) )
|
||||
Duplicate( T_extends );
|
||||
|
||||
NeedSYMBOLorNUMBER();
|
||||
|
@ -129,7 +118,7 @@ void SWEET_PARSER::parseExtends( PART* me )
|
|||
|
||||
me->inherit( *base );
|
||||
me->base = base;
|
||||
contains |= PB(EXTENDS);
|
||||
contains |= PB(extends);
|
||||
}
|
||||
|
||||
|
||||
|
@ -175,6 +164,8 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
|
|||
{
|
||||
if( tok == T_LEFT )
|
||||
{
|
||||
PROPERTY* prop;
|
||||
|
||||
tok = NextTok();
|
||||
|
||||
// because exceptions are thrown, any 'new' allocation has to be stored
|
||||
|
@ -195,13 +186,13 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
|
|||
break;
|
||||
|
||||
case T_anchor:
|
||||
if( contains & PB(ANCHOR) )
|
||||
if( contains & PB(anchor) )
|
||||
Duplicate( tok );
|
||||
NeedNUMBER( "anchor x" );
|
||||
me->anchor.x = internal( CurText() );
|
||||
NeedNUMBER( "anchor y" );
|
||||
me->anchor.y = internal( CurText() );
|
||||
contains |= PB(ANCHOR);
|
||||
contains |= PB(anchor);
|
||||
break;
|
||||
|
||||
case T_line:
|
||||
|
@ -247,119 +238,23 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
|
|||
parseText( text );
|
||||
break;
|
||||
|
||||
// reference in a PART is incomplete, it is just the prefix of an
|
||||
// unannotated reference. Only components have full reference designators.
|
||||
case T_reference:
|
||||
if( contains & PB(REFERENCE) )
|
||||
Duplicate( tok );
|
||||
contains |= PB(REFERENCE);
|
||||
NeedSYMBOLorNUMBER();
|
||||
me->reference.text = FromUTF8();
|
||||
tok = NextTok();
|
||||
if( tok == T_LEFT )
|
||||
{
|
||||
tok = NextTok();
|
||||
if( tok != T_effects )
|
||||
Expecting( T_effects );
|
||||
parseTextEffects( &me->reference.effects );
|
||||
NeedRIGHT();
|
||||
}
|
||||
else if( tok != T_RIGHT )
|
||||
Expecting( ") | effects" );
|
||||
break;
|
||||
|
||||
case T_value:
|
||||
if( contains & PB(VALUE) )
|
||||
Duplicate( tok );
|
||||
contains |= PB(VALUE);
|
||||
NeedSYMBOLorNUMBER();
|
||||
me->value.text = FromUTF8();
|
||||
tok = NextTok();
|
||||
if( tok == T_LEFT )
|
||||
{
|
||||
tok = NextTok();
|
||||
if( tok != T_effects )
|
||||
Expecting( T_effects );
|
||||
parseTextEffects( &me->value.effects );
|
||||
NeedRIGHT();
|
||||
}
|
||||
else if( tok != T_RIGHT )
|
||||
Expecting( ") | effects" );
|
||||
break;
|
||||
|
||||
case T_footprint:
|
||||
if( contains & PB(FOOTPRINT) )
|
||||
Duplicate( tok );
|
||||
contains |= PB(FOOTPRINT);
|
||||
NeedSYMBOLorNUMBER();
|
||||
me->footprint.text = FromUTF8();
|
||||
tok = NextTok();
|
||||
if( tok == T_LEFT )
|
||||
{
|
||||
tok = NextTok();
|
||||
if( tok != T_effects )
|
||||
Expecting( T_effects );
|
||||
parseTextEffects( &me->footprint.effects );
|
||||
NeedRIGHT();
|
||||
}
|
||||
else if( tok != T_RIGHT )
|
||||
Expecting( ") | effects" );
|
||||
break;
|
||||
|
||||
case T_datasheet:
|
||||
if( contains & PB(MODEL) )
|
||||
Duplicate( tok );
|
||||
contains |= PB(MODEL);
|
||||
NeedSYMBOLorNUMBER();
|
||||
me->datasheet.text = FromUTF8();
|
||||
tok = NextTok();
|
||||
if( tok == T_LEFT )
|
||||
{
|
||||
tok = NextTok();
|
||||
if( tok != T_effects )
|
||||
Expecting( T_effects );
|
||||
parseTextEffects( &me->datasheet.effects );
|
||||
NeedRIGHT();
|
||||
}
|
||||
else if( tok != T_RIGHT )
|
||||
Expecting( ") | effects" );
|
||||
break;
|
||||
|
||||
case T_model:
|
||||
if( contains & PB(MODEL) )
|
||||
Duplicate( tok );
|
||||
contains |= PB(MODEL);
|
||||
NeedSYMBOLorNUMBER();
|
||||
me->model.text = FromUTF8();
|
||||
tok = NextTok();
|
||||
if( tok == T_LEFT )
|
||||
{
|
||||
tok = NextTok();
|
||||
if( tok != T_effects )
|
||||
Expecting( T_effects );
|
||||
parseTextEffects( &me->model.effects );
|
||||
NeedRIGHT();
|
||||
}
|
||||
else if( tok != T_RIGHT )
|
||||
Expecting( ") | effects" );
|
||||
break;
|
||||
|
||||
case T_property:
|
||||
PROPERTY* property;
|
||||
property = new PROPERTY( me );
|
||||
prop = new PROPERTY( me );
|
||||
// @todo check for uniqueness
|
||||
me->properties.push_back( property );
|
||||
me->properties.push_back( prop );
|
||||
NeedSYMBOLorNUMBER();
|
||||
property->name = FromUTF8();
|
||||
prop->name = FromUTF8();
|
||||
|
||||
L_prop:
|
||||
NeedSYMBOLorNUMBER();
|
||||
property->text = FromUTF8();
|
||||
prop->text = FromUTF8();
|
||||
tok = NextTok();
|
||||
if( tok == T_LEFT )
|
||||
{
|
||||
tok = NextTok();
|
||||
if( tok != T_effects )
|
||||
Expecting( T_effects );
|
||||
parseTextEffects( &property->effects );
|
||||
parseTextEffects( prop->EffectsLookup() );
|
||||
NeedRIGHT();
|
||||
}
|
||||
else if( tok != T_RIGHT )
|
||||
|
@ -372,6 +267,43 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
|
|||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
// reference in a PART is incomplete, it is just the prefix of an
|
||||
// unannotated reference. Only components have full reference designators.
|
||||
case T_reference:
|
||||
if( contains & PB(reference) )
|
||||
Duplicate( tok );
|
||||
contains |= PB(reference);
|
||||
prop = me->FieldLookup( PART::REFERENCE );
|
||||
goto L_prop;
|
||||
|
||||
case T_value:
|
||||
if( contains & PB(value) )
|
||||
Duplicate( tok );
|
||||
contains |= PB(value);
|
||||
prop = me->FieldLookup( PART::VALUE );
|
||||
goto L_prop;
|
||||
|
||||
case T_footprint:
|
||||
if( contains & PB(footprint) )
|
||||
Duplicate( tok );
|
||||
contains |= PB(footprint);
|
||||
prop = me->FieldLookup( PART::FOOTPRINT );
|
||||
goto L_prop;
|
||||
|
||||
case T_datasheet:
|
||||
if( contains & PB(datasheet) )
|
||||
Duplicate( tok );
|
||||
contains |= PB(datasheet);
|
||||
prop = me->FieldLookup( PART::DATASHEET );
|
||||
goto L_prop;
|
||||
|
||||
case T_model:
|
||||
if( contains & PB(model) )
|
||||
Duplicate( tok );
|
||||
contains |= PB(model);
|
||||
prop = me->FieldLookup( PART::MODEL );
|
||||
goto L_prop;
|
||||
|
||||
case T_pin:
|
||||
PIN* pin;
|
||||
pin = new PIN( me );
|
||||
|
@ -404,7 +336,6 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
|
|||
|
||||
case T_route_pin_swap:
|
||||
break;
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +350,7 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
|
|||
}
|
||||
}
|
||||
|
||||
contains |= PB(PARSED);
|
||||
contains |= PB(parsed);
|
||||
|
||||
me->contains |= contains;
|
||||
}
|
||||
|
@ -804,6 +735,7 @@ void SWEET_PARSER::parsePolyLine( POLY_LINE* me )
|
|||
if( sawWidth )
|
||||
Duplicate( tok );
|
||||
NeedNUMBER( "line_width" );
|
||||
// @todo Use logical units?
|
||||
me->lineWidth = strtod( CurText(), NULL );
|
||||
NeedRIGHT();
|
||||
sawWidth = true;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <sch_lib_table.h>
|
||||
#include <sch_lib_table_lexer.h>
|
||||
#include <sch_lpid.h>
|
||||
#include <sch_part.h>
|
||||
|
||||
using namespace SCH;
|
||||
|
||||
|
@ -86,7 +87,12 @@ void LIB_TABLE::Test()
|
|||
// find a part
|
||||
LPID lpid( "meparts:tigers/ears" );
|
||||
|
||||
LookupPart( lpid );
|
||||
PART* part = LookupPart( lpid );
|
||||
|
||||
sf.Clear();
|
||||
part->Format( &sf, 0, 0 );
|
||||
|
||||
printf( "%s", sf.GetString().c_str() );
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue