Commit bdbd28a9 authored by Dick Hollenbeck's avatar Dick Hollenbeck

complete initial version of LIB_TABLE::Parse()

parent 364132cb
...@@ -144,9 +144,6 @@ set( sourceFileHeader ...@@ -144,9 +144,6 @@ set( sourceFileHeader
* your DSN lexer. * your DSN lexer.
*/ */
//#include \"fctsys.h\"
//#include \"macros.h\"
#include \"${result}_lexer.h\" #include \"${result}_lexer.h\"
namespace DSN { namespace DSN {
...@@ -228,13 +225,13 @@ class ${RESULT}_LEXER : public DSNLEXER ...@@ -228,13 +225,13 @@ class ${RESULT}_LEXER : public DSNLEXER
public: public:
/** /**
* Constructor ${RESULT}_LEXER * Constructor ${RESULT}_LEXER
* @param aClipboartTxt is std::string (8 bit) text possibly from the * @param aSExpression is (utf8) text possibly from the clipboard that you want to parse.
* clipboard that you want to parse. * @param aSource is a description of the origin of @a aSExpression, such as a filename.
* If left empty, then _("clipboard") is used.
*/ */
${RESULT}_LEXER( const std::string& aClipboardTxt ) : ${RESULT}_LEXER( const std::string& aSExpression, const wxString& aSource = wxEmptyString ) :
DSNLEXER( aClipboardTxt, DSNLEXER( DSN::${result}_keywords, DSN::${result}_keyword_count,
DSN::${result}_keywords, aSExpression, aSource )
DSN::${result}_keyword_count )
{ {
} }
...@@ -248,9 +245,8 @@ public: ...@@ -248,9 +245,8 @@ public:
* @param aFilename is the name of the opened file, needed for error reporting. * @param aFilename is the name of the opened file, needed for error reporting.
*/ */
${RESULT}_LEXER( FILE* aFile, const wxString& aFilename ) : ${RESULT}_LEXER( FILE* aFile, const wxString& aFilename ) :
DSNLEXER( aFile, aFilename, DSNLEXER( DSN::${result}_keywords, DSN::${result}_keyword_count,
DSN::${result}_keywords, aFile, aFilename )
DSN::${result}_keyword_count )
{ {
} }
......
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
#include "dsnlexer.h" #include "dsnlexer.h"
#include "fctsys.h" //#include "fctsys.h"
#include "pcbnew.h" //#include "pcbnew.h"
//#define STANDALONE 1 // enable this for stand alone testing. //#define STANDALONE 1 // enable this for stand alone testing.
...@@ -60,8 +60,8 @@ void DSNLEXER::init() ...@@ -60,8 +60,8 @@ void DSNLEXER::init()
} }
DSNLEXER::DSNLEXER( FILE* aFile, const wxString& aFilename, DSNLEXER::DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount,
const KEYWORD* aKeywordTable, unsigned aKeywordCount ) : FILE* aFile, const wxString& aFilename ) :
keywords( aKeywordTable ), keywords( aKeywordTable ),
keywordCount( aKeywordCount ) keywordCount( aKeywordCount )
{ {
...@@ -71,12 +71,13 @@ DSNLEXER::DSNLEXER( FILE* aFile, const wxString& aFilename, ...@@ -71,12 +71,13 @@ DSNLEXER::DSNLEXER( FILE* aFile, const wxString& aFilename,
} }
DSNLEXER::DSNLEXER( const std::string& aClipboardTxt, DSNLEXER::DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount,
const KEYWORD* aKeywordTable, unsigned aKeywordCount ) : const std::string& aClipboardTxt, const wxString& aSource ) :
keywords( aKeywordTable ), keywords( aKeywordTable ),
keywordCount( aKeywordCount ) keywordCount( aKeywordCount )
{ {
STRING_LINE_READER* stringReader = new STRING_LINE_READER( aClipboardTxt, _( "clipboard" ) ); STRING_LINE_READER* stringReader = new STRING_LINE_READER( aClipboardTxt, aSource.IsEmpty() ?
wxString( _( "clipboard" ) ) : aSource );
PushReader( stringReader ); PushReader( stringReader );
init(); init();
} }
...@@ -206,7 +207,7 @@ wxString DSNLEXER::GetTokenString( int aTok ) ...@@ -206,7 +207,7 @@ wxString DSNLEXER::GetTokenString( int aTok )
{ {
wxString ret; wxString ret;
ret << wxT("'") << CONV_FROM_UTF8( GetTokenText(aTok) ) << wxT("'"); ret << wxT("'") << wxConvertMB2WX( GetTokenText(aTok) ) << wxT("'");
return ret; return ret;
} }
...@@ -300,6 +301,7 @@ int DSNLEXER::NeedSYMBOLorNUMBER() throw( IO_ERROR ) ...@@ -300,6 +301,7 @@ int DSNLEXER::NeedSYMBOLorNUMBER() throw( IO_ERROR )
return tok; return tok;
} }
/** /**
* Function isspace * Function isspace
* strips the upper bits of the int to ensure the value passed to ::isspace() is * strips the upper bits of the int to ensure the value passed to ::isspace() is
......
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#ifndef _DSNLEXER_H #ifndef DSNLEXER_H_
#define _DSNLEXER_H #define DSNLEXER_H_
#include <cstdio> #include <cstdio>
#include <string> #include <string>
...@@ -162,12 +162,14 @@ public: ...@@ -162,12 +162,14 @@ public:
* @param aKeywordTable is an array of KEYWORDS holding \a aKeywordCount. This * @param aKeywordTable is an array of KEYWORDS holding \a aKeywordCount. This
* token table need not contain the lexer separators such as '(' ')', etc. * token table need not contain the lexer separators such as '(' ')', etc.
* @param aKeywordTable is the count of tokens in aKeywordTable. * @param aKeywordTable is the count of tokens in aKeywordTable.
* @param aFile is an open file, which will be closed when this is destructed.
* @param aFileName is the name of the file
*/ */
DSNLEXER( FILE* aFile, const wxString& aFilename, DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount,
const KEYWORD* aKeywordTable, unsigned aKeywordCount ); FILE* aFile, const wxString& aFileName );
DSNLEXER( const std::string& aClipboardTxt, DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount,
const KEYWORD* aKeywordTable, unsigned aKeywordCount ); const std::string& aClipboardTxt, const wxString& aSource = wxEmptyString );
~DSNLEXER() ~DSNLEXER()
{ {
...@@ -418,4 +420,4 @@ public: ...@@ -418,4 +420,4 @@ public:
} }
}; };
#endif // _DSNLEXER_H #endif // DSNLEXER_H_
...@@ -196,7 +196,7 @@ public: ...@@ -196,7 +196,7 @@ public:
* The last line does not necessarily need a trailing '\n'. * The last line does not necessarily need a trailing '\n'.
* *
* @param aSource describes the source of aString for error reporting purposes * @param aSource describes the source of aString for error reporting purposes
* can be anything meaninful, such as wxT( "cliboard" ). * can be anything meaninful, such as wxT( "clipboard" ).
*/ */
STRING_LINE_READER( const std::string& aString, const wxString& aSource ) : STRING_LINE_READER( const std::string& aString, const wxString& aSource ) :
LINE_READER( LINE_READER_LINE_DEFAULT_MAX ), LINE_READER( LINE_READER_LINE_DEFAULT_MAX ),
......
...@@ -60,14 +60,22 @@ endif() ...@@ -60,14 +60,22 @@ endif()
include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ) include_directories( ${CMAKE_CURRENT_SOURCE_DIR} )
add_executable( test_dir_lib_source sch_dir_lib_source.cpp ) add_executable( test_dir_lib_source
sch_dir_lib_source.cpp
)
target_link_libraries( test_dir_lib_source ${wxWidgets_LIBRARIES} ) target_link_libraries( test_dir_lib_source ${wxWidgets_LIBRARIES} )
add_executable( test_lib_table sch_lib_table.cpp sch_lib_table_keywords.cpp ) add_executable( test_sch_lib_table
target_link_libraries( test_lib_table ${wxWidgets_LIBRARIES} ) sch_lib_table.cpp
sch_lib_table_keywords.cpp
sch_lib.cpp
${PROJECT_SOURCE_DIR}/common/richio.cpp
${PROJECT_SOURCE_DIR}/common/dsnlexer.cpp
)
target_link_libraries( test_sch_lib_table ${wxWidgets_LIBRARIES} )
add_executable( test_sch_part sch_part.cpp ) add_executable( test_sch_part sch_part.cpp )
target_link_libraries( test_lib_table ${wxWidgets_LIBRARIES} ) target_link_libraries( test_sch_part ${wxWidgets_LIBRARIES} )
make_lexer( make_lexer(
......
...@@ -151,14 +151,14 @@ public: ...@@ -151,14 +151,14 @@ public:
* tree, otherwise only a single version of each part is recognized, namely the * tree, otherwise only a single version of each part is recognized, namely the
* one without the ".revN[N..]" trailer. * one without the ".revN[N..]" trailer.
*/ */
DIR_LIB_SOURCE( const STRING& aDirectoryPath, const STRING& aOptions = StrEmpty ) DIR_LIB_SOURCE( const STRING& aDirectoryPath, const STRING& aOptions = "" )
throw( IO_ERROR ); throw( IO_ERROR );
~DIR_LIB_SOURCE(); ~DIR_LIB_SOURCE();
//-----<LIB_SOURCE implementation functions >------------------------------ //-----<LIB_SOURCE implementation functions >------------------------------
void ReadPart( STRING* aResult, const STRING& aPartName, const STRING& aRev = StrEmpty ) void ReadPart( STRING* aResult, const STRING& aPartName, const STRING& aRev = "" )
throw( IO_ERROR ); throw( IO_ERROR );
void ReadParts( STRINGS* aResults, const STRINGS& aPartNames ) void ReadParts( STRINGS* aResults, const STRINGS& aPartNames )
...@@ -166,7 +166,7 @@ public: ...@@ -166,7 +166,7 @@ public:
void GetCategories( STRINGS* aResults ) throw( IO_ERROR ); void GetCategories( STRINGS* aResults ) throw( IO_ERROR );
void GetCategoricalPartNames( STRINGS* aResults, const STRING& aCategory = StrEmpty ) void GetCategoricalPartNames( STRINGS* aResults, const STRING& aCategory = "" )
throw( IO_ERROR ); throw( IO_ERROR );
void GetRevisions( STRINGS* aResults, const STRING& aPartName ) throw( IO_ERROR ) void GetRevisions( STRINGS* aResults, const STRING& aPartName ) throw( IO_ERROR )
......
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <sch_lib.h>
using namespace SCH;
LIB::LIB( const STRING& aLogicalLibrary, LIB_SOURCE* aSource, LIB_SINK* aSink ) :
name( aLogicalLibrary ),
source( aSource ),
sink( aSink )
{
}
LIB::~LIB()
{
delete source;
delete sink;
}
...@@ -207,7 +207,7 @@ protected: ...@@ -207,7 +207,7 @@ protected:
*/ */
class LIB class LIB
{ {
friend class LIBS; ///< the LIB factory is LIBS::GetLibrary() friend class LIB_TABLE; ///< the LIB factory is LIB_TABLE
protected: // constructor is not public, called from LIBS only. protected: // constructor is not public, called from LIBS only.
...@@ -224,21 +224,11 @@ protected: // constructor is not public, called from LIBS only. ...@@ -224,21 +224,11 @@ protected: // constructor is not public, called from LIBS only.
* @param aSink is an open LIB_SINK whose ownership is given over * @param aSink is an open LIB_SINK whose ownership is given over
* to this LIB, and it is normally NULL. * to this LIB, and it is normally NULL.
*/ */
LIB( const STRING& aLogicalLibrary, LIB_SOURCE* aSource, LIB_SINK* aSink=NULL ) : LIB( const STRING& aLogicalLibrary, LIB_SOURCE* aSource, LIB_SINK* aSink = NULL );
name( aLogicalLibrary ),
source( aSource ),
sink( aSink )
{
}
public: public:
~LIB() ~LIB();
{
delete source;
delete sink;
}
/** /**
* Function HasSink * Function HasSink
...@@ -294,9 +284,9 @@ public: ...@@ -294,9 +284,9 @@ public:
* saves the part to non-volatile storage and returns the next new revision * saves the part to non-volatile storage and returns the next new revision
* name in the sequence established by the LIB_SINK. * name in the sequence established by the LIB_SINK.
*/ */
virtual STRING WritePart( PART* aPart ) throw( IO_ERROR ); STRING WritePart( PART* aPart ) throw( IO_ERROR );
virtual void SetPartBody( PART* aPart, const STRING& aSExpression ) throw( IO_ERROR ); void SetPartBody( PART* aPart, const STRING& aSExpression ) throw( IO_ERROR );
/** /**
* Function GetRevisions * Function GetRevisions
...@@ -346,6 +336,4 @@ protected: ...@@ -346,6 +336,4 @@ protected:
} // namespace SCH } // namespace SCH
const STRING StrEmpty = "";
#endif // SCH_LIB_H_ #endif // SCH_LIB_H_
...@@ -22,10 +22,158 @@ ...@@ -22,10 +22,158 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <sch_lib_table.h> #include <sch_lib_table.h>
#include <sch_lib_table_lexer.h>
using namespace std;
using namespace SCH;
LIB_TABLE::LIB_TABLE( LIB_TABLE* aFallBackTable )
{
if( aFallBackTable )
{
const ROWS& t = aFallBackTable->rows;
for( ROWS_CITER it = t.begin(); it != t.end(); ++it )
{
// our rows are empty, expect no collisions here
auto_ptr<ROW> row( new ROW( *it ) );
row->owner = this;
rows.insert( row.release() );
}
}
}
void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
{
/* grammar:
(lib_table
(lib (logical "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
(lib (logical "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
(lib (logical "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
)
note: "(lib_table" has already been read in.
*/
ELT_T tok;
while( (tok = in->NextTok() ) != T_RIGHT && tok != T_EOF )
{
// (lib (logical "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
if( tok != T_LEFT )
in->Expecting( T_LEFT );
if( ( tok = in->NextTok() ) != T_lib )
in->Expecting( T_lib );
in->NeedLEFT();
if( ( tok = in->NextTok() ) != T_logical )
in->Expecting( T_logical );
in->NeedSYMBOLorNUMBER();
auto_ptr<ROW> row( new ROW( this ) );
row->SetLogicalName( in->CurText() );
in->NeedRIGHT();
in->NeedLEFT();
if( ( tok = in->NextTok() ) != T_type )
in->Expecting( T_type );
in->NeedSYMBOLorNUMBER();
// verify that type is one of: {dir, schematic, subversion, http}
if( strcmp( in->CurText(), "dir" ) &&
strcmp( in->CurText(), "schematic" ) &&
strcmp( in->CurText(), "subversion" ) &&
strcmp( in->CurText(), "http" ) )
{
in->Expecting( wxT( "dir|schematic|subversion|http" ) );
}
row->SetType( in->CurText() );
in->NeedRIGHT();
in->NeedLEFT();
if( ( tok = in->NextTok() ) != T_full_uri )
in->Expecting( T_full_uri );
in->NeedSYMBOLorNUMBER();
row->SetFullURI( in->CurText() );
in->NeedRIGHT();
in->NeedLEFT();
if( ( tok = in->NextTok() ) != T_options )
in->Expecting( T_options );
in->NeedSYMBOLorNUMBER();
row->SetOptions( in->CurText() );
in->NeedRIGHT();
in->NeedRIGHT(); // teriminate the (lib..)
rows.insert( row.release() );
}
return;
}
#if 1
int main( int argc, char** argv ) int main( int argc, char** argv )
{ {
// the null string is not really a legal DSN token since any double quotes
// as assumed to be a single quote. To pass an empty string, we pass " "
// to (options " ")
SCH_LIB_TABLE_LEXER slr(
"(lib_table \n"
" (lib (logical meparts) (type dir) (full_uri /tmp/eeschema-lib) (options \" \"))\n"
" (lib (logical old-project) (type schematic)(full_uri /tmp/old-schematic.sch) (options \" \"))\n"
" (lib (logical www) (type http) (full_uri http://kicad.org/libs) (options \" \"))\n",
wxT( "inline text" ) // source
);
LIB_TABLE lib_table;
// read the "( lib_table" pair of tokens
try
{
slr.NextTok();
slr.NextTok();
lib_table.Parse( &slr );
}
catch( std::exception& ex )
{
printf( "std::exception\n" );
}
catch( IO_ERROR ioe )
{
printf( "caught\n" );
printf( "exception: %s\n", (const char*) wxConvertWX2MB( ioe.errorText ) );
}
lib_table.Show();
return 0; return 0;
} }
#endif
...@@ -29,12 +29,10 @@ ...@@ -29,12 +29,10 @@
#include <boost/ptr_container/ptr_set.hpp> #include <boost/ptr_container/ptr_set.hpp>
#include <sch_lib.h> #include <sch_lib.h>
class SCH_LIB_TABLE_LEXER; // outside namespace SCH, since make_lexer() Functions.cmake can't do namespace
namespace SCH { namespace SCH {
class LIB_TABLE_LEXER;
/** /**
* Class LIB_TABLE * Class LIB_TABLE
* holds LIB_TABLE::ROW records, and can be searched in a very high speed * holds LIB_TABLE::ROW records, and can be searched in a very high speed
...@@ -52,6 +50,8 @@ public: ...@@ -52,6 +50,8 @@ public:
*/ */
class ROW class ROW
{ {
friend class LIB_TABLE;
public: public:
bool operator<( const ROW& other ) const bool operator<( const ROW& other ) const
...@@ -101,9 +101,18 @@ public: ...@@ -101,9 +101,18 @@ public:
delete lib; delete lib;
} }
#if defined(DEBUG)
void Show() const
{
printf( "(lib (logical \"%s\")(type \"%s\")(full_uri \"%s\")(options \"%s\"))\n",
logicalName.c_str(), libType.c_str(), fullURI.c_str(), options.c_str() );
}
#endif
protected: protected:
ROW() : ROW( LIB_TABLE* aOwner ) :
owner( aOwner ),
lib( 0 ) lib( 0 )
{} {}
...@@ -145,37 +154,28 @@ public: ...@@ -145,37 +154,28 @@ public:
} }
private: private:
STRING logicalName; LIB_TABLE* owner;
STRING libType; STRING logicalName;
STRING fullURI; STRING libType;
STRING options; STRING fullURI;
STRING options;
LIB* lib; LIB* lib;
}; };
/** /**
* Constructor LIB_TABLE * Constructor LIB_TABLE
* builds a library table from an s-expression form of the library table. * builds a library table from an s-expression form of the library table.
* @param aLibraryTable is an s-expression form of all the rows in a library
* table fragment. These rows take presedence over rows in @a aFallBackTable.
* @param aFallBackTable is another LIB_TABLE which is searched only when * @param aFallBackTable is another LIB_TABLE which is searched only when
* a record is not found in this table. * a record is not found in this table. No ownership is taken of aFallBackTable.
*/ */
LIB_TABLE( const STRING& aLibraryTable, LIB_TABLE* aFallBackTable = NULL ) LIB_TABLE( LIB_TABLE* aFallBackTable = NULL );
throw( PARSE_ERROR )
{
// s-expression is chosen so we can read a table fragment from either
// a schematic or a disk file, for schematic resident or
// personal table, respectively.
}
protected:
/** /**
* Function Parse * Function Parse
* fills this object from information in the input stream \a aSpec, which * fills this object from information in the input stream \a aLexer, which
* is a DSN_LEXER customized for the grammar needed to describe instances of this object. * is a DSNLEXER customized for the grammar needed to describe instances of this object.
* The entire textual element spec is <br> * The entire textual element spec is <br>
* (lib_table (logical _yourfieldname_)(value _yourvalue_) visible)) * (lib_table (logical _yourfieldname_)(value _yourvalue_) visible))
* *
...@@ -183,21 +183,33 @@ protected: ...@@ -183,21 +183,33 @@ protected:
* (lib_table * (lib_table
* (lib (logical "LOGICAL")(type "TYPE")(fullURI "FULL_URI")(options "OPTIONS")) * (lib (logical "LOGICAL")(type "TYPE")(fullURI "FULL_URI")(options "OPTIONS"))
* (lib (logical "LOGICAL")(type "TYPE")(fullURI "FULL_URI")(options "OPTIONS")) * (lib (logical "LOGICAL")(type "TYPE")(fullURI "FULL_URI")(options "OPTIONS"))
(lib (logical "LOGICAL")(type "TYPE")(fullURI "FULL_URI")(options "OPTIONS")) * (lib (logical "LOGICAL")(type "TYPE")(fullURI "FULL_URI")(options "OPTIONS"))
* </pre> * </pre>
* *
* When this function is called, the input token stream given by \a aSpec * When this function is called, the input token stream given by \a aLexer
* is assumed to be positioned at the '^' in the following example, i.e. just after the * is assumed to be positioned at the '^' in the following example, i.e. just after the
* identifying keyword and before the content specifying stuff.<br> * identifying keyword and before the content specifying stuff.<br>
* (lib_table ^ (....) ) * (lib_table ^ (....) )
* *
* @param aSpec is the input token stream of keywords and symbols. * @param aSpec is the input token stream of keywords and symbols.
*/ */
void Parse( LIB_TABLE_LEXER* aLexer ) throw( PARSE_ERROR ); void Parse( SCH_LIB_TABLE_LEXER* aLexer ) throw( IO_ERROR );
private: #if defined(DEBUG)
void Show() const
{
printf("(lib_table\n" );
for( ROWS_CITER it = rows.begin(); it != rows.end(); ++it )
it->Show();
printf(")\n" );
}
#endif
typedef boost::ptr_set<ROW> ROWS; typedef boost::ptr_set<ROW> ROWS;
typedef ROWS::iterator ROWS_ITER;
typedef ROWS::const_iterator ROWS_CITER;
private:
ROWS rows; ROWS rows;
}; };
......
...@@ -3,3 +3,4 @@ logical ...@@ -3,3 +3,4 @@ logical
type type
full_uri full_uri
options options
lib
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment