Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
29e829b7
Commit
29e829b7
authored
Dec 28, 2010
by
Dick Hollenbeck
Browse files
Options
Browse Files
Download
Plain Diff
new/sch_lpid.*, fix Doxygen errors in /new
parents
85477537
5311dd70
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
500 additions
and
90 deletions
+500
-90
TokenList2DsnLexer.cmake
CMakeModules/TokenList2DsnLexer.cmake
+7
-0
CMakeLists.txt
new/CMakeLists.txt
+5
-1
design.h
new/design.h
+2
-0
sch_dir_lib_source.cpp
new/sch_dir_lib_source.cpp
+18
-3
sch_dir_lib_source.h
new/sch_dir_lib_source.h
+6
-4
sch_lib_table.cpp
new/sch_lib_table.cpp
+22
-33
sch_lib_table.h
new/sch_lib_table.h
+42
-7
sch_libs.cpp.notused
new/sch_libs.cpp.notused
+15
-0
sch_libs.h.notused
new/sch_libs.h.notused
+81
-0
sch_lpid.cpp
new/sch_lpid.cpp
+233
-0
sch_lpid.h
new/sch_lpid.h
+69
-42
No files found.
CMakeModules/TokenList2DsnLexer.cmake
View file @
29e829b7
...
@@ -220,6 +220,13 @@ extern const unsigned ${result}_keyword_count;
...
@@ -220,6 +220,13 @@ extern const unsigned ${result}_keyword_count;
using namespace DSN; // enum
${
enum
}
is in this namespace
using namespace DSN; // enum
${
enum
}
is in this namespace
/**
* Classs
${
RESULT
}
_LEXER
* is an automatically generated class using the TokenList2DnsLexer.cmake
* technology, based on keywords provided by file:
*
${
inputFile
}
*/
class
${
RESULT
}
_LEXER : public DSNLEXER
class
${
RESULT
}
_LEXER : public DSNLEXER
{
{
public:
public:
...
...
new/CMakeLists.txt
View file @
29e829b7
...
@@ -77,6 +77,11 @@ target_link_libraries( test_sch_lib_table ${wxWidgets_LIBRARIES} )
...
@@ -77,6 +77,11 @@ target_link_libraries( test_sch_lib_table ${wxWidgets_LIBRARIES} )
add_executable
(
test_sch_part sch_part.cpp
)
add_executable
(
test_sch_part sch_part.cpp
)
target_link_libraries
(
test_sch_part
${
wxWidgets_LIBRARIES
}
)
target_link_libraries
(
test_sch_part
${
wxWidgets_LIBRARIES
}
)
add_executable
(
test_lpid
sch_lpid.cpp
)
target_link_libraries
(
test_lpid
${
wxWidgets_LIBRARIES
}
)
make_lexer
(
make_lexer
(
${
CMAKE_CURRENT_SOURCE_DIR
}
/sch_lib_table.keywords
${
CMAKE_CURRENT_SOURCE_DIR
}
/sch_lib_table.keywords
...
@@ -84,4 +89,3 @@ make_lexer(
...
@@ -84,4 +89,3 @@ make_lexer(
${
CMAKE_CURRENT_SOURCE_DIR
}
/sch_lib_table_keywords.cpp
${
CMAKE_CURRENT_SOURCE_DIR
}
/sch_lib_table_keywords.cpp
ELT_T
ELT_T
)
)
new/design.h
View file @
29e829b7
...
@@ -443,4 +443,6 @@ public:
...
@@ -443,4 +443,6 @@ public:
}
// namespace SCH
}
// namespace SCH
/// @todo remove endsWithRev() in favor of EndsWithRev(), find home for it.
// EOF
// EOF
new/sch_dir_lib_source.cpp
View file @
29e829b7
...
@@ -140,6 +140,13 @@ static const char* strrstr( const char* haystack, const char* needle )
...
@@ -140,6 +140,13 @@ static const char* strrstr( const char* haystack, const char* needle )
return
ret
;
return
ret
;
}
}
#if 1 // @todo switch over to EndsWithRev() global
static
inline
bool
isDigit
(
char
c
)
{
return
c
>=
'0'
&&
c
<=
'9'
;
}
static
inline
bool
isDigit
(
char
c
)
static
inline
bool
isDigit
(
char
c
)
{
{
...
@@ -185,6 +192,8 @@ static inline const char* endsWithRev( const STRING& aPartName, char separator )
...
@@ -185,6 +192,8 @@ static inline const char* endsWithRev( const STRING& aPartName, char separator )
return
endsWithRev
(
aPartName
.
c_str
(),
aPartName
.
c_str
()
+
aPartName
.
size
(),
separator
);
return
endsWithRev
(
aPartName
.
c_str
(),
aPartName
.
c_str
()
+
aPartName
.
size
(),
separator
);
}
}
#endif
// see struct BY_REV
// see struct BY_REV
bool
BY_REV
::
operator
()
(
const
STRING
&
s1
,
const
STRING
&
s2
)
const
bool
BY_REV
::
operator
()
(
const
STRING
&
s1
,
const
STRING
&
s2
)
const
...
@@ -587,9 +596,9 @@ void DIR_LIB_SOURCE::cacheOneDir( const STRING& aCategory ) throw( IO_ERROR )
...
@@ -587,9 +596,9 @@ void DIR_LIB_SOURCE::cacheOneDir( const STRING& aCategory ) throw( IO_ERROR )
}
}
#if
(1 || defined( TEST_DIR_LIB_SOURCE ))
&& defined(DEBUG)
#if
1
&& defined(DEBUG)
int
main
(
int
argc
,
char
**
argv
)
void
DIR_LIB_SOURCE
::
Test
(
int
argc
,
char
**
argv
)
{
{
STRINGS
partnames
;
STRINGS
partnames
;
STRINGS
sweets
;
STRINGS
sweets
;
...
@@ -601,7 +610,8 @@ int main( int argc, char** argv )
...
@@ -601,7 +610,8 @@ int main( int argc, char** argv )
// DIR_LIB_SOURCE uut( argv[1] ? argv[1] : "", "" );
// DIR_LIB_SOURCE uut( argv[1] ? argv[1] : "", "" );
DIR_LIB_SOURCE
uut
(
argv
[
1
]
?
argv
[
1
]
:
""
,
"useVersioning"
);
DIR_LIB_SOURCE
uut
(
argv
[
1
]
?
argv
[
1
]
:
""
,
"useVersioning"
);
// initially, only the NAME_CACHE sweets and STRING categories are loaded:
// show the cached content, only the directory information is cached,
// parts are cached in class LIB, not down here.
uut
.
Show
();
uut
.
Show
();
uut
.
GetCategoricalPartNames
(
&
partnames
,
"lions"
);
uut
.
GetCategoricalPartNames
(
&
partnames
,
"lions"
);
...
@@ -649,7 +659,12 @@ int main( int argc, char** argv )
...
@@ -649,7 +659,12 @@ int main( int argc, char** argv )
{
{
printf
(
"exception: %s
\n
"
,
(
const
char
*
)
wxConvertWX2MB
(
ioe
.
errorText
)
);
printf
(
"exception: %s
\n
"
,
(
const
char
*
)
wxConvertWX2MB
(
ioe
.
errorText
)
);
}
}
}
int
main
(
int
argc
,
char
**
argv
)
{
DIR_LIB_SOURCE
::
Test
(
argc
,
argv
);
return
0
;
return
0
;
}
}
...
...
new/sch_dir_lib_source.h
View file @
29e829b7
...
@@ -132,8 +132,7 @@ class DIR_LIB_SOURCE : public LIB_SOURCE
...
@@ -132,8 +132,7 @@ class DIR_LIB_SOURCE : public LIB_SOURCE
*/
*/
STRING
makeFileName
(
const
STRING
&
aPartName
);
STRING
makeFileName
(
const
STRING
&
aPartName
);
//protected:
protected
:
public
:
/**
/**
* Constructor DIR_LIB_SOURCE( const STRING& aDirectoryPath )
* Constructor DIR_LIB_SOURCE( const STRING& aDirectoryPath )
...
@@ -151,8 +150,7 @@ public:
...
@@ -151,8 +150,7 @@ public:
* tree, otherwise only a single version of each part is recognized, namely the
* tree, otherwise only a single version of each part is recognized, namely the
* one without the ".revN[N..]" trailer.
* one without the ".revN[N..]" trailer.
*/
*/
DIR_LIB_SOURCE
(
const
STRING
&
aDirectoryPath
,
const
STRING
&
aOptions
=
""
)
DIR_LIB_SOURCE
(
const
STRING
&
aDirectoryPath
,
const
STRING
&
aOptions
=
""
)
throw
(
IO_ERROR
);
throw
(
IO_ERROR
);
~
DIR_LIB_SOURCE
();
~
DIR_LIB_SOURCE
();
...
@@ -187,6 +185,10 @@ public:
...
@@ -187,6 +185,10 @@ public:
* will output a debug dump of contents.
* will output a debug dump of contents.
*/
*/
void
Show
();
void
Show
();
public
:
static
void
Test
(
int
argc
,
char
**
argv
);
#endif
#endif
};
};
...
...
new/sch_lib_table.cpp
View file @
29e829b7
...
@@ -25,29 +25,18 @@
...
@@ -25,29 +25,18 @@
#include <sch_lib_table.h>
#include <sch_lib_table.h>
#include <sch_lib_table_lexer.h>
#include <sch_lib_table_lexer.h>
#include <sch_lpid.h>
#include <set>
#include <set>
using
namespace
std
;
//using namespace std; // screws up Doxygen
using
namespace
SCH
;
using
namespace
SCH
;
LIB_TABLE
::
LIB_TABLE
(
LIB_TABLE
*
aFallBackTable
)
:
LIB_TABLE
::
LIB_TABLE
(
LIB_TABLE
*
aFallBackTable
)
:
fallBack
(
aFallBackTable
)
fallBack
(
aFallBackTable
)
{
{
/* not copying fall back, simply search aFallBackTable separately if "logicalName not found".
// not copying fall back, simply search aFallBackTable separately
if( aFallBackTable )
// if "logicalName not found".
{
const ROWS& t = aFallBackTable->rows;
for( ROWS_CITER it = t.begin(); it != t.end(); ++it )
{
// our rows are empty, expect no collisions here
auto_ptr<ROW> row( new ROW( *it->second ) );
row->owner = this;
insert( row );
}
}
*/
}
}
...
@@ -56,9 +45,9 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
...
@@ -56,9 +45,9 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
/* grammar:
/* grammar:
(lib_table
(lib_table
(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"
))
(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
))
)
)
note: "(lib_table" has already been read in.
note: "(lib_table" has already been read in.
...
@@ -66,7 +55,7 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
...
@@ -66,7 +55,7 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
ELT_T
tok
;
ELT_T
tok
;
while
(
(
tok
=
in
->
NextTok
()
)
!=
T_RIGHT
&&
tok
!=
T_EOF
)
while
(
(
tok
=
in
->
NextTok
()
)
!=
T_RIGHT
&&
tok
!=
T_EOF
)
{
{
// (lib (logical "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
// (lib (logical "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
...
@@ -83,7 +72,7 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
...
@@ -83,7 +72,7 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
in
->
NeedSYMBOLorNUMBER
();
in
->
NeedSYMBOLorNUMBER
();
auto_ptr
<
ROW
>
row
(
new
ROW
(
this
)
);
std
::
auto_ptr
<
ROW
>
row
(
new
ROW
(
this
)
);
row
->
SetLogicalName
(
in
->
CurText
()
);
row
->
SetLogicalName
(
in
->
CurText
()
);
...
@@ -127,12 +116,12 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
...
@@ -127,12 +116,12 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
row
->
SetOptions
(
in
->
CurText
()
);
row
->
SetOptions
(
in
->
CurText
()
);
in
->
NeedRIGHT
();
in
->
NeedRIGHT
();
in
->
NeedRIGHT
();
// ter
i
minate the (lib..)
in
->
NeedRIGHT
();
// terminate the (lib..)
// all logicalNames within this table fragment must be unique, so we do not
// all logicalNames within this table fragment must be unique, so we do not
//
replace. However a fallBack table can have a conflicting logicalName
//
use doReplace in InsertRow(). However a fallBack table can have a
//
and ours will supercede that one since in FindLib() we search this table
//
conflicting logicalName and ours will supercede that one since in
// before any fall back.
//
FindLib() we search this table
before any fall back.
if
(
!
InsertRow
(
row
)
)
if
(
!
InsertRow
(
row
)
)
{
{
STRING
msg
;
STRING
msg
;
...
@@ -144,7 +133,6 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
...
@@ -144,7 +133,6 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR )
throw
IO_ERROR
(
msg
);
throw
IO_ERROR
(
msg
);
}
}
}
}
return
;
}
}
...
@@ -172,11 +160,12 @@ void LIB_TABLE::ROW::Format( OUTPUTFORMATTER* out, int nestLevel ) const
...
@@ -172,11 +160,12 @@ void LIB_TABLE::ROW::Format( OUTPUTFORMATTER* out, int nestLevel ) const
STRINGS
LIB_TABLE
::
GetLogicalLibs
()
STRINGS
LIB_TABLE
::
GetLogicalLibs
()
{
{
// only return unique logical library names. Use std::set::insert() to
// Only return unique logical library names. Use std::set::insert() to
// quietly reject any duplicates, which can happen in the fall back table(s).
// quietly reject any duplicates, which can happen when encountering a duplicate
set
<
STRING
>
unique
;
// logical lib name from one of the fall back table(s).
STRINGS
ret
;
std
::
set
<
STRING
>
unique
;
STRINGS
ret
;
const
LIB_TABLE
*
cur
=
this
;
const
LIB_TABLE
*
cur
=
this
;
do
do
...
@@ -188,8 +177,8 @@ STRINGS LIB_TABLE::GetLogicalLibs()
...
@@ -188,8 +177,8 @@ STRINGS LIB_TABLE::GetLogicalLibs()
}
while
(
(
cur
=
cur
->
fallBack
)
!=
0
);
}
while
(
(
cur
=
cur
->
fallBack
)
!=
0
);
// return a sorted, unique set of STRINGS to caller
// return a sorted, unique set of
logical lib name
STRINGS to caller
for
(
set
<
STRING
>::
const_iterator
it
=
unique
.
begin
();
it
!=
unique
.
end
();
++
it
)
for
(
s
td
::
s
et
<
STRING
>::
const_iterator
it
=
unique
.
begin
();
it
!=
unique
.
end
();
++
it
)
ret
.
push_back
(
*
it
);
ret
.
push_back
(
*
it
);
return
ret
;
return
ret
;
...
@@ -228,7 +217,7 @@ const LIB_TABLE::ROW* LIB_TABLE::FindRow( const STRING& aLogicalName ) const
...
@@ -228,7 +217,7 @@ const LIB_TABLE::ROW* LIB_TABLE::FindRow( const STRING& aLogicalName ) const
}
}
bool
LIB_TABLE
::
InsertRow
(
auto_ptr
<
ROW
>&
aRow
,
bool
doReplace
)
bool
LIB_TABLE
::
InsertRow
(
std
::
auto_ptr
<
ROW
>&
aRow
,
bool
doReplace
)
{
{
// this does not need to be super fast.
// this does not need to be super fast.
...
...
new/sch_lib_table.h
View file @
29e829b7
...
@@ -41,6 +41,41 @@ class PART;
...
@@ -41,6 +41,41 @@ 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
* way based on logical library name.
* way based on logical library name.
* <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>
* The Library Type can be one of:
* <ul>
* <li> "dir"
* <li> "schematic" i.e. a parts list from another schematic.
* <li> "subversion"
* <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 (conceptual) 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 takes 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.
*
*
* @author Dick Hollenbeck
* @author Dick Hollenbeck
*/
*/
...
@@ -168,7 +203,8 @@ public:
...
@@ -168,7 +203,8 @@ public:
/**
/**
* Constructor LIB_TABLE
* Constructor LIB_TABLE
* builds a library table from an s-expression form of the library 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
* @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.
* a record is not found in this table. No ownership is taken of aFallBackTable.
*/
*/
...
@@ -176,16 +212,15 @@ public:
...
@@ -176,16 +212,15 @@ public:
/**
/**
* Function Parse
* Function Parse
* fills this
objec
t from information in the input stream \a aLexer, which
* fills this
table fragmen
t from information in the input stream \a aLexer, which
* is a DSNLEXER customized for the grammar needed to describe instances of this object.
* is a DSNLEXER customized for the grammar needed to describe instances of this object.
* The entire textual element spec is <br>
* The entire textual element spec is <br>
* (lib_table (logical _yourfieldname_)(value _yourvalue_) visible))
*
*
* <pre>
* <pre>
* (lib_table
* (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)(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
))
* </pre>
* </pre>
*
*
* When this function is called, the input token stream given by \a aLexer
* When this function is called, the input token stream given by \a aLexer
...
@@ -193,7 +228,7 @@ public:
...
@@ -193,7 +228,7 @@ public:
* identifying keyword and before the content specifying stuff.<br>
* identifying keyword and before the content specifying stuff.<br>
* (lib_table ^ (....) )
* (lib_table ^ (....) )
*
*
* @param a
Spec
is the input token stream of keywords and symbols.
* @param a
Lexer
is the input token stream of keywords and symbols.
*/
*/
void
Parse
(
SCH_LIB_TABLE_LEXER
*
aLexer
)
throw
(
IO_ERROR
);
void
Parse
(
SCH_LIB_TABLE_LEXER
*
aLexer
)
throw
(
IO_ERROR
);
...
...
new/sch_libs.cpp.notused
0 → 100644
View file @
29e829b7
/**
* 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 load a new LIB as given in the library table.
*/
static PART* SCH_LIBS::GetPart( const LPID& aLogicalPartID ) throw( IO_ERROR )
{
}
new/sch_libs.h.notused
0 → 100644
View file @
29e829b7
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2010-2011 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_LIBS_H_
#define SCH_LIBS_H_
#include <sch_lib.h>
/**
* Class LIBS
* houses a handful of functions that manage all the RAM resident LIBs, and
* provide for a global part lookup function, GetPart(), which can be the basis
* of a cross LIB hyperlink.
*/
class LIBS
{
public:
/**
* 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 load a new LIB as given in the library table.
*/
static PART* GetPart( const LPID& aLogicalPartID ) throw( IO_ERROR );
/**
* Function GetLib
* is first a lookup function and then if needed, a factory function.
* If aLogicalLibraryName has been opened, then return the already opened
* LIB. If not, then instantiate the library and fill the initial
* library PARTs (unparsed) and categories, and add it to LIB::libraries
* for future reference.
*/
static LIB* GetLib( const STRING& aLogicalLibraryName ) throw( IO_ERROR );
/**
* Function GetOpenedLibNames
* returns the logical library names of LIBs that are already opened.
* @see LPID::GetLogicalLibraries()
*/
static STRINGS GetOpendedLogicalLibNames();
/**
* Function CloseLibrary
* closes an open library @a aLibrary and removes it from class LIBS.
*/
static void CloseLibrary( LIB* aLibrary ) throw( IO_ERROR );
private:
/// collection of LIBs, searchable by logical name.
static std::map< STRING, LIB* > libraries; // owns the LIBs.
};
#endif // SCH_LIBS_H_
new/sch_lpid.cpp
View file @
29e829b7
...
@@ -22,15 +22,248 @@
...
@@ -22,15 +22,248 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
*/
#include <cstring>
#include <sch_lpid.h>
#include <sch_lpid.h>
using
namespace
SCH
;
using
namespace
SCH
;
static
inline
bool
isDigit
(
char
c
)
{
return
c
>=
'0'
&&
c
<=
'9'
;
}
const
char
*
EndsWithRev
(
const
char
*
start
,
const
char
*
tail
,
char
separator
)
{
bool
sawDigit
=
false
;
while
(
tail
>
start
&&
isDigit
(
*--
tail
)
)
{
sawDigit
=
true
;
}
// if sawDigit, tail points to the 'v' here.
if
(
sawDigit
&&
tail
-
3
>=
start
)
{
tail
-=
3
;
if
(
tail
[
0
]
==
separator
&&
tail
[
1
]
==
'r'
&&
tail
[
2
]
==
'e'
&&
tail
[
3
]
==
'v'
)
{
return
tail
+
1
;
// omit separator, return "revN[N..]"
}
}
return
0
;
}
LPID
::
LPID
(
const
STRING
&
aLPID
)
throw
(
PARSE_ERROR
)
LPID
::
LPID
(
const
STRING
&
aLPID
)
throw
(
PARSE_ERROR
)
{
{
const
char
*
rev
=
EndsWithRev
(
aLPID
);
size_t
revNdx
;
size_t
partNdx
;
size_t
baseNdx
;
//=====<revision>=========================================
if
(
rev
)
{
revNdx
=
rev
-
aLPID
.
c_str
();
revision
=
aLPID
.
substr
(
revNdx
);
--
revNdx
;
// back up to omit the '/' which preceeds the rev
}
else
revNdx
=
aLPID
.
size
();
//=====<logical>==========================================
if
(
(
partNdx
=
aLPID
.
find
(
':'
)
)
!=
aLPID
.
npos
)
{
logical
=
aLPID
.
substr
(
0
,
partNdx
);
++
partNdx
;
// skip ':'
}
else
partNdx
=
0
;
//=====<rawName && category>==============================
// "length limited" search:
const
char
*
base
=
(
const
char
*
)
memchr
(
aLPID
.
c_str
()
+
partNdx
,
'/'
,
revNdx
-
partNdx
);
if
(
base
)
{
baseNdx
=
base
-
aLPID
.
c_str
();
category
=
aLPID
.
substr
(
partNdx
,
baseNdx
-
partNdx
);
++
baseNdx
;
// skip '/'
}
else
{
baseNdx
=
partNdx
;
}
//=====<baseName>==========================================
baseName
=
aLPID
.
substr
(
baseNdx
,
revNdx
-
baseNdx
);
}
STRING
LPID
::
GetLogicalLib
()
const
{
return
logical
;
}
bool
LPID
::
SetLogicalLib
(
const
STRING
&
aLogical
)
{
if
(
aLogical
.
find_first_of
(
":/"
)
==
STRING
::
npos
)
{
logical
=
aLogical
;
return
true
;
}
return
false
;
}
STRING
LPID
::
GetCategory
()
const
{
return
category
;
}
bool
LPID
::
SetCategory
(
const
STRING
&
aCategory
)
{
if
(
aCategory
.
find_first_of
(
":/"
)
==
STRING
::
npos
)
{
category
=
aCategory
;
return
true
;
}
return
false
;
}
STRING
LPID
::
GetBaseName
()
const
{
return
baseName
;
}
bool
LPID
::
SetBaseName
(
const
STRING
&
aBaseName
)
{
if
(
aBaseName
.
find_first_of
(
":/"
)
==
STRING
::
npos
)
{
baseName
=
aBaseName
;
return
true
;
}
return
false
;
}
STRING
LPID
::
GetPartName
()
const
{
STRING
ret
;
// return [category/]baseName
if
(
category
.
size
()
)
{
ret
+=
category
;
ret
+=
'/'
;
}
ret
+=
baseName
;
return
ret
;
}
STRING
LPID
::
GetRevision
()
const
{
return
revision
;
}
bool
LPID
::
SetRevision
(
const
STRING
&
aRevision
)
{
STRING
rev
;
rev
+=
"x/"
;
rev
+=
aRevision
;
if
(
EndsWithRev
(
rev
)
)
{
revision
=
aRevision
;
return
true
;
}
return
false
;
}
}
STRING
LPID
::
GetFullText
()
const
{
STRING
ret
;
if
(
logical
.
size
()
)
{
ret
+=
logical
;
ret
+=
':'
;
}
if
(
category
.
size
()
)
{
ret
+=
category
;
ret
+=
'/'
;
}
ret
+=
baseName
;
if
(
revision
.
size
()
)
{
ret
+=
'/'
;
ret
+=
revision
;
}
return
ret
;
}
#if 1 && defined(DEBUG)
// build this with Debug CMAKE_BUILD_TYPE
void
LPID
::
Test
()
{
static
const
char
*
lpids
[]
=
{
"me:passives/R/rev0"
,
"passives/R/rev2"
,
":passives/R/rev3"
,
"C/rev22"
,
"passives/C22"
,
"R"
,
"me:R"
,
// most difficult:
"me:/R/rev0"
,
"me:R/rev0"
,
};
for
(
unsigned
i
=
0
;
i
<
sizeof
(
lpids
)
/
sizeof
(
lpids
[
0
]);
++
i
)
{
// test some round tripping
LPID
lpid
(
lpids
[
i
]
);
// parse
// format
printf
(
"input:'%s' full:'%s' base:'%s' partName:'%s' cat:'%s'
\n
"
,
lpids
[
i
],
lpid
.
GetFullText
().
c_str
(),
lpid
.
GetBaseName
().
c_str
(),
lpid
.
GetPartName
().
c_str
(),
lpid
.
GetCategory
().
c_str
()
);
}
}
int
main
(
int
argc
,
char
**
argv
)
{
LPID
::
Test
();
return
0
;
}
#endif
new/sch_lpid.h
View file @
29e829b7
...
@@ -25,8 +25,7 @@
...
@@ -25,8 +25,7 @@
#ifndef SCH_LPID_H_
#ifndef SCH_LPID_H_
#define SCH_LPID_H_
#define SCH_LPID_H_
//#include <wx/string.h>
#include <sch_lib.h> // STRING
/**
/**
* Class LPID
* Class LPID
...
@@ -45,42 +44,7 @@
...
@@ -45,42 +44,7 @@
* <li> "rev6" is the revision number, which is optional. If missing then its
* <li> "rev6" is the revision number, which is optional. If missing then its
* delimiter should also not be present.
* delimiter should also not be present.
* </ul>
* </ul>
* <p>
* @author Dick Hollenbeck
* 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
class
LPID
// aka GUID
{
{
...
@@ -95,12 +59,19 @@ public:
...
@@ -95,12 +59,19 @@ public:
LPID
(
const
STRING
&
aLPID
)
throw
(
PARSE_ERROR
);
LPID
(
const
STRING
&
aLPID
)
throw
(
PARSE_ERROR
);
/**
/**
* Function GetLogLib
* Function GetLog
ical
Lib
* returns the logical library portion of a LPID. There is not Set accessor
* 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
* for this portion since it comes from the library table and is considered
* read only here.
* read only here.
*/
*/
STRING
GetLogLib
()
const
;
STRING
GetLogicalLib
()
const
;
/**
* 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.
*/
bool
SetLogicalLib
(
const
STRING
&
aLogical
);
/**
/**
* Function GetCategory
* Function GetCategory
...
@@ -113,8 +84,35 @@ public:
...
@@ -113,8 +84,35 @@ public:
* Function SetCategory
* Function SetCategory
* overrides the category portion of the LPID to @a aCategory and is typically
* overrides the category portion of the LPID to @a aCategory and is typically
* either the empty string or a single word like "passives".
* either the empty string or a single word like "passives".
* @return bool - true unless parameter has ':' or '/' in it.
*/
bool
SetCategory
(
const
STRING
&
aCategory
);
/**
* Function GetBaseName
* returns the part name without the category.
*/
STRING
GetBaseName
()
const
;
/**
* Function SetBaseName
* overrides the base name portion of the LPID to @a aBaseName
* @return bool - true unless parameter has ':' or '/' in it.
*/
bool
SetBaseName
(
const
STRING
&
aBaseName
);
/**
* Function GetBaseName
* returns the part name, i.e. category/baseName without revision.
*/
STRING
GetPartName
()
const
;
/**
* Function SetBaseName
* overrides the part name portion of the LPID to @a aPartName
not really needed, partname is an agreggate anyway, just parse a new one.
void SetPartName( const STRING& aPartName );
*/
*/
void
SetCategory
(
const
STRING
&
aCategory
);
/**
/**
* Function GetRevision
* Function GetRevision
...
@@ -126,14 +124,43 @@ public:
...
@@ -126,14 +124,43 @@ public:
* Function SetRevision
* Function SetRevision
* overrides the revision portion of the LPID to @a aRevision and must
* overrides the revision portion of the LPID to @a aRevision and must
* be in the form "rev<num>" where "<num>" is "1", "2", etc.
* be in the form "rev<num>" where "<num>" is "1", "2", etc.
* @return bool - true unless parameter is not of the form "revN]N..]"
*/
*/
void
SetRevision
(
const
STRING
&
aRevision
);
bool
SetRevision
(
const
STRING
&
aRevision
);
/**
/**
* Function GetFullText
* Function GetFullText
* returns the full text of the LPID.
* returns the full text of the LPID.
*/
*/
STRING
GetFullText
()
const
;
STRING
GetFullText
()
const
;
#if defined(DEBUG)
static
void
Test
();
#endif
protected
:
STRING
logical
;
///< logical lib name or empty
STRING
category
;
///< or empty
STRING
baseName
;
///< excludes category
STRING
revision
;
///< "revN[N..]" or empty
};
};
/**
* 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
STRING
&
aPartName
,
char
separator
=
'/'
)
{
return
EndsWithRev
(
aPartName
.
c_str
(),
aPartName
.
c_str
()
+
aPartName
.
size
(),
separator
);
}
#endif // SCH_LPID_H_
#endif // SCH_LPID_H_
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment