++new:
* Added the basic structure to the Sweet parser in sch_part.cpp. * Got inheritence working off of the 'extends' keyword and PART::inherit() * Tossed the units support out of sweet.keywords, since we agreed to go dimensionless. ++richio: * Added the problemInputLine support to PARSE_ERROR, so UI can show the offending line of bytes. Yes bytes, not even guaranteed to be characters.
This commit is contained in:
parent
e7d5770f42
commit
84ed5f501d
|
@ -4,6 +4,17 @@ KiCad ChangeLog 2010
|
|||
Please add newer entries at the top, list the date and your name with
|
||||
email address.
|
||||
|
||||
2011-Jan-1 UPDATE Dick Hollenbeck <dick@softplc.com>
|
||||
================================================================================
|
||||
++new:
|
||||
* Added the basic structure to the Sweet parser in sch_part.cpp.
|
||||
* Got inheritence working off of the 'extends' keyword and PART::inherit()
|
||||
* Tossed the units support out of sweet.keywords, since we agreed to go dimensionless.
|
||||
++richio:
|
||||
* Added the problemInputLine support to PARSE_ERROR, so UI can show the
|
||||
offending line of bytes. Yes bytes, not even guaranteed to be characters.
|
||||
|
||||
|
||||
2010-dec-31 UPDATE Wayne Stambaugh <stambaughw@verizon.net>
|
||||
================================================================================
|
||||
++all
|
||||
|
|
|
@ -231,7 +231,7 @@ wxString DSNLEXER::GetTokenString( int aTok )
|
|||
{
|
||||
wxString ret;
|
||||
|
||||
ret << wxT("'") << wxConvertMB2WX( GetTokenText(aTok) ) << wxT("'");
|
||||
ret << wxT("'") << wxString::FromUTF8( GetTokenText(aTok) ) << wxT("'");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -249,24 +249,11 @@ bool DSNLEXER::IsSymbol( int aTok )
|
|||
}
|
||||
|
||||
|
||||
void DSNLEXER::ThrowIOError( wxString aText, int charOffset ) throw( IO_ERROR )
|
||||
{
|
||||
// @todo convert this to THROW_PARSE_ERROR()
|
||||
|
||||
// append to aText, do not overwrite
|
||||
aText << wxT(" ") << _("in") << wxT(" \"") << CurSource()
|
||||
<< wxT("\" ") << _("on line") << wxT(" ") << reader->LineNumber()
|
||||
<< wxT(" ") << _("at offset") << wxT(" ") << charOffset;
|
||||
|
||||
THROW_IO_ERROR( aText );
|
||||
}
|
||||
|
||||
|
||||
void DSNLEXER::Expecting( int aTok ) throw( IO_ERROR )
|
||||
{
|
||||
wxString errText( _("Expecting") );
|
||||
errText << wxT(" ") << GetTokenString( aTok );
|
||||
ThrowIOError( errText, CurOffset() );
|
||||
THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -274,7 +261,7 @@ void DSNLEXER::Expecting( const wxString& text ) throw( IO_ERROR )
|
|||
{
|
||||
wxString errText( _("Expecting") );
|
||||
errText << wxT(" '") << text << wxT("'");
|
||||
ThrowIOError( errText, CurOffset() );
|
||||
THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -282,15 +269,22 @@ void DSNLEXER::Unexpected( int aTok ) throw( IO_ERROR )
|
|||
{
|
||||
wxString errText( _("Unexpected") );
|
||||
errText << wxT(" ") << GetTokenString( aTok );
|
||||
ThrowIOError( errText, CurOffset() );
|
||||
THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
|
||||
}
|
||||
|
||||
void DSNLEXER::Duplicate( int aTok ) throw( IO_ERROR )
|
||||
{
|
||||
wxString errText;
|
||||
|
||||
errText.Printf( _("%s is a duplicate"), GetTokenString( aTok ).GetData() );
|
||||
THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
|
||||
}
|
||||
|
||||
void DSNLEXER::Unexpected( const wxString& text ) throw( IO_ERROR )
|
||||
{
|
||||
wxString errText( _("Unexpected") );
|
||||
errText << wxT(" '") << text << wxT("'");
|
||||
ThrowIOError( errText, CurOffset() );
|
||||
THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -408,7 +402,7 @@ L_read:
|
|||
case '"':
|
||||
break;
|
||||
default:
|
||||
ThrowIOError( errtxt, CurOffset() );
|
||||
THROW_PARSE_ERROR( errtxt, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
|
||||
}
|
||||
|
||||
curText = cc;
|
||||
|
@ -417,7 +411,7 @@ L_read:
|
|||
|
||||
if( head<limit && *head!=')' && *head!='(' && !isSpace(*head) )
|
||||
{
|
||||
ThrowIOError( errtxt, CurOffset() );
|
||||
THROW_PARSE_ERROR( errtxt, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
|
||||
}
|
||||
|
||||
curTok = DSN_QUOTE_DEF;
|
||||
|
@ -514,7 +508,7 @@ L_read:
|
|||
}
|
||||
|
||||
wxString errtxt(_("Un-terminated delimited string") );
|
||||
ThrowIOError( errtxt, CurOffset() );
|
||||
THROW_PARSE_ERROR( errtxt, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
|
||||
|
||||
#else // old code, did not understand nested quotes
|
||||
++cur; // skip over the leading delimiter: ",', or $
|
||||
|
@ -527,7 +521,7 @@ L_read:
|
|||
if( head >= limit )
|
||||
{
|
||||
wxString errtxt(_("Un-terminated delimited string") );
|
||||
ThrowIOError( errtxt, CurOffset() );
|
||||
THROW_PARSE_ERROR( errtxt, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
|
||||
}
|
||||
|
||||
curText.clear();
|
||||
|
|
|
@ -330,13 +330,6 @@ public:
|
|||
*/
|
||||
static bool IsSymbol( int aTok );
|
||||
|
||||
/**
|
||||
* Function ThrowIOError
|
||||
* encapsulates the formatting of an error message which contains the exact
|
||||
* location within the input file of something the caller is rejecting.
|
||||
*/
|
||||
void ThrowIOError( wxString aText, int charOffset ) throw( IO_ERROR );
|
||||
|
||||
/**
|
||||
* Function Expecting
|
||||
* throws an IO_ERROR exception with an input file specific error message.
|
||||
|
@ -363,6 +356,16 @@ public:
|
|||
*/
|
||||
void Unexpected( int aTok ) throw( IO_ERROR );
|
||||
|
||||
/**
|
||||
* Function Duplicate
|
||||
* throws an IO_ERROR exception with a message saying specifically that aTok
|
||||
* is a duplicate of one already seen in current context.
|
||||
* @param aTok is the token/keyword type which was not expected at the
|
||||
* current input location.
|
||||
* @throw IO_ERROR with the location within the input file of the problem.
|
||||
*/
|
||||
void Duplicate( int aTok ) throw( IO_ERROR );
|
||||
|
||||
/**
|
||||
* Function Unexpected
|
||||
* throws an IO_ERROR exception with an input file specific error message.
|
||||
|
@ -411,6 +414,16 @@ public:
|
|||
return curText.c_str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function FromUTF8
|
||||
* returns the current token text as a wxString, assuming that the input
|
||||
* byte stream is UTF8 encoded.
|
||||
*/
|
||||
wxString FromUTF8()
|
||||
{
|
||||
return wxString::FromUTF8( curText.c_str() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function CurLineNumber
|
||||
* returns the current line number within my LINE_READER
|
||||
|
@ -420,6 +433,16 @@ public:
|
|||
return reader->LineNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function CurLine
|
||||
* returns the current line of text, from which the CurText() would return
|
||||
* its token.
|
||||
*/
|
||||
const char* CurLine()
|
||||
{
|
||||
return (const char*)(*reader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function CurFilename
|
||||
* returns the current LINE_READER source.
|
||||
|
@ -433,7 +456,7 @@ public:
|
|||
|
||||
/**
|
||||
* Function CurOffset
|
||||
* returns the char offset within the current line, using a 1 based index.
|
||||
* returns the byte offset within the current line, using a 1 based index.
|
||||
* @return int - a one based index into the current line.
|
||||
*/
|
||||
int CurOffset()
|
||||
|
|
|
@ -46,8 +46,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#define IO_FORMAT _( "IO_ERROR: '%s'\n from %s : %s" )
|
||||
#define PARSE_FORMAT _( "PARSE_ERROR: '%s' in input/source '%s', line %d, offset %d\n from %s : %s" )
|
||||
#define IO_FORMAT _( "IO_ERROR: %s\n from %s : %s" )
|
||||
#define PARSE_FORMAT _( "PARSE_ERROR: %s in input/source \"%s\", line %d, offset %d\n from %s : %s" )
|
||||
|
||||
// references:
|
||||
// http://stackoverflow.com/questions/2670816/how-can-i-use-the-compile-time-constant-line-in-a-string
|
||||
|
@ -123,12 +123,11 @@ struct IO_ERROR // : std::exception
|
|||
};
|
||||
|
||||
|
||||
#define THROW_PARSE_ERROR( msg, input, line, offset ) throw PARSE_ERROR( __FILE__, __LOC__, msg, input, line, offset )
|
||||
|
||||
/**
|
||||
* Class PARSE_ERROR
|
||||
* contains a filename or source description, a line number, a character offset,
|
||||
* and an error message.
|
||||
* contains a filename or source description, a problem input line, a line number,
|
||||
* a byte offset, and an error message which contains the the caller's report and his
|
||||
* call site information: CPP source file, function, and line number.
|
||||
* @author Dick Hollenbeck
|
||||
*/
|
||||
struct PARSE_ERROR : public IO_ERROR
|
||||
|
@ -138,24 +137,36 @@ struct PARSE_ERROR : public IO_ERROR
|
|||
int lineNumber; ///< at which line number, 1 based index.
|
||||
int byteIndex; ///< at which character position within the line, 1 based index
|
||||
|
||||
/// problem line of input [say, from a LINE_READER].
|
||||
/// this is brought up in original byte format rather than wxString form, incase
|
||||
/// there was a problem with the encoding, in which case converting to wxString is
|
||||
/// not reliable in this context.
|
||||
std::string inputLine;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* which is normally called via the macro THROW_PARSE_ERROR so that
|
||||
* __FILE__ and __LOC__ can be captured from the call site.
|
||||
*/
|
||||
PARSE_ERROR( const char* aThrowersFile, const char* aThrowersLoc,
|
||||
const wxString& aMsg, const wxString& aSource,
|
||||
const char* aInputLine,
|
||||
int aLineNumber, int aByteIndex ) :
|
||||
IO_ERROR()
|
||||
{
|
||||
init( aThrowersFile, aThrowersLoc, aMsg, aSource, aLineNumber, aByteIndex );
|
||||
init( aThrowersFile, aThrowersLoc, aMsg, aSource, aInputLine, aLineNumber, aByteIndex );
|
||||
}
|
||||
|
||||
void init( const char* aThrowersFile, const char* aThrowersLoc,
|
||||
const wxString& aMsg, const wxString& aSource,
|
||||
const char* aInputLine,
|
||||
int aLineNumber, int aByteIndex )
|
||||
{
|
||||
// save line and offset in binary for Sweet text editor, which will catch exceptions
|
||||
// save inpuLine, lineNumber, and offset for UI (.e.g. Sweet text editor)
|
||||
inputLine = aInputLine;
|
||||
lineNumber = aLineNumber;
|
||||
byteIndex = aByteIndex;
|
||||
|
||||
// #define PARSE_FORMAT _( "PARSE_ERROR: %s in source %s, line %d, offset %d\nfrom cpp:%s func:%s" )
|
||||
|
||||
errorText.Printf( PARSE_FORMAT, aMsg.GetData(), aSource.GetData(),
|
||||
aLineNumber, aByteIndex,
|
||||
wxString::FromUTF8( aThrowersFile ).GetData(),
|
||||
|
@ -165,6 +176,11 @@ struct PARSE_ERROR : public IO_ERROR
|
|||
~PARSE_ERROR() throw ( /*none*/ ){}
|
||||
};
|
||||
|
||||
|
||||
#define THROW_PARSE_ERROR( aMsg, aSource, aInputLine, aLineNumber, aByteIndex ) \
|
||||
throw PARSE_ERROR( __FILE__, __LOC__, aMsg, aSource, aInputLine, aLineNumber, aByteIndex )
|
||||
|
||||
|
||||
/** @} exception_types */
|
||||
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@ for C in ${CATEGORIES}; do
|
|||
|
||||
for P in ${PARTS}; do
|
||||
for R in ${REVS}; do
|
||||
echo "#$R: (part $C/$P)" > $BASEDIR/$C/$P.part.$R
|
||||
(part $C/$P/$R extends $P/$R (value 22)(footprint SM0805)) > $BASEDIR/$C/$P.part.$R
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
|
|
|
@ -413,6 +413,12 @@ int main( int argc, char** argv )
|
|||
|
||||
lib_table.Test();
|
||||
}
|
||||
catch( PARSE_ERROR& ioe ) // most derived class first
|
||||
{
|
||||
printf( "%s\n", (const char*) ioe.errorText.ToUTF8() );
|
||||
printf( "%s", ioe.inputLine.c_str() ); // rare not to have \n at end
|
||||
printf( "%*s^\n", ioe.byteIndex-1, " " );
|
||||
}
|
||||
catch( IO_ERROR& ioe )
|
||||
{
|
||||
printf( "%s\n", (const char*) ioe.errorText.ToUTF8() );
|
||||
|
|
|
@ -187,6 +187,7 @@ LPID::LPID( const STRING& aLPID ) throw( PARSE_ERROR )
|
|||
THROW_PARSE_ERROR(
|
||||
_( "Illegal character found in LPID string" ),
|
||||
wxConvertMB2WX( aLPID.c_str() ),
|
||||
aLPID.c_str(),
|
||||
0,
|
||||
offset
|
||||
);
|
||||
|
|
|
@ -59,7 +59,7 @@ class LPID // aka GUID
|
|||
{
|
||||
public:
|
||||
|
||||
LPID();
|
||||
LPID() {}
|
||||
|
||||
/**
|
||||
* Constructor LPID
|
||||
|
|
247
new/sch_part.cpp
247
new/sch_part.cpp
|
@ -21,21 +21,258 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <wx/wx.h> // _()
|
||||
|
||||
#include <sch_part.h>
|
||||
#include <sweet_lexer.h>
|
||||
#include <wx/wx.h> // _()
|
||||
|
||||
#include <sch_lpid.h>
|
||||
#include <sch_lib_table.h>
|
||||
|
||||
using namespace SCH;
|
||||
|
||||
|
||||
void PART::Parse( SWEET_LEXER* aLexer, LIB_TABLE* aTable ) throw( PARSE_ERROR )
|
||||
{
|
||||
// Wayne's world, if he still wants it.
|
||||
//-----<temporary home for PART sub objects, move after stable>------------------
|
||||
|
||||
|
||||
|
||||
//-----</temporary home for PART sub objects, move after stable>-----------------
|
||||
|
||||
|
||||
/**
|
||||
* Class PART_PARSER
|
||||
* is a localized/hidden PART Parser. You get here through the public interface
|
||||
* PART::Parse(). Advantages of private class declaration in this situation:
|
||||
* 1) keeps all the recursive parsing helper functions out of the main public PART
|
||||
* header file and so should speed up compilation.
|
||||
* 2) Allows use of cost-less Java like inline functions, since nobody knows about
|
||||
* them but this source file. Most are only used once and called from one place.
|
||||
* <p>
|
||||
* All the functions in this class throw PARSE_ERROR. If SWEET_LEXER throws, it
|
||||
* may be an IO_ERROR, propogated from here also. The throws() statements are left off
|
||||
* to keep the noise level down.
|
||||
*/
|
||||
class PART_PARSER
|
||||
{
|
||||
SWEET_LEXER* in;
|
||||
LIB_TABLE* libs;
|
||||
int contains;
|
||||
|
||||
public:
|
||||
PART_PARSER( PART* aPart, SWEET_LEXER* aLexer, LIB_TABLE* aTable ) :
|
||||
in( aLexer ),
|
||||
libs( aTable ),
|
||||
contains( 0 )
|
||||
{
|
||||
parsePart( aPart );
|
||||
}
|
||||
|
||||
/// @param me = ja mir, the object getting stuffed, from its perspective
|
||||
void parsePart( PART* me )
|
||||
{
|
||||
PART_T tok;
|
||||
|
||||
if( (tok = in->NextTok()) == T_LEFT )
|
||||
tok = in->NextTok();
|
||||
|
||||
// a token "( part .." i.e. class PART
|
||||
// Be flexible regarding the starting point of the stream.
|
||||
// Caller may not have read the first two tokens out of the
|
||||
// stream: T_LEFT and T_part, so ignore them if seen here.
|
||||
// The 1st two tokens T_LEFT and T_part are then optional in the grammar.
|
||||
if( tok == T_part )
|
||||
{
|
||||
in->NeedSYMBOLorNUMBER(); // read in part NAME_HINT, and toss
|
||||
tok = in->NextTok();
|
||||
}
|
||||
|
||||
// extends must be _first_ thing, if it is present at all, after NAME_HINT
|
||||
if( tok == T_extends )
|
||||
{
|
||||
PART* base;
|
||||
int offset;
|
||||
|
||||
if( contains & PB(EXTENDS) )
|
||||
in->Duplicate( tok );
|
||||
in->NeedSYMBOLorNUMBER();
|
||||
me->setExtends( new LPID() );
|
||||
offset = me->extends->Parse( in->CurText() );
|
||||
if( offset > -1 ) // -1 is success
|
||||
THROW_PARSE_ERROR( _("invalid extends LPID"),
|
||||
in->CurSource(),
|
||||
in->CurLine(),
|
||||
in->CurLineNumber(),
|
||||
in->CurOffset() + offset );
|
||||
// we could be going in circles here, recursively, @todo add a max counter or stack chain
|
||||
base = libs->LookupPart( *me->extends, me->Owner() );
|
||||
me->inherit( *base );
|
||||
contains |= PB(EXTENDS);
|
||||
tok = in->NextTok();
|
||||
}
|
||||
|
||||
for( ; tok!=T_RIGHT && tok!=T_EOF; tok = in->NextTok() )
|
||||
{
|
||||
if( tok == T_LEFT )
|
||||
tok = in->NextTok();
|
||||
|
||||
switch( tok )
|
||||
{
|
||||
default:
|
||||
// describe what we expect at this level
|
||||
in->Expecting( wxT(
|
||||
"anchor|value|footprint|model|keywords|alternates\n"
|
||||
"|property\n"
|
||||
" |property_del\n"
|
||||
"|pin\n"
|
||||
" |pin_merge|pin_swap|pin_renum|pin_rename|route_pin_swap\n"
|
||||
"|polyline|line|rectangle|circle|arc|bezier|text"
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case T_anchor:
|
||||
if( contains & PB(ANCHOR) )
|
||||
in->Duplicate( tok );
|
||||
contains |= PB(ANCHOR);
|
||||
break;
|
||||
|
||||
/*
|
||||
case T_value:
|
||||
if( contains & PB(VALUE) )
|
||||
in->Duplicate( tok );
|
||||
contains |= PB(VALUE);
|
||||
in->NeedSYMBOLorNUMBER();
|
||||
// me->value = in->CurText();
|
||||
in->NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_footprint:
|
||||
break;
|
||||
|
||||
case T_model:
|
||||
break;
|
||||
|
||||
case T_keywords:
|
||||
break;
|
||||
|
||||
case T_alternates:
|
||||
break;
|
||||
|
||||
case T_property:
|
||||
break;
|
||||
|
||||
case T_property_del:
|
||||
break;
|
||||
|
||||
case T_pin:
|
||||
break;
|
||||
|
||||
case T_pin_merge:
|
||||
break;
|
||||
|
||||
case T_pin_swap:
|
||||
break;
|
||||
|
||||
case T_pin_renum:
|
||||
break;
|
||||
|
||||
case T_pin_rename:
|
||||
break;
|
||||
|
||||
case T_route_pin_swap:
|
||||
break;
|
||||
|
||||
case T_polyline:
|
||||
break;
|
||||
|
||||
case T_line:
|
||||
break;
|
||||
|
||||
case T_rectangle:
|
||||
break;
|
||||
|
||||
case T_circle:
|
||||
break;
|
||||
|
||||
case T_arc:
|
||||
break;
|
||||
|
||||
case T_bezier:
|
||||
break;
|
||||
|
||||
case T_text:
|
||||
break;
|
||||
*/
|
||||
|
||||
// Not sure about reference in a PART, comes in at COMPONENT object.
|
||||
// It is maybe just a hint here or a prefix.
|
||||
case T_reference:
|
||||
if( contains & PB(REFERENCE) )
|
||||
in->Duplicate( tok );
|
||||
contains |= PB(REFERENCE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void parseAt( PART* me )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
PART::PART( LIB* aOwner, const STRING& aPartName, const STRING& aRevision ) :
|
||||
owner( aOwner ),
|
||||
contains( 0 ),
|
||||
partName( aPartName ),
|
||||
revision( aRevision ),
|
||||
extends( 0 )
|
||||
{}
|
||||
|
||||
|
||||
PART::~PART()
|
||||
{
|
||||
delete extends;
|
||||
}
|
||||
|
||||
|
||||
void PART::setExtends( LPID* aLPID )
|
||||
{
|
||||
delete extends;
|
||||
extends = aLPID;
|
||||
}
|
||||
|
||||
|
||||
void PART::inherit( const PART& other )
|
||||
{
|
||||
contains = other.contains;
|
||||
|
||||
setExtends( other.extends ? new LPID( *other.extends ) : 0 );
|
||||
|
||||
body = other.body;
|
||||
}
|
||||
|
||||
|
||||
PART& PART::operator=( const PART& other )
|
||||
{
|
||||
owner = other.owner;
|
||||
partName = other.partName;
|
||||
revision = other.revision;
|
||||
|
||||
// maintain inherit() as a partial assignment operator.
|
||||
inherit( other );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void PART::Parse( SWEET_LEXER* aLexer, LIB_TABLE* aTable ) throw( IO_ERROR )
|
||||
{
|
||||
PART_PARSER( this, aLexer, aTable );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#if 0 && defined(DEBUG)
|
||||
|
||||
|
|
|
@ -28,9 +28,13 @@
|
|||
#include <sch_lib.h>
|
||||
|
||||
class SWEET_LEXER;
|
||||
class PART_PARSER;
|
||||
|
||||
|
||||
namespace SCH {
|
||||
|
||||
class LPID;
|
||||
|
||||
/**
|
||||
* Enum PartBit
|
||||
* is a set of bit positions that can be used to create flag bits within
|
||||
|
@ -39,9 +43,16 @@ namespace SCH {
|
|||
*/
|
||||
enum PartBit
|
||||
{
|
||||
BODY, ///< body has been read in.
|
||||
PARSED, ///< have parsed this part already, otherwise 'body' text must be parsed
|
||||
EXTENDS, ///< saw and "extends" keyword, inheriting from another PART
|
||||
|
||||
VALUE,
|
||||
ANCHOR,
|
||||
REFERENCE,
|
||||
FOOTPRINT,
|
||||
DATASHEET,
|
||||
MODEL,
|
||||
KEYWORDS,
|
||||
};
|
||||
|
||||
/// Function PB
|
||||
|
@ -63,34 +74,40 @@ static inline const int PB( PartBit oneBitOnly )
|
|||
*/
|
||||
class PART
|
||||
{
|
||||
/// LIB class has great license to modify what's in here, nobody else does.
|
||||
/// Modification is done through the LIB so it can track the state of the
|
||||
/// PART and take action as needed. Actually most of the modification will
|
||||
/// be done by PARTS_LIST, a class derived from LIB.
|
||||
friend class LIB;
|
||||
|
||||
/// a private constructor, only a LIB can instantiate a PART.
|
||||
PART( LIB* aOwner, const STRING& aPartName, const STRING& aRevision ) :
|
||||
owner( aOwner ),
|
||||
contains( 0 ),
|
||||
partName( aPartName ),
|
||||
revision( aRevision )
|
||||
{}
|
||||
friend class LIB; // is the owner of all PARTS, afterall
|
||||
friend class ::PART_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& aPartName, const STRING& aRevision );
|
||||
|
||||
/**
|
||||
* 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 );
|
||||
|
||||
|
||||
//PART( LIB* aOwner );
|
||||
|
||||
LIB* owner; ///< which LIB am I a part of (pun if you want)
|
||||
int contains; ///< has bits from Enum PartParts
|
||||
|
||||
STRING extends; ///< LPID of base part
|
||||
|
||||
STRING partName; ///< example "passives/R", immutable.
|
||||
STRING revision; // @todo need a single search key, this won't do.
|
||||
|
||||
LPID* extends; ///< of base part, NULL if none, otherwise I own it.
|
||||
|
||||
/// 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;
|
||||
|
||||
|
||||
// 3 separate lists for speed:
|
||||
|
||||
/// A property list.
|
||||
|
@ -105,16 +122,13 @@ protected: // not likely to have C++ descendants, but protected none-the-le
|
|||
/// Alternate body forms.
|
||||
//ALTERNATES alternates;
|
||||
|
||||
// lots of other stuff, like the mandatory properties.
|
||||
// lots of other stuff, like the mandatory properties, but no units, since we went with dimensionless
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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 );
|
||||
~PART();
|
||||
|
||||
PART& operator=( const PART& other );
|
||||
|
||||
/**
|
||||
* Function Owner
|
||||
|
@ -122,6 +136,7 @@ public:
|
|||
*/
|
||||
LIB* Owner() { return owner; }
|
||||
|
||||
|
||||
/**
|
||||
* Function Parse
|
||||
* translates a Sweet string into a binary form that is represented
|
||||
|
@ -133,7 +148,7 @@ public:
|
|||
* @param aLibTable is the LIB_TABLE view that is in effect for inheritance,
|
||||
* and comes from the big containing SCHEMATIC object.
|
||||
*/
|
||||
void Parse( SWEET_LEXER* aLexer, LIB_TABLE* aTable ) throw( PARSE_ERROR );
|
||||
void Parse( SWEET_LEXER* aLexer, LIB_TABLE* aTable ) throw( IO_ERROR );
|
||||
|
||||
/*
|
||||
void SetBody( const STR_UTF& aSExpression )
|
||||
|
|
|
@ -25,6 +25,7 @@ keywords
|
|||
length
|
||||
line
|
||||
line_width
|
||||
model
|
||||
name
|
||||
none
|
||||
number
|
||||
|
@ -38,6 +39,7 @@ pin_del
|
|||
pin_merge
|
||||
pin_rename
|
||||
pin_renum
|
||||
pin_swap
|
||||
polyline
|
||||
pos
|
||||
power_in
|
||||
|
@ -58,5 +60,6 @@ tristate
|
|||
unconnected
|
||||
units
|
||||
unspecified
|
||||
value
|
||||
visible
|
||||
xy
|
||||
|
|
|
@ -111,7 +111,7 @@ void WinEDA_PcbFrame::ExportToSpecctra( wxCommandEvent& event )
|
|||
// if an exception is thrown by FromBOARD or ExportPCB(), then
|
||||
// ~SPECCTRA_DB() will close the file.
|
||||
}
|
||||
catch( IO_ERROR ioe )
|
||||
catch( IO_ERROR& ioe )
|
||||
{
|
||||
ok = false;
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event )
|
|||
db.LoadSESSION( fullFileName );
|
||||
db.FromSESSION( GetBoard() );
|
||||
}
|
||||
catch( IO_ERROR ioe )
|
||||
catch( IO_ERROR& ioe )
|
||||
{
|
||||
SetLocaleTo_Default( ); // revert to the current locale
|
||||
|
||||
|
|
Loading…
Reference in New Issue