From 69801630aae827418d8705120aba8d3c93cbaf76 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Wed, 29 Dec 2010 14:30:45 -0600 Subject: [PATCH] changes --- CHANGELOG.txt | 4 +- include/kicad_exceptions.h | 9 +++- new/CMakeLists.txt | 27 ++++++---- new/design.h | 70 +++++++++++++++++-------- new/sch_dir_lib_source.cpp | 2 +- new/sch_dir_lib_source.h | 4 +- new/sch_lib.cpp | 21 ++++++++ new/sch_lib.h | 57 ++++++++++---------- new/sch_lib_table.cpp | 103 ++++++++++++++++++++++++++++++++++--- new/sch_lib_table.h | 64 +++++++++++++++++++---- new/sch_lpid.cpp | 16 +++--- new/sch_lpid.h | 37 ++++++++----- new/sch_part.cpp | 2 +- new/utf8.h | 58 +++++++++++++++++++++ 14 files changed, 366 insertions(+), 108 deletions(-) create mode 100644 new/utf8.h diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 53522cca1a..212ae4fcfc 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -7,8 +7,8 @@ email address. 2010-Dec-28 UPDATE Dick Hollenbeck ================================================================================ ++new: - Completed a good portion of /new class LIB_TABLE. - Starting LPID. + Completed most of /new class LIB_TABLE. + Completed all of /new class LPID. ++common: Tricked xnode.h into not issuing deprecation warnings. ++richio: diff --git a/include/kicad_exceptions.h b/include/kicad_exceptions.h index a05dbf268b..659f507690 100644 --- a/include/kicad_exceptions.h +++ b/include/kicad_exceptions.h @@ -25,8 +25,10 @@ #ifndef KICAD_EXCEPTIONS_H_ #define KICAD_EXCEPTIONS_H_ -/* Just exceptions -*/ +/** + * @ingroup exception_types + * @{ + */ #include @@ -84,4 +86,7 @@ struct PARSE_ERROR : public IO_ERROR } }; +/** @} exception_types */ + + #endif // KICAD_EXCEPTIONS_H_ diff --git a/new/CMakeLists.txt b/new/CMakeLists.txt index 518a45f54d..1ea96fec40 100644 --- a/new/CMakeLists.txt +++ b/new/CMakeLists.txt @@ -60,20 +60,14 @@ endif() include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ) +#================================= +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 ) + +#================================ + +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 diff --git a/new/design.h b/new/design.h index 0aadf2ec57..831af35534 100644 --- a/new/design.h +++ b/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. +

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.

-Show architecture here. - - Click here to see an architectural drawing. +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 STRINGS; - -//typedef std::vector 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 diff --git a/new/sch_dir_lib_source.cpp b/new/sch_dir_lib_source.cpp index cc9be1419b..db70c6fdad 100644 --- a/new/sch_dir_lib_source.cpp +++ b/new/sch_dir_lib_source.cpp @@ -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 ) { diff --git a/new/sch_dir_lib_source.h b/new/sch_dir_lib_source.h index 1e6d09f38f..5e64ddec05 100644 --- a/new/sch_dir_lib_source.h +++ b/new/sch_dir_lib_source.h @@ -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. */ diff --git a/new/sch_lib.cpp b/new/sch_lib.cpp index 9a5f423da7..20b4a61bca 100644 --- a/new/sch_lib.cpp +++ b/new/sch_lib.cpp @@ -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 diff --git a/new/sch_lib.h b/new/sch_lib.h index fe907e0118..bcc1cff3dc 100644 --- a/new/sch_lib.h +++ b/new/sch_lib.h @@ -25,27 +25,13 @@ #ifndef SCH_LIB_H_ #define SCH_LIB_H_ -#include -#include - +#include #include -#ifdef DEBUG -#define D(x) x -#else -#define D(x) // nothing -#endif - - -typedef std::string STRING; -typedef std::deque 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: //-------------------------------------- /** - * 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: diff --git a/new/sch_lib_table.cpp b/new/sch_lib_table.cpp index 5dd66ebfe0..4f3a05ed68 100644 --- a/new/sch_lib_table.cpp +++ b/new/sch_lib_table.cpp @@ -22,11 +22,13 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include +#include -#include #include #include -#include +#include +#include //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 source( + new DIR_LIB_SOURCE( + aRow->GetFullURI(), + aRow->GetOptions() ) ); + + /* @todo load LIB_SINK + std::auto_ptr 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& aRow, bool doReplace ) } -#if 1 && defined(DEBUG) +#if 0 && defined(DEBUG) // build this with a Debug CMAKE_BUILD_TYPE diff --git a/new/sch_lib_table.h b/new/sch_lib_table.h index 5b860a37c1..fcb8458bf3 100644 --- a/new/sch_lib_table.h +++ b/new/sch_lib_table.h @@ -27,7 +27,9 @@ #include #include + #include +//#include 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: * *

      * (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))
      * 
* * 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 ROWS; typedef ROWS::iterator ROWS_ITER; typedef ROWS::const_iterator ROWS_CITER; diff --git a/new/sch_lpid.cpp b/new/sch_lpid.cpp index 12e3dfd740..8ec603e0c5 100644 --- a/new/sch_lpid.cpp +++ b/new/sch_lpid.cpp @@ -23,8 +23,9 @@ */ #include +#include // _() + #include -#include using namespace SCH; @@ -61,7 +62,8 @@ const char* EndsWithRev( const char* start, const char* tail, char separator ) //----------------------------------------- // 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; } diff --git a/new/sch_lpid.h b/new/sch_lpid.h index 1f6127cf6a..7653c2a8a8 100644 --- a/new/sch_lpid.h +++ b/new/sch_lpid.h @@ -25,14 +25,22 @@ #ifndef SCH_LPID_H_ #define SCH_LPID_H_ -#include // STRING +#include +#include + +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. + *

+ * partName = [category/]baseName *

* Example LPID string: * "kicad:passives/R/rev6". @@ -41,8 +49,9 @@ *

  • "kicad" is the logical library name. *
  • "passives" is the category. *
  • "passives/R" is the partname. - *
  • "rev6" is the revision number, which is optional. If missing then its - * delimiter should also not be present. + *
  • "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. * * @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 diff --git a/new/sch_part.cpp b/new/sch_part.cpp index 9a93109811..12f726d759 100644 --- a/new/sch_part.cpp +++ b/new/sch_part.cpp @@ -31,7 +31,7 @@ void PART::Parse( LIB* aLexer ) throw( PARSE_ERROR ) } -#if 1 +#if 0 && defined(DEBUG) int main( int argc, char** argv ) { diff --git a/new/utf8.h b/new/utf8.h new file mode 100644 index 0000000000..94109c88ef --- /dev/null +++ b/new/utf8.h @@ -0,0 +1,58 @@ + +#ifndef UTF8_H_ +#define UTF8_H_ + +#include +#include + +/** + * @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 STRINGS_UTF8; + +typedef std::deque 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_