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
41637b36
Commit
41637b36
authored
Jan 03, 2011
by
Dick Hollenbeck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
commit
parent
0a3830b6
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
499 additions
and
82 deletions
+499
-82
sch_dir_lib_source.cpp
new/sch_dir_lib_source.cpp
+29
-4
sch_dir_lib_source.h
new/sch_dir_lib_source.h
+2
-4
sch_lib.cpp
new/sch_lib.cpp
+160
-16
sch_lib.h
new/sch_lib.h
+28
-6
sch_lib_table.h
new/sch_lib_table.h
+0
-1
sch_lpid.cpp
new/sch_lpid.cpp
+146
-1
sch_lpid.h
new/sch_lpid.h
+27
-0
sch_part.cpp
new/sch_part.cpp
+101
-44
sch_part.h
new/sch_part.h
+6
-6
No files found.
new/sch_dir_lib_source.cpp
View file @
41637b36
...
@@ -400,11 +400,11 @@ DIR_LIB_SOURCE::~DIR_LIB_SOURCE()
...
@@ -400,11 +400,11 @@ DIR_LIB_SOURCE::~DIR_LIB_SOURCE()
void
DIR_LIB_SOURCE
::
GetCategoricalPartNames
(
STRINGS
*
aResults
,
const
STRING
&
aCategory
)
void
DIR_LIB_SOURCE
::
GetCategoricalPartNames
(
STRINGS
*
aResults
,
const
STRING
&
aCategory
)
throw
(
IO_ERROR
)
throw
(
IO_ERROR
)
{
{
PN_ITER
limit
=
aCategory
.
size
()
?
PN_ITER
end
=
aCategory
.
size
()
?
partnames
.
lower_bound
(
aCategory
+
char
(
'/'
+
1
)
)
:
partnames
.
lower_bound
(
aCategory
+
char
(
'/'
+
1
)
)
:
partnames
.
end
();
partnames
.
end
();
PN_ITER
it
=
aCategory
.
size
()
?
PN_ITER
it
=
aCategory
.
size
()
?
partnames
.
upper_bound
(
aCategory
+
"/"
)
:
partnames
.
upper_bound
(
aCategory
+
"/"
)
:
partnames
.
begin
();
partnames
.
begin
();
...
@@ -414,7 +414,7 @@ void DIR_LIB_SOURCE::GetCategoricalPartNames( STRINGS* aResults, const STRING& a
...
@@ -414,7 +414,7 @@ void DIR_LIB_SOURCE::GetCategoricalPartNames( STRINGS* aResults, const STRING& a
{
{
STRING
partName
;
STRING
partName
;
while
(
it
!=
limit
)
while
(
it
!=
end
)
{
{
const
char
*
rev
=
endsWithRev
(
*
it
);
const
char
*
rev
=
endsWithRev
(
*
it
);
...
@@ -434,7 +434,32 @@ void DIR_LIB_SOURCE::GetCategoricalPartNames( STRINGS* aResults, const STRING& a
...
@@ -434,7 +434,32 @@ void DIR_LIB_SOURCE::GetCategoricalPartNames( STRINGS* aResults, const STRING& a
else
else
{
{
while
(
it
!=
limit
)
while
(
it
!=
end
)
aResults
->
push_back
(
*
it
++
);
}
}
void
DIR_LIB_SOURCE
::
GetRevisions
(
STRINGS
*
aResults
,
const
STRING
&
aPartName
)
throw
(
IO_ERROR
)
{
aResults
->
clear
();
if
(
useVersioning
)
{
STRING
partName
;
const
char
*
rev
=
endsWithRev
(
aPartName
);
if
(
rev
)
// partName is substring which omits the rev and the separator
partName
.
assign
(
aPartName
,
0
,
rev
-
aPartName
.
c_str
()
-
1
);
else
partName
=
aPartName
;
PN_ITER
it
=
partnames
.
upper_bound
(
partName
+
'/'
);
PN_ITER
end
=
partnames
.
lower_bound
(
partName
+
char
(
'/'
+
1
)
);
while
(
it
!=
end
)
aResults
->
push_back
(
*
it
++
);
aResults
->
push_back
(
*
it
++
);
}
}
}
}
...
...
new/sch_dir_lib_source.h
View file @
41637b36
...
@@ -174,10 +174,8 @@ protected:
...
@@ -174,10 +174,8 @@ protected:
void
GetCategoricalPartNames
(
STRINGS
*
aResults
,
const
STRING
&
aCategory
=
""
)
void
GetCategoricalPartNames
(
STRINGS
*
aResults
,
const
STRING
&
aCategory
=
""
)
throw
(
IO_ERROR
);
throw
(
IO_ERROR
);
void
GetRevisions
(
STRINGS
*
aResults
,
const
STRING
&
aPartName
)
throw
(
IO_ERROR
)
void
GetRevisions
(
STRINGS
*
aResults
,
const
STRING
&
aPartName
)
{
throw
(
IO_ERROR
);
// @todo
}
void
FindParts
(
STRINGS
*
aResults
,
const
STRING
&
aQuery
)
throw
(
IO_ERROR
)
void
FindParts
(
STRINGS
*
aResults
,
const
STRING
&
aQuery
)
throw
(
IO_ERROR
)
{
{
...
...
new/sch_lib.cpp
View file @
41637b36
...
@@ -25,19 +25,95 @@
...
@@ -25,19 +25,95 @@
#include <memory> // std::auto_ptr
#include <memory> // std::auto_ptr
#include <wx/string.h>
#include <wx/string.h>
#include <sch_lib.h>
#include <sch_lib.h>
#include <sch_lpid.h>
#include <sch_lpid.h>
#include <sch_part.h>
#include <sch_part.h>
#include <sweet_lexer.h>
#include <sweet_lexer.h>
#include <sch_lib_table.h>
#include <sch_lib_table.h>
#if 1
#include <map>
/*
The LIB part cache consist of a std::map of partnames without revisions at the top level.
Each top level map entry can point to another std::map which it owns and holds all the revisions
for that part name. At any point in the tree, there can be NULL pointers which
allow for lazy loading, including the very top most root pointer itself, which
is PARTS* parts. We use the key to hold the partName at one level, and revision
at the deeper nested level, and that key information may not be present within
right hand side of the map tuple.
1) Only things which are asked for are done.
2) Anything we learn we remember.
*/
namespace
SCH
{
class
PART_REVS
:
public
std
::
map
<
STRING
,
PART
*
>
{
// @todo provide an integer sort on revN.. strings here.
public
:
~
PART_REVS
()
{
for
(
iterator
it
=
begin
();
it
!=
end
();
++
it
)
{
delete
it
->
second
;
// second may be NULL, no problem
}
}
};
class
PARTS
:
public
std
::
map
<
STRING
,
PART_REVS
*
>
{
public
:
~
PARTS
()
{
for
(
iterator
it
=
begin
();
it
!=
end
();
++
it
)
{
delete
it
->
second
;
// second may be NULL, no problem
}
}
};
}
// namespace SCH
#else // was nothing but grief:
#include <boost/ptr_container/ptr_map.hpp>
namespace
SCH
{
/// PARTS' key is revision, like "rev12", PART pointer may be null until loaded.
typedef
boost
::
ptr_map
<
STRING
,
boost
::
nullable
<
PART
>
>
PARTS
;
typedef
PARTS
::
iterator
PARTS_ITER
;
typedef
PARTS
::
const_iterator
PARTS_CITER
;
/// PART_REVS' key is part name, w/o rev, PART pointer may be null until loaded.
typedef
boost
::
ptr_map
<
STRING
,
boost
::
nullable
<
PARTS
>
>
PART_REVS
;
typedef
PART_REVS
::
iterator
PART_REVS_ITER
;
typedef
PART_REVS
::
const_iterator
PART_REVS_CITER
;
}
// namespace SCH
#endif
using
namespace
SCH
;
using
namespace
SCH
;
LIB
::
LIB
(
const
STRING
&
aLogicalLibrary
,
LIB_SOURCE
*
aSource
,
LIB_SINK
*
aSink
)
:
LIB
::
LIB
(
const
STRING
&
aLogicalLibrary
,
LIB_SOURCE
*
aSource
,
LIB_SINK
*
aSink
)
:
n
ame
(
aLogicalLibrary
),
logicalN
ame
(
aLogicalLibrary
),
source
(
aSource
),
source
(
aSource
),
sink
(
aSink
)
sink
(
aSink
),
cachedCategories
(
false
),
parts
(
0
)
{
{
}
}
...
@@ -46,25 +122,99 @@ LIB::~LIB()
...
@@ -46,25 +122,99 @@ LIB::~LIB()
{
{
delete
source
;
delete
source
;
delete
sink
;
delete
sink
;
delete
parts
;
}
}
PART
*
LIB
::
LookupPart
(
const
LPID
&
aLPID
,
LIB_TABLE
*
aLibTable
)
throw
(
IO_ERROR
)
const
PART
*
LIB
::
findPart
(
const
LPID
&
aLPID
)
throw
(
IO_ERROR
)
{
{
PART
*
part
;
if
(
!
parts
)
{
parts
=
new
PARTS
;
source
->
GetCategoricalPartNames
(
&
vfetch
);
// insert a PART_REVS for each part name
for
(
STRINGS
::
const_iterator
it
=
vfetch
.
begin
();
it
!=
vfetch
.
end
();
++
it
)
{
// D(printf("findPart:%s\n", it->c_str() );)
(
*
parts
)[
*
it
]
=
new
PART_REVS
;
}
}
// load all the revisions for this part name, only if it has any
PARTS
::
iterator
pi
=
parts
->
find
(
aLPID
.
GetPartName
()
);
PART_REVS
*
revs
=
pi
!=
parts
->
end
()
?
pi
->
second
:
NULL
;
// D(printf("revs:%p partName:%s\n", revs, aLPID.GetPartName().c_str() );)
//
If part not already cached
//
if the key for parts has no aLPID.GetPartName() the part is not in this lib
if
(
1
/* @todo test cache */
)
if
(
revs
)
{
{
// load it.
if
(
revs
->
size
()
==
0
)
{
// load all the revisions for this part.
source
->
GetRevisions
(
&
vfetch
,
aLPID
.
GetPartName
()
);
// creat a PART_REV entry for revision, but leave the PART* NULL
for
(
STRINGS
::
const_iterator
it
=
vfetch
.
begin
();
it
!=
vfetch
.
end
();
++
it
)
{
// D(printf("findPartRev:%s\n", it->c_str() );)
(
*
revs
)[
*
it
]
=
0
;
}
}
PART_REVS
::
iterator
result
=
revs
->
find
(
aLPID
.
GetPartNameAndRev
()
);
if
(
result
!=
revs
->
end
()
)
{
if
(
!
result
->
second
)
// the PART has never been loaded before
{
result
->
second
=
new
PART
(
this
,
aLPID
.
GetPartNameAndRev
()
);
}
return
result
->
second
;
}
// If caller did not say what revision, find the highest numbered one and return that.
// Otherwise he knew what he wanted specifically, and we do not have it.
if
(
!
aLPID
.
GetRevision
().
size
()
&&
revs
->
size
()
)
{
result
=
revs
->
begin
();
// sort order has highest rev first
if
(
!
result
->
second
)
// the PART has never been loaded before
{
result
->
second
=
new
PART
(
this
,
LPID
::
Format
(
""
,
aLPID
.
GetPartName
(),
result
->
first
)
);
}
return
result
->
second
;
}
}
part
=
new
PART
(
this
,
aLPID
.
GetPartName
(),
aLPID
.
GetRevision
()
);
return
0
;
// no such part name in this lib
}
std
::
auto_ptr
<
PART
>
wrapped
(
part
);
PART
*
LIB
::
LookupPart
(
const
LPID
&
aLPID
,
LIB_TABLE
*
aLibTable
)
throw
(
IO_ERROR
)
{
PART
*
part
=
(
PART
*
)
findPart
(
aLPID
);
if
(
!
part
)
// part does not exist in this lib
{
wxString
msg
=
wxString
::
Format
(
_
(
"part '%s' not found in lib %s"
),
wxString
::
FromUTF8
(
aLPID
.
GetPartNameAndRev
().
c_str
()
).
GetData
(),
wxString
::
FromUTF8
(
logicalName
.
c_str
()
).
GetData
()
);
THROW_IO_ERROR
(
msg
);
}
if
(
part
->
body
.
empty
()
)
{
// load body
source
->
ReadPart
(
&
part
->
body
,
aLPID
.
GetPartName
(),
aLPID
.
GetRevision
()
);
source
->
ReadPart
(
&
part
->
body
,
aLPID
.
GetPartName
(),
aLPID
.
GetRevision
()
);
#if defined(DEBUG)
#if
0 &&
defined(DEBUG)
const STRING& body = part->body;
const STRING& body = part->body;
printf( "body: %s", body.c_str() );
printf( "body: %s", body.c_str() );
if( !body.size() || body[body.size()-1] != '\n' )
if( !body.size() || body[body.size()-1] != '\n' )
...
@@ -74,12 +224,6 @@ PART* LIB::LookupPart( const LPID& aLPID, LIB_TABLE* aLibTable ) throw( IO_ERROR
...
@@ -74,12 +224,6 @@ PART* LIB::LookupPart( const LPID& aLPID, LIB_TABLE* aLibTable ) throw( IO_ERROR
SWEET_LEXER
sw
(
part
->
body
,
wxString
::
FromUTF8
(
"body"
)
/* @todo have ReadPart give better source */
);
SWEET_LEXER
sw
(
part
->
body
,
wxString
::
FromUTF8
(
"body"
)
/* @todo have ReadPart give better source */
);
part
->
Parse
(
&
sw
,
aLibTable
);
part
->
Parse
(
&
sw
,
aLibTable
);
// stuff the part into this LIBs cache:
// @todo
wrapped
.
release
();
}
}
return
part
;
return
part
;
...
...
new/sch_lib.h
View file @
41637b36
...
@@ -105,7 +105,9 @@ protected: ///< derived classes must implement
...
@@ -105,7 +105,9 @@ protected: ///< derived classes must implement
/**
/**
* Function GetRevisions
* Function GetRevisions
* fetches all revisions for @a aPartName into @a aResults. Revisions are strings
* fetches all revisions for @a aPartName into @a aResults. Revisions are strings
* like "rev12", "rev279", and are library source agnostic. These
* like "rev12", "rev279", and are library source agnostic. These do not have to be
* in a contiguous order, but the first 3 characters must be "rev" and subsequent
* characters must consist of at least one decimal digit.
*/
*/
virtual
void
GetRevisions
(
STRINGS
*
aResults
,
const
STRING
&
aPartName
)
virtual
void
GetRevisions
(
STRINGS
*
aResults
,
const
STRING
&
aPartName
)
throw
(
IO_ERROR
)
=
0
;
throw
(
IO_ERROR
)
=
0
;
...
@@ -183,6 +185,9 @@ protected:
...
@@ -183,6 +185,9 @@ protected:
};
};
class
PARTS
;
/**
/**
* Class LIB
* Class LIB
* is a cache of parts, and because the LIB_SOURCE is abstracted, there
* is a cache of parts, and because the LIB_SOURCE is abstracted, there
...
@@ -318,17 +323,34 @@ public:
...
@@ -318,17 +323,34 @@ public:
protected
:
protected
:
STR_UTF
fetch
;
// scratch, used to fetch things, grows to worst case size.
STR_UTF
fetch
;
// scratch, used to fetch things, grows to worst case size.
STR_UTFS
vfetch
;
// scratch, used to fetch things.
STR_UTFS
vfetch
;
// scratch, used to fetch things.
STRING
n
ame
;
STRING
logicalN
ame
;
LIB_SOURCE
*
source
;
LIB_SOURCE
*
source
;
LIB_SINK
*
sink
;
LIB_SINK
*
sink
;
// STRING libraryURI;
STRINGS
categories
;
STRINGS
categories
;
bool
cachedCategories
;
/// < is true only after reading categories
/** parts are in various states of readiness:
* 1) not even loaded (if cachedParts is false)
* 2) present, but without member 'body' having been read() yet.
* 3) body has been read, but not parsed yet.
* 4) parsed and inheritance if any has been applied.
*/
PARTS
*
parts
;
/**
* Function findPart
* finds a PART, returns NULL if cannot find.
* @throw IO_ERROR if there is some kind of communications error reading
* the original list of parts.
*/
const
PART
*
findPart
(
const
LPID
&
aLPID
)
throw
(
IO_ERROR
);
// PARTS parts;
};
};
...
...
new/sch_lib_table.h
View file @
41637b36
...
@@ -375,7 +375,6 @@ private:
...
@@ -375,7 +375,6 @@ private:
typedef
boost
::
ptr_map
<
STRING
,
ROW
>
ROWS
;
typedef
boost
::
ptr_map
<
STRING
,
ROW
>
ROWS
;
typedef
ROWS
::
iterator
ROWS_ITER
;
typedef
ROWS
::
iterator
ROWS_ITER
;
typedef
ROWS
::
const_iterator
ROWS_CITER
;
typedef
ROWS
::
const_iterator
ROWS_CITER
;
// typedef std::pair<ROWS_ITER, bool> ROW_PAIR;
ROWS
rows
;
ROWS
rows
;
LIB_TABLE
*
fallBack
;
LIB_TABLE
*
fallBack
;
...
...
new/sch_lpid.cpp
View file @
41637b36
...
@@ -186,7 +186,7 @@ LPID::LPID( const STRING& aLPID ) throw( PARSE_ERROR )
...
@@ -186,7 +186,7 @@ LPID::LPID( const STRING& aLPID ) throw( PARSE_ERROR )
{
{
THROW_PARSE_ERROR
(
THROW_PARSE_ERROR
(
_
(
"Illegal character found in LPID string"
),
_
(
"Illegal character found in LPID string"
),
wx
ConvertMB2WX
(
aLPID
.
c_str
()
),
wx
String
::
FromUTF8
(
aLPID
.
c_str
()
),
aLPID
.
c_str
(),
aLPID
.
c_str
(),
0
,
0
,
offset
offset
...
@@ -249,6 +249,36 @@ int LPID::SetBaseName( const STRING& aBaseName )
...
@@ -249,6 +249,36 @@ int LPID::SetBaseName( const STRING& aBaseName )
}
}
int
LPID
::
SetPartName
(
const
STRING
&
aPartName
)
{
STRING
category
;
STRING
base
;
int
offset
;
int
separation
=
int
(
aPartName
.
find_first_of
(
"/"
)
);
if
(
separation
!=
-
1
)
{
category
=
aPartName
.
substr
(
0
,
separation
);
base
=
aPartName
.
substr
(
separation
+
1
);
}
else
{
// leave category empty
base
=
aPartName
;
}
if
(
(
offset
=
SetCategory
(
category
))
!=
-
1
)
return
offset
;
if
(
(
offset
=
SetBaseName
(
base
))
!=
-
1
)
{
return
offset
+
separation
+
1
;
}
return
-
1
;
}
int
LPID
::
SetRevision
(
const
STRING
&
aRevision
)
int
LPID
::
SetRevision
(
const
STRING
&
aRevision
)
{
{
int
offset
=
okRevision
(
aRevision
);
int
offset
=
okRevision
(
aRevision
);
...
@@ -288,6 +318,121 @@ STRING LPID::Format() const
...
@@ -288,6 +318,121 @@ STRING LPID::Format() const
}
}
STRING
LPID
::
GetPartNameAndRev
()
const
{
STRING
ret
;
if
(
category
.
size
()
)
{
ret
+=
category
;
ret
+=
'/'
;
}
ret
+=
baseName
;
if
(
revision
.
size
()
)
{
ret
+=
'/'
;
ret
+=
revision
;
}
return
ret
;
}
STRING
LPID
::
Format
(
const
STRING
&
aLogicalLib
,
const
STRING
&
aPartName
,
const
STRING
&
aRevision
)
throw
(
PARSE_ERROR
)
{
STRING
ret
;
int
offset
;
if
(
aLogicalLib
.
size
()
)
{
offset
=
okLogical
(
aLogicalLib
);
if
(
offset
!=
-
1
)
{
THROW_PARSE_ERROR
(
_
(
"Illegal character found in logical lib name"
),
wxString
::
FromUTF8
(
aLogicalLib
.
c_str
()
),
aLogicalLib
.
c_str
(),
0
,
offset
);
}
ret
+=
aLogicalLib
;
ret
+=
':'
;
}
{
STRING
category
;
STRING
base
;
int
separation
=
int
(
aPartName
.
find_first_of
(
"/"
)
);
if
(
separation
!=
-
1
)
{
category
=
aPartName
.
substr
(
0
,
separation
);
base
=
aPartName
.
substr
(
separation
+
1
);
}
else
{
// leave category empty
base
=
aPartName
;
}
if
(
(
offset
=
okCategory
(
category
))
!=
-
1
)
{
THROW_PARSE_ERROR
(
_
(
"Illegal character found in category"
),
wxString
::
FromUTF8
(
aRevision
.
c_str
()
),
aRevision
.
c_str
(),
0
,
offset
);
}
if
(
(
offset
=
okBase
(
base
))
!=
-
1
)
{
THROW_PARSE_ERROR
(
_
(
"Illegal character found in base name"
),
wxString
::
FromUTF8
(
aRevision
.
c_str
()
),
aRevision
.
c_str
(),
0
,
offset
+
separation
+
1
);
}
if
(
category
.
size
()
)
{
ret
+=
category
;
ret
+=
'/'
;
}
ret
+=
base
;
}
if
(
aRevision
.
size
()
)
{
offset
=
okRevision
(
aRevision
);
if
(
offset
!=
-
1
)
{
THROW_PARSE_ERROR
(
_
(
"Illegal character found in revision"
),
wxString
::
FromUTF8
(
aRevision
.
c_str
()
),
aRevision
.
c_str
(),
0
,
offset
);
}
ret
+=
'/'
;
ret
+=
aRevision
;
}
return
ret
;
}
#if 0 && defined(DEBUG)
#if 0 && defined(DEBUG)
// build this with Debug CMAKE_BUILD_TYPE
// build this with Debug CMAKE_BUILD_TYPE
...
...
new/sch_lpid.h
View file @
41637b36
...
@@ -145,6 +145,23 @@ public:
...
@@ -145,6 +145,23 @@ public:
return
partName
;
return
partName
;
}
}
/**
* Function GetPartNameAndRev
* returns the part name with revision if any, i.e. [category/]baseName[/revN..]
*/
STRING
GetPartNameAndRev
()
const
;
/**
* Function SetPartName
* overrides the part name portion of the LPID to @a aPartName
* @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.
* A single '/' is allowed, since that is used to separate the category from the
* base name.
*/
int
SetPartName
(
const
STRING
&
aPartName
);
/**
/**
* Function GetRevision
* Function GetRevision
* returns the revision portion of the LPID.
* returns the revision portion of the LPID.
...
@@ -170,6 +187,16 @@ public:
...
@@ -170,6 +187,16 @@ public:
*/
*/
STRING
Format
()
const
;
STRING
Format
()
const
;
/**
* Function Format
* returns a STRING in the proper format as an LPID for a combination of
* aLogicalLib, aPartName, and aRevision.
* @throw PARSE_ERROR if any of the pieces are illegal.
*/
static
STRING
Format
(
const
STRING
&
aLogicalLib
,
const
STRING
&
aPartName
,
const
STRING
&
aRevision
=
""
)
throw
(
PARSE_ERROR
);
#if defined(DEBUG)
#if defined(DEBUG)
static
void
Test
();
static
void
Test
();
#endif
#endif
...
...
new/sch_part.cpp
View file @
41637b36
...
@@ -31,8 +31,12 @@
...
@@ -31,8 +31,12 @@
using
namespace
SCH
;
using
namespace
SCH
;
//-----<temporary home for PART sub objects, move after stable>------------------
#define MAX_INHERITANCE_NESTING 10 // no problem going larger
//-----<temporary home for PART sub objects, move after stable>------------------
struct
XY
{};
struct
AT
{};
//-----</temporary home for PART sub objects, move after stable>-----------------
//-----</temporary home for PART sub objects, move after stable>-----------------
...
@@ -55,7 +59,8 @@ class PART_PARSER
...
@@ -55,7 +59,8 @@ class PART_PARSER
{
{
SWEET_LEXER
*
in
;
SWEET_LEXER
*
in
;
LIB_TABLE
*
libs
;
LIB_TABLE
*
libs
;
int
contains
;
int
contains
;
// separate from PART::contains until done
// so we can see what we inherited from base PART
public
:
public
:
PART_PARSER
(
PART
*
aPart
,
SWEET_LEXER
*
aLexer
,
LIB_TABLE
*
aTable
)
:
PART_PARSER
(
PART
*
aPart
,
SWEET_LEXER
*
aLexer
,
LIB_TABLE
*
aTable
)
:
...
@@ -66,51 +71,98 @@ public:
...
@@ -66,51 +71,98 @@ public:
parsePart
(
aPart
);
parsePart
(
aPart
);
}
}
void
parseXY
(
XY
*
me
)
{
}
void
parseAt
(
AT
*
me
)
{
}
void
parseExtends
(
PART
*
me
)
{
PART
*
base
;
int
offset
;
if
(
contains
&
PB
(
EXTENDS
)
)
in
->
Duplicate
(
T_extends
);
in
->
NeedSYMBOLorNUMBER
();
me
->
setExtends
(
new
LPID
()
);
offset
=
me
->
extends
->
Parse
(
in
->
CurText
()
);
if
(
offset
>
-
1
)
// -1 is success
THROW_PARSE_ERROR
(
_
(
"invalid extends LPID"
),
in
->
CurSource
(),
in
->
CurLine
(),
in
->
CurLineNumber
(),
in
->
CurOffset
()
+
offset
);
base
=
libs
->
LookupPart
(
*
me
->
extends
,
me
->
Owner
()
);
// we could be going in circles here, recursively, or too deep, set limits
// and disallow extending from self (even indirectly)
int
extendsDepth
=
0
;
for
(
PART
*
ancestor
=
base
;
ancestor
&&
extendsDepth
<
MAX_INHERITANCE_NESTING
;
++
extendsDepth
,
ancestor
=
ancestor
->
base
)
{
if
(
ancestor
==
me
)
{
THROW_PARSE_ERROR
(
_
(
"'extends' may not have self as any ancestor"
),
in
->
CurSource
(),
in
->
CurLine
(),
in
->
CurLineNumber
(),
in
->
CurOffset
()
);
}
}
if
(
extendsDepth
==
MAX_INHERITANCE_NESTING
)
{
THROW_PARSE_ERROR
(
_
(
"max allowed extends depth exceeded"
),
in
->
CurSource
(),
in
->
CurLine
(),
in
->
CurLineNumber
(),
in
->
CurOffset
()
);
}
me
->
inherit
(
*
base
);
me
->
base
=
base
;
contains
|=
PB
(
EXTENDS
);
}
/// @param me = ja mir, the object getting stuffed, from its perspective
/// @param me = ja mir, the object getting stuffed, from its perspective
void
parsePart
(
PART
*
me
)
void
parsePart
(
PART
*
me
)
{
{
PART_T
tok
;
PART_T
tok
=
in
->
NextTok
()
;
if
(
(
tok
=
in
->
NextTok
())
==
T_LEFT
)
tok
=
in
->
NextTok
();
// a token "( part .." i.e. class PART
// Be flexible regarding the starting point of the stream.
// Be flexible regarding the starting point of the stream.
// Caller may not have read the first two tokens out of the
// Caller may not have read the first two tokens out of the
// stream: T_LEFT and T_part, so ignore them if seen here.
// stream: T_LEFT and T_part, so ignore them if seen here.
// The 1st two tokens T_LEFT and T_part are then optional in the grammar.
// The 1st two tokens T_LEFT and T_part are then optional in the grammar.
if
(
tok
==
T_part
)
if
(
tok
==
T_LEFT
)
{
{
i
n
->
NeedSYMBOLorNUMBER
();
// read in part NAME_HINT, and toss
i
f
(
(
tok
=
in
->
NextTok
()
)
!=
T_part
)
tok
=
in
->
NextTok
(
);
in
->
Expecting
(
T_part
);
}
}
in
->
NeedSYMBOLorNUMBER
();
// read in part NAME_HINT, and toss
tok
=
in
->
NextTok
();
// extends must be _first_ thing, if it is present at all, after NAME_HINT
// extends must be _first_ thing, if it is present at all, after NAME_HINT
if
(
tok
==
T_extends
)
if
(
tok
==
T_extends
)
{
{
PART
*
base
;
parseExtends
(
me
);
int
offset
;
if
(
contains
&
PB
(
EXTENDS
)
)
in
->
Duplicate
(
tok
);
in
->
NeedSYMBOLorNUMBER
();
me
->
setExtends
(
new
LPID
()
);
offset
=
me
->
extends
->
Parse
(
in
->
CurText
()
);
if
(
offset
>
-
1
)
// -1 is success
THROW_PARSE_ERROR
(
_
(
"invalid extends LPID"
),
in
->
CurSource
(),
in
->
CurLine
(),
in
->
CurLineNumber
(),
in
->
CurOffset
()
+
offset
);
// we could be going in circles here, recursively, @todo add a max counter or stack chain
base
=
libs
->
LookupPart
(
*
me
->
extends
,
me
->
Owner
()
);
me
->
inherit
(
*
base
);
contains
|=
PB
(
EXTENDS
);
tok
=
in
->
NextTok
();
tok
=
in
->
NextTok
();
}
}
for
(
;
tok
!=
T_RIGHT
&&
tok
!=
T_EOF
;
tok
=
in
->
NextTok
()
)
for
(
;
tok
!=
T_RIGHT
;
tok
=
in
->
NextTok
()
)
{
{
if
(
tok
==
T_EOF
)
in
->
Unexpected
(
_
(
"end of input"
)
);
if
(
tok
==
T_LEFT
)
if
(
tok
==
T_LEFT
)
tok
=
in
->
NextTok
();
tok
=
in
->
NextTok
();
...
@@ -212,22 +264,26 @@ public:
...
@@ -212,22 +264,26 @@ public:
break
;
break
;
}
}
}
}
}
contains
|=
PB
(
PARSED
);
void
parseAt
(
PART
*
me
)
this
->
contains
|=
contains
;
{
}
}
};
};
PART
::
PART
(
LIB
*
aOwner
,
const
STRING
&
aPartName
,
const
STRING
&
aRevision
)
:
PART
::
PART
(
LIB
*
aOwner
,
const
STRING
&
aPartName
AndRev
)
:
owner
(
aOwner
),
owner
(
aOwner
),
contains
(
0
),
contains
(
0
),
partName
(
aPartName
),
partNameAndRev
(
aPartNameAndRev
),
revision
(
aRevision
),
extends
(
0
),
extends
(
0
)
base
(
0
)
{}
{
// Our goal is to have class LIB only instantiate what is needed, so print here
// what it is doing. It is the only class where PART can be instantiated.
D
(
printf
(
"PART::PART(%s)
\n
"
,
aPartNameAndRev
.
c_str
()
);)
}
PART
::~
PART
()
PART
::~
PART
()
...
@@ -247,19 +303,20 @@ void PART::inherit( const PART& other )
...
@@ -247,19 +303,20 @@ void PART::inherit( const PART& other )
{
{
contains
=
other
.
contains
;
contains
=
other
.
contains
;
setExtends
(
other
.
extends
?
new
LPID
(
*
other
.
extends
)
:
0
);
// @todo copy the inherited drawables, properties, and pins here
body
=
other
.
body
;
}
}
PART
&
PART
::
operator
=
(
const
PART
&
other
)
PART
&
PART
::
operator
=
(
const
PART
&
other
)
{
{
owner
=
other
.
owner
;
owner
=
other
.
owner
;
partName
=
other
.
partName
;
partNameAndRev
=
other
.
partNameAndRev
;
revision
=
other
.
revision
;
body
=
other
.
body
;
base
=
other
.
base
;
setExtends
(
other
.
extends
?
new
LPID
(
*
other
.
extends
)
:
0
);
// maintain in
herit() a
s a partial assignment operator.
// maintain in
concert with inherit(), which i
s a partial assignment operator.
inherit
(
other
);
inherit
(
other
);
return
*
this
;
return
*
this
;
...
...
new/sch_part.h
View file @
41637b36
...
@@ -43,9 +43,8 @@ class LPID;
...
@@ -43,9 +43,8 @@ class LPID;
*/
*/
enum
PartBit
enum
PartBit
{
{
BODY
,
///< body has been read in.
PARSED
,
///< have parsed this part already, otherwise 'body' text must be parsed
PARSED
,
///< have parsed this part already, otherwise 'body' text must be parsed
EXTENDS
,
///< saw
and
"extends" keyword, inheriting from another PART
EXTENDS
,
///< saw "extends" keyword, inheriting from another PART
VALUE
,
VALUE
,
ANCHOR
,
ANCHOR
,
REFERENCE
,
REFERENCE
,
...
@@ -55,6 +54,7 @@ enum PartBit
...
@@ -55,6 +54,7 @@ enum PartBit
KEYWORDS
,
KEYWORDS
,
};
};
/// Function PB
/// Function PB
/// is a PartBit shifter for PART::contains field.
/// is a PartBit shifter for PART::contains field.
static
inline
const
int
PB
(
PartBit
oneBitOnly
)
static
inline
const
int
PB
(
PartBit
oneBitOnly
)
...
@@ -80,7 +80,7 @@ class PART
...
@@ -80,7 +80,7 @@ class PART
protected
:
// not likely to have C++ descendants, but protected none-the-less.
protected
:
// not likely to have C++ descendants, but protected none-the-less.
/// a protected constructor, only a LIB can instantiate a PART.
/// a protected constructor, only a LIB can instantiate a PART.
PART
(
LIB
*
aOwner
,
const
STRING
&
aPartName
,
const
STRING
&
aRevision
);
PART
(
LIB
*
aOwner
,
const
STRING
&
aPartName
AndRev
);
/**
/**
* Function inherit
* Function inherit
...
@@ -95,10 +95,10 @@ protected: // not likely to have C++ descendants, but protected none-the-le
...
@@ -95,10 +95,10 @@ protected: // not likely to have C++ descendants, but protected none-the-le
LIB
*
owner
;
///< which LIB am I a part of (pun if you want)
LIB
*
owner
;
///< which LIB am I a part of (pun if you want)
int
contains
;
///< has bits from Enum PartParts
int
contains
;
///< has bits from Enum PartParts
STRING
partName
;
///< example "passives/R", immutable.
STRING
partNameAndRev
;
///< example "passives/R[/revN..]", immutable.
STRING
revision
;
// @todo need a single search key, this won't do.
LPID
*
extends
;
///< of base part, NULL if none, otherwise I own it.
LPID
*
extends
;
///< of base part, NULL if none, otherwise I own it.
PART
*
base
;
///< which PART am I extending, if any. no ownership.
/// encapsulate the old version deletion, take ownership of @a aLPID
/// encapsulate the old version deletion, take ownership of @a aLPID
void
setExtends
(
LPID
*
aLPID
);
void
setExtends
(
LPID
*
aLPID
);
...
@@ -107,6 +107,7 @@ protected: // not likely to have C++ descendants, but protected none-the-le
...
@@ -107,6 +107,7 @@ protected: // not likely to have C++ descendants, but protected none-the-le
/// actually becomes cached in RAM.
/// actually becomes cached in RAM.
STRING
body
;
STRING
body
;
// bool cachedRevisions; ///< allows lazy loading of revision of this same part name
// 3 separate lists for speed:
// 3 separate lists for speed:
...
@@ -136,7 +137,6 @@ public:
...
@@ -136,7 +137,6 @@ public:
*/
*/
LIB
*
Owner
()
{
return
owner
;
}
LIB
*
Owner
()
{
return
owner
;
}
/**
/**
* Function Parse
* Function Parse
* translates a Sweet string into a binary form that is represented
* translates a Sweet string into a binary form that is represented
...
...
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