From f6def3eaf4159b2c46afc9f8caeb0b3c4815e744 Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Tue, 28 Dec 2010 19:22:37 -0600 Subject: [PATCH] ++new: Completed most of /new class LIB_TABLE. Completed all of /new class LPID. --- CHANGELOG.txt | 4 +- new/sch_lpid.cpp | 145 +++++++++++++++++++++++++++++++++++++---------- new/sch_lpid.h | 40 +++++++++---- 3 files changed, 146 insertions(+), 43 deletions(-) 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/new/sch_lpid.cpp b/new/sch_lpid.cpp index 5d73680963..12e3dfd740 100644 --- a/new/sch_lpid.cpp +++ b/new/sch_lpid.cpp @@ -24,7 +24,7 @@ #include #include - +#include using namespace SCH; @@ -58,17 +58,74 @@ const char* EndsWithRev( const char* start, const char* tail, char separator ) } -LPID::LPID( const STRING& aLPID ) throw( PARSE_ERROR ) +//----------------------------------------- + +// These all return -1 on success, or >= 0 if there is an error at a +// particular character offset into their respectives arguments. + +static inline int okLogical( const STRING& aField ) { + // std::string::npos is largest positive number, casting to int makes it -1. + // Returning that means success. + return int( aField.find_first_of( ":/" ) ); +} + +static inline int okBase( const STRING& aField ) +{ + int offset = int( aField.find_first_of( ":/" ) ); + if( offset != -1 ) + return offset; + + // cannot be empty + if( !aField.size() ) + return 0; + + return offset; // ie. -1 +} + +static inline int okCategory( const STRING& aField ) +{ + return int( aField.find_first_of( ":/" ) ); +} + +static int okRevision( const STRING& aField ) +{ + char rev[32]; // C string for speed + + if( aField.size() >= 4 && aField.size() <= sizeof(rev)-3 ) + { + strcpy( rev, "x/" ); + strcat( rev, aField.c_str() ); + + if( EndsWithRev( rev ) == rev+2 ) + return -1; // success + } + + return 0; // first character position "is in error", is best we can do. +} + +//----------------------------------------- + + +int LPID::Parse( const STRING& aLPID ) +{ + logical.clear(); + category.clear(); + baseName.clear(); + revision.clear(); + const char* rev = EndsWithRev( aLPID ); size_t revNdx; size_t partNdx; size_t baseNdx; + int offset; //============================================== if( rev ) { - revNdx = rev - aLPID.c_str(); + revNdx = rev - aLPID.c_str(); + + // no need to check revision, EndsWithRev did that. revision = aLPID.substr( revNdx ); --revNdx; // back up to omit the '/' which preceeds the rev } @@ -78,7 +135,11 @@ LPID::LPID( const STRING& aLPID ) throw( PARSE_ERROR ) //=============================================== if( ( partNdx = aLPID.find( ':' ) ) != aLPID.npos ) { - logical = aLPID.substr( 0, partNdx ); + offset = SetLogicalLib( aLPID.substr( 0, partNdx ) ); + if( offset > -1 ) + { + return offset; + } ++partNdx; // skip ':' } else @@ -91,7 +152,11 @@ LPID::LPID( const STRING& aLPID ) throw( PARSE_ERROR ) if( base ) { baseNdx = base - aLPID.c_str(); - category = aLPID.substr( partNdx, baseNdx - partNdx ); + offset = SetCategory( aLPID.substr( partNdx, baseNdx - partNdx ) ); + if( offset > -1 ) + { + return offset + partNdx; + } ++baseNdx; // skip '/' } else @@ -100,7 +165,29 @@ LPID::LPID( const STRING& aLPID ) throw( PARSE_ERROR ) } //=============================================== - baseName = aLPID.substr( baseNdx, revNdx - baseNdx ); + offset = SetBaseName( aLPID.substr( baseNdx, revNdx - baseNdx ) ); + if( offset > -1 ) + { + return offset + baseNdx; + } + + return -1; +} + + +LPID::LPID( const STRING& aLPID ) throw( PARSE_ERROR ) +{ + int offset = Parse( aLPID ); + + if( offset != -1 ) + { + throw PARSE_ERROR( + _( "Illegal character found in LPID string" ), + wxConvertMB2WX( aLPID.c_str() ), + 0, + offset + ); + } } @@ -110,14 +197,14 @@ STRING LPID::GetLogicalLib() const } -bool LPID::SetLogicalLib( const STRING& aLogical ) +int LPID::SetLogicalLib( const STRING& aLogical ) { - if( aLogical.find_first_of( ":/" ) == STRING::npos ) + int offset = okLogical( aLogical ); + if( offset == -1 ) { logical = aLogical; - return true; } - return false; + return offset; } @@ -127,14 +214,14 @@ STRING LPID::GetCategory() const } -bool LPID::SetCategory( const STRING& aCategory ) +int LPID::SetCategory( const STRING& aCategory ) { - if( aCategory.find_first_of( ":/" ) == STRING::npos ) + int offset = okCategory( aCategory ); + if( offset == -1 ) { category = aCategory; - return true; } - return false; + return offset; } @@ -144,14 +231,14 @@ STRING LPID::GetBaseName() const } -bool LPID::SetBaseName( const STRING& aBaseName ) +int LPID::SetBaseName( const STRING& aBaseName ) { - if( aBaseName.find_first_of( ":/" ) == STRING::npos ) + int offset = okBase( aBaseName ); + if( offset == -1 ) { baseName = aBaseName; - return true; } - return false; + return offset; } @@ -178,23 +265,18 @@ STRING LPID::GetRevision() const } -bool LPID::SetRevision( const STRING& aRevision ) +int LPID::SetRevision( const STRING& aRevision ) { - STRING rev; - - rev += "x/"; - rev += aRevision; - - if( EndsWithRev( rev ) ) + int offset = okRevision( aRevision ); + if( offset == -1 ) { revision = aRevision; - return true; } - return false; + return offset; } -STRING LPID::GetFullText() const +STRING LPID::Format() const { STRING ret; @@ -248,12 +330,13 @@ void LPID::Test() LPID lpid( lpids[i] ); // parse // format - printf( "input:'%s' full:'%s' base:'%s' partName:'%s' cat:'%s'\n", + printf( "input:'%s' full:'%s' base:'%s' partName:'%s' cat:'%s' rev:'%s'\n", lpids[i], - lpid.GetFullText().c_str(), + lpid.Format().c_str(), lpid.GetBaseName().c_str(), lpid.GetPartName().c_str(), - lpid.GetCategory().c_str() + lpid.GetCategory().c_str(), + lpid.GetRevision().c_str() ); } } diff --git a/new/sch_lpid.h b/new/sch_lpid.h index bbbef6007b..1f6127cf6a 100644 --- a/new/sch_lpid.h +++ b/new/sch_lpid.h @@ -49,6 +49,10 @@ class LPID // aka GUID { public: + + LPID(); + + /** * Constructor LPID * takes aLPID string and parses it. A typical LPID string uses a logical @@ -58,6 +62,14 @@ public: */ LPID( const STRING& aLPID ) throw( PARSE_ERROR ); + /** + * Function Parse + * [re-]stuffs this LPID with the information from @a aLPID. + * @return int - minus 1 (i.e. -1) means success, >= 0 indicates the + * character offset into aLPID at which an error was detected. + */ + int Parse( const STRING& aLPID ); + /** * Function GetLogicalLib * returns the logical library portion of a LPID. There is not Set accessor @@ -69,9 +81,11 @@ public: /** * Function SetCategory * overrides the logical lib name portion of the LPID to @a aLogical, and can be empty. - * @return bool - true unless parameter has ':' or '/' in it. + * @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 ':'. */ - bool SetLogicalLib( const STRING& aLogical ); + int SetLogicalLib( const STRING& aLogical ); /** * Function GetCategory @@ -84,9 +98,11 @@ public: * Function SetCategory * overrides the category portion of the LPID to @a aCategory and is typically * either the empty string or a single word like "passives". - * @return bool - true unless parameter has ':' or '/' in it. + * @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 ':'. */ - bool SetCategory( const STRING& aCategory ); + int SetCategory( const STRING& aCategory ); /** * Function GetBaseName @@ -97,9 +113,11 @@ public: /** * Function SetBaseName * overrides the base name portion of the LPID to @a aBaseName - * @return bool - true unless parameter has ':' or '/' in it. + * @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 ':', or is blank. */ - bool SetBaseName( const STRING& aBaseName ); + int SetBaseName( const STRING& aBaseName ); /** * Function GetBaseName @@ -124,15 +142,17 @@ public: * Function SetRevision * overrides the revision portion of the LPID to @a aRevision and must * be in the form "rev" where "" is "1", "2", etc. - * @return bool - true unless parameter is not of the form "revN]N..]" + * @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" */ - bool SetRevision( const STRING& aRevision ); + int SetRevision( const STRING& aRevision ); /** - * Function GetFullText + * Function Format * returns the full text of the LPID. */ - STRING GetFullText() const; + STRING Format() const; #if defined(DEBUG) static void Test();