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
26be6d01
Commit
26be6d01
authored
Jan 04, 2011
by
Dick Hollenbeck
Browse files
Options
Browse Files
Download
Plain Diff
committed
parents
41637b36
b942ebdc
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
322 additions
and
111 deletions
+322
-111
edaappl.cpp
common/edaappl.cpp
+4
-0
annotate.cpp
eeschema/annotate.cpp
+159
-66
netlist.h
eeschema/netlist.h
+33
-0
sch_dir_lib_source.cpp
new/sch_dir_lib_source.cpp
+6
-2
sch_lib.cpp
new/sch_lib.cpp
+63
-31
sch_lib.h
new/sch_lib.h
+8
-5
sch_lpid.cpp
new/sch_lpid.cpp
+15
-1
sch_lpid.h
new/sch_lpid.h
+12
-0
sch_part.cpp
new/sch_part.cpp
+22
-6
No files found.
common/edaappl.cpp
View file @
26be6d01
...
...
@@ -680,7 +680,11 @@ bool WinEDA_App::SetLanguage( bool first_time )
delete
m_Locale
;
m_Locale
=
new
wxLocale
;
#if wxCHECK_VERSION( 2, 9, 0 )
if
(
!
m_Locale
->
Init
(
m_LanguageId
)
)
#else
if
(
!
m_Locale
->
Init
(
m_LanguageId
,
wxLOCALE_CONV_ENCODING
)
)
#endif
{
wxLogDebug
(
wxT
(
"This language is not supported by the system."
)
);
...
...
eeschema/annotate.cpp
View file @
26be6d01
...
...
@@ -19,14 +19,11 @@
#include "sch_component.h"
#include "lib_pin.h"
//#define USE_OLD_ALGO
static
void
BreakReference
(
SCH_REFERENCE_LIST
&
aComponentsList
);
static
void
ReAnnotateComponents
(
SCH_REFERENCE_LIST
&
aComponentsList
);
static
void
ComputeReferenceNumber
(
SCH_REFERENCE_LIST
&
aComponentsList
,
bool
aUseSheetNum
);
static
int
GetLastReferenceNumber
(
int
aObjet
,
SCH_REFERENCE_LIST
&
aComponentsList
);
static
int
ExistUnit
(
int
aObjet
,
int
aUnit
,
SCH_REFERENCE_LIST
&
aComponentList
);
/**
* Function DeleteAnnotation
* Remove current component annotations
...
...
@@ -109,7 +106,7 @@ void SCH_EDIT_FRAME::AnnotateComponents(
// Update the screen date.
screens
.
SetDate
(
GenDate
()
);
// Set sheet number and
total sheet coun
ts.
// Set sheet number and
number of shee
ts.
SetSheetNumberAndCount
();
/* Build component list */
...
...
@@ -124,7 +121,7 @@ void SCH_EDIT_FRAME::AnnotateComponents(
/* Break full components reference in name (prefix) and number:
* example: IC1 become IC, and 1 */
BreakReference
(
references
);
references
.
SplitReferences
(
);
bool
useSheetNum
=
false
;
switch
(
sortOption
)
...
...
@@ -152,36 +149,126 @@ void SCH_EDIT_FRAME::AnnotateComponents(
break
;
}
/
* Recalculate reference numbers */
/
/ Recalculate and update reference numbers in schematic
ComputeReferenceNumber
(
references
,
useSheetNum
);
ReAnnotateComponents
(
references
);
references
.
UpdateAnnotation
(
);
/* Final control (just in case ... )*/
CheckAnnotate
(
NULL
,
!
annotateSchematic
);
OnModify
();
// Update on screen refences, that can be modified by previous calculations:
m_CurrentSheet
->
UpdateAllScreenReferences
();
SetSheetNumberAndCount
();
DrawPanel
->
Refresh
(
true
);
}
/*
* Update the reference component for the schematic project (or the current sheet)
#ifdef USE_OLD_ALGO
/** helper function
* Search the last used (greatest) reference number in the component list
* for the prefix reference given by Objet
* The component list must be sorted.
*
* @param aObjet = reference item ( aComponentsList[aObjet].m_TextRef is
* the search pattern)
* @param aComponentsList = list of items
* @param aMinValue = min value for the current search
*/
static
void
ReAnnotateComponents
(
SCH_REFERENCE_LIST
&
aComponentList
)
static
int
GetLastNumberInReference
(
int
aObjet
,
SCH_REFERENCE_LIST
&
aComponentsList
,
int
aMinValue
)
{
/* update the reference numbers */
for
(
unsigned
ii
=
0
;
ii
<
aComponentList
.
GetCount
();
ii
++
)
int
lastNumber
=
aMinValue
;
for
(
unsigned
ii
=
0
;
ii
<
aComponentsList
.
GetCount
();
ii
++
)
{
aComponentList
[
ii
].
Annotate
();
// search only for the current reference prefix:
if
(
aComponentsList
[
aObjet
].
CompareRef
(
aComponentsList
[
ii
]
)
!=
0
)
continue
;
// update max value for the current reference prefix
if
(
lastNumber
<
aComponentsList
[
ii
].
m_NumRef
)
lastNumber
=
aComponentsList
[
ii
].
m_NumRef
;
}
}
return
lastNumber
;
}
void
BreakReference
(
SCH_REFERENCE_LIST
&
aComponentsList
)
#else
/**
* helper function BuildRefIdInUseList
* creates the list of reference numbers in use for a given reference prefix.
* @param aObjet = the current component index to use for reference prefix filtering.
* @param aComponentsList = the full list of components
* @param aIdList = the buffer to fill
* @param aMinRefId = the min id value to store. all values < aMinRefId are ignored
*/
static
void
BuildRefIdInUseList
(
int
aObjet
,
SCH_REFERENCE_LIST
&
aComponentsList
,
std
::
vector
<
int
>&
aIdList
,
int
aMinRefId
)
{
aIdList
.
clear
();
for
(
unsigned
ii
=
0
;
ii
<
aComponentsList
.
GetCount
();
ii
++
)
aComponentsList
[
ii
].
Split
();
{
if
(
(
aComponentsList
[
aObjet
].
CompareRef
(
aComponentsList
[
ii
]
)
==
0
)
&&
(
aComponentsList
[
ii
].
m_NumRef
>=
aMinRefId
)
)
aIdList
.
push_back
(
aComponentsList
[
ii
].
m_NumRef
);
}
sort
(
aIdList
.
begin
(),
aIdList
.
end
()
);
// Ensure each reference Id appears only once
// If there are multiple parts per package the same Id will be stored for each part.
for
(
unsigned
ii
=
1
;
ii
<
aIdList
.
size
();
ii
++
)
{
if
(
aIdList
[
ii
]
!=
aIdList
[
ii
-
1
]
)
continue
;
aIdList
.
erase
(
aIdList
.
begin
()
+
ii
);
ii
--
;
}
}
/**
* helper function CreateFirstFreeRefId
* Search for a free ref Id inside a list of reference numbers in use.
* This list is expected sorted by increasing values, and each value stored only once
* @see BuildRefIdInUseList to prepare this list
* @param aIdList = the buffer that contains Ids in use
* @param aFirstValue = the first expected free value
* @return a free (not yet used) Id
* and this new id is added in list
*/
static
int
CreateFirstFreeRefId
(
std
::
vector
<
int
>&
aIdList
,
int
aFirstValue
)
{
int
expectedId
=
aFirstValue
;
// We search for expectedId a value >= aFirstValue.
// Skip existing Id < aFirstValue
unsigned
ii
=
0
;
for
(
;
ii
<
aIdList
.
size
();
ii
++
)
{
if
(
expectedId
<=
aIdList
[
ii
]
)
break
;
}
// Ids are sorted by increasing value, from aFirstValue
// So we search from aFirstValue the first not used value, i.e. the first hole in list.
for
(;
ii
<
aIdList
.
size
();
ii
++
)
{
if
(
expectedId
!=
aIdList
[
ii
]
)
// This id is not yet used.
{
// Insert this free Id, in order to keep list sorted
aIdList
.
insert
(
aIdList
.
begin
()
+
ii
,
expectedId
);
return
expectedId
;
}
expectedId
++
;
}
// All existing Id are tested, and all values are found in use.
// So Create a new one.
aIdList
.
push_back
(
expectedId
);
return
expectedId
;
}
#endif
/*
* Compute the reference number for components without reference number
...
...
@@ -189,7 +276,11 @@ void BreakReference( SCH_REFERENCE_LIST& aComponentsList )
*/
static
void
ComputeReferenceNumber
(
SCH_REFERENCE_LIST
&
aComponentsList
,
bool
aUseSheetNum
)
{
int
LastReferenceNumber
,
NumberOfUnits
,
Unit
;
if
(
aComponentsList
.
GetCount
()
==
0
)
return
;
int
LastReferenceNumber
=
0
;
int
NumberOfUnits
,
Unit
;
/* Components with an invisible reference (power...) always are
* re-annotated. So set their .m_IsNew member to true
...
...
@@ -209,33 +300,59 @@ static void ComputeReferenceNumber( SCH_REFERENCE_LIST& aComponentsList, bool aU
* IC .. will be set to IC4, IC4, IC5 ...
*/
unsigned
first
=
0
;
/* calculate the last used number for this reference prefix: */
LastReferenceNumber
=
GetLastReferenceNumber
(
first
,
aComponentsList
);
#ifdef USE_OLD_ALGO
int
minRefId
=
0
;
// when using sheet number, ensure ref number >= sheet number* 100
if
(
aUseSheetNum
)
minRefId
=
aComponentsList
[
first
].
m_SheetNum
*
100
;
LastReferenceNumber
=
GetLastNumberInReference
(
first
,
aComponentsList
,
minRefId
);
#else
int
minRefId
=
1
;
// when using sheet number, ensure ref number >= sheet number* 100
if
(
aUseSheetNum
)
minRefId
=
aComponentsList
[
first
].
m_SheetNum
*
100
+
1
;
// This is the list of all Id already in use for a given reference prefix.
// Will be refilled for each new reference prefix.
std
::
vector
<
int
>
idList
;
BuildRefIdInUseList
(
first
,
aComponentsList
,
idList
,
minRefId
);
#endif
for
(
unsigned
ii
=
0
;
ii
<
aComponentsList
.
GetCount
();
ii
++
)
{
if
(
aComponentsList
[
ii
].
m_Flag
)
continue
;
if
(
aComponentsList
[
first
].
CompareRef
(
aComponentsList
[
ii
]
)
!=
0
)
if
(
(
aComponentsList
[
first
].
CompareRef
(
aComponentsList
[
ii
]
)
!=
0
)
||
(
aUseSheetNum
&&
(
aComponentsList
[
first
].
m_SheetNum
!=
aComponentsList
[
ii
].
m_SheetNum
)
)
)
{
/* New reference found: we need a new ref number for this
* reference */
first
=
ii
;
LastReferenceNumber
=
GetLastReferenceNumber
(
ii
,
aComponentsList
);
}
// when using sheet number, ensure annot
number >= sheet number* 100
#ifdef USE_OLD_ALGO
minRefId
=
0
;
// when using sheet number, ensure ref
number >= sheet number* 100
if
(
aUseSheetNum
)
{
int
min_num
=
aComponentsList
[
ii
].
m_SheetNum
*
100
;
if
(
LastReferenceNumber
<
min_num
)
LastReferenceNumber
=
min_num
;
minRefId
=
aComponentsList
[
ii
].
m_SheetNum
*
100
;
LastReferenceNumber
=
GetLastNumberInReference
(
ii
,
aComponentsList
,
minRefId
);
#else
minRefId
=
1
;
// when using sheet number, ensure ref number >= sheet number* 100
if
(
aUseSheetNum
)
minRefId
=
aComponentsList
[
ii
].
m_SheetNum
*
100
+
1
;
BuildRefIdInUseList
(
first
,
aComponentsList
,
idList
,
minRefId
);
#endif
}
/* Annotation of one part per package components (trivial case)*/
if
(
aComponentsList
[
ii
].
m_Entry
->
GetPartCount
()
<=
1
)
{
if
(
aComponentsList
[
ii
].
m_IsNew
)
{
#ifdef USE_OLD_ALGO
LastReferenceNumber
++
;
#else
LastReferenceNumber
=
CreateFirstFreeRefId
(
idList
,
minRefId
);
#endif
aComponentsList
[
ii
].
m_NumRef
=
LastReferenceNumber
;
}
...
...
@@ -251,7 +368,11 @@ static void ComputeReferenceNumber( SCH_REFERENCE_LIST& aComponentsList, bool aU
if
(
aComponentsList
[
ii
].
m_IsNew
)
{
#ifdef USE_OLD_ALGO
LastReferenceNumber
++
;
#else
LastReferenceNumber
=
CreateFirstFreeRefId
(
idList
,
minRefId
);
#endif
aComponentsList
[
ii
].
m_NumRef
=
LastReferenceNumber
;
if
(
!
aComponentsList
[
ii
].
IsPartsLocked
()
)
...
...
@@ -307,33 +428,6 @@ static void ComputeReferenceNumber( SCH_REFERENCE_LIST& aComponentsList, bool aU
}
/**
* Search the last used (greatest) reference number in the component list
* for the prefix reference given by Objet
* The component list must be sorted.
*
* @param aObjet = reference item ( aComponentsList[aObjet].m_TextRef is
* the search pattern)
* @param aComponentsList = list of items
*/
int
GetLastReferenceNumber
(
int
aObjet
,
SCH_REFERENCE_LIST
&
aComponentsList
)
{
int
LastNumber
=
0
;
for
(
unsigned
ii
=
0
;
ii
<
aComponentsList
.
GetCount
();
ii
++
)
{
/* New identifier. */
if
(
aComponentsList
[
aObjet
].
CompareRef
(
aComponentsList
[
ii
]
)
!=
0
)
continue
;
if
(
LastNumber
<
aComponentsList
[
ii
].
m_NumRef
)
LastNumber
=
aComponentsList
[
ii
].
m_NumRef
;
}
return
LastNumber
;
}
/**
* Search in the sorted list of components, for a given component an other
* component with the same reference and a given part unit. Mainly used to
...
...
@@ -391,7 +485,7 @@ static int ExistUnit( int aObjet, int Unit, SCH_REFERENCE_LIST& aComponentsList
*/
int
SCH_EDIT_FRAME
::
CheckAnnotate
(
wxArrayString
*
aMessageList
,
bool
aOneSheetOnly
)
{
int
error
;
int
error
=
0
;
wxString
Buff
;
wxString
msg
,
cmpref
;
...
...
@@ -410,18 +504,15 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn
/* Break full components reference in name (prefix) and number: example:
* IC1 become IC, and 1 */
BreakReference
(
ComponentsList
);
ComponentsList
.
SplitReferences
(
);
/* count not yet annotated items */
error
=
0
;
int
imax
=
ComponentsList
.
GetCount
()
-
1
;
for
(
int
ii
=
0
;
ii
<
imax
;
ii
++
)
/* count not yet annotated items or annottaion error*/
for
(
unsigned
ii
=
0
;
ii
<
ComponentsList
.
GetCount
();
ii
++
)
{
msg
.
Empty
();
Buff
.
Empty
();
if
(
ComponentsList
[
ii
].
m_IsNew
)
if
(
ComponentsList
[
ii
].
m_IsNew
)
// Not yet annotated
{
if
(
ComponentsList
[
ii
].
m_NumRef
>=
0
)
Buff
<<
ComponentsList
[
ii
].
m_NumRef
;
...
...
@@ -446,7 +537,8 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn
break
;
}
// Annotate error
// Annotate error if unit selected does not exist ( i.e. > number of parts )
// Can happen if a component has changed in a lib, after a previous annotation
if
(
MAX
(
ComponentsList
[
ii
].
m_Entry
->
GetPartCount
(),
1
)
<
ComponentsList
[
ii
].
m_Unit
)
{
if
(
ComponentsList
[
ii
].
m_NumRef
>=
0
)
...
...
@@ -477,6 +569,7 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn
return
error
;
// count the duplicated elements (if all are annotated)
int
imax
=
ComponentsList
.
GetCount
()
-
1
;
for
(
int
ii
=
0
;
(
ii
<
imax
)
&&
(
error
<
4
);
ii
++
)
{
msg
.
Empty
();
...
...
eeschema/netlist.h
View file @
26be6d01
...
...
@@ -226,6 +226,39 @@ public:
* When annotating, some or all components are not annotated,
* i.e. ref is only U or R, with no number.
*/
/**
* Function SplitReferences
* attempts to split all reference designators into a name (U) and number (1). If the
* last character is '?' or not a digit, the reference is tagged as not annotated.
* For components with multiple parts per package that are not already annotated, set
* m_Unit to a max value (0x7FFFFFFF).
* @see SCH_REFERENCE::Split()
*/
void
SplitReferences
()
{
for
(
unsigned
ii
=
0
;
ii
<
GetCount
();
ii
++
)
componentFlatList
[
ii
].
Split
();
}
/**
* function UpdateAnnotation
* Update the reference components for the schematic project (or the current sheet)
* Note: this function does not calculate the reference numbers
* stored in m_NumRef
* So, it must be called after calcultaion of new reference numbers
* @see SCH_REFERENCE::Annotate()
*/
void
UpdateAnnotation
()
{
/* update the reference numbers */
for
(
unsigned
ii
=
0
;
ii
<
GetCount
();
ii
++
)
{
componentFlatList
[
ii
].
Annotate
();
}
}
/**
* Function SortCmpByXCoordinate
* sort the flat list by X coordinates.
...
...
new/sch_dir_lib_source.cpp
View file @
26be6d01
...
...
@@ -459,8 +459,12 @@ void DIR_LIB_SOURCE::GetRevisions( STRINGS* aResults, const STRING& aPartName )
PN_ITER
it
=
partnames
.
upper_bound
(
partName
+
'/'
);
PN_ITER
end
=
partnames
.
lower_bound
(
partName
+
char
(
'/'
+
1
)
);
while
(
it
!=
end
)
aResults
->
push_back
(
*
it
++
);
for
(
;
it
!=
end
;
++
it
)
{
const
char
*
rev
=
endsWithRev
(
*
it
);
assert
(
rev
);
aResults
->
push_back
(
it
->
substr
(
rev
-
it
->
c_str
()
)
);
}
}
}
...
...
new/sch_lib.cpp
View file @
26be6d01
...
...
@@ -39,13 +39,12 @@
/*
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.
The LIB part cache consists 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 which 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.
1) Only things which are asked for are done.
2) Anything we learn we remember.
...
...
@@ -54,10 +53,31 @@ right hand side of the map tuple.
namespace
SCH
{
class
PART_REVS
:
public
std
::
map
<
STRING
,
PART
*
>
/**
* Struct LTREV
* is for PART_REVS, and provides a custom way to compare rev STRINGs.
* Namely, the revN[N..] string if present, is collated according to a
* 'higher revision first'.
*/
struct
LTREV
{
// @todo provide an integer sort on revN.. strings here.
bool
operator
()
(
const
STRING
&
s1
,
const
STRING
&
s2
)
const
{
return
RevCmp
(
s1
.
c_str
(),
s2
.
c_str
()
)
<
0
;
}
};
/**
* Class PART_REVS
* contains the collection of revisions for a particular part name, in the
* form of cached PARTs. The tuple consists of a rev string and a PART pointer.
* The rev string is like "rev1", the PART pointer will be NULL until the PART
* gets loaded, lazily.
*/
class
PART_REVS
:
public
std
::
map
<
STRING
,
PART
*
,
LTREV
>
{
public
:
~
PART_REVS
()
{
...
...
@@ -68,6 +88,15 @@ public:
}
};
/**
* Class PARTS
* contains the collection of PART_REVS for all PARTs in the lib.
* The tuple consists of a part name and a PART_REVS pointer.
* The part name does not have the revision attached (of course this is understood
* by definition of "part name"). The PART_REVS pointer will be NULL until a client
* askes about the revisions for a part name, so the loading is done lazily.
*/
class
PARTS
:
public
std
::
map
<
STRING
,
PART_REVS
*
>
{
public
:
...
...
@@ -126,7 +155,7 @@ LIB::~LIB()
}
const
PART
*
LIB
::
find
Part
(
const
LPID
&
aLPID
)
throw
(
IO_ERROR
)
const
PART
*
LIB
::
lookup
Part
(
const
LPID
&
aLPID
)
throw
(
IO_ERROR
)
{
if
(
!
parts
)
{
...
...
@@ -137,7 +166,7 @@ const PART* LIB::findPart( const LPID& aLPID ) throw( IO_ERROR )
// insert a PART_REVS for each part name
for
(
STRINGS
::
const_iterator
it
=
vfetch
.
begin
();
it
!=
vfetch
.
end
();
++
it
)
{
// D(printf("find
Part:%s\n", it->c_str() );)
D
(
printf
(
"lookup
Part:%s
\n
"
,
it
->
c_str
()
);)
(
*
parts
)[
*
it
]
=
new
PART_REVS
;
}
}
...
...
@@ -152,44 +181,46 @@ const PART* LIB::findPart( const LPID& aLPID ) throw( IO_ERROR )
// if the key for parts has no aLPID.GetPartName() the part is not in this lib
if
(
revs
)
{
if
(
revs
->
size
()
==
0
)
if
(
revs
->
size
()
==
0
)
// assume rev list has not been loaded yet
{
// load all the revisions for this part.
source
->
GetRevisions
(
&
vfetch
,
aLPID
.
GetPartName
()
);
// creat
a PART_REV entry for
revision, but leave the PART* NULL
// creat
e a PART_REV entry for each
revision, but leave the PART* NULL
for
(
STRINGS
::
const_iterator
it
=
vfetch
.
begin
();
it
!=
vfetch
.
end
();
++
it
)
{
// D(printf("find
PartRev:%s\n", it->c_str() );)
D
(
printf
(
"lookup
PartRev:%s
\n
"
,
it
->
c_str
()
);)
(
*
revs
)[
*
it
]
=
0
;
}
}
PART_REVS
::
iterator
result
=
revs
->
find
(
aLPID
.
GetPartNameAndRev
()
)
;
PART_REVS
::
iterator
rev
;
if
(
result
!=
revs
->
end
()
)
// If caller did not say what revision, find the highest numbered one and return that.
if
(
!
aLPID
.
GetRevision
().
size
()
&&
revs
->
size
()
)
{
if
(
!
result
->
second
)
// the PART has never been loaded before
rev
=
revs
->
begin
();
// sort order has highest rev first
if
(
!
rev
->
second
)
// the PART has never been instantiated before
{
re
sult
->
second
=
new
PART
(
this
,
aLPID
.
GetPartNameAndRev
(
)
);
re
v
->
second
=
new
PART
(
this
,
LPID
::
Format
(
""
,
aLPID
.
GetPartName
(),
rev
->
first
)
);
}
return
result
->
second
;
D
(
printf
(
"lookupPartLatestRev:%s
\n
"
,
rev
->
second
->
partNameAndRev
.
c_str
()
);)
return
rev
->
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
()
)
else
{
re
sult
=
revs
->
begin
();
// sort order has highest rev first
re
v
=
revs
->
find
(
aLPID
.
GetRevision
()
);
if
(
!
result
->
second
)
// the PART has never been loaded before
if
(
rev
!=
revs
->
end
()
)
{
if
(
!
rev
->
second
)
// the PART has never been instantiated before
{
result
->
second
=
new
PART
(
this
,
LPID
::
Format
(
""
,
aLPID
.
GetPartName
(),
result
->
first
)
);
rev
->
second
=
new
PART
(
this
,
aLPID
.
GetPartNameAndRev
()
);
}
return
rev
->
second
;
}
return
result
->
second
;
}
}
...
...
@@ -199,7 +230,7 @@ const PART* LIB::findPart( const LPID& aLPID ) throw( IO_ERROR )
PART
*
LIB
::
LookupPart
(
const
LPID
&
aLPID
,
LIB_TABLE
*
aLibTable
)
throw
(
IO_ERROR
)
{
PART
*
part
=
(
PART
*
)
find
Part
(
aLPID
);
PART
*
part
=
(
PART
*
)
lookup
Part
(
aLPID
);
if
(
!
part
)
// part does not exist in this lib
{
...
...
@@ -221,7 +252,8 @@ PART* LIB::LookupPart( const LPID& aLPID, LIB_TABLE* aLibTable ) throw( IO_ERROR
printf( "\n" );
#endif
SWEET_LEXER
sw
(
part
->
body
,
wxString
::
FromUTF8
(
"body"
)
/* @todo have ReadPart give better source */
);
// @todo consider changing ReadPart to return a "source"
SWEET_LEXER
sw
(
part
->
body
,
wxString
::
FromUTF8
(
aLPID
.
Format
().
c_str
()
)
);
part
->
Parse
(
&
sw
,
aLibTable
);
}
...
...
new/sch_lib.h
View file @
26be6d01
...
...
@@ -343,14 +343,17 @@ protected:
PARTS
*
parts
;
/**
* Function findPart
* finds a PART, returns NULL if cannot find.
* Function lookupPart
* looks up a PART, returns NULL if cannot find in source. Does not parse
* the part. Does not even load the part's Sweet string. No ownership
* is given to the PART, it stays in the cache that is this LIB.
*
* @throw IO_ERROR if there is some kind of communications error reading
* the original list of parts.
*
* @return PART* - the cached PART, or NULL if not found. No ownership transferred.
*/
const
PART
*
findPart
(
const
LPID
&
aLPID
)
throw
(
IO_ERROR
);
const
PART
*
lookupPart
(
const
LPID
&
aLPID
)
throw
(
IO_ERROR
);
};
...
...
new/sch_lpid.cpp
View file @
26be6d01
...
...
@@ -58,6 +58,20 @@ const char* EndsWithRev( const char* start, const char* tail, char separator )
return
0
;
}
int
RevCmp
(
const
char
*
s1
,
const
char
*
s2
)
{
int
r
=
strncmp
(
s1
,
s2
,
3
);
if
(
r
||
strlen
(
s1
)
<
4
||
strlen
(
s2
)
<
4
)
{
return
r
;
}
int
rnum1
=
atoi
(
s1
+
3
);
int
rnum2
=
atoi
(
s2
+
3
);
return
-
(
rnum1
-
rnum2
);
// swap the sign, higher revs first
}
//----<Policy and field test functions>-------------------------------------
...
...
@@ -94,7 +108,7 @@ static int okRevision( const STRING& aField )
{
char
rev
[
32
];
// C string for speed
if
(
aField
.
size
()
>=
4
&&
aField
.
size
()
<=
sizeof
(
rev
)
-
3
)
if
(
aField
.
size
()
>=
4
)
{
strcpy
(
rev
,
"x/"
);
strcat
(
rev
,
aField
.
c_str
()
);
...
...
new/sch_lpid.h
View file @
26be6d01
...
...
@@ -228,4 +228,16 @@ static inline const char* EndsWithRev( const STRING& aPartName, char separator =
}
/**
* Function RevCmp
* compares two rev strings in a way like strcmp() except that the highest numbered
* revision is considered first in the sort order. The function probably won't work
* unless you give it two rev strings.
* @param s1 is a rev string like "rev10"
* @param s2 is a rev string like "rev1".
* @return int - either negative, zero, or positive depending on whether the revision
* is greater, equal, or less on the left hand side.
*/
int
RevCmp
(
const
char
*
s1
,
const
char
*
s2
);
#endif // SCH_LPID_H_
new/sch_part.cpp
View file @
26be6d01
...
...
@@ -38,6 +38,11 @@ using namespace SCH;
struct
XY
{};
struct
AT
{};
class
POLY_LINE
{
};
//-----</temporary home for PART sub objects, move after stable>-----------------
...
...
@@ -135,19 +140,28 @@ public:
/// @param me = ja mir, the object getting stuffed, from its perspective
void
parsePart
(
PART
*
me
)
{
PART_T
tok
=
in
->
NextTok
()
;
PART_T
tok
;
#if 0
// Be flexible regarding the starting point of the stream.
// Caller may not have read the first two tokens out of the
// 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.
if
(
tok
==
T_LEFT
)
if(
(tok = in->NextTok() )
== T_LEFT )
{
if( ( tok = in->NextTok() ) != T_part )
in->Expecting( T_part );
}
#else
// "( part" are not optional
in
->
NeedLEFT
();
if
(
(
tok
=
in
->
NextTok
()
)
!=
T_part
)
in
->
Expecting
(
T_part
);
#endif
in
->
NeedSYMBOLorNUMBER
();
// read in part NAME_HINT, and toss
tok
=
in
->
NextTok
();
...
...
@@ -187,6 +201,11 @@ public:
contains
|=
PB
(
ANCHOR
);
break
;
case
T_line
:
break
;
/*
case T_value:
if( contains & PB(VALUE) )
...
...
@@ -236,9 +255,6 @@ public:
case T_polyline:
break;
case T_line:
break;
case T_rectangle:
break;
...
...
@@ -267,7 +283,7 @@ public:
contains
|=
PB
(
PARSED
);
this
->
contains
|=
contains
;
me
->
contains
|=
contains
;
}
};
...
...
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