++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
|
Please add newer entries at the top, list the date and your name with
|
||||||
email address.
|
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>
|
2010-dec-31 UPDATE Wayne Stambaugh <stambaughw@verizon.net>
|
||||||
================================================================================
|
================================================================================
|
||||||
++all
|
++all
|
||||||
|
|
|
@ -231,7 +231,7 @@ wxString DSNLEXER::GetTokenString( int aTok )
|
||||||
{
|
{
|
||||||
wxString ret;
|
wxString ret;
|
||||||
|
|
||||||
ret << wxT("'") << wxConvertMB2WX( GetTokenText(aTok) ) << wxT("'");
|
ret << wxT("'") << wxString::FromUTF8( GetTokenText(aTok) ) << wxT("'");
|
||||||
|
|
||||||
return ret;
|
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 )
|
void DSNLEXER::Expecting( int aTok ) throw( IO_ERROR )
|
||||||
{
|
{
|
||||||
wxString errText( _("Expecting") );
|
wxString errText( _("Expecting") );
|
||||||
errText << wxT(" ") << GetTokenString( aTok );
|
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") );
|
wxString errText( _("Expecting") );
|
||||||
errText << wxT(" '") << text << wxT("'");
|
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") );
|
wxString errText( _("Unexpected") );
|
||||||
errText << wxT(" ") << GetTokenString( aTok );
|
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 )
|
void DSNLEXER::Unexpected( const wxString& text ) throw( IO_ERROR )
|
||||||
{
|
{
|
||||||
wxString errText( _("Unexpected") );
|
wxString errText( _("Unexpected") );
|
||||||
errText << wxT(" '") << text << wxT("'");
|
errText << wxT(" '") << text << wxT("'");
|
||||||
ThrowIOError( errText, CurOffset() );
|
THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -408,7 +402,7 @@ L_read:
|
||||||
case '"':
|
case '"':
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ThrowIOError( errtxt, CurOffset() );
|
THROW_PARSE_ERROR( errtxt, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
|
||||||
}
|
}
|
||||||
|
|
||||||
curText = cc;
|
curText = cc;
|
||||||
|
@ -417,7 +411,7 @@ L_read:
|
||||||
|
|
||||||
if( head<limit && *head!=')' && *head!='(' && !isSpace(*head) )
|
if( head<limit && *head!=')' && *head!='(' && !isSpace(*head) )
|
||||||
{
|
{
|
||||||
ThrowIOError( errtxt, CurOffset() );
|
THROW_PARSE_ERROR( errtxt, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
|
||||||
}
|
}
|
||||||
|
|
||||||
curTok = DSN_QUOTE_DEF;
|
curTok = DSN_QUOTE_DEF;
|
||||||
|
@ -514,7 +508,7 @@ L_read:
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString errtxt(_("Un-terminated delimited string") );
|
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
|
#else // old code, did not understand nested quotes
|
||||||
++cur; // skip over the leading delimiter: ",', or $
|
++cur; // skip over the leading delimiter: ",', or $
|
||||||
|
@ -527,7 +521,7 @@ L_read:
|
||||||
if( head >= limit )
|
if( head >= limit )
|
||||||
{
|
{
|
||||||
wxString errtxt(_("Un-terminated delimited string") );
|
wxString errtxt(_("Un-terminated delimited string") );
|
||||||
ThrowIOError( errtxt, CurOffset() );
|
THROW_PARSE_ERROR( errtxt, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
|
||||||
}
|
}
|
||||||
|
|
||||||
curText.clear();
|
curText.clear();
|
||||||
|
|
|
@ -330,13 +330,6 @@ public:
|
||||||
*/
|
*/
|
||||||
static bool IsSymbol( int aTok );
|
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
|
* Function Expecting
|
||||||
* throws an IO_ERROR exception with an input file specific error message.
|
* throws an IO_ERROR exception with an input file specific error message.
|
||||||
|
@ -363,6 +356,16 @@ public:
|
||||||
*/
|
*/
|
||||||
void Unexpected( int aTok ) throw( IO_ERROR );
|
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
|
* Function Unexpected
|
||||||
* throws an IO_ERROR exception with an input file specific error message.
|
* throws an IO_ERROR exception with an input file specific error message.
|
||||||
|
@ -411,6 +414,16 @@ public:
|
||||||
return curText.c_str();
|
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
|
* Function CurLineNumber
|
||||||
* returns the current line number within my LINE_READER
|
* returns the current line number within my LINE_READER
|
||||||
|
@ -420,6 +433,16 @@ public:
|
||||||
return reader->LineNumber();
|
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
|
* Function CurFilename
|
||||||
* returns the current LINE_READER source.
|
* returns the current LINE_READER source.
|
||||||
|
@ -433,7 +456,7 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function CurOffset
|
* 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.
|
* @return int - a one based index into the current line.
|
||||||
*/
|
*/
|
||||||
int CurOffset()
|
int CurOffset()
|
||||||
|
|
|
@ -46,8 +46,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define IO_FORMAT _( "IO_ERROR: '%s'\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" )
|
#define PARSE_FORMAT _( "PARSE_ERROR: %s in input/source \"%s\", line %d, offset %d\n from %s : %s" )
|
||||||
|
|
||||||
// references:
|
// references:
|
||||||
// http://stackoverflow.com/questions/2670816/how-can-i-use-the-compile-time-constant-line-in-a-string
|
// http://stackoverflow.com/questions/2670816/how-can-i-use-the-compile-time-constant-line-in-a-string
|
||||||
|
@ -123,39 +123,50 @@ 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
|
* Class PARSE_ERROR
|
||||||
* contains a filename or source description, a line number, a character offset,
|
* contains a filename or source description, a problem input line, a line number,
|
||||||
* and an error message.
|
* 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
|
* @author Dick Hollenbeck
|
||||||
*/
|
*/
|
||||||
struct PARSE_ERROR : public IO_ERROR
|
struct PARSE_ERROR : public IO_ERROR
|
||||||
{
|
{
|
||||||
// wxString errorText is still public from IO_ERROR
|
// wxString errorText is still public from IO_ERROR
|
||||||
|
|
||||||
int lineNumber; ///< at which line number, 1 based index.
|
int lineNumber; ///< at which line number, 1 based index.
|
||||||
int byteIndex; ///< at which character position within the line, 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,
|
PARSE_ERROR( const char* aThrowersFile, const char* aThrowersLoc,
|
||||||
const wxString& aMsg, const wxString& aSource,
|
const wxString& aMsg, const wxString& aSource,
|
||||||
|
const char* aInputLine,
|
||||||
int aLineNumber, int aByteIndex ) :
|
int aLineNumber, int aByteIndex ) :
|
||||||
IO_ERROR()
|
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,
|
void init( const char* aThrowersFile, const char* aThrowersLoc,
|
||||||
const wxString& aMsg, const wxString& aSource,
|
const wxString& aMsg, const wxString& aSource,
|
||||||
|
const char* aInputLine,
|
||||||
int aLineNumber, int aByteIndex )
|
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;
|
lineNumber = aLineNumber;
|
||||||
byteIndex = aByteIndex;
|
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(),
|
errorText.Printf( PARSE_FORMAT, aMsg.GetData(), aSource.GetData(),
|
||||||
aLineNumber, aByteIndex,
|
aLineNumber, aByteIndex,
|
||||||
wxString::FromUTF8( aThrowersFile ).GetData(),
|
wxString::FromUTF8( aThrowersFile ).GetData(),
|
||||||
|
@ -165,6 +176,11 @@ struct PARSE_ERROR : public IO_ERROR
|
||||||
~PARSE_ERROR() throw ( /*none*/ ){}
|
~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 */
|
/** @} exception_types */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,7 @@ for C in ${CATEGORIES}; do
|
||||||
|
|
||||||
for P in ${PARTS}; do
|
for P in ${PARTS}; do
|
||||||
for R in ${REVS}; 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
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
@ -413,6 +413,12 @@ int main( int argc, char** argv )
|
||||||
|
|
||||||
lib_table.Test();
|
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 )
|
catch( IO_ERROR& ioe )
|
||||||
{
|
{
|
||||||
printf( "%s\n", (const char*) ioe.errorText.ToUTF8() );
|
printf( "%s\n", (const char*) ioe.errorText.ToUTF8() );
|
||||||
|
|
|
@ -187,6 +187,7 @@ LPID::LPID( const STRING& aLPID ) throw( PARSE_ERROR )
|
||||||
THROW_PARSE_ERROR(
|
THROW_PARSE_ERROR(
|
||||||
_( "Illegal character found in LPID string" ),
|
_( "Illegal character found in LPID string" ),
|
||||||
wxConvertMB2WX( aLPID.c_str() ),
|
wxConvertMB2WX( aLPID.c_str() ),
|
||||||
|
aLPID.c_str(),
|
||||||
0,
|
0,
|
||||||
offset
|
offset
|
||||||
);
|
);
|
||||||
|
|
|
@ -59,7 +59,7 @@ class LPID // aka GUID
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LPID();
|
LPID() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor LPID
|
* Constructor LPID
|
||||||
|
|
247
new/sch_part.cpp
247
new/sch_part.cpp
|
@ -21,22 +21,259 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <wx/wx.h> // _()
|
||||||
|
|
||||||
#include <sch_part.h>
|
#include <sch_part.h>
|
||||||
#include <sweet_lexer.h>
|
#include <sweet_lexer.h>
|
||||||
#include <wx/wx.h> // _()
|
#include <sch_lpid.h>
|
||||||
|
#include <sch_lib_table.h>
|
||||||
|
|
||||||
using namespace SCH;
|
using namespace SCH;
|
||||||
|
|
||||||
|
|
||||||
void PART::Parse( SWEET_LEXER* aLexer, LIB_TABLE* aTable ) throw( PARSE_ERROR )
|
//-----<temporary home for PART sub objects, move after stable>------------------
|
||||||
{
|
|
||||||
// Wayne's world, if he still wants it.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-----</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)
|
#if 0 && defined(DEBUG)
|
||||||
|
|
||||||
int main( int argc, char** argv )
|
int main( int argc, char** argv )
|
||||||
|
|
|
@ -28,9 +28,13 @@
|
||||||
#include <sch_lib.h>
|
#include <sch_lib.h>
|
||||||
|
|
||||||
class SWEET_LEXER;
|
class SWEET_LEXER;
|
||||||
|
class PART_PARSER;
|
||||||
|
|
||||||
|
|
||||||
namespace SCH {
|
namespace SCH {
|
||||||
|
|
||||||
|
class LPID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum PartBit
|
* Enum PartBit
|
||||||
* is a set of bit positions that can be used to create flag bits within
|
* is a set of bit positions that can be used to create flag bits within
|
||||||
|
@ -39,9 +43,16 @@ namespace SCH {
|
||||||
*/
|
*/
|
||||||
enum PartBit
|
enum PartBit
|
||||||
{
|
{
|
||||||
|
BODY, ///< body has been read in.
|
||||||
PARSED, ///< have parsed this part already, otherwise 'body' text must be parsed
|
PARSED, ///< have parsed this part already, otherwise 'body' text must be parsed
|
||||||
EXTENDS, ///< saw and "extends" keyword, inheriting from another PART
|
EXTENDS, ///< saw and "extends" keyword, inheriting from another PART
|
||||||
|
VALUE,
|
||||||
|
ANCHOR,
|
||||||
|
REFERENCE,
|
||||||
|
FOOTPRINT,
|
||||||
|
DATASHEET,
|
||||||
|
MODEL,
|
||||||
|
KEYWORDS,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Function PB
|
/// Function PB
|
||||||
|
@ -63,34 +74,40 @@ static inline const int PB( PartBit oneBitOnly )
|
||||||
*/
|
*/
|
||||||
class PART
|
class PART
|
||||||
{
|
{
|
||||||
/// LIB class has great license to modify what's in here, nobody else does.
|
friend class LIB; // is the owner of all PARTS, afterall
|
||||||
/// Modification is done through the LIB so it can track the state of the
|
friend class ::PART_PARSER;
|
||||||
/// 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 )
|
|
||||||
{}
|
|
||||||
|
|
||||||
protected: // not likely to have C++ descendants, but protected none-the-less.
|
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)
|
LIB* owner; ///< which LIB am I a part of (pun if you want)
|
||||||
int contains; ///< has bits from Enum PartParts
|
int contains; ///< has bits from Enum PartParts
|
||||||
|
|
||||||
STRING extends; ///< LPID of base part
|
|
||||||
|
|
||||||
STRING partName; ///< example "passives/R", immutable.
|
STRING partName; ///< example "passives/R", immutable.
|
||||||
STRING revision; // @todo need a single search key, this won't do.
|
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
|
/// s-expression text for the part, initially empty, and read in as this part
|
||||||
/// actually becomes cached in RAM.
|
/// actually becomes cached in RAM.
|
||||||
STRING body;
|
STRING body;
|
||||||
|
|
||||||
|
|
||||||
// 3 separate lists for speed:
|
// 3 separate lists for speed:
|
||||||
|
|
||||||
/// A property list.
|
/// A property list.
|
||||||
|
@ -105,16 +122,13 @@ protected: // not likely to have C++ descendants, but protected none-the-le
|
||||||
/// Alternate body forms.
|
/// Alternate body forms.
|
||||||
//ALTERNATES alternates;
|
//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:
|
public:
|
||||||
|
|
||||||
/**
|
~PART();
|
||||||
* Function Inherit
|
|
||||||
* is a specialized assignment function that copies a specific subset, enough
|
PART& operator=( const PART& other );
|
||||||
* to fulfill the requirements of the Sweet s-expression language.
|
|
||||||
*/
|
|
||||||
void Inherit( const PART& aBasePart );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Owner
|
* Function Owner
|
||||||
|
@ -122,6 +136,7 @@ public:
|
||||||
*/
|
*/
|
||||||
LIB* Owner() { return owner; }
|
LIB* Owner() { return owner; }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Parse
|
* Function Parse
|
||||||
* translates a Sweet string into a binary form that is represented
|
* 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,
|
* @param aLibTable is the LIB_TABLE view that is in effect for inheritance,
|
||||||
* and comes from the big containing SCHEMATIC object.
|
* 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 )
|
void SetBody( const STR_UTF& aSExpression )
|
||||||
|
|
|
@ -25,6 +25,7 @@ keywords
|
||||||
length
|
length
|
||||||
line
|
line
|
||||||
line_width
|
line_width
|
||||||
|
model
|
||||||
name
|
name
|
||||||
none
|
none
|
||||||
number
|
number
|
||||||
|
@ -38,6 +39,7 @@ pin_del
|
||||||
pin_merge
|
pin_merge
|
||||||
pin_rename
|
pin_rename
|
||||||
pin_renum
|
pin_renum
|
||||||
|
pin_swap
|
||||||
polyline
|
polyline
|
||||||
pos
|
pos
|
||||||
power_in
|
power_in
|
||||||
|
@ -58,5 +60,6 @@ tristate
|
||||||
unconnected
|
unconnected
|
||||||
units
|
units
|
||||||
unspecified
|
unspecified
|
||||||
|
value
|
||||||
visible
|
visible
|
||||||
xy
|
xy
|
||||||
|
|
|
@ -111,7 +111,7 @@ void WinEDA_PcbFrame::ExportToSpecctra( wxCommandEvent& event )
|
||||||
// if an exception is thrown by FromBOARD or ExportPCB(), then
|
// if an exception is thrown by FromBOARD or ExportPCB(), then
|
||||||
// ~SPECCTRA_DB() will close the file.
|
// ~SPECCTRA_DB() will close the file.
|
||||||
}
|
}
|
||||||
catch( IO_ERROR ioe )
|
catch( IO_ERROR& ioe )
|
||||||
{
|
{
|
||||||
ok = false;
|
ok = false;
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event )
|
||||||
db.LoadSESSION( fullFileName );
|
db.LoadSESSION( fullFileName );
|
||||||
db.FromSESSION( GetBoard() );
|
db.FromSESSION( GetBoard() );
|
||||||
}
|
}
|
||||||
catch( IO_ERROR ioe )
|
catch( IO_ERROR& ioe )
|
||||||
{
|
{
|
||||||
SetLocaleTo_Default( ); // revert to the current locale
|
SetLocaleTo_Default( ); // revert to the current locale
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue