Added "lookup" functions to LIB_TABLE. Fixed up Doxygen output even more.
Include image file inline on main HTML page. Added HTTP_LIB_SOURCE. Added utf8.h
This commit is contained in:
parent
a9010796e0
commit
f6265fd272
|
@ -25,8 +25,10 @@
|
|||
#ifndef KICAD_EXCEPTIONS_H_
|
||||
#define KICAD_EXCEPTIONS_H_
|
||||
|
||||
/* Just exceptions
|
||||
*/
|
||||
/**
|
||||
* @ingroup exception_types
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
#include <wx/string.h>
|
||||
|
@ -84,4 +86,7 @@ struct PARSE_ERROR : public IO_ERROR
|
|||
}
|
||||
};
|
||||
|
||||
/** @} exception_types */
|
||||
|
||||
|
||||
#endif // KICAD_EXCEPTIONS_H_
|
||||
|
|
|
@ -60,20 +60,14 @@ endif()
|
|||
|
||||
include_directories( ${CMAKE_CURRENT_SOURCE_DIR} )
|
||||
|
||||
#=====<on standby until unit testing infrastructure>============================
|
||||
if( false )
|
||||
|
||||
add_executable( test_dir_lib_source
|
||||
sch_dir_lib_source.cpp
|
||||
)
|
||||
target_link_libraries( test_dir_lib_source ${wxWidgets_LIBRARIES} )
|
||||
|
||||
add_executable( test_sch_lib_table
|
||||
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 )
|
||||
target_link_libraries( test_sch_part ${wxWidgets_LIBRARIES} )
|
||||
|
||||
|
@ -82,6 +76,21 @@ add_executable( test_lpid
|
|||
)
|
||||
target_link_libraries( test_lpid ${wxWidgets_LIBRARIES} )
|
||||
|
||||
endif( false )
|
||||
|
||||
#=====</on standby until unit testing infrastructure>===========================
|
||||
|
||||
add_executable( test_sch_lib_table
|
||||
sch_lib_table.cpp
|
||||
sch_lib_table_keywords.cpp
|
||||
sch_lib.cpp
|
||||
sch_lpid.cpp
|
||||
sch_dir_lib_source.cpp
|
||||
${PROJECT_SOURCE_DIR}/common/richio.cpp
|
||||
${PROJECT_SOURCE_DIR}/common/dsnlexer.cpp
|
||||
)
|
||||
target_link_libraries( test_sch_lib_table ${wxWidgets_LIBRARIES} )
|
||||
|
||||
|
||||
make_lexer(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sch_lib_table.keywords
|
||||
|
|
70
new/design.h
70
new/design.h
|
@ -329,6 +329,10 @@ is used on the hood ornament. When aResults pointer is passed as an argument, I
|
|||
won't refer to this as 'returning' a value, but rather 'fetching' a result to
|
||||
distinguish between the two strategies.
|
||||
|
||||
<p> Functions named as lookupSomething() or LookupSomething() are to be understood
|
||||
as "find and load if needed". This is different than a simple find operation only, in
|
||||
that an implied load operation is also done, but only if needed.
|
||||
|
||||
|
||||
@section architecture Architecture
|
||||
|
||||
|
@ -337,47 +341,59 @@ LIB_SOURCE. A library source is the backing to a library. The class name for a
|
|||
library in the new design is LIB.
|
||||
|
||||
<p>
|
||||
Show architecture here.
|
||||
|
||||
<a href="../drawing.png" > Click here to see an architectural drawing.</a>
|
||||
<IMG SRC="../drawing.png" ALT="You should see design architecture here">
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \defgroup string_types STRING Types
|
||||
* @defgroup string_types STRING Types
|
||||
* Provide some string types for use within the API.
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef std::string STRING;
|
||||
typedef std::dequeue<STRING> STRINGS;
|
||||
|
||||
//typedef std::vector<wxString> WSTRINGS;
|
||||
|
||||
|
||||
const STRING StrEmpty = "";
|
||||
|
||||
/** @} string_types STRING Types */
|
||||
|
||||
/**
|
||||
* \defgroup exception_types Exception Types
|
||||
* @defgroup exception_types Exception Types
|
||||
* Provide some exception types for use within the API.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @} exception_types Exception Types */
|
||||
/**
|
||||
* Class HTTP_LIB_SOURCE
|
||||
* implements a LIB_SOURCE to access a remote document root repository using http protocol.
|
||||
*/
|
||||
class HTTP_LIB_SOURCE : public LIB_SOURCE
|
||||
{
|
||||
friend class LIB_TABLE; ///< constructor the LIB uses these functions.
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Constructor ( const STRING& aSvnURL )
|
||||
* sets up a LIB_SOURCE using aSvnURI which points to a subversion
|
||||
* repository.
|
||||
* @see LIBS::GetLibrary().
|
||||
*
|
||||
* @param aHttpURL is a full URL of a document root repo directory. Example might
|
||||
* be "http://kicad.org/libs"
|
||||
*
|
||||
* @param aOptions is the options string from the library table. It can be any
|
||||
* string that the LIB_SOURCE can parse and understand, perhaps using comma separation
|
||||
* between options. Options and their syntax is LIB_SOURCE implementation specific.
|
||||
*/
|
||||
HTTP_LIB_SOURCE( const STRING& aHttpURL, const STRING& aOptions ) throws( IO_ERROR );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class SVN_LIB_SOURCE
|
||||
* implements a LIB_SOURCE in a subversion repository.
|
||||
* implements a LIB_SOURCE to access a [remote or local] subversion repository
|
||||
* using subversion client protocol.
|
||||
*/
|
||||
class SVN_LIB_SOURCE : public LIB_SOURCE
|
||||
{
|
||||
friend class LIBS; ///< constructor the LIB uses these functions.
|
||||
friend class LIB_TABLE; ///< constructor the LIB uses these functions.
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -389,8 +405,12 @@ protected:
|
|||
*
|
||||
* @param aSvnURL is a full URL of a subversion repo directory. Example might
|
||||
* be "svn://kicad.org/repos/library/trunk"
|
||||
*
|
||||
* @param aOptions is the options string from the library table. It can be any
|
||||
* string that the LIB_SOURCE can parse and understand, perhaps using comma separation
|
||||
* between options. Options and their syntax is LIB_SOURCE implementation specific.
|
||||
*/
|
||||
SVN_LIB_SOURCE( const STRING& aSvnURL ) throws( IO_ERROR );
|
||||
SVN_LIB_SOURCE( const STRING& aSvnURL, const STRING& aOptions ) throws( IO_ERROR );
|
||||
};
|
||||
|
||||
|
||||
|
@ -401,7 +421,7 @@ protected:
|
|||
*/
|
||||
class SCHEMATIC_LIB_SOURCE : public LIB_SOURCE
|
||||
{
|
||||
friend class LIBS; ///< constructor the LIB uses these functions.
|
||||
friend class LIB_TABLE; ///< constructor the LIB uses these functions.
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -414,8 +434,12 @@ protected:
|
|||
*
|
||||
* @param aSchematicFile is a full path and filename. Example:
|
||||
* "/home/user/kicadproject/design.sch"
|
||||
*
|
||||
* @param aOptions is the options string from the library table. It can be any
|
||||
* string that the LIB_SOURCE can parse and understand, perhaps using comma separation
|
||||
* between options. Options and their syntax is LIB_SOURCE implementation specific.
|
||||
*/
|
||||
SCHEMATIC_LIB_SOURCE( const STRING& aSchematicFile ) throws( IO_ERROR );
|
||||
SCHEMATIC_LIB_SOURCE( const STRING& aSchematicFile, const STRING& aOptions ) throws( IO_ERROR );
|
||||
};
|
||||
|
||||
|
||||
|
@ -445,4 +469,6 @@ public:
|
|||
|
||||
/// @todo remove endsWithRev() in favor of EndsWithRev(), find home for it.
|
||||
|
||||
/// @todo add simple unit test infrastructure.
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -590,7 +590,7 @@ void DIR_LIB_SOURCE::cacheOneDir( const STRING& aCategory ) throw( IO_ERROR )
|
|||
}
|
||||
|
||||
|
||||
#if 1 && defined(DEBUG)
|
||||
#if 0 && defined(DEBUG)
|
||||
|
||||
void DIR_LIB_SOURCE::Test( int argc, char** argv )
|
||||
{
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace SCH {
|
|||
*/
|
||||
class DIR_LIB_SOURCE : public LIB_SOURCE
|
||||
{
|
||||
friend class LIBS; ///< LIBS::GetLib() can construct one.
|
||||
friend class LIB_TABLE; ///< constructor is protected, LIB_TABLE can construct
|
||||
|
||||
bool useVersioning; ///< use files with extension ".revNNN..", else not
|
||||
|
||||
|
@ -146,7 +146,7 @@ protected:
|
|||
*
|
||||
* @param aOptions is the options string from the library table, currently
|
||||
* the only supported option, that this LIB_SOURCE knows about is
|
||||
* "userVersioning". If present means support versioning in the directory
|
||||
* "useVersioning". If present means support versioning in the directory
|
||||
* tree, otherwise only a single version of each part is recognized, namely the
|
||||
* one without the ".revN[N..]" trailer.
|
||||
*/
|
||||
|
|
|
@ -43,3 +43,24 @@ LIB::~LIB()
|
|||
delete sink;
|
||||
}
|
||||
|
||||
|
||||
PART* LIB::LookupPart( const LPID& aLPID ) throw( IO_ERROR )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0 && defined(DEBUG)
|
||||
|
||||
void LIB::Test( int argc, char** argv ) throw( IO_ERROR );
|
||||
{
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
LIB::Test( argc, argv );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,27 +25,13 @@
|
|||
#ifndef SCH_LIB_H_
|
||||
#define SCH_LIB_H_
|
||||
|
||||
#include <string>
|
||||
#include <deque>
|
||||
|
||||
#include <utf8.h>
|
||||
#include <kicad_exceptions.h>
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
#define D(x) x
|
||||
#else
|
||||
#define D(x) // nothing
|
||||
#endif
|
||||
|
||||
|
||||
typedef std::string STRING;
|
||||
typedef std::deque<STRING> STRINGS;
|
||||
typedef STRINGS STRINGS;
|
||||
|
||||
extern const STRING StrEmpty;
|
||||
|
||||
namespace SCH {
|
||||
|
||||
class LPID;
|
||||
class PART;
|
||||
|
||||
|
||||
|
@ -83,7 +69,7 @@ protected: ///< derived classes must implement
|
|||
* Function ReadPart
|
||||
* fetches @a aPartName's s-expression into @a aResult after clear()ing aResult.
|
||||
*/
|
||||
virtual void ReadPart( STRING* aResult, const STRING& aPartName, const STRING& aRev=StrEmpty )
|
||||
virtual void ReadPart( STRING* aResult, const STRING& aPartName, const STRING& aRev = "" )
|
||||
throw( IO_ERROR ) = 0;
|
||||
|
||||
/**
|
||||
|
@ -113,7 +99,7 @@ protected: ///< derived classes must implement
|
|||
*
|
||||
* @param aResults is a place to put the fetched result, one category per STRING.
|
||||
*/
|
||||
virtual void GetCategoricalPartNames( STRINGS* aResults, const STRING& aCategory=StrEmpty )
|
||||
virtual void GetCategoricalPartNames( STRINGS* aResults, const STRING& aCategory="" )
|
||||
throw( IO_ERROR ) = 0;
|
||||
|
||||
/**
|
||||
|
@ -186,7 +172,7 @@ protected: ///< derived classes must implement
|
|||
* part is done, then LIB::ReloadPart() must be called on this same part
|
||||
* and all parts that inherit it must be reparsed.
|
||||
* @return STRING - if the LIB_SINK support revision numbering, then return a
|
||||
* evision name that was next in the sequence, e.g. "rev22", else StrEmpty.
|
||||
* revision name that was next in the sequence, e.g. "rev22", else "".
|
||||
*/
|
||||
virtual STRING WritePart( const STRING& aPartName, const STRING& aSExpression )
|
||||
throw( IO_ERROR ) = 0;
|
||||
|
@ -207,15 +193,15 @@ protected:
|
|||
*/
|
||||
class LIB
|
||||
{
|
||||
friend class LIB_TABLE; ///< the LIB factory is LIB_TABLE
|
||||
friend class LIB_TABLE; ///< protected constructor, LIB_TABLE may construct
|
||||
|
||||
protected: // constructor is not public, called from LIBS only.
|
||||
protected: // constructor is not public, called from LIB_TABLE only.
|
||||
|
||||
/**
|
||||
* Constructor LIB
|
||||
* is not public and is only called from LIBS::GetLib()
|
||||
* is not public and is only called from class LIB_TABLE
|
||||
*
|
||||
* @param aLogicalLibrary is the name of a well know logical library, and is
|
||||
* @param aLogicalLibrary is the name of a well known logical library, and is
|
||||
* known because it already exists in the library table.
|
||||
*
|
||||
* @param aSource is an open LIB_SOURCE whose ownership is
|
||||
|
@ -246,13 +232,20 @@ public:
|
|||
//-----<use delegates: source and sink>---------------------------------
|
||||
|
||||
/**
|
||||
* Function GetPart
|
||||
* returns a PART given @a aPartName, such as "passives/R".
|
||||
* @param aPartName is local to this LIB and does not have the logical
|
||||
* library name prefixed.
|
||||
* Function LookupPart
|
||||
* returns a PART given @a aPartName, such as "passives/R". No ownership
|
||||
* is given to the PART, it stays in the cache that is this LIB.
|
||||
*
|
||||
* @param aLPID is the part to lookup. The logicalLibName can be empty in it
|
||||
* since yes, we know which LIB is in play.
|
||||
*
|
||||
* @return PART* - The desired PART and will never be NULL. No ownership is
|
||||
* given to caller. PARTs always reside in the cache that is a LIB.
|
||||
*
|
||||
* @throw IO_ERROR if the part cannot be found or loaded.
|
||||
*/
|
||||
const PART* GetPart( const STRING& aPartName ) throw( IO_ERROR );
|
||||
|
||||
PART* LookupPart( const LPID& aLPID )
|
||||
throw( IO_ERROR );
|
||||
|
||||
/**
|
||||
* Function ReloadPart
|
||||
|
@ -273,8 +266,7 @@ public:
|
|||
* creates cache entries for the very same parts if they do not already exist
|
||||
* in this LIB (i.e. cache).
|
||||
*/
|
||||
STRINGS GetCategoricalPartNames( const STRING& aCategory=StrEmpty ) throw( IO_ERROR );
|
||||
|
||||
STRINGS GetCategoricalPartNames( const STRING& aCategory = "" ) throw( IO_ERROR );
|
||||
|
||||
|
||||
//-----<.use delegates: source and sink>--------------------------------
|
||||
|
@ -317,6 +309,9 @@ public:
|
|||
return STRINGS();
|
||||
}
|
||||
|
||||
#if defined(DEBUG)
|
||||
static void Test( int argc, char** argv ) throw( IO_ERROR );
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -22,11 +22,13 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <set>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sch_lib_table.h>
|
||||
#include <sch_lib_table_lexer.h>
|
||||
#include <sch_lpid.h>
|
||||
#include <set>
|
||||
#include <sch_lib_table.h>
|
||||
#include <sch_dir_lib_source.h>
|
||||
|
||||
//using namespace std; // screws up Doxygen
|
||||
using namespace SCH;
|
||||
|
@ -185,14 +187,99 @@ STRINGS LIB_TABLE::GetLogicalLibs()
|
|||
}
|
||||
|
||||
|
||||
PART* LIB_TABLE::GetPart( const LPID& aLogicalPartID ) throw( IO_ERROR )
|
||||
PART* LIB_TABLE::LookupPart( const LPID& aLogicalPartID, LIB* aLocalLib )
|
||||
throw( IO_ERROR )
|
||||
{
|
||||
// need LIPD done.
|
||||
return 0;
|
||||
LIB* lib = lookupLib( aLogicalPartID, aLocalLib );
|
||||
|
||||
return lib->LookupPart( aLogicalPartID );
|
||||
}
|
||||
|
||||
|
||||
const LIB_TABLE::ROW* LIB_TABLE::FindRow( const STRING& aLogicalName ) const
|
||||
LIB* LIB_TABLE::lookupLib( const LPID& aLogicalPartID, LIB* aLocalLib )
|
||||
throw( IO_ERROR )
|
||||
{
|
||||
if( aLocalLib )
|
||||
{
|
||||
return aLocalLib;
|
||||
}
|
||||
else
|
||||
{
|
||||
const STRING& logName = aLogicalPartID.GetLogicalLib();
|
||||
|
||||
if( logName.size() )
|
||||
{
|
||||
ROW* row = FindRow( logName );
|
||||
if( !row )
|
||||
{
|
||||
STRING msg = "Unable to find logical lib ";
|
||||
msg += logName;
|
||||
throw IO_ERROR( msg );
|
||||
}
|
||||
|
||||
if( !row->lib )
|
||||
{
|
||||
loadLib( row );
|
||||
}
|
||||
|
||||
assert( row->lib ); // loadLib() throws if cannot load
|
||||
|
||||
return row->lib;
|
||||
}
|
||||
else
|
||||
{
|
||||
STRING msg = "No logicalLibName in LPID and no localLib";
|
||||
throw IO_ERROR( msg );
|
||||
}
|
||||
}
|
||||
|
||||
// return NULL; never get here
|
||||
}
|
||||
|
||||
|
||||
void LIB_TABLE::loadLib( ROW* aRow ) throw( IO_ERROR )
|
||||
{
|
||||
assert( !aRow->lib ); // caller should know better.
|
||||
|
||||
const STRING& libType = aRow->GetType();
|
||||
|
||||
if( !libType.compare( "dir" ) )
|
||||
{
|
||||
// autor_ptr wrap source while we create sink, in case sink throws.
|
||||
std::auto_ptr<LIB_SOURCE> source(
|
||||
new DIR_LIB_SOURCE(
|
||||
aRow->GetFullURI(),
|
||||
aRow->GetOptions() ) );
|
||||
|
||||
/* @todo load LIB_SINK
|
||||
std::auto_ptr<LIB_SINK> sink(
|
||||
new DIR_LIB_SINK(
|
||||
aRow->GetFullURI(),
|
||||
aRow->GetOptions() ) );
|
||||
*/
|
||||
|
||||
// LIB::LIB( const STRING& aLogicalLibrary, LIB_SOURCE* aSource, LIB_SINK* aSink = NULL );
|
||||
aRow->lib = new LIB( aRow->GetLogicalName(), source.release(), NULL );
|
||||
}
|
||||
|
||||
else if( !libType.compare( "schematic" ) )
|
||||
{
|
||||
// @todo code and load SCHEMATIC_LIB_SOURCE
|
||||
}
|
||||
|
||||
else if( !libType.compare( "subversion" ) )
|
||||
{
|
||||
// @todo code and load SVN_LIB_SOURCE
|
||||
}
|
||||
|
||||
else if( !libType.compare( "http" ) )
|
||||
{
|
||||
// @todo code and load HTTP_LIB_SOURCE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LIB_TABLE::ROW* LIB_TABLE::FindRow( const STRING& aLogicalName ) const
|
||||
{
|
||||
// this function must be *super* fast, so therefore should not instantiate
|
||||
// anything which would require using the heap. This function is the reason
|
||||
|
@ -207,7 +294,7 @@ const LIB_TABLE::ROW* LIB_TABLE::FindRow( const STRING& aLogicalName ) const
|
|||
if( it != cur->rows.end() )
|
||||
{
|
||||
// reference: http://myitcorner.com/blog/?p=361
|
||||
return (const LIB_TABLE::ROW*) it->second; // found
|
||||
return (LIB_TABLE::ROW*) it->second; // found
|
||||
}
|
||||
|
||||
// not found, search fall back table(s), if any
|
||||
|
@ -247,7 +334,7 @@ bool LIB_TABLE::InsertRow( std::auto_ptr<ROW>& aRow, bool doReplace )
|
|||
}
|
||||
|
||||
|
||||
#if 1 && defined(DEBUG)
|
||||
#if 0 && defined(DEBUG)
|
||||
|
||||
// build this with a Debug CMAKE_BUILD_TYPE
|
||||
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
|
||||
#include <string>
|
||||
#include <boost/ptr_container/ptr_map.hpp>
|
||||
|
||||
#include <sch_lib.h>
|
||||
//#include <sch_lpid.h>
|
||||
|
||||
class SCH_LIB_TABLE_LEXER; // outside namespace SCH, since make_lexer() Functions.cmake can't do namespace
|
||||
class OUTPUTFORMATTER;
|
||||
|
@ -197,14 +199,14 @@ public:
|
|||
STRING fullURI;
|
||||
STRING options;
|
||||
|
||||
LIB* lib;
|
||||
LIB* lib; ///< ownership of the loaded LIB is here
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Constructor LIB_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
|
||||
* a record is not found in this table. No ownership is taken of aFallBackTable.
|
||||
*/
|
||||
|
@ -218,9 +220,9 @@ public:
|
|||
*
|
||||
* <pre>
|
||||
* (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)(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))
|
||||
* </pre>
|
||||
*
|
||||
* When this function is called, the input token stream given by \a aLexer
|
||||
|
@ -236,6 +238,7 @@ public:
|
|||
* Function Format
|
||||
* serializes this object as utf8 text to an OUTPUTFORMATTER, and tries to
|
||||
* make it look good using multiple lines and indentation.
|
||||
*
|
||||
* @param out is an OUTPUTFORMATTER
|
||||
* @param nestLevel is the indentation level to base all lines of the output.
|
||||
* Actual indentation will be 2 spaces for each nestLevel.
|
||||
|
@ -243,13 +246,26 @@ public:
|
|||
void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR );
|
||||
|
||||
/**
|
||||
* Function GetPart
|
||||
* Function LookupPart
|
||||
* 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 open a LIB in this table that was not previously opened.
|
||||
*
|
||||
* @param aLogicalPartID holds the partName and may also hold the logicalLibName. If
|
||||
* logicalLibName is empty, then @a aFallBackLib should not be NULL.
|
||||
*
|
||||
* @param aFallBackLib is used only if aLogicalPartID has an empty logicalLibName.
|
||||
* This is for the case when an LPID has no logicalLibName because the LPID is using
|
||||
* a partName from the same LIB as was the referring content.
|
||||
*
|
||||
* @return PART* - this will never be NULL, and no ownership is transfered because
|
||||
* all PARTs live in LIBs. You only get to point to them in some LIB. If the PART
|
||||
* cannot be found, then an exception is thrown.
|
||||
*
|
||||
* @throw IO_ERROR if any problem occurs or if the part cannot be found.
|
||||
*/
|
||||
PART* GetPart( const LPID& aLogicalPartID ) throw( IO_ERROR );
|
||||
PART* LookupPart( const LPID& aLogicalPartID, LIB* aFallBackLib = NULL ) throw( IO_ERROR );
|
||||
|
||||
/**
|
||||
* Function GetLogicalLibs
|
||||
|
@ -322,12 +338,42 @@ protected: // only a table editor can use these
|
|||
|
||||
/**
|
||||
* Function FindRow
|
||||
* returns a ROW* if aLogicalName is found in this table or in fallBack, else NULL.
|
||||
* returns a ROW* if aLogicalName is found in this table or in any chained
|
||||
* fallBack table fragment, else NULL.
|
||||
*/
|
||||
const ROW* FindRow( const STRING& aLogicalName ) const;
|
||||
ROW* FindRow( const STRING& aLogicalName ) const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Function lookupLib
|
||||
* finds or loads a LIB based on @a aLogicalPartID or @a aFallBackLib.
|
||||
* If the LIB is already loaded then it is returned as is, else it is loaded.
|
||||
*
|
||||
* @param aLogicalPartID may hold the logicalLibName. If
|
||||
* logicalLibName is empty, then @a aLocalLib should not be NULL.
|
||||
*
|
||||
* @param aLocalLib is used if not NULL, and should be supplied especiallly if
|
||||
* aLogicalPartID has an empty logicalLibName. This is for the case when
|
||||
* a partName must come from the same LIB as the referring content.
|
||||
* For example, a PART extends another PART in the same LIB and the extends
|
||||
* LPID has no logical lib name.
|
||||
*
|
||||
* @return LIB* - this will never be NULL, and no ownership is transfered because
|
||||
* all LIBs live in the LIB_TABLEs. You only get to point to them in some LIB_TABLE.
|
||||
* If the LIB cannot be found, then an exception is thrown.
|
||||
*
|
||||
* @throw IO_ERROR if any problem occurs or if the LIB cannot be found or cannot be loaded.
|
||||
*/
|
||||
LIB* lookupLib( const LPID& aLogicalPartID, LIB* aLocalLib = NULL ) throw( IO_ERROR );
|
||||
|
||||
/**
|
||||
* Function loadLib
|
||||
* loads a LIB using information in @a aRow. Call only if LIB not
|
||||
* already loaded.
|
||||
*/
|
||||
void loadLib( ROW* aRow ) throw( IO_ERROR );
|
||||
|
||||
typedef boost::ptr_map<STRING, ROW> ROWS;
|
||||
typedef ROWS::iterator ROWS_ITER;
|
||||
typedef ROWS::const_iterator ROWS_CITER;
|
||||
|
|
|
@ -23,8 +23,9 @@
|
|||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include <wx/wx.h> // _()
|
||||
|
||||
#include <sch_lpid.h>
|
||||
#include <wx/wx.h>
|
||||
|
||||
using namespace SCH;
|
||||
|
||||
|
@ -61,7 +62,8 @@ const char* EndsWithRev( const char* start, const char* tail, char separator )
|
|||
//----<Policy and field test functions>-------------------------------------
|
||||
|
||||
// These all return -1 on success, or >= 0 if there is an error at a
|
||||
// particular character offset into their respectives arguments.
|
||||
// particular character offset into their respective arguments. If >=0,
|
||||
// then that return value gives the character offset of the error.
|
||||
|
||||
static inline int okLogical( const STRING& aField )
|
||||
{
|
||||
|
@ -97,7 +99,7 @@ static int okRevision( const STRING& aField )
|
|||
strcpy( rev, "x/" );
|
||||
strcat( rev, aField.c_str() );
|
||||
|
||||
if( EndsWithRev( rev ) == rev+2 )
|
||||
if( EndsWithRev( rev, rev + strlen(rev) ) == rev+2 )
|
||||
return -1; // success
|
||||
}
|
||||
|
||||
|
@ -191,7 +193,7 @@ LPID::LPID( const STRING& aLPID ) throw( PARSE_ERROR )
|
|||
}
|
||||
|
||||
|
||||
STRING LPID::GetLogicalLib() const
|
||||
const STRING& LPID::GetLogicalLib() const
|
||||
{
|
||||
return logical;
|
||||
}
|
||||
|
@ -208,7 +210,7 @@ int LPID::SetLogicalLib( const STRING& aLogical )
|
|||
}
|
||||
|
||||
|
||||
STRING LPID::GetCategory() const
|
||||
const STRING& LPID::GetCategory() const
|
||||
{
|
||||
return category;
|
||||
}
|
||||
|
@ -225,7 +227,7 @@ int LPID::SetCategory( const STRING& aCategory )
|
|||
}
|
||||
|
||||
|
||||
STRING LPID::GetBaseName() const
|
||||
const STRING& LPID::GetBaseName() const
|
||||
{
|
||||
return baseName;
|
||||
}
|
||||
|
@ -259,7 +261,7 @@ STRING LPID::GetPartName() const
|
|||
}
|
||||
|
||||
|
||||
STRING LPID::GetRevision() const
|
||||
const STRING& LPID::GetRevision() const
|
||||
{
|
||||
return revision;
|
||||
}
|
||||
|
|
|
@ -25,14 +25,22 @@
|
|||
#ifndef SCH_LPID_H_
|
||||
#define SCH_LPID_H_
|
||||
|
||||
#include <sch_lib.h> // STRING
|
||||
#include <utf8.h>
|
||||
#include <kicad_exceptions.h>
|
||||
|
||||
namespace SCH {
|
||||
|
||||
/**
|
||||
* Class LPID
|
||||
* (aka GUID) is a Logical Part ID and consists of various portions much like a URI.
|
||||
* It relies heavily on a logical library name to hide where actual physical library
|
||||
* sources reside. Its static functions serve as managers of the "library table" to
|
||||
* map logical library names to actual library sources.
|
||||
* It is a container for the separated portions of a logical part id STRING so they
|
||||
* can be accessed individually. The various portions of an LPID are:
|
||||
* logicalLibraryName, category, baseName, and revision. Only the baseName is
|
||||
* mandatory. There is another construct called "partName" which consists of
|
||||
* [category/]baseName. That is the category followed by a slash, but only if
|
||||
* the category is not empty.
|
||||
* <p>
|
||||
* partName = [category/]baseName
|
||||
* <p>
|
||||
* Example LPID string:
|
||||
* "kicad:passives/R/rev6".
|
||||
|
@ -41,8 +49,9 @@
|
|||
* <li> "kicad" is the logical library name.
|
||||
* <li> "passives" is the category.
|
||||
* <li> "passives/R" is the partname.
|
||||
* <li> "rev6" is the revision number, which is optional. If missing then its
|
||||
* delimiter should also not be present.
|
||||
* <li> "rev6" is the revision, which is optional. If missing then its
|
||||
* / delimiter should also not be present. A revision must begin with
|
||||
* "rev" and be followed by at least one or more decimal digits.
|
||||
* </ul>
|
||||
* @author Dick Hollenbeck
|
||||
*/
|
||||
|
@ -52,7 +61,6 @@ public:
|
|||
|
||||
LPID();
|
||||
|
||||
|
||||
/**
|
||||
* Constructor LPID
|
||||
* takes aLPID string and parses it. A typical LPID string uses a logical
|
||||
|
@ -76,7 +84,7 @@ public:
|
|||
* for this portion since it comes from the library table and is considered
|
||||
* read only here.
|
||||
*/
|
||||
STRING GetLogicalLib() const;
|
||||
const STRING& GetLogicalLib() const;
|
||||
|
||||
/**
|
||||
* Function SetCategory
|
||||
|
@ -92,7 +100,7 @@ public:
|
|||
* returns the category of this part id, "passives" in the example at the
|
||||
* top of the class description.
|
||||
*/
|
||||
STRING GetCategory() const;
|
||||
const STRING& GetCategory() const;
|
||||
|
||||
/**
|
||||
* Function SetCategory
|
||||
|
@ -108,7 +116,7 @@ public:
|
|||
* Function GetBaseName
|
||||
* returns the part name without the category.
|
||||
*/
|
||||
STRING GetBaseName() const;
|
||||
const STRING& GetBaseName() const;
|
||||
|
||||
/**
|
||||
* Function SetBaseName
|
||||
|
@ -120,7 +128,7 @@ public:
|
|||
int SetBaseName( const STRING& aBaseName );
|
||||
|
||||
/**
|
||||
* Function GetBaseName
|
||||
* Function GetPartName
|
||||
* returns the part name, i.e. category/baseName without revision.
|
||||
*/
|
||||
STRING GetPartName() const;
|
||||
|
@ -134,9 +142,9 @@ public:
|
|||
|
||||
/**
|
||||
* Function GetRevision
|
||||
* returns the revision portion of the LPID or StrEmpty if none.
|
||||
* returns the revision portion of the LPID.
|
||||
*/
|
||||
STRING GetRevision() const;
|
||||
const STRING& GetRevision() const;
|
||||
|
||||
/**
|
||||
* Function SetRevision
|
||||
|
@ -161,10 +169,11 @@ public:
|
|||
protected:
|
||||
STRING logical; ///< logical lib name or empty
|
||||
STRING category; ///< or empty
|
||||
STRING baseName; ///< excludes category
|
||||
STRING baseName; ///< without category
|
||||
STRING revision; ///< "revN[N..]" or empty
|
||||
};
|
||||
|
||||
} // namespace SCH
|
||||
|
||||
/**
|
||||
* Function EndsWithRev
|
||||
|
|
|
@ -31,7 +31,7 @@ void PART::Parse( LIB* aLexer ) throw( PARSE_ERROR )
|
|||
}
|
||||
|
||||
|
||||
#if 1
|
||||
#if 0 && defined(DEBUG)
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
|
||||
#ifndef UTF8_H_
|
||||
#define UTF8_H_
|
||||
|
||||
#include <string>
|
||||
#include <deque>
|
||||
|
||||
/**
|
||||
* @ingroup string_types
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Type STRING
|
||||
* holds a sequence of 8 bit bytes that represent a sequence
|
||||
* of variable multi-byte international characters, with unspecified encoding.
|
||||
*/
|
||||
typedef std::string STRING;
|
||||
|
||||
|
||||
/**
|
||||
* Type STRING_UTF8
|
||||
* holds a UTF8 encoded sequence of 8 bit bytes that represent a sequence
|
||||
* of variable multi-byte international characters. UTF8 is the chosen encoding
|
||||
* for all Kicad data files so that they can be transported from one nation to another
|
||||
* without ambiguity. Data files are those where Kicad controls the content.
|
||||
* This is not the same thing as filenames, which are not file content.
|
||||
* Filenames may be encoded on disk using an encoding chosen by the host operating
|
||||
* system. Nonetheless, Kicad data file _content_ is always UTF8 encoded, regardless
|
||||
* of host operating system.
|
||||
* STRING_UTF is UTF8 encoded, by definition.
|
||||
*/
|
||||
typedef STRING STRING_UTF8;
|
||||
|
||||
|
||||
/**
|
||||
* Type STRINGS_UTF8
|
||||
* is an "array like" list of STRING_UTF8s
|
||||
*/
|
||||
typedef std::deque<STRING> STRINGS_UTF8;
|
||||
|
||||
typedef std::deque<STRING> STRINGS;
|
||||
|
||||
|
||||
/** @} string_types */
|
||||
|
||||
|
||||
// @todo this does not belong here
|
||||
#ifndef D
|
||||
#ifdef DEBUG
|
||||
#define D(x) x
|
||||
#else
|
||||
#define D(x) // nothing
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // UTF8_H_
|
Loading…
Reference in New Issue