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
39194ef6
Commit
39194ef6
authored
Apr 03, 2011
by
Dick Hollenbeck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
more free software, Format()ing works now, only a few more items to Parse()
parent
16e9ddc2
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
667 additions
and
241 deletions
+667
-241
make-dir-lib-source-test-data.sh
new/make-dir-lib-source-test-data.sh
+3
-3
sch_part.cpp
new/sch_part.cpp
+340
-9
sch_part.h
new/sch_part.h
+258
-92
sch_sweet_parser.cpp
new/sch_sweet_parser.cpp
+59
-127
sch_sweet_parser.h
new/sch_sweet_parser.h
+0
-9
test_sch_lib_table.cpp
new/test_sch_lib_table.cpp
+7
-1
No files found.
new/make-dir-lib-source-test-data.sh
View file @
39194ef6
...
...
@@ -10,7 +10,7 @@ REVS="rev1 rev5 rev10"
REFERENCE
=
"
(reference U
(reference U
?
(effects (at 12 13 180)(font (size .7 1))(visible yes))
)"
...
...
@@ -71,7 +71,7 @@ for C in ${CATEGORIES}; do
for
P
in
${
PARTS
}
;
do
for
R
in
${
REVS
}
;
do
echo
"(part
$C
/
$P
(value 22)(footprint SM0805)(model Airplane)
echo
"(part
$C
/
$P
(value 22)(footprint SM0805)(model Airplane)
(datasheet http://favorite.pdf)
$REFERENCE
$LINE
$RECT
...
...
@@ -86,7 +86,7 @@ for C in ${CATEGORIES}; do
)"
>
$BASEDIR
/
$C
/
$P
.part.
$R
done
# also make the part without a rev:
echo
"(part
$C
/
$P
(value 22)(footprint SM0805)(model Airplane)
echo
"(part
$C
/
$P
(value 22)(footprint SM0805)(model Airplane)
(datasheet http://favorite.pdf)
$REFERENCE
$LINE
$RECT
...
...
new/sch_part.cpp
View file @
39194ef6
...
...
@@ -28,6 +28,7 @@
#include <sch_sweet_parser.h>
#include <sch_lpid.h>
#include <sch_lib_table.h>
#include <macros.h>
//#include <richio.h>
using
namespace
SCH
;
...
...
@@ -38,16 +39,21 @@ PART::PART( LIB* aOwner, const STRING& aPartNameAndRev ) :
contains
(
0
),
partNameAndRev
(
aPartNameAndRev
),
extends
(
0
),
base
(
0
),
base
(
0
)
/*
reference( this, wxT( "reference " ) ),
value( this, wxT( "value" ) ),
footprint( this, wxT( "footprint" ) ),
model( this, wxT( "model" ) ),
datasheet( this, wxT( "datasheet" ) )
*/
{
// 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
()
);)
for
(
int
i
=
REFERENCE
;
i
<
END
;
++
i
)
mandatory
[
i
]
=
0
;
}
...
...
@@ -69,7 +75,7 @@ void PART::clear()
delete
*
it
;
pins
.
clear
();
// delete
non-mandatory
properties I own, since their container will not destroy them:
// delete properties I own, since their container will not destroy them:
for
(
PROPERTIES
::
iterator
it
=
properties
.
begin
();
it
!=
properties
.
end
();
++
it
)
delete
*
it
;
properties
.
clear
();
...
...
@@ -78,7 +84,54 @@ void PART::clear()
contains
=
0
;
// @todo clear the mandatory fields
// clear the mandatory fields
for
(
int
ndx
=
REFERENCE
;
ndx
<
END
;
++
ndx
)
{
delete
mandatory
[
ndx
];
mandatory
[
ndx
]
=
0
;
}
}
PROPERTY
*
PART
::
FieldLookup
(
PROP_ID
aPropertyId
)
{
wxASSERT
(
unsigned
(
aPropertyId
)
<
unsigned
(
END
)
);
PROPERTY
*
p
=
mandatory
[
aPropertyId
];
if
(
!
p
)
{
switch
(
aPropertyId
)
{
case
REFERENCE
:
p
=
new
PROPERTY
(
this
,
wxT
(
"reference"
)
);
p
->
text
=
wxT
(
"U?"
);
break
;
case
VALUE
:
p
=
new
PROPERTY
(
this
,
wxT
(
"value"
)
);
break
;
case
FOOTPRINT
:
p
=
new
PROPERTY
(
this
,
wxT
(
"footprint"
)
);
break
;
case
DATASHEET
:
p
=
new
PROPERTY
(
this
,
wxT
(
"datasheet"
)
);
break
;
case
MODEL
:
p
=
new
PROPERTY
(
this
,
wxT
(
"model"
)
);
break
;
default
:
;
}
mandatory
[
aPropertyId
]
=
p
;
}
return
p
;
}
...
...
@@ -119,7 +172,7 @@ PART& PART::operator=( const PART& other )
}
void
PART
::
Parse
(
SWEET_PARSER
*
aParser
,
LIB_TABLE
*
aTable
)
throw
(
IO_ERROR
,
PARSE_ERROR
)
void
PART
::
Parse
(
SWEET_PARSER
*
aParser
,
LIB_TABLE
*
aTable
)
throw
(
IO_ERROR
,
PARSE_ERROR
)
{
aParser
->
Parse
(
this
,
aTable
);
}
...
...
@@ -151,7 +204,8 @@ PROPERTIES::iterator PART::propertyFind( const wxString& aPropertyName )
}
void
PART
::
Format
(
OUTPUTFORMATTER
*
out
,
int
indent
,
int
ctl
)
const
throw
(
IO_ERROR
)
void
PART
::
Format
(
OUTPUTFORMATTER
*
out
,
int
indent
,
int
ctl
)
const
throw
(
IO_ERROR
)
{
out
->
Print
(
indent
,
"(part %s"
,
partNameAndRev
.
c_str
()
);
...
...
@@ -160,12 +214,13 @@ void PART::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const throw( IO_E
out
->
Print
(
0
,
"
\n
"
);
/*
@todo
for( int i=0; i<MANDATORY_FIELDS; ++i )
for
(
int
i
=
REFERENCE
;
i
<
END
;
++
i
)
{
PROPERTY
*
prop
=
Field
(
PROP_ID
(
i
)
);
if
(
prop
)
prop
->
Format
(
out
,
indent
+
1
,
ctl
);
}
*/
for
(
PROPERTIES
::
const_iterator
it
=
properties
.
begin
();
it
!=
properties
.
end
();
++
it
)
{
(
*
it
)
->
Format
(
out
,
indent
+
1
,
ctl
);
...
...
@@ -178,6 +233,14 @@ void PART::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const throw( IO_E
InternalToLogical
(
anchor
.
y
)
);
}
if
(
keywords
.
size
()
)
{
out
->
Print
(
indent
+
1
,
"(keywords"
);
for
(
KEYWORDS
::
iterator
it
=
keywords
.
begin
();
it
!=
keywords
.
end
();
++
it
)
out
->
Print
(
0
,
" %s"
,
out
->
Quotew
(
*
it
).
c_str
()
);
out
->
Print
(
0
,
")
\n
"
);
}
for
(
GRAPHICS
::
const_iterator
it
=
graphics
.
begin
();
it
!=
graphics
.
end
();
++
it
)
{
(
*
it
)
->
Format
(
out
,
indent
+
1
,
ctl
);
...
...
@@ -187,6 +250,274 @@ void PART::Format( OUTPUTFORMATTER* out, int indent, int ctl ) const throw( IO_E
{
(
*
it
)
->
Format
(
out
,
indent
+
1
,
ctl
);
}
out
->
Print
(
indent
,
")
\n
"
);
}
//-----< PART objects >------------------------------------------------------
void
PROPERTY
::
Format
(
OUTPUTFORMATTER
*
out
,
int
indent
,
int
ctl
)
const
throw
(
IO_ERROR
)
{
wxASSERT
(
owner
);
// all PROPERTYs should have an owner.
int
i
;
for
(
i
=
PART
::
REFERENCE
;
i
<
PART
::
END
;
++
i
)
{
if
(
owner
->
Field
(
PART
::
PROP_ID
(
i
)
)
==
this
)
break
;
}
if
(
i
<
PART
::
END
)
// is a field not a property
out
->
Print
(
indent
,
"(%s"
,
TO_UTF8
(
name
)
);
else
out
->
Print
(
indent
,
"(property %s"
,
out
->
Quotew
(
name
).
c_str
()
);
if
(
effects
)
{
out
->
Print
(
0
,
" %s
\n
"
,
out
->
Quotew
(
text
).
c_str
()
);
effects
->
Format
(
out
,
indent
+
1
,
ctl
|
CTL_OMIT_NL
);
out
->
Print
(
0
,
")
\n
"
);
}
else
{
out
->
Print
(
0
,
" %s)
\n
"
,
out
->
Quotew
(
text
).
c_str
()
);
}
}
TEXT_EFFECTS
*
PROPERTY
::
EffectsLookup
()
{
if
(
!
effects
)
{
effects
=
new
TEXT_EFFECTS
();
}
return
effects
;
}
void
TEXT_EFFECTS
::
Format
(
OUTPUTFORMATTER
*
out
,
int
indent
,
int
ctl
)
const
throw
(
IO_ERROR
)
{
if
(
propName
.
IsEmpty
()
)
out
->
Print
(
indent
,
"(effects "
);
else
out
->
Print
(
indent
,
"(effects %s "
,
out
->
Quotew
(
propName
).
c_str
()
);
out
->
Print
(
0
,
"(at %.6g %.6g"
,
InternalToLogical
(
pos
.
x
),
InternalToLogical
(
pos
.
y
)
);
if
(
angle
)
out
->
Print
(
0
,
" %.6g)"
,
double
(
angle
)
);
else
out
->
Print
(
0
,
")"
);
font
.
Format
(
out
,
0
,
ctl
|
CTL_OMIT_NL
);
out
->
Print
(
0
,
"(visible %s))%s"
,
isVisible
?
"yes"
:
"no"
,
ctl
&
CTL_OMIT_NL
?
""
:
"
\n
"
);
}
void
FONT
::
Format
(
OUTPUTFORMATTER
*
out
,
int
indent
,
int
ctl
)
const
throw
(
IO_ERROR
)
{
if
(
name
.
IsEmpty
()
)
out
->
Print
(
indent
,
"(font "
);
else
out
->
Print
(
indent
,
"(font %s "
,
out
->
Quotew
(
name
).
c_str
()
);
out
->
Print
(
0
,
"(size %.6g %.6g)"
,
InternalToLogical
(
size
.
GetHeight
()
),
InternalToLogical
(
size
.
GetWidth
()
)
);
if
(
italic
)
out
->
Print
(
0
,
" italic"
);
if
(
bold
)
out
->
Print
(
0
,
" bold"
);
out
->
Print
(
0
,
")%s"
,
(
ctl
&
CTL_OMIT_NL
)
?
""
:
"
\n
"
);
}
void
PIN
::
Format
(
OUTPUTFORMATTER
*
out
,
int
indent
,
int
ctl
)
const
throw
(
IO_ERROR
)
{
out
->
Print
(
indent
,
"(pin %s %s "
,
ShowType
(),
ShowShape
()
);
if
(
angle
)
out
->
Print
(
0
,
"(at %.6g %.6g %.6g)"
,
InternalToLogical
(
pos
.
x
),
InternalToLogical
(
pos
.
y
),
double
(
angle
)
);
else
out
->
Print
(
0
,
"(at %.6g %.6g)"
,
InternalToLogical
(
pos
.
x
),
InternalToLogical
(
pos
.
y
)
);
out
->
Print
(
0
,
"(length %.6g)"
,
InternalToLogical
(
length
)
);
out
->
Print
(
0
,
"(visible %s)
\n
"
,
isVisible
?
"yes"
:
"no"
);
signal
.
Format
(
out
,
"signal"
,
indent
+
1
,
0
);
padname
.
Format
(
out
,
"padname"
,
indent
+
1
,
CTL_OMIT_NL
);
out
->
Print
(
0
,
")
\n
"
);
}
void
PINTEXT
::
Format
(
OUTPUTFORMATTER
*
out
,
const
char
*
aElement
,
int
indent
,
int
ctl
)
const
throw
(
IO_ERROR
)
{
out
->
Print
(
indent
,
"(%s %s "
,
aElement
,
out
->
Quotew
(
text
).
c_str
()
);
font
.
Format
(
out
,
0
,
CTL_OMIT_NL
);
out
->
Print
(
0
,
"(visible %s))%s"
,
isVisible
?
"yes"
:
"no"
,
ctl
&
CTL_OMIT_NL
?
""
:
"
\n
"
);
}
void
POLY_LINE
::
Format
(
OUTPUTFORMATTER
*
out
,
int
indent
,
int
ctl
)
const
throw
(
IO_ERROR
)
{
out
->
Print
(
indent
,
"(%s "
,
pts
.
size
()
==
2
?
"line"
:
"polyline"
);
formatContents
(
out
,
indent
,
ctl
);
}
void
POLY_LINE
::
formatContents
(
OUTPUTFORMATTER
*
out
,
int
indent
,
int
ctl
)
const
throw
(
IO_ERROR
)
{
out
->
Print
(
0
,
"(line_width %.6g)"
,
lineWidth
);
// @todo use logical units?
if
(
fillType
!=
PR
::
T_none
)
out
->
Print
(
0
,
"(fill %s)"
,
ShowFill
(
fillType
)
);
out
->
Print
(
0
,
"
\n
"
);
if
(
pts
.
size
()
)
{
const
int
maxLength
=
75
;
int
len
=
10
;
len
+=
out
->
Print
(
indent
+
1
,
"(pts "
);
for
(
POINTS
::
const_iterator
it
=
pts
.
begin
();
it
!=
pts
.
end
();
++
it
)
{
if
(
len
>
maxLength
)
{
len
=
10
;
out
->
Print
(
0
,
"
\n
"
);
out
->
Print
(
indent
+
2
,
"(xy %.6g %.6g)"
,
InternalToLogical
(
it
->
x
),
InternalToLogical
(
it
->
y
)
);
}
else
out
->
Print
(
0
,
"(xy %.6g %.6g)"
,
InternalToLogical
(
it
->
x
),
InternalToLogical
(
it
->
y
)
);
}
out
->
Print
(
0
,
")"
);
}
out
->
Print
(
0
,
")
\n
"
);
}
void
BEZIER
::
Format
(
OUTPUTFORMATTER
*
out
,
int
indent
,
int
ctl
)
const
throw
(
IO_ERROR
)
{
out
->
Print
(
indent
,
"(bezier "
);
formatContents
(
out
,
indent
,
ctl
);
// inherited from POLY_LINE
}
void
RECTANGLE
::
Format
(
OUTPUTFORMATTER
*
out
,
int
indent
,
int
ctl
)
const
throw
(
IO_ERROR
)
{
// (rectangle (start X Y) (end X Y) (line_width WIDTH) (fill FILL_TYPE))
out
->
Print
(
indent
,
"(rectangle (start %.6g %.6g)(end %.6g %.6g)(line_width %.6g)"
,
InternalToLogical
(
start
.
x
),
InternalToLogical
(
start
.
y
),
InternalToLogical
(
end
.
x
),
InternalToLogical
(
end
.
y
),
lineWidth
);
if
(
fillType
!=
PR
::
T_none
)
out
->
Print
(
0
,
"(fill %s)"
,
ShowFill
(
fillType
)
);
out
->
Print
(
0
,
")
\n
"
);
}
void
CIRCLE
::
Format
(
OUTPUTFORMATTER
*
out
,
int
indent
,
int
ctl
)
const
throw
(
IO_ERROR
)
{
/*
(circle (center X Y)(radius LENGTH)(line_width WIDTH)(fill FILL_TYPE))
*/
out
->
Print
(
indent
,
"(circle (center %.6g %.6g)(radius %.6g)(line_width %.6g)"
,
InternalToLogical
(
center
.
x
),
InternalToLogical
(
center
.
y
),
InternalToLogical
(
radius
),
lineWidth
);
if
(
fillType
!=
PR
::
T_none
)
out
->
Print
(
0
,
"(fill %s)"
,
ShowFill
(
fillType
)
);
out
->
Print
(
0
,
")
\n
"
);
}
void
ARC
::
Format
(
OUTPUTFORMATTER
*
out
,
int
indent
,
int
ctl
)
const
throw
(
IO_ERROR
)
{
/*
(arc (pos X Y)(radius RADIUS)(start X Y)(end X Y)(line_width WIDTH)(fill FILL_TYPE))
*/
out
->
Print
(
indent
,
"(arc (pos %.6g %.6g)(radius %.6g)(start %.6g %.6g)(end %.6g %.6g)(line_width %.6g)"
,
InternalToLogical
(
pos
.
x
),
InternalToLogical
(
pos
.
y
),
InternalToLogical
(
radius
),
InternalToLogical
(
start
.
x
),
InternalToLogical
(
start
.
y
),
InternalToLogical
(
end
.
x
),
InternalToLogical
(
end
.
y
),
lineWidth
);
if
(
fillType
!=
PR
::
T_none
)
out
->
Print
(
0
,
"(fill %s)"
,
ShowFill
(
fillType
)
);
out
->
Print
(
0
,
")
\n
"
);
}
void
GR_TEXT
::
Format
(
OUTPUTFORMATTER
*
out
,
int
indent
,
int
ctl
)
const
throw
(
IO_ERROR
)
{
/*
(text "This is the text that gets drawn."
(at X Y [ANGLE])
# Valid horizontal justification values are center, right, and left. Valid
# vertical justification values are center, top, bottom.
(justify HORIZONTAL_JUSTIFY VERTICAL_JUSTIFY)
(font [FONT] (size HEIGHT WIDTH) [italic] [bold])
(visible YES)
(fill FILL_TYPE)
)
*/
out
->
Print
(
indent
,
"(text %s
\n
"
,
out
->
Quotew
(
text
).
c_str
()
);
if
(
angle
)
out
->
Print
(
indent
+
1
,
"(at %.6g %.6g %.6g)"
,
InternalToLogical
(
pos
.
x
),
InternalToLogical
(
pos
.
y
),
double
(
angle
)
);
else
out
->
Print
(
indent
+
1
,
"(at %.6g %.6g)"
,
InternalToLogical
(
pos
.
x
),
InternalToLogical
(
pos
.
y
)
);
out
->
Print
(
0
,
"(justify %s %s)(visible %s)"
,
ShowJustify
(
hjustify
),
ShowJustify
(
vjustify
),
isVisible
?
"yes"
:
"no"
);
if
(
fillType
!=
PR
::
T_none
)
out
->
Print
(
0
,
"(fill %s)"
,
ShowFill
(
fillType
)
);
out
->
Print
(
0
,
"
\n
"
);
font
.
Format
(
out
,
indent
+
1
,
CTL_OMIT_NL
);
out
->
Print
(
0
,
")
\n
"
);
}
new/sch_part.h
View file @
39194ef6
...
...
@@ -29,6 +29,32 @@
#include <sch_lib.h>
#define INTERNAL_PER_LOGICAL 10000 ///< no. internal units per logical unit
/**
* Function InternalToLogical
* converts an internal coordinate to a logical coordinate. Logical coordinates
* are defined as the standard distance between pins being equal to one.
* Internal coordinates are currently INTERNAL_PER_LOGICAL times that.
*/
static
inline
double
InternalToLogical
(
int
aCoord
)
{
return
double
(
aCoord
)
/
INTERNAL_PER_LOGICAL
;
}
/**
* Function LogicalToInternal
* converts a logical coordinate to an internal coordinate. Logical coordinates
* are defined as the standard distance between pins being equal to one.
* Internal coordinates are currently INTERNAL_PER_LOGICAL times that.
*/
static
inline
int
LogicalToInternal
(
double
aCoord
)
{
return
int
(
aCoord
*
INTERNAL_PER_LOGICAL
);
}
//-----<temporary home for PART sub objects, move after stable>------------------
#include <wx/gdicmn.h>
...
...
@@ -39,6 +65,9 @@
class
OUTPUTFORMATTER
;
/// Control Bits for Format() functions
#define CTL_OMIT_NL (1<<0) ///< omit new line in Format()s.
namespace
SCH
{
class
PART
;
...
...
@@ -81,6 +110,9 @@ public:
italic
(
false
),
bold
(
false
)
{}
void
Format
(
OUTPUTFORMATTER
*
aFormatter
,
int
aNestLevel
,
int
aControlBits
)
const
throw
(
IO_ERROR
);
};
...
...
@@ -99,6 +131,9 @@ struct TEXT_EFFECTS
isVisible
(
false
),
property
(
0
)
{}
void
Format
(
OUTPUTFORMATTER
*
aFormatter
,
int
aNestLevel
,
int
aControlBits
)
const
throw
(
IO_ERROR
);
};
...
...
@@ -117,7 +152,16 @@ public:
virtual
~
BASE_GRAPHIC
()
{}
virtual
void
Format
(
OUTPUTFORMATTER
*
aOutputFormatter
,
int
aNestLevel
,
int
aControlBits
)
const
static
const
char
*
ShowFill
(
int
aFillType
)
{
return
SWEET_LEXER
::
TokenName
(
PR
::
T
(
aFillType
)
);
}
/**
* Function Format
* outputs this object to @a aFormatter in s-expression form.
*/
virtual
void
Format
(
OUTPUTFORMATTER
*
aFormatter
,
int
aNestLevel
,
int
aControlBits
)
const
throw
(
IO_ERROR
)
{}
};
...
...
@@ -134,10 +178,19 @@ protected:
int
fillType
;
// T_none, T_filled, or T_transparent
POINTS
pts
;
void
formatContents
(
OUTPUTFORMATTER
*
aFormatter
,
int
aNestLevel
,
int
aControlBits
)
const
throw
(
IO_ERROR
);
public
:
POLY_LINE
(
PART
*
aOwner
)
:
BASE_GRAPHIC
(
aOwner
)
{}
BASE_GRAPHIC
(
aOwner
),
lineWidth
(
1
),
fillType
(
PR
::
T_none
)
{
}
void
Format
(
OUTPUTFORMATTER
*
aFormatter
,
int
aNestLevel
,
int
aControlBits
)
const
throw
(
IO_ERROR
);
};
class
BEZIER
:
public
POLY_LINE
...
...
@@ -148,7 +201,13 @@ class BEZIER : public POLY_LINE
public
:
BEZIER
(
PART
*
aOwner
)
:
POLY_LINE
(
aOwner
)
{}
{
lineWidth
=
1
;
fillType
=
PR
::
T_none
;
}
void
Format
(
OUTPUTFORMATTER
*
aFormatter
,
int
aNestLevel
,
int
aControlBits
)
const
throw
(
IO_ERROR
);
};
class
RECTANGLE
:
public
BASE_GRAPHIC
...
...
@@ -164,8 +223,14 @@ protected:
public
:
RECTANGLE
(
PART
*
aOwner
)
:
BASE_GRAPHIC
(
aOwner
)
{}
BASE_GRAPHIC
(
aOwner
),
lineWidth
(
1
),
fillType
(
PR
::
T_none
)
{
}
void
Format
(
OUTPUTFORMATTER
*
aFormatter
,
int
aNestLevel
,
int
aControlBits
)
const
throw
(
IO_ERROR
);
};
...
...
@@ -182,8 +247,15 @@ protected:
public
:
CIRCLE
(
PART
*
aOwner
)
:
BASE_GRAPHIC
(
aOwner
)
{}
BASE_GRAPHIC
(
aOwner
),
radius
(
LogicalToInternal
(
0
.
5
)
),
lineWidth
(
1
),
fillType
(
PR
::
T_none
)
{
}
void
Format
(
OUTPUTFORMATTER
*
aFormatter
,
int
aNestLevel
,
int
aControlBits
)
const
throw
(
IO_ERROR
);
};
...
...
@@ -202,8 +274,15 @@ protected:
public
:
ARC
(
PART
*
aOwner
)
:
BASE_GRAPHIC
(
aOwner
)
{}
BASE_GRAPHIC
(
aOwner
),
lineWidth
(
1
),
fillType
(
PR
::
T_none
),
radius
(
LogicalToInternal
(
0
.
5
)
)
{
}
void
Format
(
OUTPUTFORMATTER
*
aFormatter
,
int
aNestLevel
,
int
aControlBits
)
const
throw
(
IO_ERROR
);
};
...
...
@@ -233,6 +312,14 @@ public:
vjustify
(
PR
::
T_bottom
),
isVisible
(
true
)
{}
static
const
char
*
ShowJustify
(
int
aJustify
)
{
return
SWEET_LEXER
::
TokenName
(
PR
::
T
(
aJustify
)
);
}
void
Format
(
OUTPUTFORMATTER
*
aFormatter
,
int
aNestLevel
,
int
aControlBits
)
const
throw
(
IO_ERROR
);
};
...
...
@@ -245,14 +332,45 @@ protected:
PART
*
birthplace
;
///< at which PART in inheritance chain was this PROPERTY added
wxString
name
;
wxString
text
;
TEXT_EFFECTS
effects
;
TEXT_EFFECTS
*
effects
;
void
clear
()
{
delete
effects
;
effects
=
0
;
name
=
wxEmptyString
;
text
=
wxEmptyString
;
}
public
:
PROPERTY
(
PART
*
aOwner
,
const
wxChar
*
aName
=
wxT
(
""
)
)
:
BASE_GRAPHIC
(
aOwner
),
birthplace
(
aOwner
),
name
(
aName
)
name
(
aName
),
effects
(
0
)
{}
~
PROPERTY
()
{
clear
();
}
/**
* Function Effects
* returns a pointer to the TEXT_EFFECTS object for this PROPERTY, and optionally
* will lazily allocate one if it did not exist previously.
* @param doAlloc if true, means do an allocation of a new TEXT_EFFECTS if one
* currently does not exist, otherwise return NULL if non-existent.
*/
TEXT_EFFECTS
*
EffectsLookup
();
TEXT_EFFECTS
*
Effects
()
const
{
return
effects
;
}
void
Format
(
OUTPUTFORMATTER
*
aFormatter
,
int
aNestLevel
,
int
aControlBits
)
const
throw
(
IO_ERROR
);
};
...
...
@@ -265,6 +383,9 @@ struct PINTEXT
PINTEXT
()
:
isVisible
(
true
)
{}
void
Format
(
OUTPUTFORMATTER
*
aFormatter
,
const
char
*
aElement
,
int
aNestLevel
,
int
aControlBits
)
const
throw
(
IO_ERROR
);
};
...
...
@@ -284,10 +405,18 @@ public:
isVisible
(
true
)
{}
/*
void Format( OUTPUTFORMATTER* aOutputFormatter, int aNestLevel, int aControlBits ) const
const
char
*
ShowType
()
const
{
return
SWEET_LEXER
::
TokenName
(
PR
::
T
(
connectionType
)
);
}
const
char
*
ShowShape
()
const
{
return
SWEET_LEXER
::
TokenName
(
PR
::
T
(
shape
)
);
}
void
Format
(
OUTPUTFORMATTER
*
aFormatter
,
int
aNestLevel
,
int
aControlBits
)
const
throw
(
IO_ERROR
);
*/
protected
:
PART
*
birthplace
;
///< at which PART in inheritance chain was this PIN added
...
...
@@ -340,86 +469,22 @@ class PART
friend
class
LIB
;
// is the owner of all PARTS, afterall
friend
class
SWEET_PARSER
;
protected
:
// not likely to have C++ descendants, but protected none-the-less.
/// a protected constructor, only a LIB can instantiate a PART.
PART
(
LIB
*
aOwner
,
const
STRING
&
aPartNameAndRev
);
/**
* Function destroy
* clears out this object, deleting all graphics, all fields, all properties,
* etc.
*/
void
clear
();
/**
* Function inherit
* is a specialized assignment function that copies a specific subset, enough
* to fulfill the requirements of the Sweet s-expression language.
*/
void
inherit
(
const
PART
&
aBasePart
);
/**
* Function propertyFind
* searches for aPropertyName and returns a PROPERTIES::iterator which
* is the found item or properties.end() if not found.
*/
PROPERTIES
::
iterator
propertyFind
(
const
wxString
&
aPropertyName
);
POINT
anchor
;
//PART( LIB* aOwner );
LIB
*
owner
;
///< which LIB am I a part of (pun if you want)
int
contains
;
///< has bits from Enum PartParts
STRING
partNameAndRev
;
///< example "passives/R[/revN..]", immutable.
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
void
setExtends
(
LPID
*
aLPID
);
/// s-expression text for the part, initially empty, and read in as this part
/// actually becomes cached in RAM.
STRING
body
;
// mandatory properties
PROPERTY
reference
;
///< prefix only, only components have full references
PROPERTY
value
;
PROPERTY
footprint
;
PROPERTY
model
;
PROPERTY
datasheet
;
// separate lists for speed:
/**
* Member properties
* holds the non-mandatory properties.
*/
PROPERTIES
properties
;
public
:
/**
* Member graphics
* owns : POLY_LINE, RECTANGLE, CIRCLE, ARC, BEZIER, and GR_TEXT objects.
* Enum PROP_ID
* is the set of "mandatory" properties within a PART. These are used by
* class PART as array indices into PART::mandatory[].
*/
GRAPHICS
graphics
;
/**
* Member pins
* owns all the PINs in pins.
*/
PINS
pins
;
/// Alternate body forms.
//ALTERNATES alternates;
KEYWORDS
keywords
;
public
:
enum
PROP_ID
{
REFERENCE
,
///< reference prefix, a template for instantiation at COMPONENT level
VALUE
,
///< value, e.g. "3.3K"
FOOTPRINT
,
///< name of PCB module, e.g. "16DIP300"
DATASHEET
,
///< URI of datasheet
MODEL
,
///< spice model name
END
///< array sentinel, not a valid index
};
virtual
~
PART
();
...
...
@@ -457,6 +522,24 @@ public:
void
PropertyDelete
(
const
wxString
&
aPropertyName
)
throw
(
IO_ERROR
);
/**
* Function Field
* returns a pointer to one of the mandatory properties, or NULL
* if non-existent. Use FieldLookup() to potentially allocate it.
*/
PROPERTY
*
Field
(
PROP_ID
aPropertyId
)
const
{
wxASSERT
(
unsigned
(
aPropertyId
)
<
unsigned
(
END
)
);
return
mandatory
[
aPropertyId
];
}
/**
* Function FieldLookup
* returns a pointer to one of the mandatory properties, which is lazily
* constructed by this function if need be.
* @param aPropertyId tells which field.
*/
PROPERTY
*
FieldLookup
(
PROP_ID
aPropertyId
);
/*
...
...
@@ -494,6 +577,89 @@ public:
body = aSExpression;
}
*/
protected
:
// not likely to have C++ descendants, but protected none-the-less.
/// a protected constructor, only a LIB can instantiate a PART.
PART
(
LIB
*
aOwner
,
const
STRING
&
aPartNameAndRev
);
/**
* Function destroy
* clears out this object, deleting everything that this PART owns and
* initializing values back to a state as if the object was just constructed
* empty.
*/
void
clear
();
/**
* Function inherit
* is a specialized assignment function that copies a specific subset, enough
* to fulfill the requirements of the Sweet s-expression language.
*/
void
inherit
(
const
PART
&
aBasePart
);
/**
* Function propertyFind
* searches for aPropertyName and returns a PROPERTIES::iterator which
* is the found item or properties.end() if not found.
*/
PROPERTIES
::
iterator
propertyFind
(
const
wxString
&
aPropertyName
);
POINT
anchor
;
//PART( LIB* aOwner );
LIB
*
owner
;
///< which LIB am I a part of (pun if you want)
int
contains
;
///< has bits from Enum PartParts
STRING
partNameAndRev
;
///< example "passives/R[/revN..]", immutable.
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
void
setExtends
(
LPID
*
aLPID
);
/// s-expression text for the part, initially empty, and read in as this part
/// actually becomes cached in RAM.
STRING
body
;
// mandatory properties
PROPERTY
*
mandatory
[
END
];
/*
PROPERTY value;
PROPERTY footprint;
PROPERTY model;
PROPERTY datasheet;
*/
// separate lists for speed:
/**
* Member properties
* holds the non-mandatory properties.
*/
PROPERTIES
properties
;
/**
* Member graphics
* owns : POLY_LINE, RECTANGLE, CIRCLE, ARC, BEZIER, and GR_TEXT objects.
*/
GRAPHICS
graphics
;
/**
* Member pins
* owns all the PINs in pins.
*/
PINS
pins
;
/// Alternate body forms.
//ALTERNATES alternates;
KEYWORDS
keywords
;
};
}
// namespace PART
...
...
new/sch_sweet_parser.cpp
View file @
39194ef6
...
...
@@ -36,20 +36,9 @@ using namespace PR;
#define MAX_INHERITANCE_NESTING 6 ///< max depth of inheritance, no problem going larger
/**
* Function log2int
* converts a logical coordinate to an internal coordinate. Logical coordinates
* are defined as the standard distance between pins being equal to one.
* Internal coordinates are currently INTERNAL_PER_LOGICAL times that.
*/
static
inline
int
log2int
(
double
aCoord
)
{
return
int
(
aCoord
*
INTERNAL_PER_LOGICAL
);
}
static
inline
int
internal
(
const
STRING
&
aCoord
)
{
return
log2int
(
strtod
(
aCoord
.
c_str
(),
NULL
)
);
return
LogicalToInternal
(
strtod
(
aCoord
.
c_str
(),
NULL
)
);
}
...
...
@@ -61,15 +50,15 @@ static inline int internal( const STRING& aCoord )
*/
enum
PartBit
{
PARSED
,
///< have parsed this part already, otherwise 'body' text must be parsed
EXTENDS
,
///< saw "extends" keyword, inheriting from another PART
VALUE
,
ANCHOR
,
REFERENCE
,
FOOTPRINT
,
DATASHEET
,
MODEL
,
KEYWORDS
,
parsed
,
///< have parsed this part already, otherwise 'body' text must be parsed
extends
,
///< saw "extends" keyword, inheriting from another PART
value
,
anchor
,
reference
,
footprint
,
datasheet
,
model
,
keywords
,
};
...
...
@@ -86,7 +75,7 @@ void SWEET_PARSER::parseExtends( PART* me )
PART
*
base
;
int
offset
;
if
(
contains
&
PB
(
EXTENDS
)
)
if
(
contains
&
PB
(
extends
)
)
Duplicate
(
T_extends
);
NeedSYMBOLorNUMBER
();
...
...
@@ -129,7 +118,7 @@ void SWEET_PARSER::parseExtends( PART* me )
me
->
inherit
(
*
base
);
me
->
base
=
base
;
contains
|=
PB
(
EXTENDS
);
contains
|=
PB
(
extends
);
}
...
...
@@ -175,6 +164,8 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
{
if
(
tok
==
T_LEFT
)
{
PROPERTY
*
prop
;
tok
=
NextTok
();
// because exceptions are thrown, any 'new' allocation has to be stored
...
...
@@ -195,13 +186,13 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
break
;
case
T_anchor
:
if
(
contains
&
PB
(
ANCHOR
)
)
if
(
contains
&
PB
(
anchor
)
)
Duplicate
(
tok
);
NeedNUMBER
(
"anchor x"
);
me
->
anchor
.
x
=
internal
(
CurText
()
);
NeedNUMBER
(
"anchor y"
);
me
->
anchor
.
y
=
internal
(
CurText
()
);
contains
|=
PB
(
ANCHOR
);
contains
|=
PB
(
anchor
);
break
;
case
T_line
:
...
...
@@ -247,130 +238,71 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
parseText
(
text
);
break
;
// reference in a PART is incomplete, it is just the prefix of an
// unannotated reference. Only components have full reference designators.
case
T_reference
:
if
(
contains
&
PB
(
REFERENCE
)
)
Duplicate
(
tok
);
contains
|=
PB
(
REFERENCE
);
case
T_property
:
prop
=
new
PROPERTY
(
me
);
// @todo check for uniqueness
me
->
properties
.
push_back
(
prop
);
NeedSYMBOLorNUMBER
();
me
->
reference
.
text
=
FromUTF8
();
prop
->
name
=
FromUTF8
();
L_prop
:
NeedSYMBOLorNUMBER
();
prop
->
text
=
FromUTF8
();
tok
=
NextTok
();
if
(
tok
==
T_LEFT
)
{
tok
=
NextTok
();
if
(
tok
!=
T_effects
)
Expecting
(
T_effects
);
parseTextEffects
(
&
me
->
reference
.
effects
);
parseTextEffects
(
prop
->
EffectsLookup
()
);
NeedRIGHT
();
}
else
if
(
tok
!=
T_RIGHT
)
Expecting
(
") | effects"
);
break
;
case
T_value
:
if
(
contains
&
PB
(
VALUE
)
)
Duplicate
(
tok
);
contains
|=
PB
(
VALUE
);
case
T_property_del
:
NeedSYMBOLorNUMBER
();
me
->
value
.
text
=
FromUTF8
();
tok
=
NextTok
();
if
(
tok
==
T_LEFT
)
{
tok
=
NextTok
();
if
(
tok
!=
T_effects
)
Expecting
(
T_effects
);
parseTextEffects
(
&
me
->
value
.
effects
);
NeedRIGHT
();
}
else
if
(
tok
!=
T_RIGHT
)
Expecting
(
") | effects"
);
me
->
PropertyDelete
(
FromUTF8
()
);
NeedRIGHT
();
break
;
// reference in a PART is incomplete, it is just the prefix of an
// unannotated reference. Only components have full reference designators.
case
T_reference
:
if
(
contains
&
PB
(
reference
)
)
Duplicate
(
tok
);
contains
|=
PB
(
reference
);
prop
=
me
->
FieldLookup
(
PART
::
REFERENCE
);
goto
L_prop
;
case
T_value
:
if
(
contains
&
PB
(
value
)
)
Duplicate
(
tok
);
contains
|=
PB
(
value
);
prop
=
me
->
FieldLookup
(
PART
::
VALUE
);
goto
L_prop
;
case
T_footprint
:
if
(
contains
&
PB
(
FOOTPRINT
)
)
if
(
contains
&
PB
(
footprint
)
)
Duplicate
(
tok
);
contains
|=
PB
(
FOOTPRINT
);
NeedSYMBOLorNUMBER
();
me
->
footprint
.
text
=
FromUTF8
();
tok
=
NextTok
();
if
(
tok
==
T_LEFT
)
{
tok
=
NextTok
();
if
(
tok
!=
T_effects
)
Expecting
(
T_effects
);
parseTextEffects
(
&
me
->
footprint
.
effects
);
NeedRIGHT
();
}
else
if
(
tok
!=
T_RIGHT
)
Expecting
(
") | effects"
);
break
;
contains
|=
PB
(
footprint
);
prop
=
me
->
FieldLookup
(
PART
::
FOOTPRINT
);
goto
L_prop
;
case
T_datasheet
:
if
(
contains
&
PB
(
MODEL
)
)
if
(
contains
&
PB
(
datasheet
)
)
Duplicate
(
tok
);
contains
|=
PB
(
MODEL
);
NeedSYMBOLorNUMBER
();
me
->
datasheet
.
text
=
FromUTF8
();
tok
=
NextTok
();
if
(
tok
==
T_LEFT
)
{
tok
=
NextTok
();
if
(
tok
!=
T_effects
)
Expecting
(
T_effects
);
parseTextEffects
(
&
me
->
datasheet
.
effects
);
NeedRIGHT
();
}
else
if
(
tok
!=
T_RIGHT
)
Expecting
(
") | effects"
);
break
;
contains
|=
PB
(
datasheet
);
prop
=
me
->
FieldLookup
(
PART
::
DATASHEET
);
goto
L_prop
;
case
T_model
:
if
(
contains
&
PB
(
MODEL
)
)
if
(
contains
&
PB
(
model
)
)
Duplicate
(
tok
);
contains
|=
PB
(
MODEL
);
NeedSYMBOLorNUMBER
();
me
->
model
.
text
=
FromUTF8
();
tok
=
NextTok
();
if
(
tok
==
T_LEFT
)
{
tok
=
NextTok
();
if
(
tok
!=
T_effects
)
Expecting
(
T_effects
);
parseTextEffects
(
&
me
->
model
.
effects
);
NeedRIGHT
();
}
else
if
(
tok
!=
T_RIGHT
)
Expecting
(
") | effects"
);
break
;
case
T_property
:
PROPERTY
*
property
;
property
=
new
PROPERTY
(
me
);
// @todo check for uniqueness
me
->
properties
.
push_back
(
property
);
NeedSYMBOLorNUMBER
();
property
->
name
=
FromUTF8
();
NeedSYMBOLorNUMBER
();
property
->
text
=
FromUTF8
();
tok
=
NextTok
();
if
(
tok
==
T_LEFT
)
{
tok
=
NextTok
();
if
(
tok
!=
T_effects
)
Expecting
(
T_effects
);
parseTextEffects
(
&
property
->
effects
);
NeedRIGHT
();
}
else
if
(
tok
!=
T_RIGHT
)
Expecting
(
") | effects"
);
break
;
case
T_property_del
:
NeedSYMBOLorNUMBER
();
me
->
PropertyDelete
(
FromUTF8
()
);
NeedRIGHT
();
break
;
contains
|=
PB
(
model
);
prop
=
me
->
FieldLookup
(
PART
::
MODEL
);
goto
L_prop
;
case
T_pin
:
PIN
*
pin
;
...
...
@@ -404,7 +336,6 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
case T_route_pin_swap:
break;
*/
}
}
...
...
@@ -419,7 +350,7 @@ void SWEET_PARSER::Parse( PART* me, LIB_TABLE* aTable ) throw( IO_ERROR, PARSE_E
}
}
contains
|=
PB
(
PARSED
);
contains
|=
PB
(
parsed
);
me
->
contains
|=
contains
;
}
...
...
@@ -804,6 +735,7 @@ void SWEET_PARSER::parsePolyLine( POLY_LINE* me )
if
(
sawWidth
)
Duplicate
(
tok
);
NeedNUMBER
(
"line_width"
);
// @todo Use logical units?
me
->
lineWidth
=
strtod
(
CurText
(),
NULL
);
NeedRIGHT
();
sawWidth
=
true
;
...
...
new/sch_sweet_parser.h
View file @
39194ef6
...
...
@@ -29,15 +29,6 @@
#include <sweet_lexer.h>
#define INTERNAL_PER_LOGICAL 10000 ///< no. internal units per logical unit
static
inline
double
InternalToLogical
(
int
aCoord
)
{
return
double
(
aCoord
)
/
INTERNAL_PER_LOGICAL
;
}
class
POINT
;
namespace
SCH
{
...
...
new/test_sch_lib_table.cpp
View file @
39194ef6
...
...
@@ -25,6 +25,7 @@
#include <sch_lib_table.h>
#include <sch_lib_table_lexer.h>
#include <sch_lpid.h>
#include <sch_part.h>
using
namespace
SCH
;
...
...
@@ -86,7 +87,12 @@ void LIB_TABLE::Test()
// find a part
LPID
lpid
(
"meparts:tigers/ears"
);
LookupPart
(
lpid
);
PART
*
part
=
LookupPart
(
lpid
);
sf
.
Clear
();
part
->
Format
(
&
sf
,
0
,
0
);
printf
(
"%s"
,
sf
.
GetString
().
c_str
()
);
}
...
...
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