Commit a6e21516 authored by Dick Hollenbeck's avatar Dick Hollenbeck

implement more of SCH::LIB_TABLE, start SCH::LPID, enhance richio

parents 7ca0b717 a7c11a0b
...@@ -65,7 +65,7 @@ DSNLEXER::DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount, ...@@ -65,7 +65,7 @@ DSNLEXER::DSNLEXER( const KEYWORD* aKeywordTable, unsigned aKeywordCount,
keywords( aKeywordTable ), keywords( aKeywordTable ),
keywordCount( aKeywordCount ) keywordCount( aKeywordCount )
{ {
FILE_LINE_READER* fileReader = new FILE_LINE_READER( aFile, aFilename, 4096 ); FILE_LINE_READER* fileReader = new FILE_LINE_READER( aFile, aFilename );
PushReader( fileReader ); PushReader( fileReader );
init(); init();
} }
......
...@@ -82,11 +82,23 @@ void LINE_READER::expandCapacity( unsigned newsize ) ...@@ -82,11 +82,23 @@ void LINE_READER::expandCapacity( unsigned newsize )
} }
FILE_LINE_READER::FILE_LINE_READER( FILE* aFile, const wxString& aFileName, unsigned aMaxLineLength ) : FILE_LINE_READER::FILE_LINE_READER( FILE* aFile, const wxString& aFileName,
bool doOwn,
unsigned aStartingLineNumber,
unsigned aMaxLineLength ) :
LINE_READER( aMaxLineLength ), LINE_READER( aMaxLineLength ),
iOwn( doOwn ),
fp( aFile ) fp( aFile )
{ {
source = aFileName; source = aFileName;
lineNum = aStartingLineNumber;
}
FILE_LINE_READER::~FILE_LINE_READER()
{
if( iOwn && fp )
fclose( fp );
} }
...@@ -117,6 +129,29 @@ unsigned FILE_LINE_READER::ReadLine() throw( IO_ERROR ) ...@@ -117,6 +129,29 @@ unsigned FILE_LINE_READER::ReadLine() throw( IO_ERROR )
} }
STRING_LINE_READER::STRING_LINE_READER( const std::string& aString, const wxString& aSource ) :
LINE_READER( LINE_READER_LINE_DEFAULT_MAX ),
lines( aString ),
ndx( 0 )
{
// Clipboard text should be nice and _use multiple lines_ so that
// we can report _line number_ oriented error messages when parsing.
source = aSource;
}
STRING_LINE_READER::STRING_LINE_READER( const STRING_LINE_READER& aStartingPoint ) :
LINE_READER( LINE_READER_LINE_DEFAULT_MAX ),
lines( aStartingPoint.lines ),
ndx( aStartingPoint.ndx )
{
// since we are keeping the same "source" name, for error reporting purposes
// we need to have the same notion of line number and offset.
source = aStartingPoint.source;
lineNum = aStartingPoint.lineNum;
}
unsigned STRING_LINE_READER::ReadLine() throw( IO_ERROR ) unsigned STRING_LINE_READER::ReadLine() throw( IO_ERROR )
{ {
size_t nlOffset = lines.find( '\n', ndx ); size_t nlOffset = lines.find( '\n', ndx );
......
...@@ -53,7 +53,7 @@ class LINE_READER ...@@ -53,7 +53,7 @@ class LINE_READER
{ {
protected: protected:
unsigned length; ///< no. bytes in line before trailing nul. unsigned length; ///< no. bytes in line before trailing nul.
int lineNum; unsigned lineNum;
char* line; ///< the read line of UTF8 text char* line; ///< the read line of UTF8 text
unsigned capacity; ///< no. bytes allocated for line. unsigned capacity; ///< no. bytes allocated for line.
...@@ -115,7 +115,7 @@ public: ...@@ -115,7 +115,7 @@ public:
* returns the line number of the last line read from this LINE_READER. Lines * returns the line number of the last line read from this LINE_READER. Lines
* start from 1. * start from 1.
*/ */
int LineNumber() const unsigned LineNumber() const
{ {
return lineNum; return lineNum;
} }
...@@ -140,7 +140,8 @@ class FILE_LINE_READER : public LINE_READER ...@@ -140,7 +140,8 @@ class FILE_LINE_READER : public LINE_READER
{ {
protected: protected:
FILE* fp; ///< I own this file bool iOwn; ///< if I own the file, I'll promise to close it, else not.
FILE* fp; ///< I may own this file, but might not.
public: public:
...@@ -151,15 +152,23 @@ public: ...@@ -151,15 +152,23 @@ public:
* *
* @param aFile is an open file. * @param aFile is an open file.
* @param aFileName is the name of the file for error reporting purposes. * @param aFileName is the name of the file for error reporting purposes.
* @param doOwn if true, means I should close the open file, else not.
* @param aStartingLineNumber is the initial line number to report on error, and is
* accessible here for the case where multiple DSNLEXERs are reading from the
* same file in sequence, all from the same open file (with @a doOwn = false).
* Internally it is incremented by one after each ReadLine(), so the first
* reported line number will always be one greater than what is provided here.
* @param aMaxLineLength is the number of bytes to use in the line buffer. * @param aMaxLineLength is the number of bytes to use in the line buffer.
*/ */
FILE_LINE_READER( FILE* aFile, const wxString& aFileName, unsigned aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX ); FILE_LINE_READER( FILE* aFile, const wxString& aFileName, bool doOwn = true,
unsigned aStartingLineNumber = 0,
unsigned aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX );
~FILE_LINE_READER() /**
{ * Destructor
if( fp ) * may or may not close the open file, depending on @a doOwn in constructor.
fclose( fp ); */
} ~FILE_LINE_READER();
unsigned ReadLine() throw( IO_ERROR ); // see LINE_READER::ReadLine() description unsigned ReadLine() throw( IO_ERROR ); // see LINE_READER::ReadLine() description
...@@ -198,17 +207,17 @@ public: ...@@ -198,17 +207,17 @@ public:
* @param aSource describes the source of aString for error reporting purposes * @param aSource describes the source of aString for error reporting purposes
* can be anything meaninful, such as wxT( "clipboard" ). * can be anything meaninful, such as wxT( "clipboard" ).
*/ */
STRING_LINE_READER( const std::string& aString, const wxString& aSource ) : STRING_LINE_READER( const std::string& aString, const wxString& aSource );
LINE_READER( LINE_READER_LINE_DEFAULT_MAX ),
lines( aString ), /**
ndx( 0 ) * Constructor STRING_LINE_READER( const STRING_LINE_READER& )
{ * allows for a continuation of the reading of a stream started by another
// Clipboard text should be nice and _use multiple lines_ so that * STRING_LINE_READER. Any stream offset and source name are used from
// we can report _line number_ oriented error messages when parsing. * @a aStartingPoint.
source = aSource; */
} STRING_LINE_READER( const STRING_LINE_READER& aStartingPoint );
unsigned ReadLine() throw( IO_ERROR ); // see LINE_READER::ReadLine() description unsigned ReadLine() throw( IO_ERROR ); // see LINE_READER::ReadLine() description
}; };
......
...@@ -371,158 +371,6 @@ const STRING StrEmpty = ""; ...@@ -371,158 +371,6 @@ const STRING StrEmpty = "";
/** @} exception_types Exception Types */ /** @} exception_types Exception Types */
/**
* 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.
* <p>
* Example LPID string:
* "kicad:passives/R/rev6".
* <p>
* <ul>
* <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.
* </ul>
* <p>
* This class owns the <b>library table</b>, which is like fstab in concept and maps logical
* library name to library URI, type, and options. It has the following columns:
* <ul>
* <li> Logical Library Name
* <li> Library Type
* <li> Library URI. The full URI to the library source, form dependent on Type.
* <li> Options, used for access, such as password
* </ul>
* <p>
* For now, the Library Type can be one of:
* <ul>
* <li> "dir"
* <li> "schematic" i.e. a parts list from another schematic.
* <li> "subversion"
* <li> "bazaar"
* <li> "http"
* </ul>
* <p>
* For now, the Library URI types needed to support the various types can be one of those
* shown below, which are typical of each type:
* <ul>
* <li> "file://C:/mylibdir"
* <li> "file://home/user/kicadwork/jtagboard.sch"
* <li> "svn://kicad.org/partlib/trunk"
* <li> "http://kicad.org/partlib"
* </ul>
* <p>
* The applicable library table is built up from several additive rows (table fragments),
* and the final table is a merging of the table fragments. Two anticipated sources of
* the rows are a personal table, and a schematic resident table. The schematic
* resident table rows are considered a higher priority in the final dynamically
* assembled library table. A row in the schematic contribution to the library table
* will take precedence over the personal table if there is a collision on logical
* library name, otherwise the rows simply combine without issue to make up the
* applicable library table.
*/
class LPID // aka GUID
{
public:
/**
* Constructor LPID
* takes aLPID string and parses it. A typical LPID string uses a logical
* library name followed by a part name.
* e.g.: "kicad:passives/R/rev2", or
* e.g.: "mylib:R33"
*/
LPID( const STRING& aLPID ) throw( PARSE_ERROR );
/**
* Function GetLogLib
* returns the logical library portion of a LPID. There is not Set accessor
* for this portion since it comes from the library table and is considered
* read only here.
*/
STRING GetLogLib() const;
/**
* Function GetCategory
* returns the category of this part id, "passives" in the example at the
* top of the class description.
*/
STRING GetCategory() const;
/**
* 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".
*/
void SetCategory( const STRING& aCategory );
/**
* Function GetRevision
* returns the revision portion of the LPID or StrEmpty if none.
*/
STRING GetRevision() const;
/**
* Function SetRevision
* overrides the revision portion of the LPID to @a aRevision and must
* be in the form "rev<num>" where "<num>" is "1", "2", etc.
*/
void SetRevision( const STRING& aRevision );
/**
* Function GetFullText
* returns the full text of the LPID.
*/
STRING GetFullText() const;
//-----<statics>-----------------------------------------------------
/**
* Function GetLogicalLibraries
* returns the logical library names, all of them that are in the
* library table.
* @param aSchematic provides access to the full library table inclusive
* of the schematic contribution, or may be NULL to exclude the schematic rows.
*/
static STRINGS GetLogicalLibraries( SCHEMATIC* aSchematic=NULL );
/**
* Function GetLibraryURI
* returns the full library path from a logical library name.
* @param aLogicalLibraryName is the short name for the library of interest.
* @param aSchematic provides access to the full library table inclusive
* of the schematic contribution, or may be NULL to exclude the schematic rows.
*/
static STRING GetLibraryURI( const STRING& aLogicalLibraryName,
SCHEMATIC* aSchematic=NULL ) const;
/**
* Function GetLibraryType
* returns the type of a logical library.
* @param aLogicalLibraryName is the short name for the library of interest.
* @param aSchematic provides access to the full library table inclusive
* of the schematic contribution, or may be NULL to exclude the schematic rows.
*/
static STRING GetLibraryType( const STRING& aLogicalLibraryName,
SCHEMATIC* aSchematic=NULL ) const;
/**
* Function GetOptions
* returns the options string for \a aLogicalLibraryName.
* @param aLogicalLibraryName is the short name for the library of interest.
* @param aSchematic provides access to the full library table inclusive
* of the schematic contribution, or may be NULL to exclude the schematic rows.
*/
static STRING GetPassword( const STRING& aLogicalLibraryName,
SCHEMATIC* aSchematic=NULL ) const;
};
/** /**
* Class SVN_LIB_SOURCE * Class SVN_LIB_SOURCE
* implements a LIB_SOURCE in a subversion repository. * implements a LIB_SOURCE in a subversion repository.
......
...@@ -30,8 +30,10 @@ using namespace std; ...@@ -30,8 +30,10 @@ using namespace std;
using namespace SCH; using namespace SCH;
LIB_TABLE::LIB_TABLE( LIB_TABLE* aFallBackTable ) LIB_TABLE::LIB_TABLE( LIB_TABLE* aFallBackTable ) :
fallBack( aFallBackTable )
{ {
/* not copying fall back, simply search it separately if "logicalName not found".
if( aFallBackTable ) if( aFallBackTable )
{ {
const ROWS& t = aFallBackTable->rows; const ROWS& t = aFallBackTable->rows;
...@@ -39,12 +41,12 @@ LIB_TABLE::LIB_TABLE( LIB_TABLE* aFallBackTable ) ...@@ -39,12 +41,12 @@ LIB_TABLE::LIB_TABLE( LIB_TABLE* aFallBackTable )
for( ROWS_CITER it = t.begin(); it != t.end(); ++it ) for( ROWS_CITER it = t.begin(); it != t.end(); ++it )
{ {
// our rows are empty, expect no collisions here // our rows are empty, expect no collisions here
auto_ptr<ROW> row( new ROW( *it ) ); auto_ptr<ROW> row( new ROW( *it->second ) );
row->owner = this; row->owner = this;
rows.insert( row.release() ); insert( row );
} }
} }
*/
} }
...@@ -126,18 +128,89 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR ) ...@@ -126,18 +128,89 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
in->NeedRIGHT(); in->NeedRIGHT();
in->NeedRIGHT(); // teriminate the (lib..) in->NeedRIGHT(); // teriminate the (lib..)
rows.insert( row.release() ); // all logicalNames within this table fragment must be unique, so we do not
// replace. However a fallBack table can have a conflicting logicalName
// and ours will supercede that one since in findLib() we search this table
// before any fall back.
if( !InsertLib( row ) )
{
char buf[300];
snprintf( buf, sizeof(buf),
"'%s' is a duplicate logical lib name",
row->logicalName.c_str() );
throw IO_ERROR( buf );
}
} }
return; return;
} }
#if 1 void LIB_TABLE::Format( OUTPUTFORMATTER* out, int nestLevel ) const
throw( IO_ERROR )
{
out->Print( nestLevel, "(lib_table\n" );
for( ROWS_CITER it = rows.begin(); it != rows.end(); ++it )
it->second->Format( out, nestLevel+1 );
out->Print( nestLevel, ")\n" );
}
void LIB_TABLE::ROW::Format( OUTPUTFORMATTER* out, int nestLevel ) const
throw( IO_ERROR )
{
out->Print( nestLevel, "(lib (logical \"%s\")(type \"%s\")(full_uri \"%s\")(options \"%s\"))\n",
logicalName.c_str(), libType.c_str(), fullURI.c_str(), options.c_str() );
}
int main( int argc, char** argv ) const LIB_TABLE::ROW* LIB_TABLE::FindLib( const STRING& aLogicalName )
{
// this function must be *super* fast, so therefore should not instantiate
// anything which would require using the heap. This function is the reason
// ptr_map<> was used instead of ptr_set<>, which would have required
// instantiating a ROW just to find a ROW.
ROWS_CITER it = rows.find( aLogicalName );
if( it != rows.end() )
{
// reference: http://myitcorner.com/blog/?p=361
return (const LIB_TABLE::ROW*) it->second; // found
}
// not found, search fall back table
if( fallBack )
return fallBack->FindLib( aLogicalName );
return 0; // not found
}
bool LIB_TABLE::InsertLib( auto_ptr<ROW>& aRow, bool doReplace )
{
ROWS_ITER it = rows.find( aRow->logicalName );
if( doReplace || it == rows.end() )
{
// be careful here, key is needed because aRow can be
// release()ed before logicalName is captured.
const STRING& key = aRow->logicalName;
rows.insert( key, aRow );
return true;
}
return false;
}
#if 1 && defined(DEBUG)
// build this with a Debug CMAKE_BUILD_TYPE
void LIB_TABLE::Test()
{ {
// the null string is not really a legal DSN token since any double quotes // the null string is not really a legal DSN token since any double quotes
// as assumed to be a single quote. To pass an empty string, we pass " " // are assumed to be a single quote. To pass an empty string, we pass " "
// to (options " ") // to (options " ")
SCH_LIB_TABLE_LEXER slr( SCH_LIB_TABLE_LEXER slr(
"(lib_table \n" "(lib_table \n"
...@@ -148,16 +221,14 @@ int main( int argc, char** argv ) ...@@ -148,16 +221,14 @@ int main( int argc, char** argv )
wxT( "inline text" ) // source wxT( "inline text" ) // source
); );
LIB_TABLE lib_table;
// read the "( lib_table" pair of tokens
try try
{ {
// read the "( lib_table" pair of tokens
slr.NextTok(); slr.NextTok();
slr.NextTok(); slr.NextTok();
lib_table.Parse( &slr ); // parse the rest of input to slr
Parse( &slr );
} }
catch( std::exception& ex ) catch( std::exception& ex )
...@@ -167,11 +238,36 @@ int main( int argc, char** argv ) ...@@ -167,11 +238,36 @@ int main( int argc, char** argv )
catch( IO_ERROR ioe ) catch( IO_ERROR ioe )
{ {
printf( "caught\n" );
printf( "exception: %s\n", (const char*) wxConvertWX2MB( ioe.errorText ) ); printf( "exception: %s\n", (const char*) wxConvertWX2MB( ioe.errorText ) );
} }
lib_table.Show(); STRING_FORMATTER sf;
Format( &sf, 0 );
printf( "test 'Parse() <-> Format()' round tripping:\n" );
printf( "%s", sf.GetString().c_str() );
printf( "\ntest a lookup of 'www':\n" );
sf.Clear();
const LIB_TABLE::ROW* www = FindLib( "www" );
if( www )
{
// found, print it just to prove it.
www->Format( &sf, 1 );
printf( "%s", sf.GetString().c_str() );
}
else
printf( "not found\n" );
}
int main( int argc, char** argv )
{
LIB_TABLE lib_table;
lib_table.Test();
return 0; return 0;
} }
......
...@@ -26,13 +26,17 @@ ...@@ -26,13 +26,17 @@
#define SCH_LIB_TABLE_H_ #define SCH_LIB_TABLE_H_
#include <string> #include <string>
#include <boost/ptr_container/ptr_set.hpp> #include <boost/ptr_container/ptr_map.hpp>
#include <sch_lib.h> #include <sch_lib.h>
class SCH_LIB_TABLE_LEXER; // outside namespace SCH, since make_lexer() Functions.cmake can't do namespace class SCH_LIB_TABLE_LEXER; // outside namespace SCH, since make_lexer() Functions.cmake can't do namespace
class OUTPUTFORMATTER;
namespace SCH { namespace SCH {
class LPID;
class PART;
/** /**
* Class LIB_TABLE * Class LIB_TABLE
* holds LIB_TABLE::ROW records, and can be searched in a very high speed * holds LIB_TABLE::ROW records, and can be searched in a very high speed
...@@ -54,10 +58,12 @@ public: ...@@ -54,10 +58,12 @@ public:
public: public:
/* was needed for ptr_set<> but not ptr_map<>
bool operator<( const ROW& other ) const bool operator<( const ROW& other ) const
{ {
return logicalName < other.logicalName; return logicalName < other.logicalName;
} }
*/
/** /**
* Function GetLogicalName * Function GetLogicalName
...@@ -101,13 +107,16 @@ public: ...@@ -101,13 +107,16 @@ public:
delete lib; delete lib;
} }
#if defined(DEBUG) /**
void Show() const * Function Format
{ * serializes this object as utf8 text to an OUTPUTFORMATTER, and tries to
printf( "(lib (logical \"%s\")(type \"%s\")(full_uri \"%s\")(options \"%s\"))\n", * make it look good using multiple lines and indentation.
logicalName.c_str(), libType.c_str(), fullURI.c_str(), options.c_str() ); * @param out is an OUTPUTFORMATTER
} * @param nestLevel is the indentation level to base all lines of the output.
#endif * Actual indentation will be 2 spaces for each nestLevel.
*/
void Format( OUTPUTFORMATTER* out, int nestLevel ) const
throw( IO_ERROR );
protected: protected:
...@@ -195,23 +204,100 @@ public: ...@@ -195,23 +204,100 @@ public:
*/ */
void Parse( SCH_LIB_TABLE_LEXER* aLexer ) throw( IO_ERROR ); void Parse( SCH_LIB_TABLE_LEXER* aLexer ) throw( IO_ERROR );
/**
* 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.
*/
void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IO_ERROR );
/**
* Function GetPart
* 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.
*/
PART* GetPart( const LPID& aLogicalPartID ) throw( IO_ERROR );
#if 0 // moved here from LPID
/**
* Function GetLogicalLibraries
* returns the logical library names, all of them that are in the
* library table.
*/
STRINGS GetLogicalLibraries();
/**
* Function GetLibraryURI
* returns the full library path from a logical library name.
* @param aLogicalLibraryName is the short name for the library of interest.
* @param aSchematic provides access to the full library table inclusive
* of the schematic contribution, or may be NULL to exclude the schematic rows.
*/
STRING GetLibraryURI( const STRING& aLogicalLibraryName,
SCHEMATIC* aSchematic=NULL ) const;
/**
* Function GetLibraryType
* returns the type of a logical library.
* @param aLogicalLibraryName is the short name for the library of interest.
* @param aSchematic provides access to the full library table inclusive
* of the schematic contribution, or may be NULL to exclude the schematic rows.
*/
STRING GetLibraryType( const STRING& aLogicalLibraryName,
SCHEMATIC* aSchematic=NULL ) const;
/**
* Function GetOptions
* returns the options string for \a aLogicalLibraryName.
* @param aLogicalLibraryName is the short name for the library of interest.
* @param aSchematic provides access to the full library table inclusive
* of the schematic contribution, or may be NULL to exclude the schematic rows.
*/
STRING GetOptions( const STRING& aLogicalLibraryName,
SCHEMATIC* aSchematic=NULL ) const;
#endif
#if defined(DEBUG) #if defined(DEBUG)
void Show() const /// implement the tests in here so we can honor the priviledge levels of the
{ /// accessors, something difficult to do from int main(int, char**)
printf("(lib_table\n" ); void Test();
for( ROWS_CITER it = rows.begin(); it != rows.end(); ++it )
it->Show();
printf(")\n" );
}
#endif #endif
typedef boost::ptr_set<ROW> ROWS; protected: // only a table editor can use these
typedef ROWS::iterator ROWS_ITER;
typedef ROWS::const_iterator ROWS_CITER; /**
* Function InsertLib
* adds aRow if it does not already exist or if doReplace is true. If doReplace
* is not true and the key for aRow already exists, the function fails and returns false.
* @param aRow is the new row to insert, or to forcibly add if doReplace is true.
* @param doReplace if true, means insert regardless if aRow's key already exists. If false, then fail
* if the key already exists.
* @return bool - true if the operation succeeded.
*/
bool InsertLib( std::auto_ptr<ROW>& aRow, bool doReplace = false );
/**
* Function FindLib
* returns a ROW* if aLogicalName is found in this table or in fallBack.
*/
const ROW* FindLib( const STRING& aLogicalName );
private: private:
ROWS rows; typedef boost::ptr_map<STRING, ROW> ROWS;
typedef ROWS::iterator ROWS_ITER;
typedef ROWS::const_iterator ROWS_CITER;
// typedef std::pair<ROWS_ITER, bool> ROW_PAIR;
ROWS rows;
LIB_TABLE* fallBack;
}; };
} // namespace SCH } // namespace SCH
......
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <sch_lpid.h>
using namespace SCH;
LPID::LPID( const STRING& aLPID ) throw( PARSE_ERROR )
{
}
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef SCH_LPID_H_
#define SCH_LPID_H_
//#include <wx/string.h>
/**
* 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.
* <p>
* Example LPID string:
* "kicad:passives/R/rev6".
* <p>
* <ul>
* <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.
* </ul>
* <p>
* This class owns the <b>library table</b>, which is like fstab in concept and maps logical
* library name to library URI, type, and options. It has the following columns:
* <ul>
* <li> Logical Library Name
* <li> Library Type
* <li> Library URI. The full URI to the library source, form dependent on Type.
* <li> Options, used for access, such as password
* </ul>
* <p>
* For now, the Library Type can be one of:
* <ul>
* <li> "dir"
* <li> "schematic" i.e. a parts list from another schematic.
* <li> "subversion"
* <li> "bazaar"
* <li> "http"
* </ul>
* <p>
* For now, the Library URI types needed to support the various types can be one of those
* shown below, which are typical of each type:
* <ul>
* <li> "file://C:/mylibdir"
* <li> "file://home/user/kicadwork/jtagboard.sch"
* <li> "svn://kicad.org/partlib/trunk"
* <li> "http://kicad.org/partlib"
* </ul>
* <p>
* The applicable library table is built up from several additive rows (table fragments),
* and the final table is a merging of the table fragments. Two anticipated sources of
* the rows are a personal table, and a schematic resident table. The schematic
* resident table rows are considered a higher priority in the final dynamically
* assembled library table. A row in the schematic contribution to the library table
* will take precedence over the personal table if there is a collision on logical
* library name, otherwise the rows simply combine without issue to make up the
* applicable library table.
*/
class LPID // aka GUID
{
public:
/**
* Constructor LPID
* takes aLPID string and parses it. A typical LPID string uses a logical
* library name followed by a part name.
* e.g.: "kicad:passives/R/rev2", or
* e.g.: "mylib:R33"
*/
LPID( const STRING& aLPID ) throw( PARSE_ERROR );
/**
* Function GetLogLib
* returns the logical library portion of a LPID. There is not Set accessor
* for this portion since it comes from the library table and is considered
* read only here.
*/
STRING GetLogLib() const;
/**
* Function GetCategory
* returns the category of this part id, "passives" in the example at the
* top of the class description.
*/
STRING GetCategory() const;
/**
* 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".
*/
void SetCategory( const STRING& aCategory );
/**
* Function GetRevision
* returns the revision portion of the LPID or StrEmpty if none.
*/
STRING GetRevision() const;
/**
* Function SetRevision
* overrides the revision portion of the LPID to @a aRevision and must
* be in the form "rev<num>" where "<num>" is "1", "2", etc.
*/
void SetRevision( const STRING& aRevision );
/**
* Function GetFullText
* returns the full text of the LPID.
*/
STRING GetFullText() const;
};
#endif // SCH_LPID_H_
...@@ -174,7 +174,7 @@ bool WinEDA_PcbFrame::ReadPcbNetlist( const wxString& aNetlistFullFilename, ...@@ -174,7 +174,7 @@ bool WinEDA_PcbFrame::ReadPcbNetlist( const wxString& aNetlistFullFilename,
if( !netfile ) if( !netfile )
return false; return false;
FILE_LINE_READER netlistReader( netfile, aNetlistFullFilename, BUFFER_CHAR_SIZE ); FILE_LINE_READER netlistReader( netfile, aNetlistFullFilename );
char* Line = netlistReader; char* Line = netlistReader;
SetLastNetListRead( aNetlistFullFilename ); SetLastNetListRead( aNetlistFullFilename );
...@@ -798,7 +798,7 @@ int BuildFootprintsListFromNetlistFile( const wxString& aNetlistFullFilename, ...@@ -798,7 +798,7 @@ int BuildFootprintsListFromNetlistFile( const wxString& aNetlistFullFilename,
if( !netfile ) if( !netfile )
return -1; return -1;
FILE_LINE_READER netlistReader( netfile, aNetlistFullFilename, BUFFER_CHAR_SIZE ); FILE_LINE_READER netlistReader( netfile, aNetlistFullFilename );
char* Line = netlistReader; char* Line = netlistReader;
State = 0; Comment = 0; State = 0; Comment = 0;
...@@ -901,7 +901,7 @@ int ReadListeModules( const wxString& CmpFullFileName, const wxString* RefCmp, ...@@ -901,7 +901,7 @@ int ReadListeModules( const wxString& CmpFullFileName, const wxString* RefCmp,
return 0; return 0;
} }
FILE_LINE_READER netlistReader( FichCmp, CmpFullFileName, BUFFER_CHAR_SIZE ); FILE_LINE_READER netlistReader( FichCmp, CmpFullFileName );
char* Line = netlistReader; char* Line = netlistReader;
while( netlistReader.ReadLine() ) while( netlistReader.ReadLine() )
......
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