Commit f6265fd2 authored by Dick Hollenbeck's avatar Dick Hollenbeck

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
parent a9010796
......@@ -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,28 +60,37 @@ 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_part sch_part.cpp )
target_link_libraries( test_sch_part ${wxWidgets_LIBRARIES} )
add_executable( test_lpid
sch_lpid.cpp
)
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} )
add_executable( test_sch_part sch_part.cpp )
target_link_libraries( test_sch_part ${wxWidgets_LIBRARIES} )
add_executable( test_lpid
sch_lpid.cpp
)
target_link_libraries( test_lpid ${wxWidgets_LIBRARIES} )
make_lexer(
${CMAKE_CURRENT_SOURCE_DIR}/sch_lib_table.keywords
......
......@@ -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;
/**
* @defgroup exception_types Exception Types
* Provide some exception types for use within the API.
*/
const STRING StrEmpty = "";
/** @} string_types STRING Types */
/**
* \defgroup exception_types Exception Types
* Provide some exception types for use within the API.
* @{
* 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:
/** @} exception_types Exception Types */
/**
* 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 );
}
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
}
}
const LIB_TABLE::ROW* LIB_TABLE::FindRow( const STRING& aLogicalName ) const
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 )
{
......
#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_
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