Loading TODO.txt +51 −1 Original line number Diff line number Diff line Loading @@ -20,12 +20,62 @@ Common WinEDA_BasicFrame ) so that file open behavior is consistent across all applications. * Look over Brian's python BOM generation scripts, which are now in scripts/python/ky and sort them out, and get something into the installation as well. scripts/python/ky and sort them out. Code came from Brian in this posting's attachment, which is ky2.zip: https://lists.launchpad.net/kicad-developers/msg06763.html but is now in scripts/python/ky temporarily. FP LIB TABLE ------------ Dialog: - - - - a) check for duplicate nicknames in a single table, complain, give the user a nice indication of the duplicate(s) b) in the uri column give a small button popup a window(dialog?) which lets user choose a file or directory local to his system by pointing at it. c) Active library table load and save functions. There are two tables active at any time, but they look like one table. Identify a place to keep the access mechanism (pointer). Modify the project specific portion of this RAM table when the board changes. Other: - - - - a) develop a syntax for nickname:footprint combo, i.e. bring to life class FPID with development and testing of parsing and formatting. b) modify cvpcb to handle the nickname:footprint, i.e. textual form of FPID. This means having a wider textfield for the FPID than was allocated for the footprint name alone. Needed is the ability to pick a footprint from any active library. c) modify the netlist format to handle nickname:footprint, save and load. The nickname needs to be optional. I would say allowed in the grammar in the footprint position are: footprint | (fp_id FPID) or just FPID # if it can be parsed when nickname is missing. d) write functions to lookup a footprint from i) FPID ii) footprint alone since most old netlists don't have nicknames in them. These i) and ii) merge into one if footprint alone is a valid FPID. Incorporate any environment variable in the the uri expansion using: const wxString FP_LIB_TABLE::ExpandSubtitutions( const wxString aString ) EESchema -------- * Drag and drop between two EESchema windows. Loading common/CMakeLists.txt +1 −1 Original line number Diff line number Diff line Loading @@ -127,7 +127,7 @@ set(PCB_COMMON_SRCS pcb_keywords.cpp ../pcbnew/pcb_parser.cpp fp_lib_table_keywords.cpp fp_lib_id.cpp # fpid.cpp fp_lib_table.cpp ) Loading common/fp_lib_id.cpp→common/fpid.cpp +14 −14 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ #include <cstring> #include <wx/wx.h> // _() #include <fp_lib_id.h> #include <fpid.h> static inline bool isDigit( char c ) Loading Loading @@ -106,7 +106,7 @@ static int okRevision( const std::string& aField ) //----</Policy and field test functions>------------------------------------- void FP_LIB_ID::clear() void FPID::clear() { logical.clear(); footprintName.clear(); Loading @@ -114,7 +114,7 @@ void FP_LIB_ID::clear() } int FP_LIB_ID::Parse( const std::string& aId ) int FPID::Parse( const std::string& aId ) { clear(); Loading Loading @@ -158,13 +158,13 @@ int FP_LIB_ID::Parse( const std::string& aId ) } FP_LIB_ID::FP_LIB_ID( const std::string& aId ) throw( PARSE_ERROR ) FPID::FPID( const std::string& aId ) throw( PARSE_ERROR ) { int offset = Parse( aId ); if( offset != -1 ) { THROW_PARSE_ERROR( _( "Illegal character found in FP_LIB_ID string" ), THROW_PARSE_ERROR( _( "Illegal character found in FPID string" ), wxString::FromUTF8( aId.c_str() ), aId.c_str(), 0, Loading @@ -173,7 +173,7 @@ FP_LIB_ID::FP_LIB_ID( const std::string& aId ) throw( PARSE_ERROR ) } int FP_LIB_ID::SetLogicalLib( const std::string& aLogical ) int FPID::SetLogicalLib( const std::string& aLogical ) { int offset = okLogical( aLogical ); Loading @@ -186,7 +186,7 @@ int FP_LIB_ID::SetLogicalLib( const std::string& aLogical ) } int FP_LIB_ID::SetFootprintName( const std::string& aFootprintName ) int FPID::SetFootprintName( const std::string& aFootprintName ) { int separation = int( aFootprintName.find_first_of( "/" ) ); Loading @@ -204,7 +204,7 @@ int FP_LIB_ID::SetFootprintName( const std::string& aFootprintName ) } int FP_LIB_ID::SetRevision( const std::string& aRevision ) int FPID::SetRevision( const std::string& aRevision ) { int offset = okRevision( aRevision ); Loading @@ -217,7 +217,7 @@ int FP_LIB_ID::SetRevision( const std::string& aRevision ) } std::string FP_LIB_ID::Format() const std::string FPID::Format() const { std::string ret; Loading @@ -237,7 +237,7 @@ std::string FP_LIB_ID::Format() const } std::string FP_LIB_ID::GetFootprintNameAndRev() const std::string FPID::GetFootprintNameAndRev() const { std::string ret; Loading @@ -251,7 +251,7 @@ std::string FP_LIB_ID::GetFootprintNameAndRev() const } std::string FP_LIB_ID::Format( const std::string& aLogicalLib, const std::string& aFootprintName, std::string FPID::Format( const std::string& aLogicalLib, const std::string& aFootprintName, const std::string& aRevision ) throw( PARSE_ERROR ) { Loading Loading @@ -300,7 +300,7 @@ std::string FP_LIB_ID::Format( const std::string& aLogicalLib, const std::string // build this with Debug CMAKE_BUILD_TYPE void FP_LIB_ID::Test() void FPID::Test() { static const char* lpids[] = { "smt:R_0805/rev0", Loading @@ -312,7 +312,7 @@ void FP_LIB_ID::Test() { // test some round tripping FP_LIB_ID lpid( lpids[i] ); // parse FPID lpid( lpids[i] ); // parse // format printf( "input:'%s' full:'%s' logical: %s footprintName:'%s' rev:'%s'\n", Loading @@ -327,7 +327,7 @@ void FP_LIB_ID::Test() int main( int argc, char** argv ) { FP_LIB_ID::Test(); FPID::Test(); return 0; } Loading include/fp_lib_table.h +1 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ #include <vector> #include <map> #include <fp_lib_id.h> //#include <fpid.h> #include <io_mgr.h> Loading include/fp_lib_id.h→include/fpip.h +33 −97 Original line number Diff line number Diff line Loading @@ -23,22 +23,22 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef _FP_LIB_ID_H_ #define _FP_LIB_ID_H_ #ifndef _FPID_H_ #define _FPID_H_ #include <richio.h> /** * Class FP_LIB_ID * Class FPID * is a Logical Footprint ID and consists of various portions much like a URI. * It is a container for the separated portions of a logical footprint id so they * can be accessed individually. The various portions of an FP_LIB_ID are: * can be accessed individually. The various portions of an FPID are: * logicalLibraryName (nick name), footprint name, and revision. The logical library * name and the footprint name are mandatory. The revision is optional and currently is * not used. * * Example FP_LIB_ID string: * Example FPID string: * "smt:R_0805/rev0". * * <p> Loading @@ -53,111 +53,77 @@ * * @author Dick Hollenbeck */ class FP_LIB_ID // aka GUID class FPID // aka GUID { public: FP_LIB_ID() {} FPID() {} /** * Constructor FP_LIB_ID * takes \a aId string and parses it. A typical FP_LIB_ID string consists of a logical * library name followed by a footprint name. * Constructor FPID * takes \a aId string and parses it. A typical FPID string consists of a * library nickname followed by a footprint name. * e.g.: "smt:R_0805", or * e.g.: "mylib:R_0805" * * @param aId is a string to be parsed into the FP_LIB_ID object. * @param aId is a string to be parsed into the FPID object. */ FP_LIB_ID( const std::string& aId ) throw( PARSE_ERROR ); FPID( const wxString& aId ) throw( PARSE_ERROR ); /** * Function Parse * [re-]stuffs this FP_LIB_ID with the information from @a aId. * [re-]stuffs this FPID with the information from @a aId. * * @param aId is the string to populate the #FP_LIB_ID object. * @param aId is the string to populate the #FPID object. * @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset into * aId at which an error was detected. */ int Parse( const std::string& aId ); int Parse( const wxString& aId ); /** * Function GetLogicalLib * returns the logical library name portion of a FP_LIB_ID. * Function GetLibNickname * returns the logical library name portion of a FPID. */ const std::string& GetLogicalLib() const const wxString& GetLibNickname() const { return logical; } /** * Function SetLogicalLib * overrides the logical footprint library name portion of the FP_LIB_ID to @a aLogical. * Function SetLibNickname * overrides the logical footprint library name portion of the FPID to @a aNickname. * @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset * into the parameter at which an error was detected, usually because it * contained '/' or ':'. */ int SetLogicalLib( const std::string& aLogical ); int SetLibNickname( const wxString& aNickname ); /** * Function GetFootprintName * returns the footprint name, i.e. footprintName part without revision. * returns the footprint name, i.e. footprintName. */ const std::string& GetFootprintName() const { return footprintName; } /** * Function GetFootprintNameAndRev * returns the part name with revision if any, i.e. footprintName[/revN..] */ std::string GetFootprintNameAndRev() const; const wxString& GetFootprintName() const; /** * Function SetFootprintName * overrides the footprint name portion of the FP_LIB_ID to @a aFootprintName * * @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset * into the parameter at which an error was detected, usually because it contained * more than one '/', or one or more ':', or is blank. * overrides the footprint name portion of the FPID to @a aFootprintName */ int SetFootprintName( const std::string& aFootprintName ); /** * Function GetRevision * returns the revision portion of the FP_LIB_ID. */ const std::string& GetRevision() const { return revision; } /** * Function SetRevision * overrides the revision portion of the FP_LIB_ID to @a aRevision and must * be in the form "rev<num>" where "<num>" is "1", "2", etc. * * @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset* * into the parameter at which an error was detected,because it did not * look like "rev23" */ int SetRevision( const std::string& aRevision ); void SetFootprintName( const wxString& aFootprintName ); /** * Function Format * returns the fully formatted text of the FP_LIB_ID. * returns the fully formatted text of the FPID. */ std::string Format() const; wxString Format() const; /** * Function Format * returns a std::string in the proper format as an FP_LIB_ID for a combination of * aLogicalLib, aFootprintName, and aRevision. * returns a wxString in the proper format as an FPID for a combination of * aLibNickname, aFootprintName, and aRevision. * * @throw PARSE_ERROR if any of the pieces are illegal. */ static std::string Format( const std::string& aLogicalLib, const std::string& aFootprintName, const std::string& aRevision="" ) static wxString Format( const wxString& aLibNickname, const wxString& aFootprintName ) throw( PARSE_ERROR ); void clear(); Loading @@ -167,39 +133,9 @@ public: #endif protected: std::string logical; ///< logical lib name or empty std::string revision; ///< "revN[N..]" or empty std::string footprintName; ///< The name of the footprint in the logical library. wxString nickname; ///< logical lib name or empty wxString footprint; ///< The name of the footprint in the logical library. }; /** * 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 std::string& aFootprintName, char separator = '/' ) { return EndsWithRev( aFootprintName.c_str(), aFootprintName.c_str()+aFootprintName.size(), separator ); } /** * Function RevCmp * compares two rev strings in a way like strcmp() except that the highest numbered * revision is considered first in the sort order. The function probably won't work * unless you give it two rev strings. * @param s1 is a rev string like "rev10" * @param s2 is a rev string like "rev1". * @return int - either negative, zero, or positive depending on whether the revision * is greater, equal, or less on the left hand side. */ int RevCmp( const char* s1, const char* s2 ); #endif // _FP_LIB_ID_H_ #endif // _FPID_H_ Loading
TODO.txt +51 −1 Original line number Diff line number Diff line Loading @@ -20,12 +20,62 @@ Common WinEDA_BasicFrame ) so that file open behavior is consistent across all applications. * Look over Brian's python BOM generation scripts, which are now in scripts/python/ky and sort them out, and get something into the installation as well. scripts/python/ky and sort them out. Code came from Brian in this posting's attachment, which is ky2.zip: https://lists.launchpad.net/kicad-developers/msg06763.html but is now in scripts/python/ky temporarily. FP LIB TABLE ------------ Dialog: - - - - a) check for duplicate nicknames in a single table, complain, give the user a nice indication of the duplicate(s) b) in the uri column give a small button popup a window(dialog?) which lets user choose a file or directory local to his system by pointing at it. c) Active library table load and save functions. There are two tables active at any time, but they look like one table. Identify a place to keep the access mechanism (pointer). Modify the project specific portion of this RAM table when the board changes. Other: - - - - a) develop a syntax for nickname:footprint combo, i.e. bring to life class FPID with development and testing of parsing and formatting. b) modify cvpcb to handle the nickname:footprint, i.e. textual form of FPID. This means having a wider textfield for the FPID than was allocated for the footprint name alone. Needed is the ability to pick a footprint from any active library. c) modify the netlist format to handle nickname:footprint, save and load. The nickname needs to be optional. I would say allowed in the grammar in the footprint position are: footprint | (fp_id FPID) or just FPID # if it can be parsed when nickname is missing. d) write functions to lookup a footprint from i) FPID ii) footprint alone since most old netlists don't have nicknames in them. These i) and ii) merge into one if footprint alone is a valid FPID. Incorporate any environment variable in the the uri expansion using: const wxString FP_LIB_TABLE::ExpandSubtitutions( const wxString aString ) EESchema -------- * Drag and drop between two EESchema windows. Loading
common/CMakeLists.txt +1 −1 Original line number Diff line number Diff line Loading @@ -127,7 +127,7 @@ set(PCB_COMMON_SRCS pcb_keywords.cpp ../pcbnew/pcb_parser.cpp fp_lib_table_keywords.cpp fp_lib_id.cpp # fpid.cpp fp_lib_table.cpp ) Loading
common/fp_lib_id.cpp→common/fpid.cpp +14 −14 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ #include <cstring> #include <wx/wx.h> // _() #include <fp_lib_id.h> #include <fpid.h> static inline bool isDigit( char c ) Loading Loading @@ -106,7 +106,7 @@ static int okRevision( const std::string& aField ) //----</Policy and field test functions>------------------------------------- void FP_LIB_ID::clear() void FPID::clear() { logical.clear(); footprintName.clear(); Loading @@ -114,7 +114,7 @@ void FP_LIB_ID::clear() } int FP_LIB_ID::Parse( const std::string& aId ) int FPID::Parse( const std::string& aId ) { clear(); Loading Loading @@ -158,13 +158,13 @@ int FP_LIB_ID::Parse( const std::string& aId ) } FP_LIB_ID::FP_LIB_ID( const std::string& aId ) throw( PARSE_ERROR ) FPID::FPID( const std::string& aId ) throw( PARSE_ERROR ) { int offset = Parse( aId ); if( offset != -1 ) { THROW_PARSE_ERROR( _( "Illegal character found in FP_LIB_ID string" ), THROW_PARSE_ERROR( _( "Illegal character found in FPID string" ), wxString::FromUTF8( aId.c_str() ), aId.c_str(), 0, Loading @@ -173,7 +173,7 @@ FP_LIB_ID::FP_LIB_ID( const std::string& aId ) throw( PARSE_ERROR ) } int FP_LIB_ID::SetLogicalLib( const std::string& aLogical ) int FPID::SetLogicalLib( const std::string& aLogical ) { int offset = okLogical( aLogical ); Loading @@ -186,7 +186,7 @@ int FP_LIB_ID::SetLogicalLib( const std::string& aLogical ) } int FP_LIB_ID::SetFootprintName( const std::string& aFootprintName ) int FPID::SetFootprintName( const std::string& aFootprintName ) { int separation = int( aFootprintName.find_first_of( "/" ) ); Loading @@ -204,7 +204,7 @@ int FP_LIB_ID::SetFootprintName( const std::string& aFootprintName ) } int FP_LIB_ID::SetRevision( const std::string& aRevision ) int FPID::SetRevision( const std::string& aRevision ) { int offset = okRevision( aRevision ); Loading @@ -217,7 +217,7 @@ int FP_LIB_ID::SetRevision( const std::string& aRevision ) } std::string FP_LIB_ID::Format() const std::string FPID::Format() const { std::string ret; Loading @@ -237,7 +237,7 @@ std::string FP_LIB_ID::Format() const } std::string FP_LIB_ID::GetFootprintNameAndRev() const std::string FPID::GetFootprintNameAndRev() const { std::string ret; Loading @@ -251,7 +251,7 @@ std::string FP_LIB_ID::GetFootprintNameAndRev() const } std::string FP_LIB_ID::Format( const std::string& aLogicalLib, const std::string& aFootprintName, std::string FPID::Format( const std::string& aLogicalLib, const std::string& aFootprintName, const std::string& aRevision ) throw( PARSE_ERROR ) { Loading Loading @@ -300,7 +300,7 @@ std::string FP_LIB_ID::Format( const std::string& aLogicalLib, const std::string // build this with Debug CMAKE_BUILD_TYPE void FP_LIB_ID::Test() void FPID::Test() { static const char* lpids[] = { "smt:R_0805/rev0", Loading @@ -312,7 +312,7 @@ void FP_LIB_ID::Test() { // test some round tripping FP_LIB_ID lpid( lpids[i] ); // parse FPID lpid( lpids[i] ); // parse // format printf( "input:'%s' full:'%s' logical: %s footprintName:'%s' rev:'%s'\n", Loading @@ -327,7 +327,7 @@ void FP_LIB_ID::Test() int main( int argc, char** argv ) { FP_LIB_ID::Test(); FPID::Test(); return 0; } Loading
include/fp_lib_table.h +1 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ #include <vector> #include <map> #include <fp_lib_id.h> //#include <fpid.h> #include <io_mgr.h> Loading
include/fp_lib_id.h→include/fpip.h +33 −97 Original line number Diff line number Diff line Loading @@ -23,22 +23,22 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef _FP_LIB_ID_H_ #define _FP_LIB_ID_H_ #ifndef _FPID_H_ #define _FPID_H_ #include <richio.h> /** * Class FP_LIB_ID * Class FPID * is a Logical Footprint ID and consists of various portions much like a URI. * It is a container for the separated portions of a logical footprint id so they * can be accessed individually. The various portions of an FP_LIB_ID are: * can be accessed individually. The various portions of an FPID are: * logicalLibraryName (nick name), footprint name, and revision. The logical library * name and the footprint name are mandatory. The revision is optional and currently is * not used. * * Example FP_LIB_ID string: * Example FPID string: * "smt:R_0805/rev0". * * <p> Loading @@ -53,111 +53,77 @@ * * @author Dick Hollenbeck */ class FP_LIB_ID // aka GUID class FPID // aka GUID { public: FP_LIB_ID() {} FPID() {} /** * Constructor FP_LIB_ID * takes \a aId string and parses it. A typical FP_LIB_ID string consists of a logical * library name followed by a footprint name. * Constructor FPID * takes \a aId string and parses it. A typical FPID string consists of a * library nickname followed by a footprint name. * e.g.: "smt:R_0805", or * e.g.: "mylib:R_0805" * * @param aId is a string to be parsed into the FP_LIB_ID object. * @param aId is a string to be parsed into the FPID object. */ FP_LIB_ID( const std::string& aId ) throw( PARSE_ERROR ); FPID( const wxString& aId ) throw( PARSE_ERROR ); /** * Function Parse * [re-]stuffs this FP_LIB_ID with the information from @a aId. * [re-]stuffs this FPID with the information from @a aId. * * @param aId is the string to populate the #FP_LIB_ID object. * @param aId is the string to populate the #FPID object. * @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset into * aId at which an error was detected. */ int Parse( const std::string& aId ); int Parse( const wxString& aId ); /** * Function GetLogicalLib * returns the logical library name portion of a FP_LIB_ID. * Function GetLibNickname * returns the logical library name portion of a FPID. */ const std::string& GetLogicalLib() const const wxString& GetLibNickname() const { return logical; } /** * Function SetLogicalLib * overrides the logical footprint library name portion of the FP_LIB_ID to @a aLogical. * Function SetLibNickname * overrides the logical footprint library name portion of the FPID to @a aNickname. * @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset * into the parameter at which an error was detected, usually because it * contained '/' or ':'. */ int SetLogicalLib( const std::string& aLogical ); int SetLibNickname( const wxString& aNickname ); /** * Function GetFootprintName * returns the footprint name, i.e. footprintName part without revision. * returns the footprint name, i.e. footprintName. */ const std::string& GetFootprintName() const { return footprintName; } /** * Function GetFootprintNameAndRev * returns the part name with revision if any, i.e. footprintName[/revN..] */ std::string GetFootprintNameAndRev() const; const wxString& GetFootprintName() const; /** * Function SetFootprintName * overrides the footprint name portion of the FP_LIB_ID to @a aFootprintName * * @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset * into the parameter at which an error was detected, usually because it contained * more than one '/', or one or more ':', or is blank. * overrides the footprint name portion of the FPID to @a aFootprintName */ int SetFootprintName( const std::string& aFootprintName ); /** * Function GetRevision * returns the revision portion of the FP_LIB_ID. */ const std::string& GetRevision() const { return revision; } /** * Function SetRevision * overrides the revision portion of the FP_LIB_ID to @a aRevision and must * be in the form "rev<num>" where "<num>" is "1", "2", etc. * * @return int - minus 1 (i.e. -1) means success, >= 0 indicates the character offset* * into the parameter at which an error was detected,because it did not * look like "rev23" */ int SetRevision( const std::string& aRevision ); void SetFootprintName( const wxString& aFootprintName ); /** * Function Format * returns the fully formatted text of the FP_LIB_ID. * returns the fully formatted text of the FPID. */ std::string Format() const; wxString Format() const; /** * Function Format * returns a std::string in the proper format as an FP_LIB_ID for a combination of * aLogicalLib, aFootprintName, and aRevision. * returns a wxString in the proper format as an FPID for a combination of * aLibNickname, aFootprintName, and aRevision. * * @throw PARSE_ERROR if any of the pieces are illegal. */ static std::string Format( const std::string& aLogicalLib, const std::string& aFootprintName, const std::string& aRevision="" ) static wxString Format( const wxString& aLibNickname, const wxString& aFootprintName ) throw( PARSE_ERROR ); void clear(); Loading @@ -167,39 +133,9 @@ public: #endif protected: std::string logical; ///< logical lib name or empty std::string revision; ///< "revN[N..]" or empty std::string footprintName; ///< The name of the footprint in the logical library. wxString nickname; ///< logical lib name or empty wxString footprint; ///< The name of the footprint in the logical library. }; /** * 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 std::string& aFootprintName, char separator = '/' ) { return EndsWithRev( aFootprintName.c_str(), aFootprintName.c_str()+aFootprintName.size(), separator ); } /** * Function RevCmp * compares two rev strings in a way like strcmp() except that the highest numbered * revision is considered first in the sort order. The function probably won't work * unless you give it two rev strings. * @param s1 is a rev string like "rev10" * @param s2 is a rev string like "rev1". * @return int - either negative, zero, or positive depending on whether the revision * is greater, equal, or less on the left hand side. */ int RevCmp( const char* s1, const char* s2 ); #endif // _FP_LIB_ID_H_ #endif // _FPID_H_