new/sch_lpid.*, fix Doxygen errors in /new
This commit is contained in:
commit
29e829b7c0
|
@ -220,6 +220,13 @@ extern const unsigned ${result}_keyword_count;
|
||||||
|
|
||||||
using namespace DSN; // enum ${enum} is in this namespace
|
using namespace DSN; // enum ${enum} is in this namespace
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classs ${RESULT}_LEXER
|
||||||
|
* is an automatically generated class using the TokenList2DnsLexer.cmake
|
||||||
|
* technology, based on keywords provided by file:
|
||||||
|
* ${inputFile}
|
||||||
|
*/
|
||||||
class ${RESULT}_LEXER : public DSNLEXER
|
class ${RESULT}_LEXER : public DSNLEXER
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -77,6 +77,11 @@ 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_sch_part ${wxWidgets_LIBRARIES} )
|
target_link_libraries( test_sch_part ${wxWidgets_LIBRARIES} )
|
||||||
|
|
||||||
|
add_executable( test_lpid
|
||||||
|
sch_lpid.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries( test_lpid ${wxWidgets_LIBRARIES} )
|
||||||
|
|
||||||
|
|
||||||
make_lexer(
|
make_lexer(
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/sch_lib_table.keywords
|
${CMAKE_CURRENT_SOURCE_DIR}/sch_lib_table.keywords
|
||||||
|
@ -84,4 +89,3 @@ make_lexer(
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/sch_lib_table_keywords.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/sch_lib_table_keywords.cpp
|
||||||
ELT_T
|
ELT_T
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -443,4 +443,6 @@ public:
|
||||||
} // namespace SCH
|
} // namespace SCH
|
||||||
|
|
||||||
|
|
||||||
|
/// @todo remove endsWithRev() in favor of EndsWithRev(), find home for it.
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -140,6 +140,13 @@ static const char* strrstr( const char* haystack, const char* needle )
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1 // @todo switch over to EndsWithRev() global
|
||||||
|
|
||||||
|
static inline bool isDigit( char c )
|
||||||
|
{
|
||||||
|
return c >= '0' && c <= '9';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool isDigit( char c )
|
static inline bool isDigit( char c )
|
||||||
{
|
{
|
||||||
|
@ -185,6 +192,8 @@ static inline const char* endsWithRev( const STRING& aPartName, char separator )
|
||||||
return endsWithRev( aPartName.c_str(), aPartName.c_str()+aPartName.size(), separator );
|
return endsWithRev( aPartName.c_str(), aPartName.c_str()+aPartName.size(), separator );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// see struct BY_REV
|
// see struct BY_REV
|
||||||
bool BY_REV::operator() ( const STRING& s1, const STRING& s2 ) const
|
bool BY_REV::operator() ( const STRING& s1, const STRING& s2 ) const
|
||||||
|
@ -587,9 +596,9 @@ void DIR_LIB_SOURCE::cacheOneDir( const STRING& aCategory ) throw( IO_ERROR )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (1 || defined( TEST_DIR_LIB_SOURCE )) && defined(DEBUG)
|
#if 1 && defined(DEBUG)
|
||||||
|
|
||||||
int main( int argc, char** argv )
|
void DIR_LIB_SOURCE::Test( int argc, char** argv )
|
||||||
{
|
{
|
||||||
STRINGS partnames;
|
STRINGS partnames;
|
||||||
STRINGS sweets;
|
STRINGS sweets;
|
||||||
|
@ -601,7 +610,8 @@ int main( int argc, char** argv )
|
||||||
// DIR_LIB_SOURCE uut( argv[1] ? argv[1] : "", "" );
|
// DIR_LIB_SOURCE uut( argv[1] ? argv[1] : "", "" );
|
||||||
DIR_LIB_SOURCE uut( argv[1] ? argv[1] : "", "useVersioning" );
|
DIR_LIB_SOURCE uut( argv[1] ? argv[1] : "", "useVersioning" );
|
||||||
|
|
||||||
// initially, only the NAME_CACHE sweets and STRING categories are loaded:
|
// show the cached content, only the directory information is cached,
|
||||||
|
// parts are cached in class LIB, not down here.
|
||||||
uut.Show();
|
uut.Show();
|
||||||
|
|
||||||
uut.GetCategoricalPartNames( &partnames, "lions" );
|
uut.GetCategoricalPartNames( &partnames, "lions" );
|
||||||
|
@ -649,7 +659,12 @@ int main( int argc, char** argv )
|
||||||
{
|
{
|
||||||
printf( "exception: %s\n", (const char*) wxConvertWX2MB( ioe.errorText ) );
|
printf( "exception: %s\n", (const char*) wxConvertWX2MB( ioe.errorText ) );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main( int argc, char** argv )
|
||||||
|
{
|
||||||
|
DIR_LIB_SOURCE::Test( argc, argv );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,8 +132,7 @@ class DIR_LIB_SOURCE : public LIB_SOURCE
|
||||||
*/
|
*/
|
||||||
STRING makeFileName( const STRING& aPartName );
|
STRING makeFileName( const STRING& aPartName );
|
||||||
|
|
||||||
//protected:
|
protected:
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor DIR_LIB_SOURCE( const STRING& aDirectoryPath )
|
* Constructor DIR_LIB_SOURCE( const STRING& aDirectoryPath )
|
||||||
|
@ -151,8 +150,7 @@ 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 = "" )
|
DIR_LIB_SOURCE( const STRING& aDirectoryPath, const STRING& aOptions = "" ) throw( IO_ERROR );
|
||||||
throw( IO_ERROR );
|
|
||||||
|
|
||||||
~DIR_LIB_SOURCE();
|
~DIR_LIB_SOURCE();
|
||||||
|
|
||||||
|
@ -187,6 +185,10 @@ public:
|
||||||
* will output a debug dump of contents.
|
* will output a debug dump of contents.
|
||||||
*/
|
*/
|
||||||
void Show();
|
void Show();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void Test( int argc, char** argv );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,29 +25,18 @@
|
||||||
|
|
||||||
#include <sch_lib_table.h>
|
#include <sch_lib_table.h>
|
||||||
#include <sch_lib_table_lexer.h>
|
#include <sch_lib_table_lexer.h>
|
||||||
|
#include <sch_lpid.h>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
using namespace std;
|
//using namespace std; // screws up Doxygen
|
||||||
using namespace SCH;
|
using namespace SCH;
|
||||||
|
|
||||||
|
|
||||||
LIB_TABLE::LIB_TABLE( LIB_TABLE* aFallBackTable ) :
|
LIB_TABLE::LIB_TABLE( LIB_TABLE* aFallBackTable ) :
|
||||||
fallBack( aFallBackTable )
|
fallBack( aFallBackTable )
|
||||||
{
|
{
|
||||||
/* not copying fall back, simply search aFallBackTable separately if "logicalName not found".
|
// not copying fall back, simply search aFallBackTable separately
|
||||||
if( aFallBackTable )
|
// if "logicalName not found".
|
||||||
{
|
|
||||||
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->second ) );
|
|
||||||
row->owner = this;
|
|
||||||
insert( row );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,9 +45,9 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
|
||||||
/* grammar:
|
/* grammar:
|
||||||
|
|
||||||
(lib_table
|
(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"))
|
(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.
|
note: "(lib_table" has already been read in.
|
||||||
|
@ -66,7 +55,7 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
|
||||||
|
|
||||||
ELT_T tok;
|
ELT_T tok;
|
||||||
|
|
||||||
while( (tok = in->NextTok() ) != T_RIGHT && tok != T_EOF )
|
while( ( tok = in->NextTok() ) != T_RIGHT && tok != T_EOF )
|
||||||
{
|
{
|
||||||
// (lib (logical "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
|
// (lib (logical "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
|
||||||
|
|
||||||
|
@ -83,7 +72,7 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
|
||||||
|
|
||||||
in->NeedSYMBOLorNUMBER();
|
in->NeedSYMBOLorNUMBER();
|
||||||
|
|
||||||
auto_ptr<ROW> row( new ROW( this ) );
|
std::auto_ptr<ROW> row( new ROW( this ) );
|
||||||
|
|
||||||
row->SetLogicalName( in->CurText() );
|
row->SetLogicalName( in->CurText() );
|
||||||
|
|
||||||
|
@ -127,12 +116,12 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
|
||||||
row->SetOptions( in->CurText() );
|
row->SetOptions( in->CurText() );
|
||||||
|
|
||||||
in->NeedRIGHT();
|
in->NeedRIGHT();
|
||||||
in->NeedRIGHT(); // teriminate the (lib..)
|
in->NeedRIGHT(); // terminate the (lib..)
|
||||||
|
|
||||||
// all logicalNames within this table fragment must be unique, so we do not
|
// all logicalNames within this table fragment must be unique, so we do not
|
||||||
// replace. However a fallBack table can have a conflicting logicalName
|
// use doReplace in InsertRow(). However a fallBack table can have a
|
||||||
// and ours will supercede that one since in FindLib() we search this table
|
// conflicting logicalName and ours will supercede that one since in
|
||||||
// before any fall back.
|
// FindLib() we search this table before any fall back.
|
||||||
if( !InsertRow( row ) )
|
if( !InsertRow( row ) )
|
||||||
{
|
{
|
||||||
STRING msg;
|
STRING msg;
|
||||||
|
@ -144,7 +133,6 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
|
||||||
throw IO_ERROR( msg );
|
throw IO_ERROR( msg );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,12 +160,13 @@ void LIB_TABLE::ROW::Format( OUTPUTFORMATTER* out, int nestLevel ) const
|
||||||
|
|
||||||
STRINGS LIB_TABLE::GetLogicalLibs()
|
STRINGS LIB_TABLE::GetLogicalLibs()
|
||||||
{
|
{
|
||||||
// only return unique logical library names. Use std::set::insert() to
|
// Only return unique logical library names. Use std::set::insert() to
|
||||||
// quietly reject any duplicates, which can happen in the fall back table(s).
|
// quietly reject any duplicates, which can happen when encountering a duplicate
|
||||||
set<STRING> unique;
|
// logical lib name from one of the fall back table(s).
|
||||||
STRINGS ret;
|
|
||||||
|
|
||||||
const LIB_TABLE* cur = this;
|
std::set<STRING> unique;
|
||||||
|
STRINGS ret;
|
||||||
|
const LIB_TABLE* cur = this;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -188,8 +177,8 @@ STRINGS LIB_TABLE::GetLogicalLibs()
|
||||||
|
|
||||||
} while( ( cur = cur->fallBack ) != 0 );
|
} while( ( cur = cur->fallBack ) != 0 );
|
||||||
|
|
||||||
// return a sorted, unique set of STRINGS to caller
|
// return a sorted, unique set of logical lib name STRINGS to caller
|
||||||
for( set<STRING>::const_iterator it = unique.begin(); it!=unique.end(); ++it )
|
for( std::set<STRING>::const_iterator it = unique.begin(); it!=unique.end(); ++it )
|
||||||
ret.push_back( *it );
|
ret.push_back( *it );
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -228,7 +217,7 @@ const LIB_TABLE::ROW* LIB_TABLE::FindRow( const STRING& aLogicalName ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LIB_TABLE::InsertRow( auto_ptr<ROW>& aRow, bool doReplace )
|
bool LIB_TABLE::InsertRow( std::auto_ptr<ROW>& aRow, bool doReplace )
|
||||||
{
|
{
|
||||||
// this does not need to be super fast.
|
// this does not need to be super fast.
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,41 @@ class PART;
|
||||||
* 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
|
||||||
* way based on logical library name.
|
* way based on logical library name.
|
||||||
|
* <p>
|
||||||
|
* This class owns the <b>library table</b>, which is like fstab in concept and maps logical
|
||||||
|
* library name to library URI, type, and options. It has the following columns:
|
||||||
|
* <ul>
|
||||||
|
* <li> Logical Library Name
|
||||||
|
* <li> Library Type
|
||||||
|
* <li> Library URI. The full URI to the library source, form dependent on Type.
|
||||||
|
* <li> Options, used for access, such as password
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* The Library Type can be one of:
|
||||||
|
* <ul>
|
||||||
|
* <li> "dir"
|
||||||
|
* <li> "schematic" i.e. a parts list from another schematic.
|
||||||
|
* <li> "subversion"
|
||||||
|
* <li> "http"
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* For now, the Library URI types needed to support the various types can be one of those
|
||||||
|
* shown below, which are typical of each type:
|
||||||
|
* <ul>
|
||||||
|
* <li> "file://C:/mylibdir"
|
||||||
|
* <li> "file://home/user/kicadwork/jtagboard.sch"
|
||||||
|
* <li> "svn://kicad.org/partlib/trunk"
|
||||||
|
* <li> "http://kicad.org/partlib"
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* The applicable library table is built up from several additive rows (table fragments),
|
||||||
|
* and the final table is a (conceptual) merging of the table fragments. Two
|
||||||
|
* anticipated sources of the rows are a personal table, and a schematic resident
|
||||||
|
* table. The schematic resident table rows are considered a higher priority in
|
||||||
|
* the final dynamically assembled library table. A row in the schematic
|
||||||
|
* contribution to the library table takes precedence over the personal table
|
||||||
|
* if there is a collision on logical library name, otherwise the rows simply
|
||||||
|
* combine without issue to make up the applicable library table.
|
||||||
*
|
*
|
||||||
* @author Dick Hollenbeck
|
* @author Dick Hollenbeck
|
||||||
*/
|
*/
|
||||||
|
@ -168,7 +203,8 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor LIB_TABLE
|
* Constructor LIB_TABLE
|
||||||
* builds a library table from an s-expression form of the library table.
|
* builds a library table by pre-pending this table fragment in front of
|
||||||
|
* @a aFallBackTable. Loading of this table fragment is done by using Parse().
|
||||||
* @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. No ownership is taken of aFallBackTable.
|
* a record is not found in this table. No ownership is taken of aFallBackTable.
|
||||||
*/
|
*/
|
||||||
|
@ -176,16 +212,15 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Parse
|
* Function Parse
|
||||||
* fills this object from information in the input stream \a aLexer, which
|
* fills this table fragment from information in the input stream \a aLexer, which
|
||||||
* is a DSNLEXER 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))
|
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* (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 aLexer
|
* When this function is called, the input token stream given by \a aLexer
|
||||||
|
@ -193,7 +228,7 @@ public:
|
||||||
* 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 aLexer is the input token stream of keywords and symbols.
|
||||||
*/
|
*/
|
||||||
void Parse( SCH_LIB_TABLE_LEXER* aLexer ) throw( IO_ERROR );
|
void Parse( SCH_LIB_TABLE_LEXER* aLexer ) throw( IO_ERROR );
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetPart
|
||||||
|
* finds and loads a PART, and parses it. As long as the part is
|
||||||
|
* accessible in any LIB_SOURCE, opened or not opened, this function
|
||||||
|
* will find it and load it into its containing LIB, even if that means
|
||||||
|
* having to load a new LIB as given in the library table.
|
||||||
|
*/
|
||||||
|
static PART* SCH_LIBS::GetPart( const LPID& aLogicalPartID ) throw( IO_ERROR )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2011 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SCH_LIBS_H_
|
||||||
|
#define SCH_LIBS_H_
|
||||||
|
|
||||||
|
#include <sch_lib.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class LIBS
|
||||||
|
* houses a handful of functions that manage all the RAM resident LIBs, and
|
||||||
|
* provide for a global part lookup function, GetPart(), which can be the basis
|
||||||
|
* of a cross LIB hyperlink.
|
||||||
|
*/
|
||||||
|
class LIBS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetPart
|
||||||
|
* finds and loads a PART, and parses it. As long as the part is
|
||||||
|
* accessible in any LIB_SOURCE, opened or not opened, this function
|
||||||
|
* will find it and load it into its containing LIB, even if that means
|
||||||
|
* having to load a new LIB as given in the library table.
|
||||||
|
*/
|
||||||
|
static PART* GetPart( const LPID& aLogicalPartID ) throw( IO_ERROR );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetLib
|
||||||
|
* is first a lookup function and then if needed, a factory function.
|
||||||
|
* If aLogicalLibraryName has been opened, then return the already opened
|
||||||
|
* LIB. If not, then instantiate the library and fill the initial
|
||||||
|
* library PARTs (unparsed) and categories, and add it to LIB::libraries
|
||||||
|
* for future reference.
|
||||||
|
*/
|
||||||
|
static LIB* GetLib( const STRING& aLogicalLibraryName ) throw( IO_ERROR );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetOpenedLibNames
|
||||||
|
* returns the logical library names of LIBs that are already opened.
|
||||||
|
* @see LPID::GetLogicalLibraries()
|
||||||
|
*/
|
||||||
|
static STRINGS GetOpendedLogicalLibNames();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CloseLibrary
|
||||||
|
* closes an open library @a aLibrary and removes it from class LIBS.
|
||||||
|
*/
|
||||||
|
static void CloseLibrary( LIB* aLibrary ) throw( IO_ERROR );
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// collection of LIBs, searchable by logical name.
|
||||||
|
static std::map< STRING, LIB* > libraries; // owns the LIBs.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SCH_LIBS_H_
|
237
new/sch_lpid.cpp
237
new/sch_lpid.cpp
|
@ -22,15 +22,248 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <sch_lpid.h>
|
#include <sch_lpid.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace SCH;
|
using namespace SCH;
|
||||||
|
|
||||||
|
static inline bool isDigit( char c )
|
||||||
LPID::LPID( const STRING& aLPID ) throw( PARSE_ERROR )
|
|
||||||
{
|
{
|
||||||
|
return c >= '0' && c <= '9';
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* EndsWithRev( const char* start, const char* tail, char separator )
|
||||||
|
{
|
||||||
|
bool sawDigit = false;
|
||||||
|
|
||||||
|
while( tail > start && isDigit( *--tail ) )
|
||||||
|
{
|
||||||
|
sawDigit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if sawDigit, tail points to the 'v' here.
|
||||||
|
|
||||||
|
if( sawDigit && tail-3 >= start )
|
||||||
|
{
|
||||||
|
tail -= 3;
|
||||||
|
|
||||||
|
if( tail[0]==separator && tail[1]=='r' && tail[2]=='e' && tail[3]=='v' )
|
||||||
|
{
|
||||||
|
return tail+1; // omit separator, return "revN[N..]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LPID::LPID( const STRING& aLPID ) throw( PARSE_ERROR )
|
||||||
|
{
|
||||||
|
const char* rev = EndsWithRev( aLPID );
|
||||||
|
size_t revNdx;
|
||||||
|
size_t partNdx;
|
||||||
|
size_t baseNdx;
|
||||||
|
|
||||||
|
//=====<revision>=========================================
|
||||||
|
if( rev )
|
||||||
|
{
|
||||||
|
revNdx = rev - aLPID.c_str();
|
||||||
|
revision = aLPID.substr( revNdx );
|
||||||
|
--revNdx; // back up to omit the '/' which preceeds the rev
|
||||||
|
}
|
||||||
|
else
|
||||||
|
revNdx = aLPID.size();
|
||||||
|
|
||||||
|
//=====<logical>==========================================
|
||||||
|
if( ( partNdx = aLPID.find( ':' ) ) != aLPID.npos )
|
||||||
|
{
|
||||||
|
logical = aLPID.substr( 0, partNdx );
|
||||||
|
++partNdx; // skip ':'
|
||||||
|
}
|
||||||
|
else
|
||||||
|
partNdx = 0;
|
||||||
|
|
||||||
|
//=====<rawName && category>==============================
|
||||||
|
// "length limited" search:
|
||||||
|
const char* base = (const char*) memchr( aLPID.c_str() + partNdx, '/', revNdx - partNdx );
|
||||||
|
|
||||||
|
if( base )
|
||||||
|
{
|
||||||
|
baseNdx = base - aLPID.c_str();
|
||||||
|
category = aLPID.substr( partNdx, baseNdx - partNdx );
|
||||||
|
++baseNdx; // skip '/'
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
baseNdx = partNdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=====<baseName>==========================================
|
||||||
|
baseName = aLPID.substr( baseNdx, revNdx - baseNdx );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STRING LPID::GetLogicalLib() const
|
||||||
|
{
|
||||||
|
return logical;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LPID::SetLogicalLib( const STRING& aLogical )
|
||||||
|
{
|
||||||
|
if( aLogical.find_first_of( ":/" ) == STRING::npos )
|
||||||
|
{
|
||||||
|
logical = aLogical;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STRING LPID::GetCategory() const
|
||||||
|
{
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LPID::SetCategory( const STRING& aCategory )
|
||||||
|
{
|
||||||
|
if( aCategory.find_first_of( ":/" ) == STRING::npos )
|
||||||
|
{
|
||||||
|
category = aCategory;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STRING LPID::GetBaseName() const
|
||||||
|
{
|
||||||
|
return baseName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LPID::SetBaseName( const STRING& aBaseName )
|
||||||
|
{
|
||||||
|
if( aBaseName.find_first_of( ":/" ) == STRING::npos )
|
||||||
|
{
|
||||||
|
baseName = aBaseName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STRING LPID::GetPartName() const
|
||||||
|
{
|
||||||
|
STRING ret;
|
||||||
|
|
||||||
|
// return [category/]baseName
|
||||||
|
if( category.size() )
|
||||||
|
{
|
||||||
|
ret += category;
|
||||||
|
ret += '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
ret += baseName;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STRING LPID::GetRevision() const
|
||||||
|
{
|
||||||
|
return revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LPID::SetRevision( const STRING& aRevision )
|
||||||
|
{
|
||||||
|
STRING rev;
|
||||||
|
|
||||||
|
rev += "x/";
|
||||||
|
rev += aRevision;
|
||||||
|
|
||||||
|
if( EndsWithRev( rev ) )
|
||||||
|
{
|
||||||
|
revision = aRevision;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STRING LPID::GetFullText() const
|
||||||
|
{
|
||||||
|
STRING ret;
|
||||||
|
|
||||||
|
if( logical.size() )
|
||||||
|
{
|
||||||
|
ret += logical;
|
||||||
|
ret += ':';
|
||||||
|
}
|
||||||
|
|
||||||
|
if( category.size() )
|
||||||
|
{
|
||||||
|
ret += category;
|
||||||
|
ret += '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
ret += baseName;
|
||||||
|
|
||||||
|
if( revision.size() )
|
||||||
|
{
|
||||||
|
ret += '/';
|
||||||
|
ret += revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 1 && defined(DEBUG)
|
||||||
|
|
||||||
|
// build this with Debug CMAKE_BUILD_TYPE
|
||||||
|
|
||||||
|
void LPID::Test()
|
||||||
|
{
|
||||||
|
static const char* lpids[] = {
|
||||||
|
"me:passives/R/rev0",
|
||||||
|
"passives/R/rev2",
|
||||||
|
":passives/R/rev3",
|
||||||
|
"C/rev22",
|
||||||
|
"passives/C22",
|
||||||
|
"R",
|
||||||
|
"me:R",
|
||||||
|
// most difficult:
|
||||||
|
"me:/R/rev0",
|
||||||
|
"me:R/rev0",
|
||||||
|
};
|
||||||
|
|
||||||
|
for( unsigned i=0; i<sizeof(lpids)/sizeof(lpids[0]); ++i )
|
||||||
|
{
|
||||||
|
// test some round tripping
|
||||||
|
|
||||||
|
LPID lpid( lpids[i] ); // parse
|
||||||
|
|
||||||
|
// format
|
||||||
|
printf( "input:'%s' full:'%s' base:'%s' partName:'%s' cat:'%s'\n",
|
||||||
|
lpids[i],
|
||||||
|
lpid.GetFullText().c_str(),
|
||||||
|
lpid.GetBaseName().c_str(),
|
||||||
|
lpid.GetPartName().c_str(),
|
||||||
|
lpid.GetCategory().c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main( int argc, char** argv )
|
||||||
|
{
|
||||||
|
LPID::Test();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
111
new/sch_lpid.h
111
new/sch_lpid.h
|
@ -25,8 +25,7 @@
|
||||||
#ifndef SCH_LPID_H_
|
#ifndef SCH_LPID_H_
|
||||||
#define SCH_LPID_H_
|
#define SCH_LPID_H_
|
||||||
|
|
||||||
//#include <wx/string.h>
|
#include <sch_lib.h> // STRING
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class LPID
|
* Class LPID
|
||||||
|
@ -45,42 +44,7 @@
|
||||||
* <li> "rev6" is the revision number, which is optional. If missing then its
|
* <li> "rev6" is the revision number, which is optional. If missing then its
|
||||||
* delimiter should also not be present.
|
* delimiter should also not be present.
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p>
|
* @author Dick Hollenbeck
|
||||||
* This class owns the <b>library table</b>, which is like fstab in concept and maps logical
|
|
||||||
* library name to library URI, type, and options. It has the following columns:
|
|
||||||
* <ul>
|
|
||||||
* <li> Logical Library Name
|
|
||||||
* <li> Library Type
|
|
||||||
* <li> Library URI. The full URI to the library source, form dependent on Type.
|
|
||||||
* <li> Options, used for access, such as password
|
|
||||||
* </ul>
|
|
||||||
* <p>
|
|
||||||
* For now, the Library Type can be one of:
|
|
||||||
* <ul>
|
|
||||||
* <li> "dir"
|
|
||||||
* <li> "schematic" i.e. a parts list from another schematic.
|
|
||||||
* <li> "subversion"
|
|
||||||
* <li> "bazaar"
|
|
||||||
* <li> "http"
|
|
||||||
* </ul>
|
|
||||||
* <p>
|
|
||||||
* For now, the Library URI types needed to support the various types can be one of those
|
|
||||||
* shown below, which are typical of each type:
|
|
||||||
* <ul>
|
|
||||||
* <li> "file://C:/mylibdir"
|
|
||||||
* <li> "file://home/user/kicadwork/jtagboard.sch"
|
|
||||||
* <li> "svn://kicad.org/partlib/trunk"
|
|
||||||
* <li> "http://kicad.org/partlib"
|
|
||||||
* </ul>
|
|
||||||
* <p>
|
|
||||||
* The applicable library table is built up from several additive rows (table fragments),
|
|
||||||
* and the final table is a merging of the table fragments. Two anticipated sources of
|
|
||||||
* the rows are a personal table, and a schematic resident table. The schematic
|
|
||||||
* resident table rows are considered a higher priority in the final dynamically
|
|
||||||
* assembled library table. A row in the schematic contribution to the library table
|
|
||||||
* will take precedence over the personal table if there is a collision on logical
|
|
||||||
* library name, otherwise the rows simply combine without issue to make up the
|
|
||||||
* applicable library table.
|
|
||||||
*/
|
*/
|
||||||
class LPID // aka GUID
|
class LPID // aka GUID
|
||||||
{
|
{
|
||||||
|
@ -95,12 +59,19 @@ public:
|
||||||
LPID( const STRING& aLPID ) throw( PARSE_ERROR );
|
LPID( const STRING& aLPID ) throw( PARSE_ERROR );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetLogLib
|
* Function GetLogicalLib
|
||||||
* returns the logical library portion of a LPID. There is not Set accessor
|
* returns the logical library portion of a LPID. There is not Set accessor
|
||||||
* for this portion since it comes from the library table and is considered
|
* for this portion since it comes from the library table and is considered
|
||||||
* read only here.
|
* read only here.
|
||||||
*/
|
*/
|
||||||
STRING GetLogLib() const;
|
STRING GetLogicalLib() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetCategory
|
||||||
|
* overrides the logical lib name portion of the LPID to @a aLogical, and can be empty.
|
||||||
|
* @return bool - true unless parameter has ':' or '/' in it.
|
||||||
|
*/
|
||||||
|
bool SetLogicalLib( const STRING& aLogical );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetCategory
|
* Function GetCategory
|
||||||
|
@ -113,8 +84,35 @@ public:
|
||||||
* Function SetCategory
|
* Function SetCategory
|
||||||
* overrides the category portion of the LPID to @a aCategory and is typically
|
* overrides the category portion of the LPID to @a aCategory and is typically
|
||||||
* either the empty string or a single word like "passives".
|
* either the empty string or a single word like "passives".
|
||||||
|
* @return bool - true unless parameter has ':' or '/' in it.
|
||||||
|
*/
|
||||||
|
bool SetCategory( const STRING& aCategory );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetBaseName
|
||||||
|
* returns the part name without the category.
|
||||||
|
*/
|
||||||
|
STRING GetBaseName() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetBaseName
|
||||||
|
* overrides the base name portion of the LPID to @a aBaseName
|
||||||
|
* @return bool - true unless parameter has ':' or '/' in it.
|
||||||
|
*/
|
||||||
|
bool SetBaseName( const STRING& aBaseName );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetBaseName
|
||||||
|
* returns the part name, i.e. category/baseName without revision.
|
||||||
|
*/
|
||||||
|
STRING GetPartName() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function SetBaseName
|
||||||
|
* overrides the part name portion of the LPID to @a aPartName
|
||||||
|
not really needed, partname is an agreggate anyway, just parse a new one.
|
||||||
|
void SetPartName( const STRING& aPartName );
|
||||||
*/
|
*/
|
||||||
void SetCategory( const STRING& aCategory );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetRevision
|
* Function GetRevision
|
||||||
|
@ -126,14 +124,43 @@ public:
|
||||||
* Function SetRevision
|
* Function SetRevision
|
||||||
* overrides the revision portion of the LPID to @a aRevision and must
|
* overrides the revision portion of the LPID to @a aRevision and must
|
||||||
* be in the form "rev<num>" where "<num>" is "1", "2", etc.
|
* be in the form "rev<num>" where "<num>" is "1", "2", etc.
|
||||||
|
* @return bool - true unless parameter is not of the form "revN]N..]"
|
||||||
*/
|
*/
|
||||||
void SetRevision( const STRING& aRevision );
|
bool SetRevision( const STRING& aRevision );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetFullText
|
* Function GetFullText
|
||||||
* returns the full text of the LPID.
|
* returns the full text of the LPID.
|
||||||
*/
|
*/
|
||||||
STRING GetFullText() const;
|
STRING GetFullText() const;
|
||||||
|
|
||||||
|
#if defined(DEBUG)
|
||||||
|
static void Test();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
STRING logical; ///< logical lib name or empty
|
||||||
|
STRING category; ///< or empty
|
||||||
|
STRING baseName; ///< excludes category
|
||||||
|
STRING revision; ///< "revN[N..]" or empty
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function EndsWithRev
|
||||||
|
* returns a pointer to the final string segment: "revN[N..]" or NULL if none.
|
||||||
|
* @param start is the beginning of string segment to test, the partname or
|
||||||
|
* any middle portion of it.
|
||||||
|
* @param tail is a pointer to the terminating nul, or one past inclusive end of
|
||||||
|
* segment, i.e. the string segment of interest is [start,tail)
|
||||||
|
* @param separator is the separating byte, expected: '.' or '/', depending on context.
|
||||||
|
*/
|
||||||
|
const char* EndsWithRev( const char* start, const char* tail, char separator = '/' );
|
||||||
|
|
||||||
|
static inline const char* EndsWithRev( const STRING& aPartName, char separator = '/' )
|
||||||
|
{
|
||||||
|
return EndsWithRev( aPartName.c_str(), aPartName.c_str()+aPartName.size(), separator );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // SCH_LPID_H_
|
#endif // SCH_LPID_H_
|
||||||
|
|
Loading…
Reference in New Issue