1) make PART::Format() omit any defaults for conciseness.

2) switch spec format to *.fodt, and edit it, mentioning lots of defaults.

3) Code pin_merge, but did not test it.
This commit is contained in:
Dick Hollenbeck 2011-04-18 01:26:00 -05:00
parent 6c89776bfd
commit 5679e675d2
10 changed files with 2056 additions and 241 deletions

View File

@ -11,56 +11,56 @@ REVS="rev1 rev5 rev10"
REFERENCE="
(reference U?
(effects (at 12 13 180)(font (size .7 1))(visible yes))
(effects (at 12 13 180)(font (size 7 10))(visible yes))
)"
LINE="
(line
(pts (xy 12 13)(xy 12 20))(line_width 1.5)
(pts (xy 12 13)(xy 12 20))(stroke 1.5)
)"
RECT="
(rectangle
(start 4 5)(end 6 8)(line_width 2.3)(fill transparent)
(start 4 5)(end 6 8)(stroke 2.3)(fill transparent)
)"
CIRCLE="
(circle
(center 1 0)(radius 5)(line_width 2.1)(fill none)
(center 1 0)(radius 5)(stroke 2.1)(fill none)
)"
ARC="
(arc
(pos 22 33)(radius 12)(start 2 4)(end 13 33)(line_width 2.3)(fill filled)
(pos 22 33)(radius 12)(start 2 4)(end 13 33)(stroke 2.3)(fill filled)
)"
BEZIER="
(bezier
(fill none)(line_width 2.0)(pts (xy 0 1)(xy 2 4))
(fill none)(stroke 2.0)(pts (xy 0 1)(xy 2 4))
)"
TEXT="
(text (at 23 23 90.0) \"This is some text\" (justify left bottom)(visible yes)(fill filled)
(font arial (size .8 1.2))
(font arial (size 8 12))
)"
PIN1="
(pin output line (at 7 8 90)(length 2)(visible yes)
(signal #WE (font (size 0.9 1.1) bold)(visible yes))
(padname A23 (font (size 0.9 1.1) italic bold) (visible yes))
(pin out line (at 7 8 90)
(signal #WE (font (size 8 10) bold)(visible no))
(pad A23 (font (size 9 11) italic bold))
)"
PIN2="
(pin input line (at 8 8)(length 2)(visible yes)
(signal #WAIT (font (size 0.9 1.1) bold)(visible yes))
(padname A24 (font (size 0.9 1.1) italic bold) (visible yes))
(pin in line (at 8 8)(visible yes)
(signal #WAIT (visible yes))
(pad A24 (visible yes))
)"
PIN3="
(pin (padname A25))"
(pin (pad A25))"
PINS="
(pin (padname Z12))(pin (padname Y14))(pin (padname Z13))(pin (padname Y15))"
(pin (pad Z12))(pin (pad Y14))(pin (pad Z13))(pin (pad Y15))"
PIN_SWAP="
@ -70,17 +70,17 @@ PIN_RENUM="
(pin_renum A24 B24)"
PIN_RENAME="
(pin_rename #WE LED)"
(pin_rename B24 LED)"
PIN_DELETE="
(pin_del B24)"
PIN_MERGE="(pin_merge A23 (hide Z12 Y14))(pin_merge A25 (hide Z13 Y15))"
PIN_MERGE="(pin_merge A23 (pads Z12 Y14))(pin_merge A25 (pads Z13 Y15))"
PROP1="
(property mWatts 12
(effects (at 1 34 270)(font (size .5 1) italic bold)(visible no))
(effects (at 1 34 270)(font (size 5 9) italic bold)(visible no))
)"
KEYWORDS="

View File

@ -47,7 +47,6 @@ class LIB_TABLE;
*/
class LIB_SOURCE
{
friend class LIBS; ///< the LIB factory is thru LIB_TABLE::LookupPart()
friend class LIB; ///< the LIB uses these functions.
protected: ///< derived classes must implement

View File

@ -29,7 +29,6 @@
#include <sch_lpid.h>
#include <sch_lib_table.h>
#include <macros.h>
//#include <richio.h>
/**
@ -38,11 +37,21 @@
*/
static void formatAt( OUTPUTFORMATTER* out, const POINT& aPos, ANGLE aAngle, int indent=0 )
throw( IO_ERROR )
{
// if( aPos.x || aPos.y || aAngle )
{
out->Print( indent, aAngle!=0.0 ? "(at %.6g %.6g %.6g)" : "(at %.6g %.6g)",
InternalToLogical( aPos.x ), InternalToLogical( aPos.y ),
double( aAngle ) );
}
}
static void formatStroke( OUTPUTFORMATTER* out, STROKE aStroke, int indent=0 )
throw( IO_ERROR )
{
if( aStroke == STROKE_DEFAULT )
out->Print( indent, "(stroke %.6g)", InternalToWidth( aStroke ) );
}
using namespace SCH;
@ -145,13 +154,13 @@ PROPERTY* PART::FieldLookup( PROP_ID aPropertyId )
return p;
}
PINS::iterator PART::pinFindByPadName( const wxString& aPadName )
PINS::iterator PART::pinFindByPad( const wxString& aPad )
{
PINS::iterator it;
for( it = pins.begin(); it != pins.end(); ++it )
{
if( (*it)->padname.text == aPadName )
if( (*it)->pad.text == aPad )
break;
}
@ -159,23 +168,21 @@ PINS::iterator PART::pinFindByPadName( const wxString& aPadName )
}
PINS::iterator PART::pinFindBySignal( const wxString& aSignal )
void PART::PinsFindBySignal( PIN_LIST* aResults, const wxString& aSignal )
{
PINS::iterator it;
for( it = pins.begin(); it != pins.end(); ++it )
for( PINS::const_iterator it = pins.begin(); it != pins.end(); ++it )
{
if( (*it)->signal.text == aSignal )
break;
}
return it;
}
bool PART::PinDelete( const wxString& aPadName )
{
PINS::iterator it = pinFindByPadName( aPadName );
aResults->push_back( *it );
}
}
}
bool PART::PinDelete( const wxString& aPad )
{
PINS::iterator it = pinFindByPad( aPad );
if( it != pins.end() )
{
delete *it;
@ -313,7 +320,7 @@ void PART::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
for( MERGE_SETS::const_iterator mit = pin_merges.begin(); mit != pin_merges.end(); ++mit )
{
out->Print( indent+1, "(pin_merge %s (hide", out->Quotew( mit->first ).c_str() );
out->Print( indent+1, "(pin_merge %s (pads", out->Quotew( mit->first ).c_str() );
const MERGE_SET& mset = *mit->second;
for( MERGE_SET::const_iterator pit = mset.begin(); pit != mset.end(); ++pit )
@ -391,6 +398,8 @@ void TEXT_EFFECTS::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
void FONT::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
throw( IO_ERROR )
{
if( italic || bold || !name.IsEmpty() || size.height != FONTZ_DEFAULT || size.width != FONTZ_DEFAULT )
{
if( name.IsEmpty() )
out->Print( indent, "(font " );
@ -398,8 +407,8 @@ void FONT::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
out->Print( indent, "(font %s ", out->Quotew( name ).c_str() );
out->Print( 0, "(size %.6g %.6g)",
InternalToLogical( size.GetHeight() ),
InternalToLogical( size.GetWidth() ) );
InternalToFontz( size.height ),
InternalToFontz( size.width ) );
if( italic )
out->Print( 0, " italic" );
@ -409,25 +418,39 @@ void FONT::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
out->Print( 0, ")%s", (ctl & CTL_OMIT_NL) ? "" : "\n" );
}
}
void PIN::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
throw( IO_ERROR )
{
bool hasSignal = !signal.text.IsEmpty();
bool hasPadName = !padname.text.IsEmpty();
bool hasPad = !pad.text.IsEmpty();
out->Print( indent, "(pin %s %s ", ShowType(), ShowShape() );
out->Print( indent, "(pin" );
if( connectionType != PIN_CONN_DEFAULT )
out->Print( 0, " %s", ShowType() );
if( shape != PIN_SHAPE_DEFAULT )
out->Print( 0, " %s", ShowShape() );
out->Print( 0, " " );
if( pos.x || pos.y || angle )
formatAt( out, pos, angle );
if( length != PIN_LEN_DEFAULT )
out->Print( 0, "(length %.6g)", InternalToLogical( length ) );
out->Print( 0, "(visible %s)\n", isVisible ? "yes" : "no" );
if( !isVisible )
out->Print( 0, "(visible %s)", isVisible ? "yes" : "no" );
if( hasSignal )
signal.Format( out, "signal", indent+1, hasPadName ? 0 : CTL_OMIT_NL );
signal.Format( out, "signal", 0, CTL_OMIT_NL );
if( hasPadName )
padname.Format( out, "padname", indent+1, CTL_OMIT_NL );
if( hasPad )
pad.Format( out, "pad", 0, CTL_OMIT_NL );
out->Print( 0, ")\n" );
}
@ -442,10 +465,13 @@ void PINTEXT::Format( OUTPUTFORMATTER* out, const char* aElement, int indent, in
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" );
if( !isVisible )
out->Print( 0, " (visible %s)", isVisible ? "yes" : "no" );
out->Print( 0, ")%s", ctl & CTL_OMIT_NL ? "" : "\n" );
}
@ -460,7 +486,7 @@ void POLY_LINE::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
void POLY_LINE::formatContents( OUTPUTFORMATTER* out, int indent, int ctl ) const
throw( IO_ERROR )
{
out->Print( 0, "(line_width %.6g)", InternalToWidth( lineWidth ) );
formatStroke( out, stroke );
if( fillType != PR::T_none )
out->Print( 0, "(fill %s)", ShowFill( fillType ) );
@ -506,12 +532,14 @@ void BEZIER::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
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))
// (rectangle (start X Y) (end X Y) [(stroke WIDTH)] (fill FILL_TYPE))
out->Print( indent, "(rectangle (start %.6g %.6g)(end %.6g %.6g)(line_width %.6g)",
out->Print( indent, "(rectangle (start %.6g %.6g)(end %.6g %.6g)",
InternalToLogical( start.x ), InternalToLogical( start.y ),
InternalToLogical( end.x ), InternalToLogical( end.y ),
InternalToWidth( lineWidth ) );
InternalToLogical( end.x ), InternalToLogical( end.y )
);
formatStroke( out, stroke );
if( fillType != PR::T_none )
out->Print( 0, "(fill %s)", ShowFill( fillType ) );
@ -524,13 +552,14 @@ 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))
(circle (center X Y)(radius LENGTH) [(stroke WIDTH)] (fill FILL_TYPE))
*/
out->Print( indent, "(circle (center %.6g %.6g)(radius %.6g)(line_width %.6g)",
out->Print( indent, "(circle (center %.6g %.6g)(radius %.6g)",
InternalToLogical( center.x ), InternalToLogical( center.y ),
InternalToLogical( radius),
InternalToWidth( lineWidth ) );
InternalToLogical( radius) );
formatStroke( out, stroke );
if( fillType != PR::T_none )
out->Print( 0, "(fill %s)", ShowFill( fillType ) );
@ -543,15 +572,17 @@ 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))
(arc (pos X Y)(radius RADIUS)(start X Y)(end X Y) [(stroke WIDTH)] (fill FILL_TYPE))
*/
out->Print( indent, "(arc (pos %.6g %.6g)(radius %.6g)(start %.6g %.6g)(end %.6g %.6g)(line_width %.6g)",
out->Print( indent, "(arc (pos %.6g %.6g)(radius %.6g)(start %.6g %.6g)(end %.6g %.6g)",
InternalToLogical( pos.x ), InternalToLogical( pos.y ),
InternalToLogical( radius),
InternalToLogical( start.x ), InternalToLogical( start.y ),
InternalToLogical( end.x ), InternalToLogical( end.y ),
InternalToWidth( lineWidth ) );
InternalToLogical( end.x ), InternalToLogical( end.y )
);
formatStroke( out, stroke );
if( fillType != PR::T_none )
out->Print( 0, "(fill %s)", ShowFill( fillType ) );
@ -574,11 +605,14 @@ void GR_TEXT::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const
formatAt( out, pos, angle, indent+1 );
out->Print( 0, "(justify %s %s)(visible %s)",
ShowJustify( hjustify ), ShowJustify( vjustify ),
isVisible ? "yes" : "no" );
if( hjustify != PR::T_left || vjustify != PR::T_bottom )
out->Print( 0, "(justify %s %s)",
ShowJustify( hjustify ), ShowJustify( vjustify ) );
if( fillType != PR::T_none )
if( !isVisible )
out->Print( 0, "(visible %s)", isVisible ? "yes" : "no" );
if( fillType != PR::T_filled )
out->Print( 0, "(fill %s)", ShowFill( fillType ) );
font.Format( out, 0, CTL_OMIT_NL );

View File

@ -71,6 +71,18 @@ static inline double InternalToWidth( int aWidth )
return InternalToLogical( aWidth ) * 100;
}
static inline int FontzToInternal( double aFontSize )
{
// sweet font sizes are deci-pins
return LogicalToInternal( aFontSize ) / 10;
}
static inline double InternalToFontz( int aFontSize )
{
// sweet font sizes are deci-pins
return InternalToLogical( aFontSize ) * 10;
}
//-----<temporary home for PART sub objects, move after stable>------------------
@ -113,7 +125,30 @@ public:
{}
};
/**
* Class FONTZ
* is the size of a font, and comes with a constructor which initializes
* height and width to special values which defer font size decision to
* a higher control.
*/
class FONTZ
{
public:
#define FONTZ_DEFAULT -1 ///< when size defers to higher control
FONTZ() :
height( FONTZ_DEFAULT ),
width( FONTZ_DEFAULT )
{}
int height;
int width;
};
typedef float ANGLE;
typedef int STROKE; ///< will be a class someday, currently only line width
namespace SCH {
@ -125,7 +160,8 @@ class FONT
protected:
wxString name; ///< name or other id such as number, TBD
wxSize size;
FONTZ size;
bool italic;
bool bold;
@ -161,6 +197,11 @@ struct TEXT_EFFECTS
};
#define STROKE_DEFAULT -1 ///< defer line width decision to higher control
#define FILL_TYPE_DEFAULT PR::T_none ///< fillType defaut
class BASE_GRAPHIC
{
friend class PART;
@ -200,7 +241,7 @@ class POLY_LINE : public BASE_GRAPHIC
friend class SWEET_PARSER;
protected:
int lineWidth;
STROKE stroke;
int fillType; // T_none, T_filled, or T_transparent
POINTS pts;
@ -210,7 +251,7 @@ protected:
public:
POLY_LINE( PART* aOwner ) :
BASE_GRAPHIC( aOwner ),
lineWidth( 1 ),
stroke( STROKE_DEFAULT ),
fillType( PR::T_none )
{
}
@ -228,7 +269,7 @@ public:
BEZIER( PART* aOwner ) :
POLY_LINE( aOwner )
{
lineWidth = 1;
stroke = STROKE_DEFAULT;
fillType = PR::T_none;
}
@ -242,7 +283,7 @@ class RECTANGLE : public BASE_GRAPHIC
friend class SWEET_PARSER;
protected:
int lineWidth;
STROKE stroke;
int fillType; // T_none, T_filled, or T_transparent
POINT start;
POINT end;
@ -250,8 +291,8 @@ protected:
public:
RECTANGLE( PART* aOwner ) :
BASE_GRAPHIC( aOwner ),
lineWidth( 1 ),
fillType( PR::T_none )
stroke( STROKE_DEFAULT ),
fillType( FILL_TYPE_DEFAULT )
{
}
@ -268,15 +309,15 @@ class CIRCLE : public BASE_GRAPHIC
protected:
POINT center;
int radius;
int lineWidth;
STROKE stroke;
int fillType; // T_none, T_filled, or T_transparent
public:
CIRCLE( PART* aOwner ) :
BASE_GRAPHIC( aOwner ),
radius( LogicalToInternal( 0.5 ) ),
lineWidth( 1 ),
fillType( PR::T_none )
stroke( STROKE_DEFAULT ),
fillType( FILL_TYPE_DEFAULT )
{
}
@ -292,7 +333,7 @@ class ARC : public BASE_GRAPHIC
protected:
POINT pos;
int lineWidth;
STROKE stroke;
int fillType; // T_none, T_filled, or T_transparent
int radius;
POINT start;
@ -301,8 +342,8 @@ protected:
public:
ARC( PART* aOwner ) :
BASE_GRAPHIC( aOwner ),
lineWidth( 1 ),
fillType( PR::T_none ),
stroke( STROKE_DEFAULT ),
fillType( FILL_TYPE_DEFAULT ),
radius( LogicalToInternal( 0.5 ) )
{
}
@ -322,6 +363,7 @@ protected:
ANGLE angle;
int fillType; ///< T_none, T_filled, or T_transparent
int hjustify; ///< T_center, T_right, or T_left
int vjustify; ///< T_center, T_top, or T_bottom
@ -413,6 +455,10 @@ struct PINTEXT
};
#define PIN_LEN_DEFAULT -1 ///< use standard pin length for given type
#define PIN_SHAPE_DEFAULT PR::T_line ///< use standard pin shape
#define PIN_CONN_DEFAULT PR::T_in ///< use standard pin connection type
class PIN : public BASE_GRAPHIC
{
friend class PART;
@ -422,9 +468,9 @@ public:
PIN( PART* aOwner ) :
BASE_GRAPHIC( aOwner ),
angle( 0 ),
connectionType( PR::T_input ),
shape( PR::T_line ),
length( 0 ),
connectionType( PIN_CONN_DEFAULT ),
shape( PIN_SHAPE_DEFAULT ),
length( PIN_LEN_DEFAULT ),
isVisible( true )
{}
@ -447,10 +493,10 @@ protected:
POINT pos;
ANGLE angle;
PINTEXT padname;
PINTEXT pad;
PINTEXT signal;
int connectionType; ///< T_input, T_output, T_bidirectional, T_tristate, T_passive, T_unspecified,
int connectionType; ///< T_in, T_out, T_inout, T_tristate, T_passive, T_unspecified,
///< T_power_in, T_power_out, T_open_collector, T_open_emitter, or T_unconnected.
int shape; ///< T_none, T_line, T_inverted, T_clock, T_inverted_clk, T_input_low, T_clock_low,
@ -459,7 +505,7 @@ protected:
int length; ///< length of pin in internal units
bool isVisible; ///< pin is visible
wxString pin_merge; ///< padname of (pin_merge ...) that I am a member of, else empty if none
wxString pin_merge; ///< pad of (pin_merge ...) that I am a member of, else empty if none
};
@ -526,6 +572,7 @@ typedef std::vector< BASE_GRAPHIC* > GRAPHICS;
typedef std::vector< PROPERTY* > PROPERTIES;
typedef std::vector< PIN* > PINS;
typedef std::vector< PIN* > PIN_LIST; ///< no ownership, used for searches
class LPID;
@ -624,29 +671,29 @@ public:
PROPERTY* FieldLookup( PROP_ID aPropertyId );
/**
* Function PinFindByPadName
* finds a PIN based on aPadName or returns NULL if not found.
* @param aPadName is the pin to find
* Function PinFindByPad
* finds a PIN based on aPad or returns NULL if not found.
* @param aPad is the pin to find
* @return PIN* - the found PIN or NULL if not found.
*/
PIN* PinFindByPadName( const wxString& aPadName )
PIN* PinFindByPad( const wxString& aPad )
{
PINS::iterator it = pinFindByPadName( aPadName );
return it != pins.end() ? *it : NULL;
}
PIN* PinFindBySignal( const wxString& aSignal )
{
PINS::iterator it = pinFindBySignal( aSignal );
PINS::iterator it = pinFindByPad( aPad );
return it != pins.end() ? *it : NULL;
}
/**
* Function PinsFindBySignal
* fetches all the pins matching aSignal into aResults.
*/
void PinsFindBySignal( PIN_LIST* aResults, const wxString& aSignal );
/**
* Function PinDelete
* deletes the pin with aPadName if found and returns true, else false
* deletes the pin with aPad if found and returns true, else false
* if not found.
*/
bool PinDelete( const wxString& aPadName );
bool PinDelete( const wxString& aPad );
/*
@ -714,13 +761,11 @@ protected: // not likely to have C++ descendants, but protected none-the-le
PROPERTIES::iterator propertyFind( const wxString& aPropertyName );
/**
* Function pinFindByPadName
* searches for a PIN with aPadName and returns a PROPERTIES::iterator which
* Function pinFindByPad
* searches for a PIN with aPad and returns a PROPERTIES::iterator which
* is the found item or pins.end() if not found.
*/
PINS::iterator pinFindByPadName( const wxString& aPadName );
PINS::iterator pinFindBySignal( const wxString& aSignal );
PINS::iterator pinFindByPad( const wxString& aPad );
POINT anchor;

View File

@ -46,6 +46,11 @@ static inline int fromWidth( const STRING& aWidth )
return WidthToInternal( strtod( aWidth.c_str(), NULL ) );
}
static inline int fromFontz( const STRING& aFontSize )
{
return FontzToInternal( strtod( aFontSize.c_str(), NULL ) );
}
/**
* Enum PartBit
@ -265,6 +270,7 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
break;
case T_pin:
// @todo PADNAMEs must be unique
PIN* pin;
pin = new PIN( me );
me->pins.push_back( pin );
@ -447,10 +453,10 @@ void SWEET_PARSER::parseFont( FONT* me )
sawSize = true;
NeedNUMBER( "size height" );
me->size.SetHeight( internal( CurText() ) );
me->size.height = fromFontz( CurText() );
NeedNUMBER( "size width" );
me->size.SetWidth( internal( CurText() ) );
me->size.width = fromFontz( CurText() );
NeedRIGHT();
break;
@ -500,18 +506,32 @@ void SWEET_PARSER::parseBool( bool* aBool )
}
void SWEET_PARSER::parseStroke( STROKE* me )
{
/*
(stroke [WIDTH] [(style [(dashed...)]...)])
future place holder for arrow heads, dashed lines, all line glamour
*/
NeedNUMBER( "stroke" );
*me = fromWidth( CurText() );
NeedRIGHT();
}
void SWEET_PARSER::parsePinText( PINTEXT* me )
{
/* either:
(signal SIGNAL (font [FONT] (size HEIGHT WIDTH) [italic] [bold])(visible YES))
or
(padname PADNAME (font [FONT] (size HEIGHT WIDTH) [italic] [bold])(visible YES))
(pad PADNAME (font [FONT] (size HEIGHT WIDTH) [italic] [bold])(visible YES))
*/
T tok;
bool sawFont = false;
bool sawVis = false;
// padname or signal text
// pad or signal text
NeedSYMBOLorNUMBER();
me->text = FromUTF8();
@ -562,7 +582,7 @@ void SWEET_PARSER::parsePin( PIN* me )
(at X Y [ANGLE])
(length LENGTH)
(signal NAME (font [FONT] (size HEIGHT WIDTH) [italic] [bold])(visible YES))
(padname NUMBER (font [FONT] (size HEIGHT WIDTH) [italic] [bold] (visible YES))
(pad NUMBER (font [FONT] (size HEIGHT WIDTH) [italic] [bold] (visible YES))
(visible YES)
)
*/
@ -573,7 +593,7 @@ void SWEET_PARSER::parsePin( PIN* me )
bool sawAt = false;
bool sawLen = false;
bool sawSignal = false;
bool sawPadName = false;
bool sawPad = false;
bool sawVis = false;
while( ( tok = NextTok() ) != T_RIGHT )
@ -607,11 +627,11 @@ void SWEET_PARSER::parsePin( PIN* me )
parsePinText( &me->signal );
break;
case T_padname:
if( sawPadName )
case T_pad:
if( sawPad )
Duplicate( tok );
sawPadName = true;
parsePinText( &me->padname );
sawPad = true;
parsePinText( &me->pad );
break;
case T_visible:
@ -631,9 +651,9 @@ void SWEET_PARSER::parsePin( PIN* me )
{
switch( tok )
{
case T_input:
case T_output:
case T_bidirectional:
case T_in:
case T_out:
case T_inout:
case T_tristate:
case T_passive:
case T_unspecified:
@ -673,17 +693,17 @@ void SWEET_PARSER::parsePin( PIN* me )
void SWEET_PARSER::parsePinDel( PART* me )
{
wxString padName;
wxString pad;
// we do this somewhat unorthodoxically because we want to avoid doing two lookups,
// which would need to be done to 1) find pin, and 2) delete pin. Only one
// lookup is needed with this scheme.
NeedSYMBOLorNUMBER();
padName = FromUTF8();
pad = FromUTF8();
// lookup now while CurOffset() is still meaningful.
PINS::iterator it = me->pinFindByPadName( padName );
PINS::iterator it = me->pinFindByPad( pad );
if( it == me->pins.end() )
{
THROW_PARSE_ERROR( _("undefined pin"),
@ -716,13 +736,13 @@ void SWEET_PARSER::parsePinSwap( PART* me )
PIN* pin1;
PIN* pin2;
wxString padName;
wxString pad;
NeedSYMBOLorNUMBER();
padName = FromUTF8();
pad = FromUTF8();
// lookup now while CurOffset() is still meaningful.
pin1 = me->PinFindByPadName( padName );
pin1 = me->PinFindByPad( pad );
if( !pin1 )
{
THROW_PARSE_ERROR( _("undefined pin"),
@ -733,9 +753,9 @@ void SWEET_PARSER::parsePinSwap( PART* me )
}
NeedSYMBOLorNUMBER();
padName = FromUTF8();
pad = FromUTF8();
pin2 = me->PinFindByPadName( padName );
pin2 = me->PinFindByPad( pad );
if( !pin2 )
{
THROW_PARSE_ERROR( _("undefined pin"),
@ -748,8 +768,8 @@ void SWEET_PARSER::parsePinSwap( PART* me )
NeedRIGHT();
// swap only the text, but might want to swap entire PIN_TEXTs
pin2->padname.text = pin1->padname.text;
pin1->padname.text = padName;
pin2->pad.text = pin1->pad.text;
pin1->pad.text = pad;
}
@ -757,14 +777,14 @@ void SWEET_PARSER::parsePinRenum( PART* me )
{
PIN* pin;
wxString oldPadName;
wxString newPadName;
wxString oldPad;
wxString newPad;
NeedSYMBOLorNUMBER();
oldPadName = FromUTF8();
oldPad = FromUTF8();
// lookup now while CurOffset() is still meaningful.
pin = me->PinFindByPadName( oldPadName );
pin = me->PinFindByPad( oldPad );
if( !pin )
{
THROW_PARSE_ERROR( _("undefined pin"),
@ -775,12 +795,12 @@ void SWEET_PARSER::parsePinRenum( PART* me )
}
NeedSYMBOLorNUMBER();
newPadName = FromUTF8();
newPad = FromUTF8();
NeedRIGHT();
// @todo: check for padname legalities
pin->padname.text = newPadName;
// @todo: check for pad legalities
pin->pad.text = newPad;
}
@ -788,14 +808,14 @@ void SWEET_PARSER::parsePinRename( PART* me )
{
PIN* pin;
wxString oldSignal;
wxString pad;
wxString newSignal;
NeedSYMBOLorNUMBER();
oldSignal = FromUTF8();
pad = FromUTF8();
// lookup now while CurOffset() is still meaningful.
pin = me->PinFindBySignal( oldSignal );
pin = me->PinFindByPad( pad );
if( !pin )
{
THROW_PARSE_ERROR( _("undefined pin"),
@ -817,18 +837,19 @@ void SWEET_PARSER::parsePinRename( PART* me )
void SWEET_PARSER::parsePinMerge( PART* me )
{
T tok;
wxString padName;
wxString pad;
wxString signal;
wxString msg;
NeedSYMBOLorNUMBER();
wxString anchorPadName = FromUTF8();
wxString anchorPad = FromUTF8();
// lookup now while CurOffset() is still good.
PINS::iterator pit = me->pinFindByPadName( anchorPadName );
PINS::iterator pit = me->pinFindByPad( anchorPad );
if( pit == me->pins.end() )
{
msg.Printf( _( "undefined pin %s" ), anchorPadName.GetData() );
msg.Printf( _( "undefined pin %s" ), anchorPad.GetData() );
THROW_PARSE_ERROR( msg,
CurSource(),
CurLine(),
@ -836,10 +857,10 @@ void SWEET_PARSER::parsePinMerge( PART* me )
CurOffset() );
}
if( !(*pit)->pin_merge.IsEmpty() && anchorPadName != (*pit)->pin_merge )
if( !(*pit)->pin_merge.IsEmpty() && anchorPad != (*pit)->pin_merge )
{
msg.Printf( _( "pin %s already in pin_merge group %s" ),
anchorPadName.GetData(), (*pit)->pin_merge.GetData() );
anchorPad.GetData(), (*pit)->pin_merge.GetData() );
THROW_PARSE_ERROR( msg,
CurSource(),
@ -848,34 +869,38 @@ void SWEET_PARSER::parsePinMerge( PART* me )
CurOffset() );
}
NeedLEFT();
tok = NextTok();
if( tok != T_hide )
Expecting( T_hide );
(*pit)->isVisible = true;
(*pit)->pin_merge = anchorPadName;
(*pit)->pin_merge = anchorPad;
// allocate or find a MERGE_SET;
MERGE_SET& ms = me->pin_merges[anchorPadName];
MERGE_SET& ms = me->pin_merges[anchorPad];
while( ( tok = NextTok() ) != T_RIGHT )
{
if( tok == T_LEFT )
{
tok = NextTok();
switch( tok )
{
case T_signals:
{
PINS sigPins; // no ownership
while( ( tok = NextTok() ) != T_RIGHT )
{
if( !IsSymbol( tok ) && tok != T_NUMBER )
Expecting( "padname" );
Expecting( "signal" );
padName = FromUTF8();
signal = FromUTF8();
D(printf("padName=%s\n", TO_UTF8( padName ) );)
sigPins.clear();
// find the PIN and mark it as being in this MERGE_SET or throw
// error if already in another MERGET_SET.
me->PinsFindBySignal( &sigPins, signal );
pit = me->pinFindByPadName( padName );
if( pit == me->pins.end() )
if( !sigPins.size() )
{
msg.Printf( _( "undefined pin %s" ), padName.GetData() );
msg.Printf( _( "no pins with signal %s" ), signal.GetData() );
THROW_PARSE_ERROR( msg,
CurSource(),
CurLine(),
@ -883,10 +908,56 @@ void SWEET_PARSER::parsePinMerge( PART* me )
CurOffset() );
}
if( !(*pit)->pin_merge.IsEmpty() && anchorPadName != (*pit)->pin_merge )
for( pit = sigPins.begin(); pit != sigPins.end(); ++pit )
{
if( !(*pit)->pin_merge.IsEmpty() && anchorPad != (*pit)->pin_merge )
{
msg.Printf( _( "signal pin %s already in pin_merge group %s" ),
pad.GetData(), (*pit)->pin_merge.GetData() );
THROW_PARSE_ERROR( msg,
CurSource(),
CurLine(),
CurLineNumber(),
CurOffset() );
}
(*pit)->isVisible = true;
(*pit)->pin_merge = anchorPad;
ms.insert( pad );
}
}
}
break;
case T_pads:
while( ( tok = NextTok() ) != T_RIGHT )
{
if( !IsSymbol( tok ) && tok != T_NUMBER )
Expecting( "pad" );
pad = FromUTF8();
D(printf("pad=%s\n", TO_UTF8( pad ) );)
// find the PIN and mark it as being in this MERGE_SET or throw
// error if already in another MERGET_SET.
pit = me->pinFindByPad( pad );
if( pit == me->pins.end() )
{
msg.Printf( _( "undefined pin %s" ), pad.GetData() );
THROW_PARSE_ERROR( msg,
CurSource(),
CurLine(),
CurLineNumber(),
CurOffset() );
}
if( !(*pit)->pin_merge.IsEmpty() /* && anchorPad != (*pit)->pin_merge */ )
{
msg.Printf( _( "pin %s already in pin_merge group %s" ),
padName.GetData(), (*pit)->pin_merge.GetData() );
pad.GetData(), (*pit)->pin_merge.GetData() );
THROW_PARSE_ERROR( msg,
CurSource(),
@ -896,12 +967,22 @@ void SWEET_PARSER::parsePinMerge( PART* me )
}
(*pit)->isVisible = false;
(*pit)->pin_merge = anchorPadName;
(*pit)->pin_merge = anchorPad;
ms.insert( padName );
ms.insert( pad );
}
break;
NeedRIGHT();
default:
Expecting( "pads|signals" );
break;
}
}
else
{
Expecting( T_LEFT );
}
}
}
@ -998,8 +1079,9 @@ void SWEET_PARSER::parsePolyLine( POLY_LINE* me )
(polyline|line
(pts (xy X Y) (xy X Y) (xy X Y) (xy X Y) (xy X Y))
# Line widths are in units as defined above.
(line_width WIDTH)
# Line widths are in percent of a pin delta
[(stroke [WIDTH] [(style [(dashed...)]...)])]
# Valid fill types are none, filled, and transparent.
(fill FILL_TYPE)
@ -1008,7 +1090,7 @@ void SWEET_PARSER::parsePolyLine( POLY_LINE* me )
T tok;
int count = 0;
bool sawWidth = false;
bool sawStroke = false;
bool sawFill = false;
while( ( tok = NextTok() ) != T_RIGHT )
@ -1020,13 +1102,11 @@ void SWEET_PARSER::parsePolyLine( POLY_LINE* me )
switch( tok )
{
case T_line_width:
if( sawWidth )
case T_stroke:
if( sawStroke )
Duplicate( tok );
NeedNUMBER( "line_width" );
me->lineWidth = fromWidth( CurText() );
NeedRIGHT();
sawWidth = true;
sawStroke = true;
parseStroke( &me->stroke );
break;
case T_pts:
@ -1074,7 +1154,7 @@ void SWEET_PARSER::parsePolyLine( POLY_LINE* me )
break;
default:
Expecting( "pts|line_width|fill" );
Expecting( "pts|stroke|fill" );
}
}
}
@ -1089,13 +1169,13 @@ void SWEET_PARSER::parseBezier( BEZIER* me )
void SWEET_PARSER::parseRectangle( RECTANGLE* me )
{
/*
(rectangle (start X Y) (end X Y) (line_width WIDTH) (fill FILL_TYPE))
(rectangle (start X Y) (end X Y) (stroke WIDTH) (fill FILL_TYPE))
*/
T tok;
bool sawStart = false;
bool sawEnd = false;
bool sawWidth = false;
bool sawStroke = false;
bool sawFill = false;
while( ( tok = NextTok() ) != T_RIGHT )
@ -1107,13 +1187,11 @@ void SWEET_PARSER::parseRectangle( RECTANGLE* me )
switch( tok )
{
case T_line_width:
if( sawWidth )
case T_stroke:
if( sawStroke )
Duplicate( tok );
sawWidth = true;
NeedNUMBER( "line_width" );
me->lineWidth = fromWidth( CurText() );
NeedRIGHT();
sawStroke = true;
parseStroke( &me->stroke );
break;
case T_fill:
@ -1157,7 +1235,7 @@ void SWEET_PARSER::parseRectangle( RECTANGLE* me )
break;
default:
Expecting( "start|end|line_width|fill" );
Expecting( "start|end|stroke|fill" );
}
}
}
@ -1169,7 +1247,7 @@ void SWEET_PARSER::parseCircle( CIRCLE* me )
(circle (center X Y)
# Radius length is in units if defined or mils.
(radius LENGTH)
(line_width WIDTH)
(stroke WIDTH)
(fill FILL_TYPE)
)
*/
@ -1177,7 +1255,7 @@ void SWEET_PARSER::parseCircle( CIRCLE* me )
T tok;
bool sawCenter = false;
bool sawRadius = false;
bool sawWidth = false;
bool sawStroke = false;
bool sawFill = false;
while( ( tok = NextTok() ) != T_RIGHT )
@ -1189,13 +1267,11 @@ void SWEET_PARSER::parseCircle( CIRCLE* me )
switch( tok )
{
case T_line_width:
if( sawWidth )
case T_stroke:
if( sawStroke )
Duplicate( tok );
sawWidth = true;
NeedNUMBER( "line_width" );
me->lineWidth = fromWidth( CurText() );
NeedRIGHT();
sawStroke = true;
parseStroke( &me->stroke );
break;
case T_fill:
@ -1237,7 +1313,7 @@ void SWEET_PARSER::parseCircle( CIRCLE* me )
break;
default:
Expecting( "center|radius|line_width|fill" );
Expecting( "center|radius|stroke|fill" );
}
}
}
@ -1247,7 +1323,7 @@ void SWEET_PARSER::parseArc( ARC* me )
{
/*
(arc (pos X Y) (radius RADIUS) (start X Y) (end X Y)
(line_width WIDTH)
(stroke WIDTH)
(fill FILL_TYPE)
)
*/
@ -1257,7 +1333,7 @@ void SWEET_PARSER::parseArc( ARC* me )
bool sawStart = false;
bool sawEnd = false;
bool sawRadius = false;
bool sawWidth = false;
bool sawStroke = false;
bool sawFill = false;
while( ( tok = NextTok() ) != T_RIGHT )
@ -1269,13 +1345,11 @@ void SWEET_PARSER::parseArc( ARC* me )
switch( tok )
{
case T_line_width:
if( sawWidth )
case T_stroke:
if( sawStroke )
Duplicate( tok );
sawWidth = true;
NeedNUMBER( "line_width" );
me->lineWidth = fromWidth( CurText() );
NeedRIGHT();
sawStroke = true;
parseStroke( &me->stroke );
break;
case T_fill:
@ -1339,7 +1413,7 @@ void SWEET_PARSER::parseArc( ARC* me )
break;
default:
Expecting( "center|radius|line_width|fill" );
Expecting( "center|radius|stroke|fill" );
}
}
}

View File

@ -30,6 +30,7 @@
class POINT;
typedef int STROKE;
namespace SCH {
@ -90,6 +91,7 @@ class SWEET_PARSER : public SWEET_LEXER
void parsePinRenum( PART* me );
void parsePinRename( PART* me );
void parsePinMerge( PART* me );
void parseStroke( STROKE* me );
public:

1659
new/sweet.fodt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@ anchor
arc
at
bezier
bidirectional
inout
bold
bottom
center
@ -21,7 +21,7 @@ filled
font
footprint
hide
input
in
input_low
inverted
inverted_clk
@ -31,15 +31,15 @@ keywords
left
length
line
line_width
model
no
non_logic
none
open_collector
open_emitter
output
padname
out
pad
pads
part
passive
pin
@ -62,9 +62,11 @@ right
route_alt_swap
route_pin_swap
signal
signals
size
start
start_angle
stroke
text
top
transparent