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
f0ba106e
Commit
f0ba106e
authored
Feb 07, 2008
by
dickelbeck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
more amazing free software
parent
70fde0fd
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1488 additions
and
1429 deletions
+1488
-1429
change_log.txt
change_log.txt
+42
-36
specctra.cpp
pcbnew/specctra.cpp
+497
-484
specctra.h
pcbnew/specctra.h
+611
-612
specctra_export.cpp
pcbnew/specctra_export.cpp
+246
-246
specctra_import.cpp
pcbnew/specctra_import.cpp
+92
-51
No files found.
change_log.txt
View file @
f0ba106e
...
...
@@ -5,6 +5,12 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with
email address.
2008-Feb-7 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+pcbnew
specctra import of *.ses, done by end of today probably.
2008-Feb-6 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+pcbnew
...
...
@@ -17,27 +23,27 @@ email address.
specctra_export.cpp now supports blind/buried/microvias. Fixed how modules
are displayed on back of board. Added a circle keepout for each copper-less
through hole.
2008-Feb-3 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+pcbnew
* specctra_export.cpp was not exporting the nets correctly, now fixed.
* Had a problem with an isolated pad modification on a single module instance
in the context of several unmodified instances of same module, now fixed.
* Fixed oval pads to make freerouting.net happy.
* specctra_export.cpp was not exporting the nets correctly, now fixed.
* Had a problem with an isolated pad modification on a single module instance
in the context of several unmodified instances of same module, now fixed.
* Fixed oval pads to make freerouting.net happy.
See: http://www.freerouting.net/usren/viewtopic.php?f=3&t=317#p408
Done with specctra export for now, will think about adding controls (by dialog)
on the export later.
* Beautification of a few modules.
* Beautification of a few modules.
2008-Jan-31 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+pcbnew:
remove the old EDGEZONE class.
A ZONE_CONTAINER class is used instead to handle the creation of a new zone outline
2008-Jan-29 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
...
...
@@ -60,7 +66,7 @@ email address.
================================================================================
+all:
I got a patch from Mr. Wayne Stambaugh which makes it possible to compile
infospgm.cpp once and link the same *.o file multiple times.
infospgm.cpp once and link the same *.o file multiple times.
Jean-Pierre, if you not yet using CMake, you should edit your make.include
so that infospgm.cpp is only compiled once for everything, not once per
program. Wayne is a competent developer who contacted me about contributing.
...
...
@@ -75,7 +81,7 @@ email address.
See page bottom of page 74 of the SECCTRA Design Language Reference, May 2000.
* HISTORY_NUMBER was spelt with a zero.
* Width was spelt as Widht
2008-Jan-25 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
...
...
@@ -90,9 +96,9 @@ email address.
in Dimensions/track and via menu, and placed by ctrl v.
They are intended to connect small pitch BGA pins to the inner layer, and can be drilled by laser
if the hole diameter is small < 0.2mm. A laser can only drill a hole between 2 adjacent layers ).
** Currently use buried via for tests only, not for production **.
2008-Jan-24 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
...
...
@@ -102,9 +108,9 @@ email address.
* added COLLECTOR::BasePtr(), which is used in qsort. Could have used
* std::sort() instead.
* Wrote D_PAD::Compare()
* updated todo.txt
* updated todo.txt
2008-Jan-24 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+pcbnew:
...
...
@@ -126,7 +132,7 @@ email address.
Plot option in GERBER format Plot (Exclude Edge Pcb layer) modification:
- the default is OFF (like odl pcbnew versions)
- this setup is now save in config (is persistant)
In Zone creation, now delete last created corner works.
2008-Jan-22 UPDATE Dick Hollenbeck <dick@softplc.com>
...
...
@@ -154,14 +160,14 @@ email address.
menubarpcb.cpp, and pcbframe.cpp. After dsn export, I intend to add an
import, and a session file feedback merge. See the revised
how-to-build-kicad.txt for the new boost c++ libraries requirement.
2008-Jan-21 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+eeschema:
labels and texts display changed when rotated 180 degres:
horizontal text are now right justified insteed of 180 degree rotated, and are readable.
+pcbnew:
bug 1874663 solved (edit a pad netname does not work very well)
...
...
@@ -177,7 +183,7 @@ email address.
+all:
filtering small mouse moves ( < 5 pixels) when clicking.
Starting a wire or a track is now more easily because these small moves do not start a block commnad.
+pcbnew:
rework of drill filles creation (excellon and reports)
needed to have a clean implantation of buried vias and mainly microvia
...
...
@@ -239,7 +245,7 @@ email address.
has commented out code that I tested as part of a possible new scheme to support
custom layer names per project.
* More specctra dsn import export work.
2008-jan-05 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
...
...
@@ -277,7 +283,7 @@ email address.
2007-Dec-23 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+all
* Because of the discussion 4 months ago about using Boost::Python, and
* Because of the discussion 4 months ago about using Boost::Python, and
because of an excellent boost::ptr_vector class, I want to make some of the
boost libraries be necessary for building Kicad. These would be:
1) boost pointer container library (immediately)
...
...
@@ -289,7 +295,7 @@ email address.
fixed this.
2) boost::python when building python in.
* Added FIND_PACKAGE(Boost) to CMakeLists.txt
2007-Dec-22 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
...
...
@@ -313,7 +319,7 @@ email address.
+pcbnew:
some changes about zones: enhanced dialog, and files reorganisation
2007-Dec-14 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+pcbnew
...
...
@@ -341,11 +347,11 @@ email address.
pcbnew/zones.cpp, see:
http://tech.groups.yahoo.com/group/kicad-users/message/2993
2007-Dec-11 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+all
* Fixed hotkey table for '+' and '-' bug. The lookup table in
* Fixed hotkey table for '+' and '-' bug. The lookup table in
common/hotkeys_basic.cpp had bad entries for + and -. These hotkeys
were not working on Linux.
* Added polygon directory to Doxyfile.
...
...
@@ -370,13 +376,13 @@ email address.
+pcbnew
Very minor bug in drill map : inaccurate via shapes (I believe EXCELLON drill file has no problems)
2007-Dec-06 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+all
Solved zoom key command problems (under linux and windows)
(seen http://sourceforge.net/tracker/index.php?func=detail&aid=1844960&group_id=145591&atid=762476)
+pcbnew
solved bug when loading a footprint in modedit: invisible text attribute was lost (trunk and tag)
...
...
@@ -387,7 +393,7 @@ email address.
added the D() macro to fctsys.h to ease conditional debug printf()s.
worked on http://sourceforge.net/tracker/index.php?func=detail&aid=1844960&group_id=145591&atid=762476
but could not resolve it in 1/2 day.
2007-Dec-4 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
...
...
@@ -395,8 +401,8 @@ email address.
* drc.cpp and dialog_drc.cpp update.
Added double click support on a MARKER or unconnected DRC_ITEM in the listboxes.
On Linux, it sometimes pops up the menu from PcbGeneralLocateAndDisplay()
for some reason after repositioning the cursor. That is not intended, but
after several attempts to work around it, I realized it is not so bad to
for some reason after repositioning the cursor. That is not intended, but
after several attempts to work around it, I realized it is not so bad to
have this happen.
* Added right click popup menus to the list boxes. User must first select
the item he wants to go to, as the right click does not change the selection.
...
...
@@ -404,7 +410,7 @@ email address.
out of pcbnew/find.cpp
Done now, its ready for folks to start using it and testing it.
2007-Dec-02 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+eeschema:
...
...
@@ -416,7 +422,7 @@ email address.
================================================================================
+pcbnew
drc.cpp and dialog_drc.cpp intermediate update.
2007-Nov-30 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
...
...
@@ -425,12 +431,12 @@ email address.
* added classes DRC, REPORT_ISSUE, DRC_ITEM and rearranged drc.cpp entirely
to comprize the DRC class. The result has finer granularity of functions
and each is fairly well documented in English, see drc_stuff.h.
Keeping old stuff commented out at bottom of drc.cpp until some more usage
Keeping old stuff commented out at bottom of drc.cpp until some more usage
and testing is done.
* Made the DRC dialog modeless, so it can sit off to the side while the MARKER
are inspected one by one.
2007-Nov-29 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+pcbnew:
...
...
@@ -444,7 +450,7 @@ email address.
* Moved BOARD's MARKERs from m_Drawings to vector<MARKER*> m_markers so
they can be easily deleted and navigated to from the drc dialog.
* deprecated the MARKER::Unlink() function.
* Added
* Added
BOARD::Add( BOARD_ITEM*, int )
BOARD::GetMARKER(int)
BOARD::Delete( BOARD_ITEM* )
...
...
@@ -454,7 +460,7 @@ email address.
* Revised BOARD::Visit() to know about BOARD::m_markers.
* Revised pcbnew/find.cpp to know about BOARD::m_markers.
* removed wxYield() from drc.cpp
2007-Nov-26 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
...
...
pcbnew/specctra.cpp
View file @
f0ba106e
...
...
@@ -4,47 +4,47 @@
*
* Copyright (C) 2007-2008 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2007 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.,
* 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
*/
/* This source file implements export and import capabilities to the
/* This source file implements export and import capabilities to the
specctra dsn file format. The grammar for that file format is documented
fairly well. There are classes for each major type of descriptor in the
spec.
Since there are so many classes in here, it may be helpful to generate
Since there are so many classes in here, it may be helpful to generate
the Doxygen directory:
$ cd <kicadSourceRoot>
$ doxygen
Then you can view the html documentation in the <kicadSourceRoot>/doxygen
directory. The main class in this file is SPECCTRA_DB and its main
functions are LoadPCB(), LoadSESSION(), and ExportPCB().
Wide use is made of boost::ptr_vector<> and std::vector<> template classes.
If the contained object is small, then std::vector tends to be used.
If the contained object is large, variable size, or would require writing
an assignment operator() or copy constructor, then boost::ptr_vector
cannot be beat.
*/
*/
#include <cstdarg>
...
...
@@ -70,7 +70,7 @@
namespace
DSN
{
#define NESTWIDTH 2 ///< how many spaces per nestLevel
#define NESTWIDTH 2 ///< how many spaces per nestLevel
...
...
@@ -84,7 +84,7 @@ void SPECCTRA_DB::ThrowIOError( const wxChar* fmt, ... ) throw( IOError )
va_start
(
args
,
fmt
);
errText
.
PrintfV
(
fmt
,
args
);
va_end
(
args
);
throw
IOError
(
errText
);
}
...
...
@@ -93,28 +93,28 @@ void SPECCTRA_DB::expecting( DSN_T aTok ) throw( IOError )
{
wxString
errText
(
_
(
"Expecting"
)
);
errText
<<
wxT
(
" "
)
<<
LEXER
::
GetTokenString
(
aTok
);
lexer
->
ThrowIOError
(
errText
,
lexer
->
CurOffset
()
);
lexer
->
ThrowIOError
(
errText
,
lexer
->
CurOffset
()
);
}
void
SPECCTRA_DB
::
expecting
(
const
char
*
text
)
throw
(
IOError
)
{
wxString
errText
(
_
(
"Expecting"
)
);
errText
<<
wxT
(
" '"
)
<<
CONV_FROM_UTF8
(
text
)
<<
wxT
(
"'"
);
lexer
->
ThrowIOError
(
errText
,
lexer
->
CurOffset
()
);
lexer
->
ThrowIOError
(
errText
,
lexer
->
CurOffset
()
);
}
void
SPECCTRA_DB
::
unexpected
(
DSN_T
aTok
)
throw
(
IOError
)
{
wxString
errText
(
_
(
"Unexpected"
)
);
errText
<<
wxT
(
" "
)
<<
LEXER
::
GetTokenString
(
aTok
);
lexer
->
ThrowIOError
(
errText
,
lexer
->
CurOffset
()
);
lexer
->
ThrowIOError
(
errText
,
lexer
->
CurOffset
()
);
}
void
SPECCTRA_DB
::
unexpected
(
const
char
*
text
)
throw
(
IOError
)
{
wxString
errText
(
_
(
"Unexpected"
)
);
errText
<<
wxT
(
" '"
)
<<
CONV_FROM_UTF8
(
text
)
<<
wxT
(
"'"
);
lexer
->
ThrowIOError
(
errText
,
lexer
->
CurOffset
()
);
lexer
->
ThrowIOError
(
errText
,
lexer
->
CurOffset
()
);
}
...
...
@@ -130,7 +130,7 @@ bool SPECCTRA_DB::isSymbol( DSN_T aTok )
// if aTok is >= 0, then it might be a coincidental match to a keyword.
return
aTok
==
T_SYMBOL
||
aTok
==
T_STRING
||
aTok
>=
0
;
}
void
SPECCTRA_DB
::
needLEFT
()
throw
(
IOError
)
{
...
...
@@ -157,22 +157,22 @@ void SPECCTRA_DB::needSYMBOL() throw( IOError )
void
SPECCTRA_DB
::
readCOMPnPIN
(
std
::
string
*
component_id
,
std
::
string
*
pin_id
)
throw
(
IOError
)
{
DSN_T
tok
;
static
const
char
pin_def
[]
=
"<pin_reference>::=<component_id>-<pin_id>"
;
static
const
char
pin_def
[]
=
"<pin_reference>::=<component_id>-<pin_id>"
;
if
(
!
isSymbol
(
lexer
->
CurTok
()
)
)
expecting
(
pin_def
);
// case for: A12-14, i.e. no wrapping quotes. This should be a single
// token, so split it.
// token, so split it.
if
(
lexer
->
CurTok
()
!=
T_STRING
)
{
const
char
*
toktext
=
lexer
->
CurText
();
const
char
*
dash
=
strchr
(
toktext
,
'-'
);
if
(
!
dash
)
expecting
(
pin_def
);
while
(
toktext
!=
dash
)
*
component_id
+=
*
toktext
++
;
...
...
@@ -181,7 +181,7 @@ void SPECCTRA_DB::readCOMPnPIN( std::string* component_id, std::string* pin_id )
while
(
*
toktext
)
*
pin_id
+=
*
toktext
++
;
}
// quoted string: "U12"-"14" or "U12"-14, 3 tokens in either case
else
{
...
...
@@ -190,7 +190,7 @@ void SPECCTRA_DB::readCOMPnPIN( std::string* component_id, std::string* pin_id )
tok
=
nextTok
();
if
(
tok
!=
T_DASH
)
expecting
(
pin_def
);
nextTok
();
// accept anything after the dash.
*
pin_id
=
lexer
->
CurText
();
}
...
...
@@ -200,18 +200,18 @@ void SPECCTRA_DB::readCOMPnPIN( std::string* component_id, std::string* pin_id )
void
SPECCTRA_DB
::
readTIME
(
time_t
*
time_stamp
)
throw
(
IOError
)
{
DSN_T
tok
;
struct
tm
mytime
;
static
const
char
time_toks
[]
=
"<month> <day> <hour> : <minute> : <second> <year>"
;
static
const
char
time_toks
[]
=
"<month> <day> <hour> : <minute> : <second> <year>"
;
static
const
char
*
months
[]
=
{
// index 0 = Jan
"Jan"
,
"Feb"
,
"Mar"
,
"Apr"
,
"May"
,
"Jun"
,
"Jan"
,
"Feb"
,
"Mar"
,
"Apr"
,
"May"
,
"Jun"
,
"Jul"
,
"Aug"
,
"Sep"
,
"Oct"
,
"Nov"
,
"Dec"
,
NULL
};
needSYMBOL
();
// month
const
char
*
ptok
=
lexer
->
CurText
();
mytime
.
tm_mon
=
0
;
// remains if we don't find a month match.
...
...
@@ -223,18 +223,18 @@ void SPECCTRA_DB::readTIME( time_t* time_stamp ) throw( IOError )
break
;
}
}
tok
=
nextTok
();
// day
if
(
tok
!=
T_NUMBER
)
expecting
(
time_toks
);
mytime
.
tm_mday
=
atoi
(
lexer
->
CurText
()
);
tok
=
nextTok
();
// hour
if
(
tok
!=
T_NUMBER
)
expecting
(
time_toks
);
mytime
.
tm_hour
=
atoi
(
lexer
->
CurText
()
);
// : colon
// : colon
needSYMBOL
();
if
(
*
lexer
->
CurText
()
!=
':'
||
strlen
(
lexer
->
CurText
()
)
!=
1
)
expecting
(
time_toks
);
...
...
@@ -243,8 +243,8 @@ void SPECCTRA_DB::readTIME( time_t* time_stamp ) throw( IOError )
if
(
tok
!=
T_NUMBER
)
expecting
(
time_toks
);
mytime
.
tm_min
=
atoi
(
lexer
->
CurText
()
);
// : colon
// : colon
needSYMBOL
();
if
(
*
lexer
->
CurText
()
!=
':'
||
strlen
(
lexer
->
CurText
()
)
!=
1
)
expecting
(
time_toks
);
...
...
@@ -253,42 +253,42 @@ void SPECCTRA_DB::readTIME( time_t* time_stamp ) throw( IOError )
if
(
tok
!=
T_NUMBER
)
expecting
(
time_toks
);
mytime
.
tm_sec
=
atoi
(
lexer
->
CurText
()
);
tok
=
nextTok
();
// year
if
(
tok
!=
T_NUMBER
)
expecting
(
time_toks
);
mytime
.
tm_year
=
atoi
(
lexer
->
CurText
()
)
-
1900
;
*
time_stamp
=
mktime
(
&
mytime
);
*
time_stamp
=
mktime
(
&
mytime
);
}
void
SPECCTRA_DB
::
LoadPCB
(
const
wxString
&
filename
)
throw
(
IOError
)
{
wxFFile
file
;
FILE
*
fp
=
wxFopen
(
filename
,
wxT
(
"r"
)
);
if
(
!
fp
)
{
ThrowIOError
(
_
(
"Unable to open file
\"
%s
\"
"
),
filename
.
GetData
()
);
ThrowIOError
(
_
(
"Unable to open file
\"
%s
\"
"
),
filename
.
GetData
()
);
}
file
.
Attach
(
fp
);
// "exception safe" way to close the file.
delete
lexer
;
delete
lexer
;
lexer
=
0
;
lexer
=
new
LEXER
(
file
.
fp
(),
filename
);
if
(
nextTok
()
!=
T_LEFT
)
expecting
(
T_LEFT
);
if
(
nextTok
()
!=
T_pcb
)
expecting
(
T_pcb
);
SetPCB
(
new
PCB
()
);
doPCB
(
pcb
);
}
...
...
@@ -296,29 +296,29 @@ void SPECCTRA_DB::LoadPCB( const wxString& filename ) throw( IOError )
void
SPECCTRA_DB
::
LoadSESSION
(
const
wxString
&
filename
)
throw
(
IOError
)
{
wxFFile
file
;
FILE
*
fp
=
wxFopen
(
filename
,
wxT
(
"r"
)
);
if
(
!
fp
)
{
ThrowIOError
(
_
(
"Unable to open file
\"
%s
\"
"
),
filename
.
GetData
()
);
ThrowIOError
(
_
(
"Unable to open file
\"
%s
\"
"
),
filename
.
GetData
()
);
}
file
.
Attach
(
fp
);
// "exception safe" way to close the file.
delete
lexer
;
delete
lexer
;
lexer
=
0
;
lexer
=
new
LEXER
(
file
.
fp
(),
filename
);
if
(
nextTok
()
!=
T_LEFT
)
expecting
(
T_LEFT
);
if
(
nextTok
()
!=
T_session
)
expecting
(
T_session
);
SetSESSION
(
new
SESSION
()
);
doSESSION
(
session
);
}
...
...
@@ -349,15 +349,15 @@ void SPECCTRA_DB::doPCB( PCB* growth ) throw( IOError )
[<color_descriptor> ]
)
*/
needSYMBOL
();
growth
->
pcbname
=
lexer
->
CurText
();
growth
->
pcbname
=
lexer
->
CurText
();
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -367,21 +367,21 @@ void SPECCTRA_DB::doPCB( PCB* growth ) throw( IOError )
growth
->
parser
=
new
PARSER
(
growth
);
doPARSER
(
growth
->
parser
);
break
;
case
T_unit
:
if
(
growth
->
unit
)
unexpected
(
tok
);
growth
->
unit
=
new
UNIT_RES
(
growth
,
tok
);
doUNIT
(
growth
->
unit
);
break
;
case
T_resolution
:
if
(
growth
->
resolution
)
unexpected
(
tok
);
growth
->
resolution
=
new
UNIT_RES
(
growth
,
tok
);
doRESOLUTION
(
growth
->
resolution
);
break
;
case
T_structure
:
if
(
growth
->
structure
)
unexpected
(
tok
);
...
...
@@ -395,14 +395,14 @@ void SPECCTRA_DB::doPCB( PCB* growth ) throw( IOError )
growth
->
placement
=
new
PLACEMENT
(
growth
);
doPLACEMENT
(
growth
->
placement
);
break
;
case
T_library
:
if
(
growth
->
library
)
unexpected
(
tok
);
growth
->
library
=
new
LIBRARY
(
growth
);
doLIBRARY
(
growth
->
library
);
break
;
case
T_network
:
if
(
growth
->
network
)
unexpected
(
tok
);
...
...
@@ -416,12 +416,12 @@ void SPECCTRA_DB::doPCB( PCB* growth ) throw( IOError )
growth
->
wiring
=
new
WIRING
(
growth
);
doWIRING
(
growth
->
wiring
);
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
}
tok
=
nextTok
();
if
(
tok
!=
T_EOF
)
expecting
(
T_EOF
);
...
...
@@ -431,7 +431,7 @@ void SPECCTRA_DB::doPCB( PCB* growth ) throw( IOError )
void
SPECCTRA_DB
::
doPARSER
(
PARSER
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
;
/* <parser_descriptor >::=
(parser
[(string_quote <quote_char >)]
...
...
@@ -447,12 +447,12 @@ void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IOError )
[(via_rotate_first [on | off])]
)
*/
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -462,29 +462,29 @@ void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IOError )
expecting
(
T_QUOTE_DEF
);
lexer
->
SetStringDelimiter
(
(
unsigned
char
)
*
lexer
->
CurText
()
);
growth
->
string_quote
=
*
lexer
->
CurText
();
quote_char
=
lexer
->
CurText
();
needRIGHT
();
quote_char
=
lexer
->
CurText
();
needRIGHT
();
break
;
case
T_space_in_quoted_tokens
:
tok
=
nextTok
();
if
(
tok
!=
T_on
&&
tok
!=
T_off
)
expecting
(
"on|off"
);
lexer
->
SetSpaceInQuotedTokens
(
tok
==
T_on
);
growth
->
space_in_quoted_tokens
=
(
tok
==
T_on
);
needRIGHT
();
needRIGHT
();
break
;
case
T_host_cad
:
needSYMBOL
();
growth
->
host_cad
=
lexer
->
CurText
();
needRIGHT
();
needRIGHT
();
break
;
case
T_host_version
:
needSYMBOL
();
growth
->
host_version
=
lexer
->
CurText
();
needRIGHT
();
needRIGHT
();
break
;
case
T_constant
:
...
...
@@ -492,7 +492,7 @@ void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IOError )
growth
->
const_id1
=
lexer
->
CurText
();
needSYMBOL
();
growth
->
const_id2
=
lexer
->
CurText
();
needRIGHT
();
needRIGHT
();
break
;
case
T_write_resolution
:
// [(writee_resolution {<character> <positive_integer >})]
...
...
@@ -532,15 +532,15 @@ void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IOError )
if
(
tok
!=
T_testpoint
)
expecting
(
T_testpoint
);
growth
->
routes_include_testpoint
=
true
;
needRIGHT
();
needRIGHT
();
break
;
case
T_case_sensitive
:
tok
=
nextTok
();
if
(
tok
!=
T_on
&&
tok
!=
T_off
)
expecting
(
"on|off"
);
growth
->
case_sensitive
=
(
tok
==
T_on
);
needRIGHT
();
needRIGHT
();
break
;
case
T_via_rotate_first
:
// [(via_rotate_first [on | off])]
...
...
@@ -548,14 +548,14 @@ void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IOError )
if
(
tok
!=
T_on
&&
tok
!=
T_off
)
expecting
(
"on|off"
);
growth
->
via_rotate_first
=
(
tok
==
T_on
);
needRIGHT
();
needRIGHT
();
break
;
case
T_generated_by_freeroute
:
growth
->
generated_by_freeroute
=
true
;
needRIGHT
();
needRIGHT
();
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -579,13 +579,13 @@ void SPECCTRA_DB::doRESOLUTION( UNIT_RES* growth ) throw(IOError)
default
:
expecting
(
"inch|mil|cm|mm|um"
);
}
tok
=
nextTok
();
if
(
tok
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
growth
->
value
=
atoi
(
lexer
->
CurText
()
);
needRIGHT
();
}
...
...
@@ -606,7 +606,7 @@ void SPECCTRA_DB::doUNIT( UNIT_RES* growth ) throw(IOError)
default
:
expecting
(
"inch|mil|cm|mm|um"
);
}
needRIGHT
();
}
...
...
@@ -618,7 +618,7 @@ void SPECCTRA_DB::doLAYER_PAIR( LAYER_PAIR* growth ) throw( IOError )
needSYMBOL
();
growth
->
layer_id1
=
lexer
->
CurText
();
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
growth
->
layer_weight
=
strtod
(
lexer
->
CurText
(),
0
);
...
...
@@ -630,15 +630,15 @@ void SPECCTRA_DB::doLAYER_PAIR( LAYER_PAIR* growth ) throw( IOError )
void
SPECCTRA_DB
::
doLAYER_NOISE_WEIGHT
(
LAYER_NOISE_WEIGHT
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
;
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
if
(
nextTok
()
!=
T_layer_pair
)
expecting
(
T_layer_pair
);
LAYER_PAIR
*
layer_pair
=
new
LAYER_PAIR
(
growth
);
growth
->
layer_pairs
.
push_back
(
layer_pair
);
doLAYER_PAIR
(
layer_pair
);
...
...
@@ -649,12 +649,12 @@ void SPECCTRA_DB::doLAYER_NOISE_WEIGHT( LAYER_NOISE_WEIGHT* growth ) throw( IOEr
void
SPECCTRA_DB
::
doSTRUCTURE
(
STRUCTURE
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
;
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -664,7 +664,7 @@ void SPECCTRA_DB::doSTRUCTURE( STRUCTURE* growth ) throw(IOError)
growth
->
unit
=
new
UNIT_RES
(
growth
,
tok
);
doUNIT
(
growth
->
unit
);
break
;
case
T_resolution
:
if
(
growth
->
unit
)
unexpected
(
tok
);
...
...
@@ -675,16 +675,16 @@ void SPECCTRA_DB::doSTRUCTURE( STRUCTURE* growth ) throw(IOError)
case
T_layer_noise_weight
:
growth
->
layer_noise_weight
=
new
LAYER_NOISE_WEIGHT
(
growth
);
doLAYER_NOISE_WEIGHT
(
growth
->
layer_noise_weight
);
break
;
break
;
case
T_place_boundary
:
L_place
:
L_place
:
if
(
growth
->
place_boundary
)
unexpected
(
tok
);
growth
->
place_boundary
=
new
BOUNDARY
(
growth
,
T_place_boundary
);
doBOUNDARY
(
growth
->
place_boundary
);
break
;
case
T_boundary
:
if
(
growth
->
boundary
)
{
...
...
@@ -709,10 +709,10 @@ L_place:
growth
->
regions
.
push_back
(
region
);
doREGION
(
region
);
break
;
case
T_snap_angle
:
STRINGPROP
*
stringprop
;
stringprop
=
new
STRINGPROP
(
growth
,
T_snap_angle
);
stringprop
=
new
STRINGPROP
(
growth
,
T_snap_angle
);
growth
->
Append
(
stringprop
);
doSTRINGPROP
(
stringprop
);
break
;
...
...
@@ -721,7 +721,7 @@ L_place:
growth
->
via
=
new
VIA
(
growth
);
doVIA
(
growth
->
via
);
break
;
case
T_control
:
growth
->
control
=
new
CONTROL
(
growth
);
doCONTROL
(
growth
->
control
);
...
...
@@ -742,8 +742,8 @@ L_place:
case
T_place_rule
:
growth
->
place_rules
=
new
RULE
(
growth
,
T_place_rule
);
doRULE
(
growth
->
place_rules
);
break
;
break
;
case
T_keepout
:
case
T_place_keepout
:
case
T_via_keepout
:
...
...
@@ -762,7 +762,7 @@ L_place:
growth
->
grids
.
push_back
(
grid
);
doGRID
(
grid
);
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -773,21 +773,21 @@ L_place:
void
SPECCTRA_DB
::
doKEEPOUT
(
KEEPOUT
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
=
nextTok
();
if
(
isSymbol
(
tok
)
)
{
growth
->
name
=
lexer
->
CurText
();
tok
=
nextTok
();
}
if
(
tok
!=
T_LEFT
)
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
while
(
tok
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -797,35 +797,35 @@ void SPECCTRA_DB::doKEEPOUT( KEEPOUT* growth ) throw( IOError )
growth
->
sequence_number
=
atoi
(
lexer
->
CurText
()
);
needRIGHT
();
break
;
case
T_rule
:
if
(
growth
->
rules
)
unexpected
(
tok
);
growth
->
rules
=
new
RULE
(
growth
,
T_rule
);
doRULE
(
growth
->
rules
);
break
;
case
T_place_rule
:
if
(
growth
->
place_rules
)
unexpected
(
tok
);
growth
->
place_rules
=
new
RULE
(
growth
,
T_place_rule
);
doRULE
(
growth
->
place_rules
);
break
;
case
T_rect
:
if
(
growth
->
shape
)
unexpected
(
tok
);
growth
->
shape
=
new
RECTANGLE
(
growth
);
doRECTANGLE
(
(
RECTANGLE
*
)
growth
->
shape
);
break
;
case
T_circle
:
if
(
growth
->
shape
)
unexpected
(
tok
);
growth
->
shape
=
new
CIRCLE
(
growth
);
doCIRCLE
(
(
CIRCLE
*
)
growth
->
shape
);
break
;
case
T_polyline_path
:
tok
=
T_path
;
case
T_path
:
...
...
@@ -835,14 +835,14 @@ void SPECCTRA_DB::doKEEPOUT( KEEPOUT* growth ) throw( IOError )
growth
->
shape
=
new
PATH
(
growth
,
tok
);
doPATH
(
(
PATH
*
)
growth
->
shape
);
break
;
case
T_qarc
:
if
(
growth
->
shape
)
unexpected
(
tok
);
growth
->
shape
=
new
QARC
(
growth
);
doQARC
(
(
QARC
*
)
growth
->
shape
);
break
;
case
T_window
:
WINDOW
*
window
;
window
=
new
WINDOW
(
growth
);
...
...
@@ -853,7 +853,7 @@ void SPECCTRA_DB::doKEEPOUT( KEEPOUT* growth ) throw( IOError )
default
:
unexpected
(
lexer
->
CurText
()
);
}
tok
=
nextTok
();
}
}
...
...
@@ -862,12 +862,12 @@ void SPECCTRA_DB::doKEEPOUT( KEEPOUT* growth ) throw( IOError )
void
SPECCTRA_DB
::
doWINDOW
(
WINDOW
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
=
nextTok
();
while
(
tok
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -877,14 +877,14 @@ void SPECCTRA_DB::doWINDOW( WINDOW* growth ) throw( IOError )
growth
->
shape
=
new
RECTANGLE
(
growth
);
doRECTANGLE
(
(
RECTANGLE
*
)
growth
->
shape
);
break
;
case
T_circle
:
if
(
growth
->
shape
)
unexpected
(
tok
);
growth
->
shape
=
new
CIRCLE
(
growth
);
doCIRCLE
(
(
CIRCLE
*
)
growth
->
shape
);
break
;
case
T_polyline_path
:
tok
=
T_path
;
case
T_path
:
...
...
@@ -894,18 +894,18 @@ void SPECCTRA_DB::doWINDOW( WINDOW* growth ) throw( IOError )
growth
->
shape
=
new
PATH
(
growth
,
tok
);
doPATH
(
(
PATH
*
)
growth
->
shape
);
break
;
case
T_qarc
:
if
(
growth
->
shape
)
unexpected
(
tok
);
growth
->
shape
=
new
QARC
(
growth
);
doQARC
(
(
QARC
*
)
growth
->
shape
);
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
tok
=
nextTok
();
}
}
...
...
@@ -914,16 +914,16 @@ void SPECCTRA_DB::doWINDOW( WINDOW* growth ) throw( IOError )
void
SPECCTRA_DB
::
doBOUNDARY
(
BOUNDARY
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
=
nextTok
();
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
if
(
tok
==
T_rect
)
{
if
(
growth
->
paths
.
size
()
)
unexpected
(
"rect when path already encountered"
);
growth
->
rectangle
=
new
RECTANGLE
(
growth
);
doRECTANGLE
(
growth
->
rectangle
);
needRIGHT
();
...
...
@@ -937,10 +937,10 @@ void SPECCTRA_DB::doBOUNDARY( BOUNDARY* growth ) throw( IOError )
{
if
(
tok
!=
T_path
)
expecting
(
T_path
);
PATH
*
path
=
new
PATH
(
growth
,
T_path
)
;
growth
->
paths
.
push_back
(
path
);
doPATH
(
path
);
tok
=
nextTok
();
...
...
@@ -950,7 +950,7 @@ void SPECCTRA_DB::doBOUNDARY( BOUNDARY* growth ) throw( IOError )
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
tok
=
nextTok
();
}
}
else
...
...
@@ -964,43 +964,43 @@ void SPECCTRA_DB::doPATH( PATH* growth ) throw( IOError )
if
(
!
isSymbol
(
tok
)
)
expecting
(
"layer_id"
);
growth
->
layer_id
=
lexer
->
CurText
();
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
"aperture_width"
);
growth
->
aperture_width
=
strtod
(
lexer
->
CurText
(),
NULL
);
POINT
ptTemp
;
tok
=
nextTok
();
do
{
if
(
tok
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
ptTemp
.
x
=
strtod
(
lexer
->
CurText
(),
NULL
);
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
ptTemp
.
y
=
strtod
(
lexer
->
CurText
(),
NULL
);
growth
->
points
.
push_back
(
ptTemp
);
}
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
&&
tok
!=
T_LEFT
);
if
(
tok
==
T_LEFT
)
{
if
(
nextTok
()
!=
T_aperture_type
)
expecting
(
T_aperture_type
);
tok
=
nextTok
();
if
(
tok
!=
T_round
&&
tok
!=
T_square
)
expecting
(
"round|square"
);
growth
->
aperture_type
=
tok
;
needRIGHT
();
}
}
...
...
@@ -1010,7 +1010,7 @@ void SPECCTRA_DB::doRECTANGLE( RECTANGLE* growth ) throw( IOError )
{
needSYMBOL
();
growth
->
layer_id
=
lexer
->
CurText
();
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
growth
->
point0
.
x
=
strtod
(
lexer
->
CurText
(),
NULL
);
...
...
@@ -1034,23 +1034,23 @@ void SPECCTRA_DB::doRECTANGLE( RECTANGLE* growth ) throw( IOError )
void
SPECCTRA_DB
::
doCIRCLE
(
CIRCLE
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
;
needSYMBOL
();
growth
->
layer_id
=
lexer
->
CurText
();
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
growth
->
diameter
=
strtod
(
lexer
->
CurText
(),
0
);
tok
=
nextTok
();
if
(
tok
==
T_NUMBER
)
{
growth
->
vertex
.
x
=
strtod
(
lexer
->
CurText
(),
0
);
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
growth
->
vertex
.
y
=
strtod
(
lexer
->
CurText
(),
0
);
tok
=
nextTok
();
}
...
...
@@ -1063,23 +1063,23 @@ void SPECCTRA_DB::doQARC( QARC* growth ) throw( IOError )
{
needSYMBOL
();
growth
->
layer_id
=
lexer
->
CurText
();
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
growth
->
aperture_width
=
strtod
(
lexer
->
CurText
(),
0
);
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
growth
->
vertex
[
i
].
x
=
strtod
(
lexer
->
CurText
(),
0
);
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
growth
->
vertex
[
i
].
y
=
strtod
(
lexer
->
CurText
(),
0
);
}
needRIGHT
();
needRIGHT
();
}
...
...
@@ -1094,32 +1094,32 @@ void SPECCTRA_DB::doSTRINGPROP( STRINGPROP* growth ) throw( IOError )
void
SPECCTRA_DB
::
doTOKPROP
(
TOKPROP
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
=
nextTok
();
if
(
tok
<
0
)
unexpected
(
lexer
->
CurText
()
);
growth
->
value
=
tok
;
needRIGHT
();
needRIGHT
();
}
void
SPECCTRA_DB
::
doVIA
(
VIA
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
;
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
==
T_LEFT
)
{
if
(
nextTok
()
!=
T_spare
)
expecting
(
T_spare
);
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
!
isSymbol
(
tok
)
)
expecting
(
T_SYMBOL
);
growth
->
spares
.
push_back
(
lexer
->
CurText
()
);
}
}
...
...
@@ -1136,7 +1136,7 @@ void SPECCTRA_DB::doVIA( VIA* growth ) throw( IOError )
void
SPECCTRA_DB
::
doCONTROL
(
CONTROL
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
;
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
...
...
@@ -1152,7 +1152,7 @@ void SPECCTRA_DB::doCONTROL( CONTROL* growth ) throw( IOError )
growth
->
via_at_smd
=
(
tok
==
T_on
);
needRIGHT
();
break
;
case
T_off_grid
:
case
T_route_to_fanout_only
:
case
T_force_to_terminal_point
:
...
...
@@ -1172,7 +1172,7 @@ void SPECCTRA_DB::doCONTROL( CONTROL* growth ) throw( IOError )
growth
->
Append
(
tokprop
);
doTOKPROP
(
tokprop
);
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -1189,16 +1189,16 @@ void SPECCTRA_DB::doPROPERTIES( PROPERTIES* growth ) throw( IOError )
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
needSYMBOL
();
property
.
name
=
lexer
->
CurText
();
needSYMBOL
();
needSYMBOL
();
property
.
value
=
lexer
->
CurText
();
growth
->
push_back
(
property
);
needRIGHT
();
needRIGHT
();
}
}
...
...
@@ -1206,12 +1206,12 @@ void SPECCTRA_DB::doPROPERTIES( PROPERTIES* growth ) throw( IOError )
void
SPECCTRA_DB
::
doLAYER
(
LAYER
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
=
nextTok
();
if
(
!
isSymbol
(
tok
)
)
expecting
(
T_SYMBOL
);
growth
->
name
=
lexer
->
CurText
();
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
...
...
@@ -1233,11 +1233,11 @@ void SPECCTRA_DB::doLAYER( LAYER* growth ) throw( IOError )
growth
->
rules
=
new
RULE
(
growth
,
T_rule
);
doRULE
(
growth
->
rules
);
break
;
case
T_property
:
doPROPERTIES
(
&
growth
->
properties
);
break
;
case
T_direction
:
tok
=
nextTok
();
switch
(
tok
)
...
...
@@ -1281,9 +1281,9 @@ void SPECCTRA_DB::doLAYER( LAYER* growth ) throw( IOError )
growth
->
cost
=
tok
;
break
;
case
T_NUMBER
:
// store as negative so we can differentiate between
// store as negative so we can differentiate between
// DSN_T (positive) and T_NUMBER (negative)
growth
->
cost
=
-
atoi
(
lexer
->
CurText
()
);
growth
->
cost
=
-
atoi
(
lexer
->
CurText
()
);
break
;
default
:
expecting
(
"forbidden|high|medium|low|free|<positive_integer>|-1"
);
...
...
@@ -1293,15 +1293,15 @@ void SPECCTRA_DB::doLAYER( LAYER* growth ) throw( IOError )
{
if
(
nextTok
()
!=
T_type
)
unexpected
(
lexer
->
CurText
()
);
tok
=
nextTok
();
if
(
tok
!=
T_length
&&
tok
!=
T_way
)
expecting
(
"length|way"
);
growth
->
cost_type
=
tok
;
if
(
nextTok
()
!=
T_RIGHT
)
expecting
(
T_RIGHT
);
tok
=
nextTok
();
}
if
(
tok
!=
T_RIGHT
)
...
...
@@ -1313,13 +1313,13 @@ void SPECCTRA_DB::doLAYER( LAYER* growth ) throw( IOError )
{
if
(
!
isSymbol
(
tok
)
)
expecting
(
T_SYMBOL
);
growth
->
use_net
.
push_back
(
lexer
->
CurText
()
);
}
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
unexpected
(
lexer
->
CurText
()
);
}
}
}
...
...
@@ -1334,10 +1334,10 @@ void SPECCTRA_DB::doRULE( RULE* growth ) throw( IOError )
while
(
bracketNesting
!=
0
&&
tok
!=
T_EOF
)
{
tok
=
nextTok
();
if
(
tok
==
T_LEFT
)
++
bracketNesting
;
else
if
(
tok
==
T_RIGHT
)
--
bracketNesting
;
...
...
@@ -1348,9 +1348,9 @@ void SPECCTRA_DB::doRULE( RULE* growth ) throw( IOError )
if
(
tok
==
T_STRING
)
builder
+=
quote_char
;
builder
+=
lexer
->
CurText
();
if
(
tok
==
T_STRING
)
builder
+=
quote_char
;
}
...
...
@@ -1364,7 +1364,7 @@ void SPECCTRA_DB::doRULE( RULE* growth ) throw( IOError )
builder
.
clear
();
}
}
if
(
tok
==
T_EOF
)
unexpected
(
T_EOF
);
}
...
...
@@ -1380,32 +1380,32 @@ void SPECCTRA_DB::doPLACE_RULE( PLACE_RULE* growth, bool expect_object_type ) th
<opposite_side_descriptor> ]}
)
*/
DSN_T tok = nextTok();
if( tok!=T_LEFT )
expecting( T_LEFT );
tok = nextTok();
if( tok==T_object_type )
{
if( !expect_object_type )
unexpected( tok );
/* [(object_type
[pcb |
image_set [large | small | discrete | capacitor | resistor]
[(image_type [smd | pin])]]
)]
*/
tok = nextTok();
switch( tok )
{
case T_pcb:
growth->object_type = tok;
break;
case T_image_set:
tok = nextTok();
switch( tok )
...
...
@@ -1421,35 +1421,35 @@ void SPECCTRA_DB::doPLACE_RULE( PLACE_RULE* growth, bool expect_object_type ) th
unexpected( lexer->CurText() );
}
break;
default:
unexpected( lexer->CurText() );
}
tok = nextTok();
if( tok == T_LEFT )
{
tok = nextTok();
if( tok != T_image_type )
expecting( T_image_type );
tok = nextTok();
if( tok!=T_smd && tok!=T_pin )
expecting( "smd|pin" );
needRIGHT();
tok = nextTok();
}
if( tok != T_RIGHT )
expecting( T_RIGHT );
tok = nextTok();
}
/* {[<spacing_descriptor> |
<permit_orient_descriptor> |
/* {[<spacing_descriptor> |
<permit_orient_descriptor> |
<permit_side_descriptor> | <opposite_side_descriptor> ]}
*/
doRULE( growth );
...
...
@@ -1460,7 +1460,7 @@ void SPECCTRA_DB::doPLACE_RULE( PLACE_RULE* growth, bool expect_object_type ) th
void
SPECCTRA_DB
::
doREGION
(
REGION
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
=
nextTok
();
if
(
isSymbol
(
tok
)
)
{
growth
->
region_id
=
lexer
->
CurText
();
...
...
@@ -1481,36 +1481,36 @@ void SPECCTRA_DB::doREGION( REGION* growth ) throw( IOError )
growth
->
rectangle
=
new
RECTANGLE
(
growth
);
doRECTANGLE
(
growth
->
rectangle
);
break
;
case
T_polygon
:
if
(
growth
->
polygon
)
unexpected
(
tok
);
growth
->
polygon
=
new
PATH
(
growth
,
T_polygon
);
doPATH
(
growth
->
polygon
);
break
;
case
T_region_net
:
case
T_region_class
:
STRINGPROP
*
stringprop
;
stringprop
=
new
STRINGPROP
(
growth
,
tok
);
growth
->
Append
(
stringprop
);
doSTRINGPROP
(
stringprop
);
break
;
break
;
case
T_region_class_class
:
CLASS_CLASS
*
class_class
;
class_class
=
new
CLASS_CLASS
(
growth
,
tok
);
growth
->
Append
(
class_class
);
doCLASS_CLASS
(
class_class
);
doCLASS_CLASS
(
class_class
);
break
;
case
T_rule
:
if
(
growth
->
rules
)
unexpected
(
tok
);
growth
->
rules
=
new
RULE
(
growth
,
T_rule
);
doRULE
(
growth
->
rules
);
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -1529,10 +1529,10 @@ void SPECCTRA_DB::doREGION( REGION* growth ) throw( IOError )
void
SPECCTRA_DB
::
doCLASS_CLASS
(
CLASS_CLASS
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
=
nextTok
();
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
switch
(
tok
)
...
...
@@ -1543,7 +1543,7 @@ void SPECCTRA_DB::doCLASS_CLASS( CLASS_CLASS* growth ) throw( IOError )
growth
->
classes
=
new
CLASSES
(
growth
);
doCLASSES
(
growth
->
classes
);
break
;
case
T_rule
:
// only T_class_class takes a T_rule
if
(
growth
->
Type
()
==
T_region_class_class
)
...
...
@@ -1553,7 +1553,7 @@ void SPECCTRA_DB::doCLASS_CLASS( CLASS_CLASS* growth ) throw( IOError )
growth
->
Append
(
rule
);
doRULE
(
rule
);
break
;
case
T_layer_rule
:
// only T_class_class takes a T_layer_rule
if
(
growth
->
Type
()
==
T_region_class_class
)
...
...
@@ -1563,8 +1563,8 @@ void SPECCTRA_DB::doCLASS_CLASS( CLASS_CLASS* growth ) throw( IOError )
growth
->
Append
(
layer_rule
);
doLAYER_RULE
(
layer_rule
);
break
;
default
:
default
:
unexpected
(
tok
);
}
}
...
...
@@ -1576,20 +1576,20 @@ void SPECCTRA_DB::doCLASSES( CLASSES* growth ) throw( IOError )
DSN_T
tok
=
nextTok
();
// require at least 2 class_ids
if
(
!
isSymbol
(
tok
)
)
expecting
(
"class_id"
);
growth
->
class_ids
.
push_back
(
lexer
->
CurText
()
);
do
{
tok
=
nextTok
();
if
(
!
isSymbol
(
tok
)
)
expecting
(
"class_id"
);
growth
->
class_ids
.
push_back
(
lexer
->
CurText
()
);
}
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
);
}
...
...
@@ -1597,7 +1597,7 @@ void SPECCTRA_DB::doCLASSES( CLASSES* growth ) throw( IOError )
void
SPECCTRA_DB
::
doGRID
(
GRID
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
=
nextTok
();
switch
(
tok
)
{
case
T_via
:
...
...
@@ -1629,12 +1629,12 @@ void SPECCTRA_DB::doGRID( GRID* growth ) throw( IOError )
{
if
(
growth
->
grid_type
==
T_place
)
unexpected
(
tok
);
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
growth
->
offset
=
strtod
(
lexer
->
CurText
(),
0
);
if
(
nextTok
()
!=
T_RIGHT
)
expecting
(
T_RIGHT
);
}
...
...
@@ -1662,24 +1662,24 @@ void SPECCTRA_DB::doGRID( GRID* growth ) throw( IOError )
void
SPECCTRA_DB
::
doLAYER_RULE
(
LAYER_RULE
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
;
needSYMBOL
();
do
{
growth
->
layer_ids
.
push_back
(
lexer
->
CurText
()
);
}
while
(
isSymbol
(
tok
=
nextTok
())
);
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
if
(
nextTok
()
!=
T_rule
)
expecting
(
T_rule
);
growth
->
rule
=
new
RULE
(
growth
,
T_rule
);
doRULE
(
growth
->
rule
);
needRIGHT
();
}
...
...
@@ -1687,30 +1687,30 @@ void SPECCTRA_DB::doLAYER_RULE( LAYER_RULE* growth ) throw( IOError )
void
SPECCTRA_DB
::
doPLACE
(
PLACE
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
=
nextTok
();
if
(
!
isSymbol
(
tok
)
)
expecting
(
"component_id"
);
growth
->
component_id
=
lexer
->
CurText
();
growth
->
component_id
=
lexer
->
CurText
();
tok
=
nextTok
();
if
(
tok
==
T_NUMBER
)
{
POINT
point
;
point
.
x
=
strtod
(
lexer
->
CurText
(),
0
);
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
point
.
y
=
strtod
(
lexer
->
CurText
(),
0
);
growth
->
SetVertex
(
point
);
tok
=
nextTok
();
if
(
tok
!=
T_front
&&
tok
!=
T_back
)
expecting
(
"front|back"
);
growth
->
side
=
tok
;
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
"rotation"
);
growth
->
SetRotation
(
strtod
(
lexer
->
CurText
(),
0
)
);
...
...
@@ -1720,7 +1720,7 @@ void SPECCTRA_DB::doPLACE( PLACE* growth ) throw( IOError )
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -1731,7 +1731,7 @@ void SPECCTRA_DB::doPLACE( PLACE* growth ) throw( IOError )
else
expecting
(
"x|y|xy|off"
);
break
;
case
T_status
:
tok
=
nextTok
();
if
(
tok
==
T_added
||
tok
==
T_deleted
||
tok
==
T_substituted
)
...
...
@@ -1739,7 +1739,7 @@ void SPECCTRA_DB::doPLACE( PLACE* growth ) throw( IOError )
else
expecting
(
"added|deleted|substituted"
);
break
;
case
T_logical_part
:
if
(
growth
->
logical_part
.
size
()
)
unexpected
(
tok
);
...
...
@@ -1748,20 +1748,20 @@ void SPECCTRA_DB::doPLACE( PLACE* growth ) throw( IOError )
expecting
(
"logical_part_id"
);
growth
->
logical_part
=
lexer
->
CurText
();
break
;
case
T_place_rule
:
if
(
growth
->
place_rules
)
unexpected
(
tok
);
growth
->
place_rules
=
new
RULE
(
growth
,
T_place_rule
);
doRULE
(
growth
->
place_rules
);
break
;
case
T_property
:
if
(
growth
->
properties
.
size
()
)
unexpected
(
tok
);
doPROPERTIES
(
&
growth
->
properties
);
break
;
case
T_lock_type
:
tok
=
nextTok
();
if
(
tok
==
T_position
||
tok
==
T_gate
||
tok
==
T_subgate
||
tok
==
T_pin
)
...
...
@@ -1791,7 +1791,7 @@ void SPECCTRA_DB::doPLACE( PLACE* growth ) throw( IOError )
growth
->
part_number
=
lexer
->
CurText
();
needRIGHT
();
break
;
default
:
unexpected
(
tok
);
}
...
...
@@ -1802,7 +1802,7 @@ void SPECCTRA_DB::doPLACE( PLACE* growth ) throw( IOError )
void
SPECCTRA_DB
::
doCOMPONENT
(
COMPONENT
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
=
nextTok
();
if
(
!
isSymbol
(
tok
)
)
expecting
(
"image_id"
);
growth
->
image_id
=
lexer
->
CurText
();
...
...
@@ -1811,7 +1811,7 @@ void SPECCTRA_DB::doCOMPONENT( COMPONENT* growth ) throw( IOError )
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -1821,7 +1821,7 @@ void SPECCTRA_DB::doCOMPONENT( COMPONENT* growth ) throw( IOError )
growth
->
places
.
push_back
(
place
);
doPLACE
(
place
);
break
;
default
:
unexpected
(
tok
);
}
...
...
@@ -1832,9 +1832,9 @@ void SPECCTRA_DB::doCOMPONENT( COMPONENT* growth ) throw( IOError )
void
SPECCTRA_DB
::
doPLACEMENT
(
PLACEMENT
*
growth
)
throw
(
IOError
)
{
DSN_T
tok
;
needLEFT
();
tok
=
nextTok
();
if
(
tok
==
T_unit
||
tok
==
T_resolution
)
{
...
...
@@ -1843,21 +1843,21 @@ void SPECCTRA_DB::doPLACEMENT( PLACEMENT* growth ) throw( IOError )
doRESOLUTION
(
growth
->
unit
);
else
doUNIT
(
growth
->
unit
);
if
(
nextTok
()
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
}
if
(
tok
==
T_place_control
)
{
if
(
nextTok
()
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
if
(
tok
!=
T_flip_style
)
expecting
(
T_flip_style
);
tok
=
nextTok
();
if
(
tok
==
T_mirror_first
||
tok
==
T_rotate_first
)
growth
->
flip_style
=
tok
;
...
...
@@ -1866,7 +1866,7 @@ void SPECCTRA_DB::doPLACEMENT( PLACEMENT* growth ) throw( IOError )
needRIGHT
();
needRIGHT
();
needLEFT
();
needLEFT
();
tok
=
nextTok
();
}
...
...
@@ -1875,15 +1875,15 @@ void SPECCTRA_DB::doPLACEMENT( PLACEMENT* growth ) throw( IOError )
COMPONENT
*
component
=
new
COMPONENT
(
growth
);
growth
->
components
.
push_back
(
component
);
doCOMPONENT
(
component
);
tok
=
nextTok
();
if
(
tok
==
T_RIGHT
)
return
;
else
if
(
tok
==
T_LEFT
)
else
if
(
tok
==
T_LEFT
)
tok
=
nextTok
();
}
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -1905,18 +1905,18 @@ void SPECCTRA_DB::doPADSTACK( PADSTACK* growth ) throw( IOError )
[(absolute [on | off])]
[(rule <clearance_descriptor> )])
*/
// padstack_id may be a number
if
(
!
isSymbol
(
tok
)
&&
tok
!=
T_NUMBER
)
expecting
(
"padstack_id"
);
growth
->
padstack_id
=
lexer
->
CurText
();
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -1942,7 +1942,7 @@ void SPECCTRA_DB::doPADSTACK( PADSTACK* growth ) throw( IOError )
growth
->
absolute
=
tok
;
needRIGHT
();
break
;
case
T_shape
:
SHAPE
*
shape
;
shape
=
new
SHAPE
(
growth
);
...
...
@@ -1960,27 +1960,27 @@ void SPECCTRA_DB::doPADSTACK( PADSTACK* growth ) throw( IOError )
{
if
(
nextTok
()
!=
T_use_via
)
expecting
(
T_use_via
);
needSYMBOL
();
growth
->
via_id
=
lexer
->
CurText
();
needRIGHT
();
needRIGHT
();
needRIGHT
();
}
break
;
/*
case T_via_site: not supported
break;
*/
*/
case
T_rule
:
if
(
growth
->
rules
)
unexpected
(
tok
);
growth
->
rules
=
new
RULE
(
growth
,
T_rule
);
doRULE
(
growth
->
rules
);
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -1997,12 +1997,12 @@ void SPECCTRA_DB::doSHAPE( SHAPE* growth ) throw( IOError )
[(connect [on | off])]
[{<window_descriptor> }])
*/
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -2013,7 +2013,7 @@ void SPECCTRA_DB::doSHAPE( SHAPE* growth ) throw( IOError )
case
T_path
:
case
T_polygon
:
case
T_qarc
:
L_done_that
:
L_done_that
:
if
(
growth
->
shape
)
unexpected
(
tok
);
break
;
...
...
@@ -2025,25 +2025,25 @@ L_done_that:
goto
L_done_that
;
}
}
switch
(
tok
)
{
case
T_rect
:
growth
->
shape
=
new
RECTANGLE
(
growth
);
doRECTANGLE
(
(
RECTANGLE
*
)
growth
->
shape
);
break
;
case
T_circle
:
growth
->
shape
=
new
CIRCLE
(
growth
);
doCIRCLE
(
(
CIRCLE
*
)
growth
->
shape
);
break
;
case
T_path
:
case
T_polygon
:
growth
->
shape
=
new
PATH
(
growth
,
tok
);
doPATH
(
(
PATH
*
)
growth
->
shape
);
break
;
case
T_qarc
:
growth
->
shape
=
new
QARC
(
growth
);
doQARC
(
(
QARC
*
)
growth
->
shape
);
...
...
@@ -2063,7 +2063,7 @@ L_done_that:
growth
->
windows
.
push_back
(
window
);
doWINDOW
(
window
);
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -2094,14 +2094,14 @@ void SPECCTRA_DB::doIMAGE( IMAGE* growth ) throw( IOError )
if
(
!
isSymbol
(
tok
)
)
expecting
(
"image_id"
);
growth
->
image_id
=
lexer
->
CurText
();
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -2133,7 +2133,7 @@ void SPECCTRA_DB::doIMAGE( IMAGE* growth ) throw( IOError )
growth
->
pins
.
push_back
(
pin
);
doPIN
(
pin
);
break
;
case
T_rule
:
if
(
growth
->
rules
)
unexpected
(
tok
);
...
...
@@ -2159,7 +2159,7 @@ void SPECCTRA_DB::doIMAGE( IMAGE* growth ) throw( IOError )
growth
->
keepouts
.
push_back
(
keepout
);
doKEEPOUT
(
keepout
);
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -2179,23 +2179,23 @@ void SPECCTRA_DB::doPIN( PIN* growth ) throw( IOError )
// a padstack_id may be a number
if
(
!
isSymbol
(
tok
)
&&
tok
!=
T_NUMBER
)
expecting
(
"padstack_id"
);
growth
->
padstack_id
=
lexer
->
CurText
();
tok
=
nextTok
();
if
(
tok
==
T_LEFT
)
{
tok
=
nextTok
();
if
(
tok
!=
T_rotate
)
expecting
(
T_rotate
);
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
growth
->
SetRotation
(
strtod
(
lexer
->
CurText
(),
0
)
);
needRIGHT
();
tok
=
nextTok
();
}
if
(
!
isSymbol
(
tok
)
&&
tok
!=
T_NUMBER
)
expecting
(
"pin_id"
);
...
...
@@ -2204,7 +2204,7 @@ void SPECCTRA_DB::doPIN( PIN* growth ) throw( IOError )
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
growth
->
vertex
.
x
=
strtod
(
lexer
->
CurText
(),
0
);
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
growth
->
vertex
.
y
=
strtod
(
lexer
->
CurText
(),
0
);
...
...
@@ -2231,12 +2231,12 @@ void SPECCTRA_DB::doLIBRARY( LIBRARY* growth ) throw( IOError )
[{<image_image_descriptor> }]
)
*/
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -2246,7 +2246,7 @@ void SPECCTRA_DB::doLIBRARY( LIBRARY* growth ) throw( IOError )
growth
->
unit
=
new
UNIT_RES
(
growth
,
tok
);
doUNIT
(
growth
->
unit
);
break
;
case
T_padstack
:
PADSTACK
*
padstack
;
padstack
=
new
PADSTACK
(
growth
);
...
...
@@ -2260,7 +2260,7 @@ void SPECCTRA_DB::doLIBRARY( LIBRARY* growth ) throw( IOError )
growth
->
images
.
push_back
(
image
);
doIMAGE
(
image
);
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -2295,14 +2295,14 @@ void SPECCTRA_DB::doNET( NET* growth ) throw( IOError )
if
(
!
isSymbol
(
tok
)
)
expecting
(
"net_id"
);
growth
->
net_id
=
lexer
->
CurText
();
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -2325,7 +2325,7 @@ void SPECCTRA_DB::doNET( NET* growth ) throw( IOError )
PIN_REF
empty
(
growth
);
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
// copy the empty one, then fill its copy later thru pin_ref.
// copy the empty one, then fill its copy later thru pin_ref.
growth
->
pins
.
push_back
(
empty
);
PIN_REF
*
pin_ref
=
&
growth
->
pins
.
back
();
...
...
@@ -2341,7 +2341,7 @@ void SPECCTRA_DB::doNET( NET* growth ) throw( IOError )
growth
->
comp_order
=
new
COMP_ORDER
(
growth
);
doCOMP_ORDER
(
growth
->
comp_order
);
break
;
case
T_type
:
tok
=
nextTok
();
if
(
tok
!=
T_fix
&&
tok
!=
T_normal
)
...
...
@@ -2350,7 +2350,7 @@ void SPECCTRA_DB::doNET( NET* growth ) throw( IOError )
needRIGHT
();
break
;
/* @todo
/* @todo
case T_circuit:
break;
*/
...
...
@@ -2361,14 +2361,14 @@ void SPECCTRA_DB::doNET( NET* growth ) throw( IOError )
growth
->
rules
=
new
RULE
(
growth
,
T_rule
);
doRULE
(
growth
->
rules
);
break
;
case
T_layer_rule
:
LAYER_RULE
*
layer_rule
;
layer_rule
=
new
LAYER_RULE
(
growth
);
growth
->
layer_rules
.
push_back
(
layer_rule
);
doLAYER_RULE
(
layer_rule
);
break
;
case
T_fromto
:
FROMTO
*
fromto
;
fromto
=
new
FROMTO
(
growth
);
...
...
@@ -2396,7 +2396,7 @@ void SPECCTRA_DB::doTOPOLOGY( TOPOLOGY* growth ) throw( IOError )
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -2406,7 +2406,7 @@ void SPECCTRA_DB::doTOPOLOGY( TOPOLOGY* growth ) throw( IOError )
growth
->
fromtos
.
push_back
(
fromto
);
doFROMTO
(
fromto
);
break
;
case
T_comp_order
:
COMP_ORDER
*
comp_order
;
comp_order
=
new
COMP_ORDER
(
growth
);
...
...
@@ -2436,7 +2436,7 @@ void SPECCTRA_DB::doCLASS( CLASS* growth ) throw( IOError )
*/
needSYMBOL
();
growth
->
class_id
=
lexer
->
CurText
();
// do net_ids, do not support <composite_name_list>s at this time
...
...
@@ -2444,13 +2444,13 @@ void SPECCTRA_DB::doCLASS( CLASS* growth ) throw( IOError )
{
growth
->
net_ids
.
push_back
(
lexer
->
CurText
()
);
}
while
(
tok
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -2460,54 +2460,54 @@ void SPECCTRA_DB::doCLASS( CLASS* growth ) throw( IOError )
growth
->
rules
=
new
RULE
(
growth
,
T_rule
);
doRULE
(
growth
->
rules
);
break
;
case
T_layer_rule
:
LAYER_RULE
*
layer_rule
;
layer_rule
=
new
LAYER_RULE
(
growth
);
growth
->
layer_rules
.
push_back
(
layer_rule
);
doLAYER_RULE
(
layer_rule
);
break
;
case
T_topology
:
if
(
growth
->
topology
)
unexpected
(
tok
);
growth
->
topology
=
new
TOPOLOGY
(
growth
);
doTOPOLOGY
(
growth
->
topology
);
break
;
default
:
// handle all the circuit_descriptor here as strings
{
std
::
string
builder
;
int
bracketNesting
=
1
;
// we already saw the opening T_LEFT
DSN_T
tok
=
T_NONE
;
builder
+=
'('
;
builder
+=
lexer
->
CurText
();
while
(
bracketNesting
!=
0
&&
tok
!=
T_EOF
)
{
tok
=
nextTok
();
if
(
tok
==
T_LEFT
)
++
bracketNesting
;
else
if
(
tok
==
T_RIGHT
)
--
bracketNesting
;
if
(
bracketNesting
>=
1
)
{
if
(
lexer
->
PrevTok
()
!=
T_LEFT
&&
tok
!=
T_RIGHT
)
builder
+=
' '
;
if
(
tok
==
T_STRING
)
builder
+=
quote_char
;
builder
+=
lexer
->
CurText
();
if
(
tok
==
T_STRING
)
builder
+=
quote_char
;
}
// When the nested rule is closed with a T_RIGHT and we are back down
// to bracketNesting == 0, then save the builder and break;
if
(
bracketNesting
==
0
)
...
...
@@ -2517,14 +2517,14 @@ void SPECCTRA_DB::doCLASS( CLASS* growth ) throw( IOError )
break
;
}
}
if
(
tok
==
T_EOF
)
unexpected
(
T_EOF
);
}
// scope bracket
}
// switch
tok
=
nextTok
();
}
// while
}
...
...
@@ -2549,7 +2549,7 @@ void SPECCTRA_DB::doNETWORK( NETWORK* growth ) throw( IOError )
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -2559,7 +2559,7 @@ void SPECCTRA_DB::doNETWORK( NETWORK* growth ) throw( IOError )
growth
->
nets
.
push_back
(
net
);
doNET
(
net
);
break
;
case
T_class
:
CLASS
*
myclass
;
myclass
=
new
CLASS
(
growth
);
...
...
@@ -2586,7 +2586,7 @@ void SPECCTRA_DB::doCOMP_ORDER( COMP_ORDER* growth ) throw( IOError )
{
growth
->
placement_ids
.
push_back
(
lexer
->
CurText
()
);
}
if
(
tok
!=
T_RIGHT
)
expecting
(
T_RIGHT
);
}
...
...
@@ -2608,20 +2608,20 @@ void SPECCTRA_DB::doFROMTO( FROMTO* growth ) throw( IOError )
)}
*/
// read the first two grammar items in as 2 single tokens, i.e. do not
// split apart the <pin_reference>s into 3 separate tokens. Do this by
// turning off the string delimiter in the lexer.
int
old
=
lexer
->
SetStringDelimiter
(
0
);
if
(
!
isSymbol
(
nextTok
()
)
)
{
lexer
->
SetStringDelimiter
(
old
);
expecting
(
T_SYMBOL
);
}
growth
->
fromText
=
lexer
->
CurText
();
if
(
!
isSymbol
(
nextTok
()
)
)
{
lexer
->
SetStringDelimiter
(
old
);
...
...
@@ -2630,12 +2630,12 @@ void SPECCTRA_DB::doFROMTO( FROMTO* growth ) throw( IOError )
growth
->
toText
=
lexer
->
CurText
();
lexer
->
SetStringDelimiter
(
old
);
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -2646,7 +2646,7 @@ void SPECCTRA_DB::doFROMTO( FROMTO* growth ) throw( IOError )
growth
->
fromto_type
=
tok
;
needRIGHT
();
break
;
case
T_rule
:
if
(
growth
->
rules
)
unexpected
(
tok
);
...
...
@@ -2668,9 +2668,9 @@ void SPECCTRA_DB::doFROMTO( FROMTO* growth ) throw( IOError )
growth
->
net_id
=
lexer
->
CurText
();
needRIGHT
();
break
;
// circuit descriptor not supported at this time
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -2713,7 +2713,7 @@ void SPECCTRA_DB::doWIRE( WIRE* growth ) throw( IOError )
growth
->
shape
=
new
RECTANGLE
(
growth
);
doRECTANGLE
(
(
RECTANGLE
*
)
growth
->
shape
);
break
;
case
T_circle
:
if
(
growth
->
shape
)
unexpected
(
tok
);
...
...
@@ -2730,7 +2730,7 @@ void SPECCTRA_DB::doWIRE( WIRE* growth ) throw( IOError )
growth
->
shape
=
new
PATH
(
growth
,
tok
);
doPATH
(
(
PATH
*
)
growth
->
shape
);
break
;
case
T_qarc
:
if
(
growth
->
shape
)
unexpected
(
tok
);
...
...
@@ -2743,14 +2743,14 @@ void SPECCTRA_DB::doWIRE( WIRE* growth ) throw( IOError )
growth
->
net_id
=
lexer
->
CurText
();
needRIGHT
();
break
;
case
T_turret
:
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
T_NUMBER
);
growth
->
turret
=
atoi
(
lexer
->
CurText
()
);
needRIGHT
();
break
;
case
T_type
:
tok
=
nextTok
();
if
(
tok
!=
T_fix
&&
tok
!=
T_route
&&
tok
!=
T_normal
&&
tok
!=
T_protect
)
...
...
@@ -2772,28 +2772,28 @@ void SPECCTRA_DB::doWIRE( WIRE* growth ) throw( IOError )
growth
->
shield
=
lexer
->
CurText
();
needRIGHT
();
break
;
case
T_window
:
WINDOW
*
window
;
window
=
new
WINDOW
(
growth
);
growth
->
windows
.
push_back
(
window
);
doWINDOW
(
window
);
break
;
case
T_connect
:
if
(
growth
->
connect
)
unexpected
(
tok
);
/* @todo
/* @todo
growth->connect = new CONNECT( growth );
doCONNECT( growth->connect );
*/
*/
break
;
case
T_supply
:
growth
->
supply
=
true
;
needRIGHT
();
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -2805,7 +2805,7 @@ void SPECCTRA_DB::doWIRE_VIA( WIRE_VIA* growth ) throw( IOError )
{
DSN_T
tok
;
POINT
point
;
/* <wire_via_descriptor >::=
(via
<padstack_id > {<vertex> }
...
...
@@ -2828,12 +2828,12 @@ void SPECCTRA_DB::doWIRE_VIA( WIRE_VIA* growth ) throw( IOError )
while
(
(
tok
=
nextTok
())
==
T_NUMBER
)
{
point
.
x
=
strtod
(
lexer
->
CurText
(),
0
);
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
"vertex.y"
);
point
.
y
=
strtod
(
lexer
->
CurText
(),
0
);
growth
->
vertexes
.
push_back
(
point
);
}
...
...
@@ -2841,7 +2841,7 @@ void SPECCTRA_DB::doWIRE_VIA( WIRE_VIA* growth ) throw( IOError )
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -2850,14 +2850,14 @@ void SPECCTRA_DB::doWIRE_VIA( WIRE_VIA* growth ) throw( IOError )
growth
->
net_id
=
lexer
->
CurText
();
needRIGHT
();
break
;
case
T_via_number
:
if
(
nextTok
()
!=
T_NUMBER
)
expecting
(
"<via#>"
);
growth
->
via_number
=
atoi
(
lexer
->
CurText
()
);
needRIGHT
();
break
;
case
T_type
:
tok
=
nextTok
();
if
(
tok
!=
T_fix
&&
tok
!=
T_route
&&
tok
!=
T_normal
&&
tok
!=
T_protect
)
...
...
@@ -2865,7 +2865,7 @@ void SPECCTRA_DB::doWIRE_VIA( WIRE_VIA* growth ) throw( IOError )
growth
->
via_type
=
tok
;
needRIGHT
();
break
;
case
T_attr
:
tok
=
nextTok
();
if
(
tok
!=
T_test
&&
tok
!=
T_fanout
&&
tok
!=
T_jumper
&&
tok
!=
T_virtual_pin
)
...
...
@@ -2878,7 +2878,7 @@ void SPECCTRA_DB::doWIRE_VIA( WIRE_VIA* growth ) throw( IOError )
}
needRIGHT
();
break
;
case
T_contact
:
needSYMBOL
();
tok
=
T_SYMBOL
;
...
...
@@ -2890,16 +2890,16 @@ void SPECCTRA_DB::doWIRE_VIA( WIRE_VIA* growth ) throw( IOError )
if
(
tok
!=
T_RIGHT
)
expecting
(
T_RIGHT
);
break
;
case
T_supply
:
growth
->
supply
=
true
;
needRIGHT
();
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
tok
=
nextTok
();
}
}
...
...
@@ -2922,7 +2922,7 @@ void SPECCTRA_DB::doWIRING( WIRING* growth ) throw( IOError )
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -2932,14 +2932,14 @@ void SPECCTRA_DB::doWIRING( WIRING* growth ) throw( IOError )
growth
->
unit
=
new
UNIT_RES
(
growth
,
tok
);
doUNIT
(
growth
->
unit
);
break
;
case
T_resolution
:
if
(
growth
->
unit
)
unexpected
(
tok
);
growth
->
unit
=
new
UNIT_RES
(
growth
,
tok
);
doRESOLUTION
(
growth
->
unit
);
break
;
case
T_wire
:
WIRE
*
wire
;
wire
=
new
WIRE
(
growth
);
...
...
@@ -2953,7 +2953,7 @@ void SPECCTRA_DB::doWIRING( WIRING* growth ) throw( IOError )
growth
->
wire_vias
.
push_back
(
wire_via
);
doWIRE_VIA
(
wire_via
);
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -2969,15 +2969,15 @@ void SPECCTRA_DB::doANCESTOR( ANCESTOR* growth ) throw( IOError )
(ancestor <file_path_name> (created_time <time_stamp> )
[(comment <comment_string> )])
*/
needSYMBOL
();
growth
->
filename
=
lexer
->
CurText
();
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -2985,13 +2985,13 @@ void SPECCTRA_DB::doANCESTOR( ANCESTOR* growth ) throw( IOError )
readTIME
(
&
growth
->
time_stamp
);
needRIGHT
();
break
;
case
T_comment
:
needSYMBOL
();
growth
->
comment
=
lexer
->
CurText
();
needRIGHT
();
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -3006,12 +3006,12 @@ void SPECCTRA_DB::doHISTORY( HISTORY* growth ) throw( IOError )
/* <history_descriptor >::=
(history [{<ancestor_file_descriptor> }] <self_descriptor> )
*/
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -3021,33 +3021,33 @@ void SPECCTRA_DB::doHISTORY( HISTORY* growth ) throw( IOError )
growth
->
ancestors
.
push_back
(
ancestor
);
doANCESTOR
(
ancestor
);
break
;
case
T_self
:
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
tok
=
nextTok
();
switch
(
tok
)
{
case
T_created_time
:
readTIME
(
&
growth
->
time_stamp
);
needRIGHT
();
break
;
case
T_comment
:
needSYMBOL
();
growth
->
comments
.
push_back
(
lexer
->
CurText
()
);
needRIGHT
();
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
}
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -3072,7 +3072,7 @@ void SPECCTRA_DB::doSESSION( SESSION* growth ) throw( IOError )
[<route_descriptor> ]
)
*/
needSYMBOL
();
growth
->
session_id
=
lexer
->
CurText
();
...
...
@@ -3080,7 +3080,7 @@ void SPECCTRA_DB::doSESSION( SESSION* growth ) throw( IOError )
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -3089,28 +3089,28 @@ void SPECCTRA_DB::doSESSION( SESSION* growth ) throw( IOError )
growth
->
base_design
=
lexer
->
CurText
();
needRIGHT
();
break
;
case
T_history
:
if
(
growth
->
history
)
unexpected
(
tok
);
growth
->
history
=
new
HISTORY
(
growth
);
doHISTORY
(
growth
->
history
);
break
;
case
T_structure
:
if
(
growth
->
structure
)
unexpected
(
tok
);
growth
->
structure
=
new
STRUCTURE
(
growth
);
doSTRUCTURE
(
growth
->
structure
);
break
;
case
T_placement
:
if
(
growth
->
placement
)
unexpected
(
tok
);
growth
->
placement
=
new
PLACEMENT
(
growth
);
doPLACEMENT
(
growth
->
placement
);
break
;
case
T_was_is
:
if
(
growth
->
was_is
)
unexpected
(
tok
);
...
...
@@ -3124,7 +3124,7 @@ void SPECCTRA_DB::doSESSION( SESSION* growth ) throw( IOError )
growth
->
route
=
new
ROUTE
(
growth
);
doROUTE
(
growth
->
route
);
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -3145,27 +3145,27 @@ void SPECCTRA_DB::doWAS_IS( WAS_IS* growth ) throw( IOError )
// none of the pins is ok too
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
case
T_pins
:
// copy the empty one, then fill its copy later thru pin_pair.
// copy the empty one, then fill its copy later thru pin_pair.
growth
->
pin_pairs
.
push_back
(
empty
);
pin_pair
=
&
growth
->
pin_pairs
.
back
();
needSYMBOL
();
// readCOMPnPIN() expects 1st token to have been read
readCOMPnPIN
(
&
pin_pair
->
was
.
component_id
,
&
pin_pair
->
was
.
pin_id
);
needSYMBOL
();
// readCOMPnPIN() expects 1st token to have been read
readCOMPnPIN
(
&
pin_pair
->
is
.
component_id
,
&
pin_pair
->
is
.
pin_id
);
needRIGHT
();
break
;
default
:
unexpected
(
lexer
->
CurText
()
);
}
...
...
@@ -3192,7 +3192,7 @@ void SPECCTRA_DB::doROUTE( ROUTE* growth ) throw( IOError )
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -3223,20 +3223,20 @@ void SPECCTRA_DB::doROUTE( ROUTE* growth ) throw( IOError )
growth
->
library
=
new
LIBRARY
(
growth
,
tok
);
doLIBRARY
(
growth
->
library
);
break
;
case
T_network_out
:
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
if
(
tok
!=
T_net
)
// it is class NET_OUT, but token T_net
unexpected
(
lexer
->
CurText
()
);
NET_OUT
*
net_out
;
net_out
=
new
NET_OUT
(
growth
);
growth
->
net_outs
.
push_back
(
net_out
);
doNET_OUT
(
net_out
);
}
...
...
@@ -3262,15 +3262,15 @@ void SPECCTRA_DB::doNET_OUT( NET_OUT* growth ) throw( IOError )
{[<supply_pin_descriptor> ]}
)
*/
needSYMBOL
();
growth
->
net_id
=
lexer
->
CurText
();
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
tok
!=
T_LEFT
)
expecting
(
T_LEFT
);
tok
=
nextTok
();
switch
(
tok
)
{
...
...
@@ -3302,7 +3302,7 @@ void SPECCTRA_DB::doNET_OUT( NET_OUT* growth ) throw( IOError )
growth
->
wire_vias
.
push_back
(
wire_via
);
doWIRE_VIA
(
wire_via
);
break
;
case
T_supply_pin
:
SUPPLY_PIN
*
supply_pin
;
supply_pin
=
new
SUPPLY_PIN
(
growth
);
...
...
@@ -3325,18 +3325,18 @@ void SPECCTRA_DB::doSUPPLY_PIN( SUPPLY_PIN* growth ) throw( IOError )
/* <supply_pin_descriptor >::=
(supply_pin {<pin_reference> } [(net <net_id >)])
*/
needSYMBOL
();
growth
->
net_id
=
lexer
->
CurText
();
while
(
(
tok
=
nextTok
())
!=
T_RIGHT
)
{
if
(
isSymbol
(
tok
)
)
{
growth
->
pin_refs
.
push_back
(
empty
);
PIN_REF
*
pin_ref
=
&
growth
->
pin_refs
.
back
();
readCOMPnPIN
(
&
pin_ref
->
component_id
,
&
pin_ref
->
pin_id
);
}
else
if
(
tok
==
T_LEFT
)
...
...
@@ -3358,92 +3358,92 @@ int SPECCTRA_DB::Print( int nestLevel, const char* fmt, ... ) throw( IOError )
va_list
args
;
va_start
(
args
,
fmt
);
int
result
=
0
;
int
total
=
0
;
for
(
int
i
=
0
;
i
<
nestLevel
;
++
i
)
{
result
=
fprintf
(
fp
,
"%*c"
,
NESTWIDTH
,
' '
);
if
(
result
<
0
)
break
;
total
+=
result
;
}
if
(
result
<
0
||
(
result
=
vfprintf
(
fp
,
fmt
,
args
))
<
0
)
ThrowIOError
(
_
(
"System file error writing to file
\"
%s
\"
"
),
filename
.
GetData
()
);
va_end
(
args
);
total
+=
result
;
return
total
;
}
// factor out a common GetQuoteChar
const
char
*
OUTPUTFORMATTER
::
GetQuoteChar
(
const
char
*
wrapee
,
const
char
*
quote_char
)
const
char
*
OUTPUTFORMATTER
::
GetQuoteChar
(
const
char
*
wrapee
,
const
char
*
quote_char
)
{
// I include '#' so a symbol is not confused with a comment. We intend
// to wrap any symbol starting with a '#'.
// Our LEXER class handles comments, and comments appear to be an extension
// to the SPECCTRA DSN specification.
// to the SPECCTRA DSN specification.
if
(
*
wrapee
==
'#'
)
return
quote_char
;
if
(
strlen
(
wrapee
)
==
0
)
return
quote_char
;
bool
isNumber
=
true
;
for
(
;
*
wrapee
;
++
wrapee
)
{
static
const
char
quoteThese
[]
=
"
\t
()"
"%"
// per Alfons of freerouting.net, he does not like this unquoted as of 1-Feb-2008
;
// if the string to be wrapped (wrapee) has a delimiter in it,
// if the string to be wrapped (wrapee) has a delimiter in it,
// return the quote_char so caller wraps the wrapee.
if
(
strchr
(
quoteThese
,
*
wrapee
)
)
return
quote_char
;
if
(
!
strchr
(
"01234567890.-+"
,
*
wrapee
)
)
isNumber
=
false
;
}
if
(
isNumber
)
return
quote_char
;
return
""
;
// can use an unwrapped string.
}
const
char
*
SPECCTRA_DB
::
GetQuoteChar
(
const
char
*
wrapee
)
const
char
*
SPECCTRA_DB
::
GetQuoteChar
(
const
char
*
wrapee
)
{
return
OUTPUTFORMATTER
::
GetQuoteChar
(
wrapee
,
quote_char
.
c_str
()
);
return
OUTPUTFORMATTER
::
GetQuoteChar
(
wrapee
,
quote_char
.
c_str
()
);
}
void
SPECCTRA_DB
::
ExportPCB
(
wxString
filename
,
bool
aNameChange
)
throw
(
IOError
)
{
fp
=
wxFopen
(
filename
,
wxT
(
"w"
)
);
if
(
!
fp
)
{
ThrowIOError
(
_
(
"Unable to open file
\"
%s
\"
"
),
filename
.
GetData
()
);
ThrowIOError
(
_
(
"Unable to open file
\"
%s
\"
"
),
filename
.
GetData
()
);
}
if
(
pcb
)
{
if
(
aNameChange
)
pcb
->
pcbname
=
CONV_TO_UTF8
(
filename
);
pcb
->
pcbname
=
CONV_TO_UTF8
(
filename
);
pcb
->
Format
(
this
,
0
);
}
// if an exception is thrown by Format, then ~SPECCTRA_DB() will close
// the file.
fclose
(
fp
);
fp
=
0
;
}
...
...
@@ -3452,15 +3452,15 @@ void SPECCTRA_DB::ExportPCB( wxString filename, bool aNameChange ) throw( IOErro
void
SPECCTRA_DB
::
ExportSESSION
(
wxString
filename
)
{
fp
=
wxFopen
(
filename
,
wxT
(
"w"
)
);
if
(
!
fp
)
{
ThrowIOError
(
_
(
"Unable to open file
\"
%s
\"
"
),
filename
.
GetData
()
);
ThrowIOError
(
_
(
"Unable to open file
\"
%s
\"
"
),
filename
.
GetData
()
);
}
if
(
session
)
session
->
Format
(
this
,
0
);
session
->
Format
(
this
,
0
);
fclose
(
fp
);
fp
=
0
;
}
...
...
@@ -3469,22 +3469,22 @@ void SPECCTRA_DB::ExportSESSION( wxString filename )
PCB
*
SPECCTRA_DB
::
MakePCB
()
{
PCB
*
pcb
=
new
PCB
();
pcb
->
parser
=
new
PARSER
(
pcb
);
pcb
->
resolution
=
new
UNIT_RES
(
pcb
,
T_resolution
);
pcb
->
unit
=
new
UNIT_RES
(
pcb
,
T_unit
);
pcb
->
structure
=
new
STRUCTURE
(
pcb
);
pcb
->
structure
->
boundary
=
new
BOUNDARY
(
pcb
->
structure
);
pcb
->
structure
->
via
=
new
VIA
(
pcb
->
structure
);
pcb
->
structure
->
rules
=
new
RULE
(
pcb
->
structure
,
T_rule
);
pcb
->
placement
=
new
PLACEMENT
(
pcb
);
pcb
->
library
=
new
LIBRARY
(
pcb
);
pcb
->
network
=
new
NETWORK
(
pcb
);
pcb
->
wiring
=
new
WIRING
(
pcb
);
return
pcb
;
...
...
@@ -3493,13 +3493,13 @@ PCB* SPECCTRA_DB::MakePCB()
//-----<STRINGFORMATTER>----------------------------------------------------
const
char
*
STRINGFORMATTER
::
GetQuoteChar
(
const
char
*
wrapee
)
const
char
*
STRINGFORMATTER
::
GetQuoteChar
(
const
char
*
wrapee
)
{
// for what we are using STRINGFORMATTER for at this time, we can return the nul string
// always.
return
""
;
// return OUTPUTFORMATTER::GetQuoteChar( const char* wrapee, "\"" );
// return OUTPUTFORMATTER::GetQuoteChar( const char* wrapee, "\"" );
}
int
STRINGFORMATTER
::
vprint
(
const
char
*
fmt
,
va_list
ap
)
...
...
@@ -3510,12 +3510,12 @@ int STRINGFORMATTER::vprint( const char* fmt, va_list ap )
buffer
.
reserve
(
ret
+
200
);
ret
=
vsnprintf
(
&
buffer
[
0
],
buffer
.
size
(),
fmt
,
ap
);
}
if
(
ret
>
0
)
mystring
.
append
(
(
const
char
*
)
&
buffer
[
0
]
);
return
ret
;
}
}
int
STRINGFORMATTER
::
sprint
(
const
char
*
fmt
,
...
)
...
...
@@ -3525,9 +3525,9 @@ int STRINGFORMATTER::sprint( const char* fmt, ... )
va_start
(
args
,
fmt
);
int
ret
=
vprint
(
fmt
,
args
);
va_end
(
args
);
return
ret
;
}
}
int
STRINGFORMATTER
::
Print
(
int
nestLevel
,
const
char
*
fmt
,
...
)
throw
(
IOError
)
...
...
@@ -3535,26 +3535,26 @@ int STRINGFORMATTER::Print( int nestLevel, const char* fmt, ... ) throw( IOError
va_list
args
;
va_start
(
args
,
fmt
);
int
result
=
0
;
int
total
=
0
;
for
(
int
i
=
0
;
i
<
nestLevel
;
++
i
)
{
result
=
sprint
(
"%*c"
,
NESTWIDTH
,
' '
);
if
(
result
<
0
)
break
;
total
+=
result
;
}
if
(
result
<
0
||
(
result
=
vprint
(
fmt
,
args
))
<
0
)
{
throw
IOError
(
_
(
"Error writing to STRINGFORMATTER"
)
);
}
va_end
(
args
);
total
+=
result
;
return
total
;
}
...
...
@@ -3563,9 +3563,9 @@ int STRINGFORMATTER::Print( int nestLevel, const char* fmt, ... ) throw( IOError
void
STRINGFORMATTER
::
StripUseless
()
{
std
::
string
copy
=
mystring
;
mystring
.
clear
();
for
(
std
::
string
::
iterator
i
=
copy
.
begin
();
i
!=
copy
.
end
();
++
i
)
{
if
(
!
isspace
(
*
i
)
&&
*
i
!=
')'
&&
*
i
!=
'('
&&
*
i
!=
'"'
)
...
...
@@ -3590,13 +3590,22 @@ ELEM::~ELEM()
}
UNIT_RES
*
ELEM
::
GetUnits
()
const
{
if
(
parent
)
return
parent
->
GetUnits
();
return
&
UNIT_RES
::
Default
;
}
void
ELEM
::
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
out
->
Print
(
nestLevel
,
"(%s
\n
"
,
LEXER
::
GetTokenText
(
Type
()
)
);
out
->
Print
(
nestLevel
,
"(%s
\n
"
,
LEXER
::
GetTokenText
(
Type
()
)
);
FormatContents
(
out
,
nestLevel
+
1
);
out
->
Print
(
nestLevel
,
")
\n
"
);
out
->
Print
(
nestLevel
,
")
\n
"
);
}
...
...
@@ -3624,6 +3633,10 @@ int ELEM_HOLDER::FindElem( DSN_T aType, int instanceNum )
return
-
1
;
}
//-----<UNIT_RES>---------------------------------------------------------
UNIT_RES
UNIT_RES
::
Default
(
NULL
,
T_resolution
);
//-----<PADSTACK>---------------------------------------------------------
...
...
@@ -3631,10 +3644,10 @@ int PADSTACK::Compare( PADSTACK* lhs, PADSTACK* rhs )
{
if
(
!
lhs
->
hash
.
size
()
)
lhs
->
hash
=
lhs
->
makeHash
();
if
(
!
rhs
->
hash
.
size
()
)
rhs
->
hash
=
rhs
->
makeHash
();
int
result
=
lhs
->
hash
.
compare
(
rhs
->
hash
);
return
result
;
}
...
...
@@ -3646,14 +3659,14 @@ int IMAGE::Compare( IMAGE* lhs, IMAGE* rhs )
{
if
(
!
lhs
->
hash
.
size
()
)
lhs
->
hash
=
lhs
->
makeHash
();
if
(
!
rhs
->
hash
.
size
()
)
rhs
->
hash
=
rhs
->
makeHash
();
int
result
=
lhs
->
hash
.
compare
(
rhs
->
hash
);
// printf("\"%s\" \"%s\" ret=%d\n", lhs->hash.c_str(), rhs->hash.c_str(), result );
return
result
;
}
...
...
@@ -3665,7 +3678,7 @@ int COMPONENT::Compare( COMPONENT* lhs, COMPONENT* rhs )
{
if( !lhs->hash.size() )
lhs->hash = lhs->makeHash();
if( !rhs->hash.size() )
rhs->hash = rhs->makeHash();
...
...
@@ -3689,7 +3702,7 @@ PARSER::PARSER( ELEM* aParent ) :
routes_include_image_conductor
=
false
;
via_rotate_first
=
true
;
generated_by_freeroute
=
false
;
host_cad
=
"Kicad's PCBNEW"
;
host_version
=
CONV_TO_UTF8
(
g_BuildVersion
);
}
...
...
@@ -3699,11 +3712,11 @@ void PARSER::FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOErro
{
out
->
Print
(
nestLevel
,
"(string_quote %c)
\n
"
,
string_quote
);
out
->
Print
(
nestLevel
,
"(space_in_quoted_tokens %s)
\n
"
,
space_in_quoted_tokens
?
"on"
:
"off"
);
out
->
Print
(
nestLevel
,
"(host_cad
\"
%s
\"
)
\n
"
,
host_cad
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(host_cad
\"
%s
\"
)
\n
"
,
host_cad
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(host_version
\"
%s
\"
)
\n
"
,
host_version
.
c_str
()
);
if
(
const_id1
.
length
()
>
0
||
const_id2
.
length
()
>
0
)
out
->
Print
(
nestLevel
,
"(constant %c%s%c %c%s%c)
\n
"
,
out
->
Print
(
nestLevel
,
"(constant %c%s%c %c%s%c)
\n
"
,
string_quote
,
const_id1
.
c_str
(),
string_quote
,
string_quote
,
const_id2
.
c_str
(),
string_quote
);
...
...
@@ -3712,14 +3725,14 @@ void PARSER::FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOErro
routes_include_testpoint
?
" testpoint"
:
""
,
routes_include_guides
?
" guides"
:
""
,
routes_include_image_conductor
?
" image_conductor"
:
""
);
if
(
wires_include_testpoint
)
out
->
Print
(
nestLevel
,
"(wires_include testpoint)
\n
"
);
if
(
!
via_rotate_first
)
out
->
Print
(
nestLevel
,
"(via_rotate_first off)
\n
"
);
if
(
case_sensitive
)
if
(
case_sensitive
)
out
->
Print
(
nestLevel
,
"(case_sensitive %s)
\n
"
,
case_sensitive
?
"on"
:
"off"
);
}
...
...
@@ -3727,22 +3740,22 @@ void PARSER::FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOErro
void
PLACE
::
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
bool
useMultiLine
;
const
char
*
quote
=
out
->
GetQuoteChar
(
component_id
.
c_str
()
);
if
(
place_rules
||
properties
.
size
()
||
rules
||
region
)
{
useMultiLine
=
true
;
out
->
Print
(
nestLevel
,
"(%s %s%s%s
\n
"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
component_id
.
c_str
(),
quote
);
out
->
Print
(
nestLevel
+
1
,
"%s"
,
""
);
}
else
{
useMultiLine
=
false
;
out
->
Print
(
nestLevel
,
"(%s %s%s%s"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
component_id
.
c_str
(),
quote
);
}
...
...
@@ -3750,30 +3763,30 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
if
(
hasVertex
)
{
out
->
Print
(
0
,
" %.6g %.6g"
,
vertex
.
x
,
vertex
.
y
);
out
->
Print
(
0
,
" %s"
,
LEXER
::
GetTokenText
(
side
)
);
out
->
Print
(
0
,
" %.6g"
,
rotation
);
}
const
char
*
space
=
" "
;
// one space, as c string.
if
(
mirror
!=
T_NONE
)
{
out
->
Print
(
0
,
"%s(mirror %s)"
,
space
,
LEXER
::
GetTokenText
(
mirror
)
);
space
=
""
;
}
if
(
status
!=
T_NONE
)
{
out
->
Print
(
0
,
"%s(status %s)"
,
space
,
LEXER
::
GetTokenText
(
status
)
);
space
=
""
;
}
if
(
logical_part
.
size
()
)
{
quote
=
out
->
GetQuoteChar
(
logical_part
.
c_str
()
);
out
->
Print
(
0
,
"%s(logical_part %s%s%s)"
,
space
,
out
->
Print
(
0
,
"%s(logical_part %s%s%s)"
,
space
,
quote
,
logical_part
.
c_str
(),
quote
);
space
=
""
;
}
...
...
@@ -3785,11 +3798,11 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
place_rules
->
Format
(
out
,
nestLevel
+
1
);
}
if
(
properties
.
size
()
)
{
out
->
Print
(
nestLevel
+
1
,
"(property
\n
"
);
for
(
PROPERTIES
::
const_iterator
i
=
properties
.
begin
();
i
!=
properties
.
end
();
++
i
)
{
...
...
@@ -3798,14 +3811,14 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
out
->
Print
(
nestLevel
+
1
,
")
\n
"
);
}
if
(
lock_type
!=
T_NONE
)
out
->
Print
(
nestLevel
+
1
,
"(lock_type %s)
\n
"
,
out
->
Print
(
nestLevel
+
1
,
"(lock_type %s)
\n
"
,
LEXER
::
GetTokenText
(
lock_type
)
);
if
(
rules
)
rules
->
Format
(
out
,
nestLevel
+
1
);
if
(
region
)
region
->
Format
(
out
,
nestLevel
+
1
);
if
(
part_number
.
size
()
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
part_number
.
c_str
()
);
...
...
@@ -3817,7 +3830,7 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
if
(
lock_type
!=
T_NONE
)
{
out
->
Print
(
0
,
"%s(lock_type %s)"
,
space
,
out
->
Print
(
0
,
"%s(lock_type %s)"
,
space
,
LEXER
::
GetTokenText
(
lock_type
)
);
space
=
""
;
}
...
...
@@ -3829,7 +3842,7 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
quote
,
part_number
.
c_str
(),
quote
);
}
}
out
->
Print
(
0
,
")
\n
"
);
}
...
...
@@ -3854,25 +3867,25 @@ int main( int argc, char** argv )
SPECCTRA_DB
db
;
bool
failed
=
false
;
setlocale
(
LC_NUMERIC
,
"C"
);
// Switch the locale to standard C
setlocale
(
LC_NUMERIC
,
"C"
);
// Switch the locale to standard C
if
(
argc
==
2
)
{
filename
=
CONV_FROM_UTF8
(
argv
[
1
]
);
}
try
try
{
db
.
LoadPCB
(
filename
);
// db.LoadSESSION( filename );
}
}
catch
(
IOError
ioe
)
{
fprintf
(
stderr
,
"%s
\n
"
,
CONV_TO_UTF8
(
ioe
.
errorText
)
);
failed
=
true
;
}
if
(
!
failed
)
if
(
!
failed
)
fprintf
(
stderr
,
"loaded OK
\n
"
);
// export what we read in, making this test program basically a beautifier
...
...
@@ -3882,10 +3895,10 @@ int main( int argc, char** argv )
DSN
::
PCB
*
pcb
=
db
.
GetPCB
();
// hose the beautified DSN file to stdout.
db
.
SetFILE
(
stdout
);
db
.
SetFILE
(
stdout
);
pcb
->
Format
(
&
db
,
0
);
setlocale
(
LC_NUMERIC
,
""
);
// revert to the current
locale
setlocale
(
LC_NUMERIC
,
""
);
// revert to the current locale
}
#endif
...
...
pcbnew/specctra.h
View file @
f0ba106e
...
...
@@ -3,29 +3,29 @@
*
* Copyright (C) 2007-2008 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2007 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.,
* 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 SPECCTRA_H_
#define SPECCTRA_H_
// see http://www.boost.org/libs/ptr_container/doc/ptr_sequence_adapter.html
#include <boost/ptr_container/ptr_vector.hpp>
...
...
@@ -37,29 +37,29 @@ class TYPE_COLLECTOR; // outside the DSN namespace
/**
This source file implements export and import capabilities to the
This source file implements export and import capabilities to the
specctra dsn file format. The grammar for that file format is documented
fairly well. There are classes for each major type of descriptor in the
spec.
Since there are so many classes in here, it may be helpful to generate
Since there are so many classes in here, it may be helpful to generate
the Doxygen directory:
$ cd <kicadSourceRoot>
$ doxygen
Then you can view the html documentation in the <kicadSourceRoot>/doxygen
directory. The main class in this file is SPECCTRA_DB and its main
functions are LoadPCB(), LoadSESSION(), and ExportPCB().
Wide use is made of boost::ptr_vector<> and std::vector<> template classes.
If the contained object is small, then std::vector tends to be used.
If the contained object is large, variable size, or would require writing
an assignment operator() or copy constructore, then boost::ptr_vector
cannot be beat.
*/
*/
namespace
DSN
{
class
SPECCTRA_DB
;
...
...
@@ -76,16 +76,16 @@ class OUTPUTFORMATTER
// See http://docs.freebsd.org/info/gcc/gcc.info.Function_Attributes.html
// Then to get format checking during the compile, compile with -Wall or -Wformat
#define PRINTF_FUNC __attribute__ ((format (printf, 3, 4)))
public
:
/**
* Function print
* formats and writes text to the output stream.
*
* @param nestLevel The multiple of spaces to preceed the output with.
* @param nestLevel The multiple of spaces to preceed the output with.
* @param fmt A printf() style format string.
* @param ... a variable list of parameters that will get blended into
* @param ... a variable list of parameters that will get blended into
* the output under control of the format string.
* @return int - the number of characters output.
* @throw IOError, if there is a problem outputting, such as a full disk.
...
...
@@ -94,7 +94,7 @@ public:
/**
* Function GetQuoteChar
* returns the quote character as a single character string for a given
* returns the quote character as a single character string for a given
* input wrapee string. Often the return value is "" the null string if
* there are no delimiters in the input string. If you want the quote_char
* to be assuredly not "", then pass in "(" as the wrappee.
...
...
@@ -114,7 +114,7 @@ public:
* @return const char* - the quote_char as a single character string, or ""
* if the wrapee does not need to be wrapped.
*/
static
const
char
*
GetQuoteChar
(
const
char
*
wrapee
,
const
char
*
quote_char
);
static
const
char
*
GetQuoteChar
(
const
char
*
wrapee
,
const
char
*
quote_char
);
};
...
...
@@ -122,12 +122,12 @@ public:
* Class STRINGFORMATTER
* implements OUTPUTFORMATTER to a memory buffer. After Print()ing the
* string is available through GetString()
*/
*/
class
STRINGFORMATTER
:
public
OUTPUTFORMATTER
{
std
::
vector
<
char
>
buffer
;
std
::
string
mystring
;
int
sprint
(
const
char
*
fmt
,
...
);
int
vprint
(
const
char
*
fmt
,
va_list
ap
);
...
...
@@ -142,7 +142,7 @@ public:
{
}
/**
* Function Clear
* clears the buffer and empties the internal string.
...
...
@@ -158,10 +158,10 @@ public:
*/
void
StripUseless
();
/*
/*
const char* c_str()
{
return mystring.c_str();
return mystring.c_str();
}
*/
...
...
@@ -169,12 +169,12 @@ public:
{
return
mystring
;
}
//-----<OUTPUTFORMATTER>------------------------------------------------
//-----<OUTPUTFORMATTER>------------------------------------------------
int
PRINTF_FUNC
Print
(
int
nestLevel
,
const
char
*
fmt
,
...
)
throw
(
IOError
);
const
char
*
GetQuoteChar
(
const
char
*
wrapee
);
//-----</OUTPUTFORMATTER>-----------------------------------------------
//-----</OUTPUTFORMATTER>-----------------------------------------------
};
...
...
@@ -187,36 +187,36 @@ struct POINT
{
double
x
;
double
y
;
POINT
()
{
x
=
0
.
0
;
y
=
0
.
0
;
}
POINT
(
double
aX
,
double
aY
)
:
x
(
aX
),
y
(
aY
)
{
}
bool
operator
==
(
const
POINT
&
other
)
const
{
return
x
==
other
.
x
&&
y
==
other
.
y
;
}
bool
operator
!=
(
const
POINT
&
other
)
const
{
return
!
(
*
this
==
other
);
}
POINT
&
operator
+=
(
const
POINT
&
other
)
{
x
+=
other
.
x
;
y
+=
other
.
y
;
return
*
this
;
}
POINT
&
operator
=
(
const
POINT
&
other
)
{
x
=
other
.
x
;
y
=
other
.
y
;
return
*
this
;
return
*
this
;
}
/**
...
...
@@ -232,10 +232,10 @@ struct POINT
if
(
y
==
-
0
.
0
)
y
=
0
.
0
;
}
/**
* Function Format
* writes this object as ASCII out to an OUTPUTFORMATTER according to the
* writes this object as ASCII out to an OUTPUTFORMATTER according to the
* SPECCTRA DSN format.
* @param out The formatter to write to.
* @param nestLevel A multiple of the number of spaces to preceed the output with.
...
...
@@ -243,7 +243,7 @@ struct POINT
*/
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
const
throw
(
IOError
)
{
out
->
Print
(
nestLevel
,
" %.6g %.6g"
,
x
,
y
);
out
->
Print
(
nestLevel
,
" %.6g %.6g"
,
x
,
y
);
}
};
...
...
@@ -257,7 +257,7 @@ struct PROPERTY
/**
* Function Format
* writes this object as ASCII out to an OUTPUTFORMATTER according to the
* writes this object as ASCII out to an OUTPUTFORMATTER according to the
* SPECCTRA DSN format.
* @param out The formatter to write to.
* @param nestLevel A multiple of the number of spaces to preceed the output with.
...
...
@@ -267,27 +267,27 @@ struct PROPERTY
{
const
char
*
quoteName
=
out
->
GetQuoteChar
(
name
.
c_str
()
);
const
char
*
quoteValue
=
out
->
GetQuoteChar
(
value
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s%s%s %s%s%s)
\n
"
,
out
->
Print
(
nestLevel
,
"(%s%s%s %s%s%s)
\n
"
,
quoteName
,
name
.
c_str
(),
quoteName
,
quoteValue
,
value
.
c_str
(),
quoteValue
);
}
};
typedef
std
::
vector
<
PROPERTY
>
PROPERTIES
;
class
UNIT_RES
;
/**
* Class ELEM
* is a base class for any DSN element class.
* is a base class for any DSN element class.
* See class ELEM_HOLDER also.
*/
*/
class
ELEM
{
friend
class
SPECCTRA_DB
;
protected
:
protected
:
DSN_T
type
;
ELEM
*
parent
;
...
...
@@ -298,47 +298,40 @@ protected:
* ELEMs of the same derived class as "this" one.
* It is not useable for all derived classes, only those which plan for
* it by implementing a FormatContents() function that captures all info
* which will be used in the subsequent string compare. THIS SHOULD
* which will be used in the subsequent string compare. THIS SHOULD
* NORMALLY EXCLUDE THE TYPENAME, AND INSTANCE NAME OR ID AS WELL.
*/
std
::
string
makeHash
()
{
STRINGFORMATTER
sf
;
FormatContents
(
&
sf
,
0
);
sf
.
StripUseless
();
return
sf
.
GetString
();
}
public
:
ELEM
(
DSN_T
aType
,
ELEM
*
aParent
=
0
);
virtual
~
ELEM
();
DSN_T
Type
()
const
{
return
type
;
}
/**
* Function GetUnits
* returns the units for this section. Derived classes may override this
* to check for section specific overrides.
* @return
DSN_T - one of the allowed values to <unit_descriptor>
* @return
UNIT_RES* - from a local or parent scope
*/
virtual
DSN_T
GetUnits
()
const
{
if
(
parent
)
return
parent
->
GetUnits
();
return
T_inch
;
}
virtual
UNIT_RES
*
GetUnits
()
const
;
/**
* Function Format
* writes this object as ASCII out to an OUTPUTFORMATTER according to the
* writes this object as ASCII out to an OUTPUTFORMATTER according to the
* SPECCTRA DSN format.
* @param out The formatter to write to.
* @param nestLevel A multiple of the number of spaces to preceed the output with.
...
...
@@ -346,10 +339,10 @@ public:
*/
virtual
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
);
/**
* Function FormatContents
* writes the contents as ASCII out to an OUTPUTFORMATTER according to the
* writes the contents as ASCII out to an OUTPUTFORMATTER according to the
* SPECCTRA DSN format. This is the same as Format() except that the outer
* wrapper is not included.
* @param out The formatter to write to.
...
...
@@ -360,7 +353,7 @@ public:
{
// overridden in ELEM_HOLDER
}
void
SetParent
(
ELEM
*
aParent
)
{
parent
=
aParent
;
...
...
@@ -372,25 +365,25 @@ public:
* Class ELEM_HOLDER
* is a holder for any DSN class. It can contain other
* class instances, including classes derived from this class.
*/
*/
class
ELEM_HOLDER
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
typedef
boost
::
ptr_vector
<
ELEM
>
ELEM_ARRAY
;
ELEM_ARRAY
kids
;
///< ELEM pointers
public
:
public
:
ELEM_HOLDER
(
DSN_T
aType
,
ELEM
*
aParent
=
0
)
:
ELEM
(
aType
,
aParent
)
{
}
virtual
void
FormatContents
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
);
//-----< list operations >--------------------------------------------
/**
...
...
@@ -402,7 +395,7 @@ public:
*/
int
FindElem
(
DSN_T
aType
,
int
instanceNum
=
0
);
/**
* Function Length
* returns the number of ELEMs in this ELEM.
...
...
@@ -412,7 +405,7 @@ public:
{
return
kids
.
size
();
}
void
Append
(
ELEM
*
aElem
)
{
kids
.
push_back
(
aElem
);
...
...
@@ -434,19 +427,19 @@ public:
{
kids
.
insert
(
kids
.
begin
()
+
aIndex
,
aElem
);
}
ELEM
*
At
(
int
aIndex
)
const
{
// we have varying sized objects and are using polymorphism, so we
// must return a pointer not a reference.
return
(
ELEM
*
)
&
kids
[
aIndex
];
}
ELEM
*
operator
[](
int
aIndex
)
const
{
return
At
(
aIndex
);
}
void
Delete
(
int
aIndex
)
{
kids
.
erase
(
kids
.
begin
()
+
aIndex
);
...
...
@@ -472,14 +465,14 @@ class PARSER : public ELEM
bool
routes_include_image_conductor
;
bool
via_rotate_first
;
bool
generated_by_freeroute
;
std
::
string
const_id1
;
std
::
string
const_id2
;
std
::
string
host_cad
;
std
::
string
host_version
;
public
:
PARSER
(
ELEM
*
aParent
);
...
...
@@ -496,11 +489,19 @@ public:
class
UNIT_RES
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
DSN_T
units
;
int
value
;
public
:
/**
* A static instance which holds the default units of T_inch and 2540000.
* See page 108 of the specctra spec, May 2000.
*/
static
UNIT_RES
Default
;
UNIT_RES
(
ELEM
*
aParent
,
DSN_T
aType
)
:
ELEM
(
aType
,
aParent
)
{
...
...
@@ -508,20 +509,18 @@ public:
value
=
2540000
;
}
DSN_T
GetEngUnits
()
const
{
return
units
;
}
int
GetValue
()
const
{
return
value
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
if
(
type
==
T_unit
)
out
->
Print
(
nestLevel
,
"(%s %s)
\n
"
,
LEXER
::
GetTokenText
(
Type
()
),
LEXER
::
GetTokenText
(
units
)
);
out
->
Print
(
nestLevel
,
"(%s %s)
\n
"
,
LEXER
::
GetTokenText
(
Type
()
),
LEXER
::
GetTokenText
(
units
)
);
else
// T_resolution
out
->
Print
(
nestLevel
,
"(%s %s %d)
\n
"
,
LEXER
::
GetTokenText
(
Type
()
),
LEXER
::
GetTokenText
(
units
),
value
);
}
DSN_T
GetUnits
()
const
{
return
units
;
else
// T_resolution
out
->
Print
(
nestLevel
,
"(%s %s %d)
\n
"
,
LEXER
::
GetTokenText
(
Type
()
),
LEXER
::
GetTokenText
(
units
),
value
);
}
};
...
...
@@ -529,12 +528,12 @@ public:
class
RECTANGLE
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
std
::
string
layer_id
;
POINT
point0
;
POINT
point1
;
public
:
RECTANGLE
(
ELEM
*
aParent
)
:
...
...
@@ -546,23 +545,23 @@ public:
{
layer_id
=
aLayerId
;
}
void
SetCorners
(
const
POINT
&
aPoint0
,
const
POINT
&
aPoint1
)
{
point0
=
aPoint0
;
point0
.
FixNegativeZero
();
point0
.
FixNegativeZero
();
point1
=
aPoint1
;
point1
.
FixNegativeZero
();
point1
.
FixNegativeZero
();
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
char
*
newline
=
nestLevel
?
"
\n
"
:
""
;
const
char
*
quote
=
out
->
GetQuoteChar
(
layer_id
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s %.6g %.6g %.6g %.6g)%s"
,
out
->
Print
(
nestLevel
,
"(%s %s%s%s %.6g %.6g %.6g %.6g)%s"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
layer_id
.
c_str
(),
quote
,
point0
.
x
,
point0
.
y
,
...
...
@@ -592,15 +591,15 @@ public:
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
out
->
Print
(
nestLevel
,
"(%s"
,
LEXER
::
GetTokenText
(
Type
()
)
);
bool
singleLine
;
if
(
rules
.
size
()
==
1
)
{
singleLine
=
true
;
out
->
Print
(
0
,
" %s)"
,
rules
.
begin
()
->
c_str
()
);
}
else
{
out
->
Print
(
0
,
"
\n
"
);
...
...
@@ -609,7 +608,7 @@ public:
out
->
Print
(
nestLevel
+
1
,
"%s
\n
"
,
i
->
c_str
()
);
out
->
Print
(
nestLevel
,
")"
);
}
if
(
nestLevel
||
!
singleLine
)
out
->
Print
(
0
,
"
\n
"
);
}
...
...
@@ -619,10 +618,10 @@ public:
class
LAYER_RULE
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
STRINGS
layer_ids
;
RULE
*
rule
;
public
:
LAYER_RULE
(
ELEM
*
aParent
)
:
...
...
@@ -634,21 +633,21 @@ public:
{
delete
rule
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
out
->
Print
(
nestLevel
,
"(%s"
,
LEXER
::
GetTokenText
(
Type
()
)
);
for
(
STRINGS
::
const_iterator
i
=
layer_ids
.
begin
();
i
!=
layer_ids
.
end
();
++
i
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
i
->
c_str
()
);
out
->
Print
(
0
,
" %s%s%s"
,
quote
,
i
->
c_str
(),
quote
);
}
out
->
Print
(
0
,
"
\n
"
);
if
(
rule
)
rule
->
Format
(
out
,
nestLevel
+
1
);
out
->
Print
(
nestLevel
,
")
\n
"
);
}
};
...
...
@@ -663,13 +662,13 @@ typedef boost::ptr_vector<LAYER_RULE> LAYER_RULES;
class
PATH
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
std
::
string
layer_id
;
double
aperture_width
;
POINTS
points
;
POINTS
points
;
DSN_T
aperture_type
;
public
:
PATH
(
ELEM
*
aParent
,
DSN_T
aType
=
T_path
)
:
...
...
@@ -678,27 +677,27 @@ public:
aperture_width
=
0
.
0
;
aperture_type
=
T_round
;
}
void
AppendPoint
(
const
POINT
&
aPoint
)
{
points
.
push_back
(
aPoint
);
}
void
SetLayerId
(
const
char
*
aLayerId
)
{
layer_id
=
aLayerId
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
char
*
newline
=
nestLevel
?
"
\n
"
:
""
;
const
char
*
quote
=
out
->
GetQuoteChar
(
layer_id
.
c_str
()
);
const
int
RIGHTMARGIN
=
70
;
int
perLine
=
out
->
Print
(
nestLevel
,
"(%s %s%s%s %.6g"
,
const
int
RIGHTMARGIN
=
70
;
int
perLine
=
out
->
Print
(
nestLevel
,
"(%s %s%s%s %.6g"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
layer_id
.
c_str
(),
quote
,
quote
,
layer_id
.
c_str
(),
quote
,
aperture_width
);
int
wrapNest
=
MAX
(
nestLevel
+
1
,
6
);
...
...
@@ -711,7 +710,7 @@ public:
}
else
perLine
+=
out
->
Print
(
0
,
" "
);
perLine
+=
out
->
Print
(
0
,
"%.6g %.6g"
,
points
[
i
].
x
,
points
[
i
].
y
);
}
...
...
@@ -719,8 +718,8 @@ public:
{
out
->
Print
(
0
,
"(aperture_type square)"
);
}
out
->
Print
(
0
,
")%s"
,
newline
);
out
->
Print
(
0
,
")%s"
,
newline
);
}
};
typedef
boost
::
ptr_vector
<
PATH
>
PATHS
;
...
...
@@ -729,12 +728,12 @@ typedef boost::ptr_vector<PATH> PATHS;
class
BOUNDARY
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
// only one or the other of these two is used, not both
PATHS
paths
;
RECTANGLE
*
rectangle
;
public
:
BOUNDARY
(
ELEM
*
aParent
,
DSN_T
aType
=
T_boundary
)
:
...
...
@@ -742,12 +741,12 @@ public:
{
rectangle
=
0
;
}
~
BOUNDARY
()
{
delete
rectangle
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
out
->
Print
(
nestLevel
,
"(%s
\n
"
,
LEXER
::
GetTokenText
(
Type
()
)
);
...
...
@@ -759,8 +758,8 @@ public:
for
(
PATHS
::
iterator
i
=
paths
.
begin
();
i
!=
paths
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
+
1
);
}
out
->
Print
(
nestLevel
,
")
\n
"
);
out
->
Print
(
nestLevel
,
")
\n
"
);
}
};
...
...
@@ -768,23 +767,23 @@ public:
class
CIRCLE
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
std
::
string
layer_id
;
double
diameter
;
POINT
vertex
;
// POINT's constructor sets to (0,0)
public
:
public
:
CIRCLE
(
ELEM
*
aParent
)
:
ELEM
(
T_circle
,
aParent
)
{
diameter
=
0
.
0
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
char
*
newline
=
nestLevel
?
"
\n
"
:
""
;
const
char
*
quote
=
out
->
GetQuoteChar
(
layer_id
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s %.6g"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
layer_id
.
c_str
(),
quote
,
...
...
@@ -795,17 +794,17 @@ public:
else
out
->
Print
(
0
,
")%s"
,
newline
);
}
void
SetLayerId
(
const
char
*
aLayerId
)
{
layer_id
=
aLayerId
;
}
void
SetDiameter
(
double
aDiameter
)
{
diameter
=
aDiameter
;
}
void
SetVertex
(
const
POINT
&
aVertex
)
{
vertex
=
aVertex
;
...
...
@@ -816,33 +815,33 @@ public:
class
QARC
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
std
::
string
layer_id
;
double
aperture_width
;
POINT
vertex
[
3
];
public
:
public
:
QARC
(
ELEM
*
aParent
)
:
ELEM
(
T_qarc
,
aParent
)
{
aperture_width
=
0
.
0
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
char
*
newline
=
nestLevel
?
"
\n
"
:
""
;
const
char
*
quote
=
out
->
GetQuoteChar
(
layer_id
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s %.6g"
,
LEXER
::
GetTokenText
(
Type
()
)
,
quote
,
layer_id
.
c_str
(),
quote
,
aperture_width
);
for
(
int
i
=
0
;
i
<
3
;
++
i
)
out
->
Print
(
0
,
" %.6g %.6g"
,
vertex
[
i
].
x
,
vertex
[
i
].
y
);
out
->
Print
(
0
,
")%s"
,
newline
);
}
void
SetLayerId
(
const
char
*
aLayerId
)
{
layer_id
=
aLayerId
;
...
...
@@ -872,7 +871,7 @@ class WINDOW : public ELEM
{
friend
class
SPECCTRA_DB
;
protected
:
protected
:
/* shape holds one of these
PATH* path; ///< used for both path and polygon
RECTANGLE* rectangle;
...
...
@@ -880,15 +879,15 @@ protected:
QARC* qarc;
*/
ELEM
*
shape
;
public
:
WINDOW
(
ELEM
*
aParent
,
DSN_T
aType
=
T_window
)
:
ELEM
(
aType
,
aParent
)
{
shape
=
0
;
}
~
WINDOW
()
{
delete
shape
;
...
...
@@ -898,24 +897,24 @@ public:
{
delete
shape
;
shape
=
aShape
;
if
(
aShape
)
{
wxASSERT
(
aShape
->
Type
()
==
T_rect
||
aShape
->
Type
()
==
T_circle
||
aShape
->
Type
()
==
T_qarc
||
aShape
->
Type
()
==
T_path
wxASSERT
(
aShape
->
Type
()
==
T_rect
||
aShape
->
Type
()
==
T_circle
||
aShape
->
Type
()
==
T_qarc
||
aShape
->
Type
()
==
T_path
||
aShape
->
Type
()
==
T_polygon
);
aShape
->
SetParent
(
this
);
aShape
->
SetParent
(
this
);
}
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
out
->
Print
(
nestLevel
,
"(%s "
,
LEXER
::
GetTokenText
(
Type
()
)
);
if
(
shape
)
shape
->
Format
(
out
,
0
);
out
->
Print
(
0
,
")
\n
"
);
}
};
...
...
@@ -930,12 +929,12 @@ class KEEPOUT : public ELEM
{
friend
class
SPECCTRA_DB
;
protected
:
protected
:
std
::
string
name
;
int
sequence_number
;
RULE
*
rules
;
RULE
*
place_rules
;
WINDOWS
windows
;
/* <shape_descriptor >::=
...
...
@@ -946,7 +945,7 @@ protected:
<qarc_descriptor> ]
*/
ELEM
*
shape
;
public
:
/**
...
...
@@ -960,36 +959,36 @@ public:
rules
=
0
;
place_rules
=
0
;
shape
=
0
;
sequence_number
=
-
1
;
}
~
KEEPOUT
()
{
delete
rules
;
delete
place_rules
;
delete
shape
;
}
void
SetShape
(
ELEM
*
aShape
)
{
delete
shape
;
shape
=
aShape
;
if
(
aShape
)
{
wxASSERT
(
aShape
->
Type
()
==
T_rect
||
aShape
->
Type
()
==
T_circle
||
aShape
->
Type
()
==
T_qarc
||
aShape
->
Type
()
==
T_path
wxASSERT
(
aShape
->
Type
()
==
T_rect
||
aShape
->
Type
()
==
T_circle
||
aShape
->
Type
()
==
T_qarc
||
aShape
->
Type
()
==
T_path
||
aShape
->
Type
()
==
T_polygon
);
aShape
->
SetParent
(
this
);
aShape
->
SetParent
(
this
);
}
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
char
*
newline
=
"
\n
"
;
out
->
Print
(
nestLevel
,
"(%s"
,
LEXER
::
GetTokenText
(
Type
()
)
);
if
(
name
.
size
()
)
...
...
@@ -1000,20 +999,20 @@ public:
if
(
sequence_number
!=
-
1
)
out
->
Print
(
0
,
" (sequence_number %d)"
,
sequence_number
);
if
(
shape
)
{
out
->
Print
(
0
,
" "
);
shape
->
Format
(
out
,
0
);
}
if
(
rules
)
{
out
->
Print
(
0
,
"%s"
,
newline
);
newline
=
""
;
rules
->
Format
(
out
,
nestLevel
+
1
);
}
if
(
place_rules
)
{
out
->
Print
(
0
,
"%s"
,
newline
);
...
...
@@ -1025,12 +1024,12 @@ public:
{
out
->
Print
(
0
,
"%s"
,
newline
);
newline
=
""
;
for
(
WINDOWS
::
iterator
i
=
windows
.
begin
();
i
!=
windows
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
+
1
);
}
out
->
Print
(
0
,
")
\n
"
);
out
->
Print
(
0
,
")
\n
"
);
}
};
typedef
boost
::
ptr_vector
<
KEEPOUT
>
KEEPOUTS
;
...
...
@@ -1058,12 +1057,12 @@ public:
{
padstacks
.
push_back
(
aViaName
);
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
int
RIGHTMARGIN
=
80
;
int
perLine
=
out
->
Print
(
nestLevel
,
"(%s"
,
LEXER
::
GetTokenText
(
Type
()
)
);
for
(
STRINGS
::
iterator
i
=
padstacks
.
begin
();
i
!=
padstacks
.
end
();
++
i
)
{
if
(
perLine
>
RIGHTMARGIN
)
...
...
@@ -1075,11 +1074,11 @@ public:
const
char
*
quote
=
out
->
GetQuoteChar
(
i
->
c_str
()
);
perLine
+=
out
->
Print
(
0
,
" %s%s%s"
,
quote
,
i
->
c_str
(),
quote
);
}
if
(
spares
.
size
()
)
{
out
->
Print
(
0
,
"
\n
"
);
perLine
=
out
->
Print
(
nestLevel
+
1
,
"(spare"
);
for
(
STRINGS
::
iterator
i
=
spares
.
begin
();
i
!=
spares
.
end
();
++
i
)
...
...
@@ -1092,10 +1091,10 @@ public:
const
char
*
quote
=
out
->
GetQuoteChar
(
i
->
c_str
()
);
perLine
+=
out
->
Print
(
0
,
" %s%s%s"
,
quote
,
i
->
c_str
(),
quote
);
}
out
->
Print
(
0
,
")"
);
}
out
->
Print
(
0
,
")
\n
"
);
}
};
...
...
@@ -1106,13 +1105,13 @@ class CLASSES : public ELEM
friend
class
SPECCTRA_DB
;
STRINGS
class_ids
;
public
:
CLASSES
(
ELEM
*
aParent
)
:
ELEM
(
T_classes
,
aParent
)
{
}
void
FormatContents
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
for
(
STRINGS
::
iterator
i
=
class_ids
.
begin
();
i
!=
class_ids
.
end
();
++
i
)
...
...
@@ -1127,15 +1126,15 @@ public:
class
CLASS_CLASS
:
public
ELEM_HOLDER
{
friend
class
SPECCTRA_DB
;
CLASSES
*
classes
;
/* rule | layer_rule are put into the kids container.
*/
public
:
/**
* Constructor CLASS_CLASS
* @param aType May be either T_class_class or T_region_class_class
...
...
@@ -1145,7 +1144,7 @@ public:
{
classes
=
0
;
}
~
CLASS_CLASS
()
{
delete
classes
;
...
...
@@ -1168,7 +1167,7 @@ class CONTROL : public ELEM_HOLDER
bool
via_at_smd
;
bool
via_at_smd_grid_on
;
public
:
CONTROL
(
ELEM
*
aParent
)
:
ELEM_HOLDER
(
T_control
,
aParent
)
...
...
@@ -1176,11 +1175,11 @@ public:
via_at_smd
=
false
;
via_at_smd_grid_on
=
false
;
}
~
CONTROL
()
{
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
out
->
Print
(
nestLevel
,
"(%s
\n
"
,
LEXER
::
GetTokenText
(
Type
()
)
);
...
...
@@ -1190,7 +1189,7 @@ public:
out
->
Print
(
nestLevel
+
1
,
"(via_at_smd %s"
,
via_at_smd
?
"on"
:
"off"
);
if
(
via_at_smd_grid_on
)
out
->
Print
(
0
,
" grid %s"
,
via_at_smd_grid_on
?
"on"
:
"off"
);
out
->
Print
(
0
,
")
\n
"
);
}
...
...
@@ -1198,8 +1197,8 @@ public:
{
At
(
i
)
->
Format
(
out
,
nestLevel
+
1
);
}
out
->
Print
(
nestLevel
,
")
\n
"
);
out
->
Print
(
nestLevel
,
")
\n
"
);
}
};
...
...
@@ -1207,17 +1206,17 @@ public:
class
LAYER
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
std
::
string
name
;
DSN_T
layer_type
;
///< one of: T_signal, T_power, T_mixed, T_jumper
int
direction
;
int
cost
;
///< [forbidden | high | medium | low | free | <positive_integer > | -1]
int
cost_type
;
///< T_length | T_way
int
cost_type
;
///< T_length | T_way
RULE
*
rules
;
STRINGS
use_net
;
PROPERTIES
properties
;
public
:
LAYER
(
ELEM
*
aParent
)
:
...
...
@@ -1227,19 +1226,19 @@ public:
direction
=
-
1
;
cost
=
-
1
;
cost_type
=
-
1
;
rules
=
0
;
}
~
LAYER
()
{
delete
rules
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
name
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s
\n
"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
name
.
c_str
(),
quote
);
...
...
@@ -1248,31 +1247,31 @@ public:
if
(
properties
.
size
()
)
{
out
->
Print
(
nestLevel
+
1
,
"(property
\n
"
);
for
(
PROPERTIES
::
iterator
i
=
properties
.
begin
();
i
!=
properties
.
end
();
++
i
)
{
i
->
Format
(
out
,
nestLevel
+
2
);
}
out
->
Print
(
nestLevel
+
1
,
")
\n
"
);
}
if
(
direction
!=
-
1
)
out
->
Print
(
nestLevel
+
1
,
"(direction %s)
\n
"
,
out
->
Print
(
nestLevel
+
1
,
"(direction %s)
\n
"
,
LEXER
::
GetTokenText
(
(
DSN_T
)
direction
)
);
if
(
rules
)
rules
->
Format
(
out
,
nestLevel
+
1
);
if
(
cost
!=
-
1
)
{
if
(
cost
<
0
)
out
->
Print
(
nestLevel
+
1
,
"(cost %d"
,
-
cost
);
// positive integer, stored as negative
else
out
->
Print
(
nestLevel
+
1
,
"(cost %s"
,
LEXER
::
GetTokenText
(
(
DSN_T
)
cost
)
);
if
(
cost_type
!=
-
1
)
out
->
Print
(
0
,
" (type %s)"
,
LEXER
::
GetTokenText
(
(
DSN_T
)
cost_type
)
);
out
->
Print
(
0
,
")
\n
"
);
}
...
...
@@ -1286,8 +1285,8 @@ public:
}
out
->
Print
(
0
,
")
\n
"
);
}
out
->
Print
(
nestLevel
,
")
\n
"
);
out
->
Print
(
nestLevel
,
")
\n
"
);
}
};
...
...
@@ -1299,8 +1298,8 @@ class LAYER_PAIR : public ELEM
std
::
string
layer_id0
;
std
::
string
layer_id1
;
double
layer_weight
;
double
layer_weight
;
public
:
LAYER_PAIR
(
ELEM
*
aParent
)
:
ELEM
(
T_layer_pair
,
aParent
)
...
...
@@ -1312,7 +1311,7 @@ public:
{
const
char
*
quote0
=
out
->
GetQuoteChar
(
layer_id0
.
c_str
()
);
const
char
*
quote1
=
out
->
GetQuoteChar
(
layer_id1
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s %s%s%s %.6g)
\n
"
,
LEXER
::
GetTokenText
(
Type
()
),
quote0
,
layer_id0
.
c_str
(),
quote0
,
quote1
,
layer_id1
.
c_str
(),
quote1
,
...
...
@@ -1325,23 +1324,23 @@ typedef boost::ptr_vector<LAYER_PAIR> LAYER_PAIRS;
class
LAYER_NOISE_WEIGHT
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
LAYER_PAIRS
layer_pairs
;
public
:
LAYER_NOISE_WEIGHT
(
ELEM
*
aParent
)
:
ELEM
(
T_layer_noise_weight
,
aParent
)
{
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
out
->
Print
(
nestLevel
,
"(%s
\n
"
,
LEXER
::
GetTokenText
(
Type
()
)
);
for
(
LAYER_PAIRS
::
iterator
i
=
layer_pairs
.
begin
();
i
!=
layer_pairs
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
+
1
);
out
->
Print
(
nestLevel
,
")
\n
"
);
}
};
...
...
@@ -1355,7 +1354,7 @@ class COPPER_PLANE : public KEEPOUT
{
friend
class
SPECCTRA_DB
;
public
:
public
:
COPPER_PLANE
(
ELEM
*
aParent
)
:
KEEPOUT
(
aParent
,
T_plane
)
{}
...
...
@@ -1380,7 +1379,7 @@ public:
ELEM
(
aType
,
aParent
)
{
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
out
->
Print
(
nestLevel
,
"(%s %s)
\n
"
,
LEXER
::
GetTokenText
(
Type
()
),
...
...
@@ -1406,11 +1405,11 @@ public:
ELEM
(
aType
,
aParent
)
{
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
value
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s)
\n
"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
value
.
c_str
(),
quote
);
}
...
...
@@ -1431,8 +1430,8 @@ class REGION : public ELEM_HOLDER
/* region_net | region_class | region_class_class are all mutually
exclusive and are put into the kids container.
*/
RULE
*
rules
;
RULE
*
rules
;
public
:
REGION
(
ELEM
*
aParent
)
:
...
...
@@ -1449,7 +1448,7 @@ public:
delete
polygon
;
delete
rules
;
}
void
FormatContents
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
if
(
region_id
.
size
()
)
...
...
@@ -1457,15 +1456,15 @@ public:
const
char
*
quote
=
out
->
GetQuoteChar
(
region_id
.
c_str
()
);
out
->
Print
(
nestLevel
,
"%s%s%s
\n
"
,
quote
,
region_id
.
c_str
(),
quote
);
}
if
(
rectangle
)
rectangle
->
Format
(
out
,
nestLevel
);
if
(
polygon
)
polygon
->
Format
(
out
,
nestLevel
);
ELEM_HOLDER
::
FormatContents
(
out
,
nestLevel
);
if
(
rules
)
rules
->
Format
(
out
,
nestLevel
);
}
...
...
@@ -1479,15 +1478,15 @@ class GRID : public ELEM
DSN_T
grid_type
;
///< T_via | T_wire | T_via_keepout | T_place | T_snap
double
dimension
;
DSN_T
direction
;
///< T_x | T_y | -1 for both
double
offset
;
DSN_T
image_type
;
public
:
GRID
(
ELEM
*
aParent
)
:
ELEM
(
T_grid
,
aParent
)
{
...
...
@@ -1497,13 +1496,13 @@ public:
offset
=
0
.
0
;
image_type
=
T_NONE
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
out
->
Print
(
nestLevel
,
"(%s %s %.6g"
,
LEXER
::
GetTokenText
(
Type
()
),
LEXER
::
GetTokenText
(
grid_type
),
dimension
);
if
(
grid_type
==
T_place
)
{
if
(
image_type
==
T_smd
||
image_type
==
T_pin
)
...
...
@@ -1514,10 +1513,10 @@ public:
if
(
direction
==
T_x
||
direction
==
T_y
)
out
->
Print
(
0
,
" (direction %s)"
,
LEXER
::
GetTokenText
(
direction
)
);
}
if
(
offset
!=
0
.
0
)
out
->
Print
(
0
,
" (offset %.6g)"
,
offset
);
out
->
Print
(
0
,
")
\n
"
);
}
};
...
...
@@ -1526,32 +1525,32 @@ public:
class
STRUCTURE
:
public
ELEM_HOLDER
{
friend
class
SPECCTRA_DB
;
UNIT_RES
*
unit
;
typedef
boost
::
ptr_vector
<
LAYER
>
LAYERS
;
LAYERS
layers
;
LAYER_NOISE_WEIGHT
*
layer_noise_weight
;
BOUNDARY
*
boundary
;
BOUNDARY
*
place_boundary
;
VIA
*
via
;
CONTROL
*
control
;
RULE
*
rules
;
KEEPOUTS
keepouts
;
COPPER_PLANES
planes
;
typedef
boost
::
ptr_vector
<
REGION
>
REGIONS
;
REGIONS
regions
;
RULE
*
place_rules
;
typedef
boost
::
ptr_vector
<
GRID
>
GRIDS
;
GRIDS
grids
;
public
:
STRUCTURE
(
ELEM
*
aParent
)
:
...
...
@@ -1566,7 +1565,7 @@ public:
rules
=
0
;
place_rules
=
0
;
}
~
STRUCTURE
()
{
delete
unit
;
...
...
@@ -1578,7 +1577,7 @@ public:
delete
rules
;
delete
place_rules
;
}
void
SetBOUNDARY
(
BOUNDARY
*
aBoundary
)
{
delete
boundary
;
...
...
@@ -1588,7 +1587,7 @@ public:
boundary
->
SetParent
(
this
);
}
}
void
SetPlaceBOUNDARY
(
BOUNDARY
*
aBoundary
)
{
delete
place_boundary
;
...
...
@@ -1596,18 +1595,18 @@ public:
if
(
place_boundary
)
place_boundary
->
SetParent
(
this
);
}
void
FormatContents
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
if
(
unit
)
unit
->
Format
(
out
,
nestLevel
);
for
(
LAYERS
::
iterator
i
=
layers
.
begin
();
i
!=
layers
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
i
->
Format
(
out
,
nestLevel
);
if
(
layer_noise_weight
)
layer_noise_weight
->
Format
(
out
,
nestLevel
);
if
(
boundary
)
boundary
->
Format
(
out
,
nestLevel
);
...
...
@@ -1619,36 +1618,36 @@ public:
for
(
REGIONS
::
iterator
i
=
regions
.
begin
();
i
!=
regions
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
for
(
KEEPOUTS
::
iterator
i
=
keepouts
.
begin
();
i
!=
keepouts
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
if
(
via
)
via
->
Format
(
out
,
nestLevel
);
if
(
control
)
control
->
Format
(
out
,
nestLevel
);
for
(
int
i
=
0
;
i
<
Length
();
++
i
)
{
At
(
i
)
->
Format
(
out
,
nestLevel
);
}
if
(
rules
)
rules
->
Format
(
out
,
nestLevel
);
if
(
place_rules
)
place_rules
->
Format
(
out
,
nestLevel
);
for
(
GRIDS
::
iterator
i
=
grids
.
begin
();
i
!=
grids
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
}
DSN_T
GetUnits
()
const
UNIT_RES
*
GetUnits
()
const
{
if
(
unit
)
return
unit
->
GetUnits
()
;
return
unit
;
return
ELEM
::
GetUnits
();
}
};
...
...
@@ -1661,49 +1660,49 @@ public:
class
PLACE
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
std
::
string
component_id
;
///< reference designator
DSN_T
side
;
double
rotation
;
bool
hasVertex
;
POINT
vertex
;
DSN_T
mirror
;
DSN_T
status
;
std
::
string
logical_part
;
RULE
*
place_rules
;
PROPERTIES
properties
;
DSN_T
lock_type
;
//-----<mutually exclusive>--------------
//-----<mutually exclusive>--------------
RULE
*
rules
;
REGION
*
region
;
//-----</mutually exclusive>-------------
//-----</mutually exclusive>-------------
std
::
string
part_number
;
public
:
PLACE
(
ELEM
*
aParent
)
:
ELEM
(
T_place
,
aParent
)
{
side
=
T_front
;
rotation
=
0
.
0
;
hasVertex
=
false
;
mirror
=
T_NONE
;
status
=
T_NONE
;
place_rules
=
0
;
lock_type
=
T_NONE
;
rules
=
0
;
region
=
0
;
...
...
@@ -1715,7 +1714,7 @@ public:
delete
rules
;
delete
region
;
}
void
SetVertex
(
const
POINT
&
aVertex
)
{
vertex
=
aVertex
;
...
...
@@ -1727,7 +1726,7 @@ public:
{
rotation
=
aRotation
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
);
};
typedef
boost
::
ptr_vector
<
PLACE
>
PLACES
;
...
...
@@ -1742,35 +1741,35 @@ class COMPONENT : public ELEM
friend
class
SPECCTRA_DB
;
// std::string hash; ///< a hash string used by Compare(), not Format()ed/exported.
std
::
string
image_id
;
PLACES
places
;
public
:
COMPONENT
(
ELEM
*
aParent
)
:
ELEM
(
T_component
,
aParent
)
{
}
const
std
::
string
&
GetImageId
()
const
{
return
image_id
;
}
void
SetImageId
(
const
std
::
string
&
aImageId
)
void
SetImageId
(
const
std
::
string
&
aImageId
)
{
image_id
=
aImageId
;
}
/**
* Function Compare
* compares two objects of this type and returns <0, 0, or >0.
*/
// static int Compare( IMAGE* lhs, IMAGE* rhs );
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
image_id
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s
\n
"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
image_id
.
c_str
(),
quote
);
FormatContents
(
out
,
nestLevel
+
1
);
out
->
Print
(
nestLevel
,
")
\n
"
);
...
...
@@ -1790,12 +1789,12 @@ class PLACEMENT : public ELEM
friend
class
SPECCTRA_DB
;
UNIT_RES
*
unit
;
DSN_T
flip_style
;
COMPONENTS
components
;
public
:
public
:
PLACEMENT
(
ELEM
*
aParent
)
:
ELEM
(
T_placement
,
aParent
)
{
...
...
@@ -1822,33 +1821,33 @@ public:
if
(
0
==
components
[
i
].
GetImageId
().
compare
(
imageName
)
)
return
&
components
[
i
];
}
COMPONENT
*
added
=
new
COMPONENT
(
this
);
components
.
push_back
(
added
);
added
->
SetImageId
(
imageName
);
return
added
;
}
void
FormatContents
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
if
(
unit
)
unit
->
Format
(
out
,
nestLevel
);
if
(
flip_style
!=
T_NONE
)
{
out
->
Print
(
nestLevel
,
"(place_control (flip_style %s))
\n
"
,
LEXER
::
GetTokenText
(
flip_style
)
);
}
for
(
COMPONENTS
::
iterator
i
=
components
.
begin
();
i
!=
components
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
}
DSN_T
GetUnits
()
const
UNIT_RES
*
GetUnits
()
const
{
if
(
unit
)
return
unit
->
GetUnits
()
;
return
unit
;
return
ELEM
::
GetUnits
();
}
};
...
...
@@ -1866,7 +1865,7 @@ class SHAPE : public WINDOW
friend
class
SPECCTRA_DB
;
DSN_T
connect
;
/* <shape_descriptor >::=
[<rectangle_descriptor> |
<circle_descriptor> |
...
...
@@ -1877,7 +1876,7 @@ class SHAPE : public WINDOW
*/
WINDOWS
windows
;
public
:
SHAPE
(
ELEM
*
aParent
,
DSN_T
aType
=
T_shape
)
:
WINDOW
(
aParent
,
aType
)
...
...
@@ -1889,25 +1888,25 @@ public:
{
connect
=
aConnect
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
out
->
Print
(
nestLevel
,
"(%s "
,
LEXER
::
GetTokenText
(
Type
()
)
);
if
(
shape
)
shape
->
Format
(
out
,
0
);
if
(
connect
==
T_off
)
out
->
Print
(
0
,
"(connect %s)"
,
LEXER
::
GetTokenText
(
connect
)
);
if
(
windows
.
size
()
)
{
out
->
Print
(
0
,
"
\n
"
);
for
(
WINDOWS
::
iterator
i
=
windows
.
begin
();
i
!=
windows
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
+
1
);
out
->
Print
(
nestLevel
,
")
\n
"
);
out
->
Print
(
nestLevel
,
")
\n
"
);
}
else
out
->
Print
(
0
,
")
\n
"
);
...
...
@@ -1924,7 +1923,7 @@ class PIN : public ELEM
bool
isRotated
;
std
::
string
pin_id
;
POINT
vertex
;
public
:
PIN
(
ELEM
*
aParent
)
:
ELEM
(
T_pin
,
aParent
)
...
...
@@ -1938,26 +1937,26 @@ public:
rotation
=
aRotation
;
isRotated
=
(
aRotation
!=
0
.
0
);
}
void
SetVertex
(
const
POINT
&
aPoint
)
{
vertex
=
aPoint
;
vertex
.
FixNegativeZero
();
vertex
.
FixNegativeZero
();
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
padstack_id
.
c_str
()
);
if
(
isRotated
)
out
->
Print
(
nestLevel
,
"(pin %s%s%s (rotate %.6g)"
,
out
->
Print
(
nestLevel
,
"(pin %s%s%s (rotate %.6g)"
,
quote
,
padstack_id
.
c_str
(),
quote
,
rotation
);
else
out
->
Print
(
nestLevel
,
"(pin %s%s%s"
,
quote
,
padstack_id
.
c_str
(),
quote
);
quote
=
out
->
GetQuoteChar
(
pin_id
.
c_str
()
);
out
->
Print
(
0
,
" %s%s%s %.6g %.6g)
\n
"
,
quote
,
pin_id
.
c_str
(),
quote
,
out
->
Print
(
0
,
" %s%s%s %.6g %.6g)
\n
"
,
quote
,
pin_id
.
c_str
(),
quote
,
vertex
.
x
,
vertex
.
y
);
}
};
...
...
@@ -1967,18 +1966,18 @@ class IMAGE : public ELEM_HOLDER
{
friend
class
SPECCTRA_DB
;
friend
class
LIBRARY
;
std
::
string
hash
;
///< a hash string used by Compare(), not Format()ed/exported.
std
::
string
image_id
;
DSN_T
side
;
UNIT_RES
*
unit
;
/* The grammar spec says only one outline is supported, but I am seeing
*.dsn examples with multiple outlines. So the outlines will go into
the kids list.
*.dsn examples with multiple outlines. So the outlines will go into
the kids list.
*/
typedef
boost
::
ptr_vector
<
PIN
>
PINS
;
PINS
pins
;
...
...
@@ -1986,11 +1985,11 @@ class IMAGE : public ELEM_HOLDER
RULE
*
place_rules
;
KEEPOUTS
keepouts
;
int
duplicated
;
///< no. times this image_id is duplicated
int
duplicated
;
///< no. times this image_id is duplicated
public
:
IMAGE
(
ELEM
*
aParent
)
:
ELEM_HOLDER
(
T_image
,
aParent
)
{
...
...
@@ -2018,26 +2017,26 @@ public:
if
(
duplicated
)
{
char
buf
[
32
];
std
::
string
ret
=
image_id
;
ret
+=
"::"
;
sprintf
(
buf
,
"%d"
,
duplicated
);
ret
+=
buf
;
return
ret
;
}
return
image_id
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
std
::
string
imageId
=
GetImageId
();
const
char
*
quote
=
out
->
GetQuoteChar
(
imageId
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
imageId
.
c_str
(),
quote
);
FormatContents
(
out
,
nestLevel
+
1
);
out
->
Print
(
nestLevel
,
")
\n
"
);
...
...
@@ -2048,34 +2047,34 @@ public:
{
if
(
side
!=
T_both
)
out
->
Print
(
0
,
" (side %s)"
,
LEXER
::
GetTokenText
(
side
)
);
out
->
Print
(
0
,
"
\n
"
);
if
(
unit
)
unit
->
Format
(
out
,
nestLevel
);
// format the kids, which in this class are the shapes
ELEM_HOLDER
::
FormatContents
(
out
,
nestLevel
);
for
(
PINS
::
iterator
i
=
pins
.
begin
();
i
!=
pins
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
if
(
rules
)
rules
->
Format
(
out
,
nestLevel
);
if
(
place_rules
)
place_rules
->
Format
(
out
,
nestLevel
);
for
(
KEEPOUTS
::
iterator
i
=
keepouts
.
begin
();
i
!=
keepouts
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
}
DSN_T
GetUnits
()
const
UNIT_RES
*
GetUnits
()
const
{
if
(
unit
)
return
unit
->
GetUnits
()
;
return
unit
;
return
ELEM
::
GetUnits
();
}
};
...
...
@@ -2091,9 +2090,9 @@ class PADSTACK : public ELEM_HOLDER
friend
class
SPECCTRA_DB
;
std
::
string
hash
;
///< a hash string used by Compare(), not Format()ed/exported.
std
::
string
padstack_id
;
std
::
string
padstack_id
;
UNIT_RES
*
unit
;
/* The shapes are stored in the kids list */
...
...
@@ -2102,11 +2101,11 @@ class PADSTACK : public ELEM_HOLDER
DSN_T
absolute
;
DSN_T
attach
;
std
::
string
via_id
;
RULE
*
rules
;
public
:
PADSTACK
(
ELEM
*
aParent
)
:
ELEM_HOLDER
(
T_padstack
,
aParent
)
{
...
...
@@ -2122,7 +2121,7 @@ public:
delete
rules
;
}
/**
* Function Compare
* compares two objects of this type and returns <0, 0, or >0.
...
...
@@ -2133,20 +2132,20 @@ public:
{
padstack_id
=
aPadstackId
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
padstack_id
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s
\n
"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
padstack_id
.
c_str
(),
quote
);
FormatContents
(
out
,
nestLevel
+
1
);
out
->
Print
(
nestLevel
,
")
\n
"
);
}
// this factored out for use by Compare()
void
FormatContents
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
...
...
@@ -2157,9 +2156,9 @@ public:
ELEM_HOLDER
::
FormatContents
(
out
,
nestLevel
);
out
->
Print
(
nestLevel
,
"%s"
,
""
);
// spec for <attach_descriptor> says default is on, so
// print the off condition to override this.
// print the off condition to override this.
if
(
attach
==
T_off
)
out
->
Print
(
0
,
"(attach off)"
);
else
if
(
attach
==
T_on
)
...
...
@@ -2168,7 +2167,7 @@ public:
out
->
Print
(
0
,
"(attach on (use_via %s%s%s))"
,
quote
,
via_id
.
c_str
(),
quote
);
}
if
(
rotate
==
T_off
)
// print the non-default
out
->
Print
(
0
,
"(rotate %s)"
,
LEXER
::
GetTokenText
(
rotate
)
);
...
...
@@ -2176,17 +2175,17 @@ public:
out
->
Print
(
0
,
"(absolute %s)"
,
LEXER
::
GetTokenText
(
absolute
)
);
out
->
Print
(
0
,
"
\n
"
);
if
(
rules
)
rules
->
Format
(
out
,
nestLevel
);
}
DSN_T
GetUnits
()
const
UNIT_RES
*
GetUnits
()
const
{
if
(
unit
)
return
unit
->
GetUnits
()
;
return
unit
;
return
ELEM
::
GetUnits
();
}
};
...
...
@@ -2196,28 +2195,28 @@ typedef boost::ptr_vector<PADSTACK> PADSTACKS;
/**
* Class LIBRARY
* corresponds to the <library_descriptor> in the specctra dsn specification.
* Only unit_descriptor, image_descriptors, and padstack_descriptors are
* Only unit_descriptor, image_descriptors, and padstack_descriptors are
* included as children at this time.
*/
class
LIBRARY
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
UNIT_RES
*
unit
;
IMAGES
images
;
PADSTACKS
padstacks
;
/// The start of the vias within the padstacks, which trail the pads.
/// This field is not Format()ed.
int
via_start_index
;
int
via_start_index
;
public
:
LIBRARY
(
ELEM
*
aParent
,
DSN_T
aType
=
T_library
)
:
ELEM
(
aType
,
aParent
)
{
unit
=
0
;
via_start_index
=
-
1
;
// 0 or greater means there is at least one via
via_start_index
=
-
1
;
// 0 or greater means there is at least one via
}
~
LIBRARY
()
{
...
...
@@ -2238,7 +2237,7 @@ public:
return
via_start_index
;
}
/**
* Function FindIMAGE
* searches this LIBRARY for an image which matches the argument.
...
...
@@ -2255,17 +2254,17 @@ public:
// There is no match to the IMAGE contents, but now generate a unique
// name for it.
int
dups
=
1
;
int
dups
=
1
;
for
(
i
=
0
;
i
<
images
.
size
();
++
i
)
{
if
(
0
==
aImage
->
image_id
.
compare
(
images
[
i
].
image_id
)
)
aImage
->
duplicated
=
dups
++
;
}
return
-
1
;
}
/**
* Function AppendIMAGE
* adds the image to the image list.
...
...
@@ -2322,7 +2321,7 @@ public:
aPadstack
->
SetParent
(
this
);
padstacks
.
push_back
(
aPadstack
);
}
/**
* Function LookupVia
* will add the via only if one exactly like it does not already exist
...
...
@@ -2341,24 +2340,24 @@ public:
}
return
&
padstacks
[
ndx
];
}
void
FormatContents
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
if
(
unit
)
unit
->
Format
(
out
,
nestLevel
);
for
(
IMAGES
::
iterator
i
=
images
.
begin
();
i
!=
images
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
for
(
PADSTACKS
::
iterator
i
=
padstacks
.
begin
();
i
!=
padstacks
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
}
DSN_T
GetUnits
()
const
UNIT_RES
*
GetUnits
()
const
{
if
(
unit
)
return
unit
->
GetUnits
()
;
return
unit
;
return
ELEM
::
GetUnits
();
}
};
...
...
@@ -2374,7 +2373,7 @@ class PIN_REF : public ELEM
std
::
string
component_id
;
std
::
string
pin_id
;
public
:
PIN_REF
(
ELEM
*
aParent
)
:
...
...
@@ -2393,16 +2392,16 @@ public:
// the quotes unconditional on this one.
const
char
*
newline
=
nestLevel
?
"
\n
"
:
""
;
#if 0
return out->Print( nestLevel, "\"%s\"-\"%s\"%s",
#if 0
return out->Print( nestLevel, "\"%s\"-\"%s\"%s",
component_id.c_str(), pin_id.c_str(), newline );
#else
const
char
*
cquote
=
out
->
GetQuoteChar
(
component_id
.
c_str
()
);
const
char
*
pquote
=
out
->
GetQuoteChar
(
pin_id
.
c_str
()
);
return
out
->
Print
(
nestLevel
,
"%s%s%s-%s%s%s%s"
,
cquote
,
component_id
.
c_str
(),
cquote
,
pquote
,
pin_id
.
c_str
(),
pquote
,
return
out
->
Print
(
nestLevel
,
"%s%s%s-%s%s%s%s"
,
cquote
,
component_id
.
c_str
(),
cquote
,
pquote
,
pin_id
.
c_str
(),
pquote
,
newline
);
#endif
}
...
...
@@ -2413,18 +2412,18 @@ typedef std::vector<PIN_REF> PIN_REFS;
class
FROMTO
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
std
::
string
fromText
;
std
::
string
toText
;
DSN_T
fromto_type
;
std
::
string
net_id
;
RULE
*
rules
;
// std::string circuit;
LAYER_RULES
layer_rules
;
public
:
public
:
FROMTO
(
ELEM
*
aParent
)
:
ELEM
(
T_fromto
,
aParent
)
{
...
...
@@ -2435,16 +2434,16 @@ public:
{
delete
rules
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
// no quoting on these two, the lexer preserved the quotes on input
out
->
Print
(
nestLevel
,
"(%s %s %s "
,
out
->
Print
(
nestLevel
,
"(%s %s %s "
,
LEXER
::
GetTokenText
(
Type
()
),
fromText
.
c_str
(),
toText
.
c_str
()
);
if
(
fromto_type
!=
T_NONE
)
out
->
Print
(
0
,
"(type %s)"
,
LEXER
::
GetTokenText
(
fromto_type
)
);
if
(
net_id
.
size
()
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
net_id
.
c_str
()
);
...
...
@@ -2452,24 +2451,24 @@ public:
}
bool
singleLine
=
true
;
if
(
rules
||
layer_rules
.
size
()
)
{
out
->
Print
(
0
,
"
\n
"
);
singleLine
=
false
;
}
if
(
rules
)
rules
->
Format
(
out
,
nestLevel
+
1
);
/*
if( circuit.size() )
out->Print( nestLevel, "%s\n", circuit.c_str() );
*/
for
(
LAYER_RULES
::
iterator
i
=
layer_rules
.
begin
();
i
!=
layer_rules
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
+
1
);
out
->
Print
(
singleLine
?
0
:
nestLevel
,
")"
);
if
(
nestLevel
||
!
singleLine
)
out
->
Print
(
0
,
"
\n
"
);
...
...
@@ -2487,23 +2486,23 @@ class COMP_ORDER : public ELEM
friend
class
SPECCTRA_DB
;
STRINGS
placement_ids
;
public
:
public
:
COMP_ORDER
(
ELEM
*
aParent
)
:
ELEM
(
T_comp_order
,
aParent
)
{
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
out
->
Print
(
nestLevel
,
"(%s"
,
LEXER
::
GetTokenText
(
Type
()
)
);
for
(
STRINGS
::
iterator
i
=
placement_ids
.
begin
();
i
!=
placement_ids
.
end
();
++
i
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
i
->
c_str
()
);
out
->
Print
(
0
,
" %s%s%s"
,
quote
,
i
->
c_str
(),
quote
);
}
out
->
Print
(
0
,
")"
);
if
(
nestLevel
)
out
->
Print
(
0
,
"
\n
"
);
...
...
@@ -2520,21 +2519,21 @@ class NET : public ELEM
int
net_number
;
DSN_T
pins_type
;
///< T_pins | T_order
PIN_REFS
pins
;
DSN_T
type
;
///< T_fix | T_normal
DSN_T
supply
;
///< T_power | T_ground
RULE
*
rules
;
LAYER_RULES
layer_rules
;
FROMTOS
fromtos
;
COMP_ORDER
*
comp_order
;
public
:
NET
(
ELEM
*
aParent
)
:
...
...
@@ -2543,39 +2542,39 @@ public:
unassigned
=
false
;
net_number
=
T_NONE
;
pins_type
=
T_pins
;
type
=
T_NONE
;
supply
=
T_NONE
;
rules
=
0
;
comp_order
=
0
;
}
~
NET
()
{
delete
rules
;
delete
comp_order
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
net_id
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s "
,
LEXER
::
GetTokenText
(
Type
()
),
out
->
Print
(
nestLevel
,
"(%s %s%s%s "
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
net_id
.
c_str
(),
quote
);
if
(
unassigned
)
out
->
Print
(
0
,
"(unassigned)"
);
if
(
net_number
!=
T_NONE
)
out
->
Print
(
0
,
"(net_number %d)"
,
net_number
);
out
->
Print
(
0
,
"
\n
"
);
const
int
RIGHTMARGIN
=
80
;
int
perLine
=
out
->
Print
(
nestLevel
+
1
,
"(%s"
,
LEXER
::
GetTokenText
(
pins_type
)
);
for
(
PIN_REFS
::
iterator
i
=
pins
.
begin
();
i
!=
pins
.
end
();
++
i
)
{
if
(
perLine
>
RIGHTMARGIN
)
...
...
@@ -2585,26 +2584,26 @@ public:
}
else
perLine
+=
out
->
Print
(
0
,
" "
);
perLine
+=
i
->
FormatIt
(
out
,
0
);
}
out
->
Print
(
0
,
")
\n
"
);
if
(
comp_order
)
comp_order
->
Format
(
out
,
nestLevel
+
1
);
if
(
type
!=
T_NONE
)
out
->
Print
(
nestLevel
+
1
,
"(type %s)
\n
"
,
LEXER
::
GetTokenText
(
type
)
);
if
(
rules
)
rules
->
Format
(
out
,
nestLevel
+
1
);
for
(
LAYER_RULES
::
iterator
i
=
layer_rules
.
begin
();
i
!=
layer_rules
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
+
1
);
for
(
FROMTOS
::
iterator
i
=
fromtos
.
begin
();
i
!=
fromtos
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
+
1
);
out
->
Print
(
nestLevel
,
")
\n
"
);
}
};
...
...
@@ -2613,13 +2612,13 @@ public:
class
TOPOLOGY
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
FROMTOS
fromtos
;
typedef
boost
::
ptr_vector
<
COMP_ORDER
>
COMP_ORDERS
;
COMP_ORDERS
comp_orders
;
public
:
public
:
TOPOLOGY
(
ELEM
*
aParent
)
:
ELEM
(
T_topology
,
aParent
)
{
...
...
@@ -2629,7 +2628,7 @@ public:
{
for
(
FROMTOS
::
iterator
i
=
fromtos
.
begin
();
i
!=
fromtos
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
for
(
COMP_ORDERS
::
iterator
i
=
comp_orders
.
begin
();
i
!=
comp_orders
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
}
...
...
@@ -2639,20 +2638,20 @@ public:
class
CLASS
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
std
::
string
class_id
;
STRINGS
net_ids
;
/// <circuit_descriptor> list
STRINGS
circuit
;
RULE
*
rules
;
LAYER_RULES
layer_rules
;
TOPOLOGY
*
topology
;
public
:
CLASS
(
ELEM
*
aParent
)
:
...
...
@@ -2667,14 +2666,14 @@ public:
delete
topology
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
int
RIGHTMARGIN
=
80
;
const
char
*
quote
=
out
->
GetQuoteChar
(
class_id
.
c_str
()
);
int
perLine
=
out
->
Print
(
nestLevel
,
"(%s %s%s%s"
,
int
perLine
=
out
->
Print
(
nestLevel
,
"(%s %s%s%s"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
class_id
.
c_str
(),
quote
);
...
...
@@ -2685,11 +2684,11 @@ public:
out
->
Print
(
0
,
"
\n
"
);
perLine
=
out
->
Print
(
nestLevel
+
1
,
"%s"
,
""
);
}
quote
=
out
->
GetQuoteChar
(
i
->
c_str
()
);
perLine
+=
out
->
Print
(
0
,
" %s%s%s"
,
quote
,
i
->
c_str
(),
quote
);
}
bool
newLine
=
false
;
if
(
circuit
.
size
()
||
layer_rules
.
size
()
||
topology
)
{
...
...
@@ -2702,14 +2701,14 @@ public:
for
(
LAYER_RULES
::
iterator
i
=
layer_rules
.
begin
();
i
!=
layer_rules
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
+
1
);
if
(
topology
)
topology
->
Format
(
out
,
nestLevel
+
1
);
out
->
Print
(
newLine
?
nestLevel
:
0
,
")
\n
"
);
}
};
class
NETWORK
:
public
ELEM
{
...
...
@@ -2717,23 +2716,23 @@ class NETWORK : public ELEM
typedef
boost
::
ptr_vector
<
NET
>
NETS
;
NETS
nets
;
typedef
boost
::
ptr_vector
<
CLASS
>
CLASSLIST
;
CLASSLIST
classes
;
public
:
NETWORK
(
ELEM
*
aParent
)
:
ELEM
(
T_network
,
aParent
)
{
}
void
FormatContents
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
for
(
NETS
::
iterator
i
=
nets
.
begin
();
i
!=
nets
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
for
(
CLASSLIST
::
iterator
i
=
classes
.
begin
();
i
!=
classes
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
}
...
...
@@ -2743,7 +2742,7 @@ public:
class
CONNECT
:
public
ELEM
{
// @todo not completed.
public
:
CONNECT
(
ELEM
*
parent
)
:
ELEM
(
T_connect
,
parent
)
{}
...
...
@@ -2766,7 +2765,7 @@ class WIRE : public ELEM
<qarc_descriptor> ]
*/
ELEM
*
shape
;
std
::
string
net_id
;
int
turret
;
DSN_T
wire_type
;
...
...
@@ -2775,20 +2774,20 @@ class WIRE : public ELEM
WINDOWS
windows
;
CONNECT
*
connect
;
bool
supply
;
public
:
WIRE
(
ELEM
*
aParent
)
:
ELEM
(
T_wire
,
aParent
)
{
shape
=
0
;
connect
=
0
;
turret
=
-
1
;
wire_type
=
T_NONE
;
attr
=
T_NONE
;
supply
=
false
;
}
~
WIRE
()
{
delete
shape
;
...
...
@@ -2799,61 +2798,61 @@ public:
{
delete
shape
;
shape
=
aShape
;
if
(
aShape
)
{
wxASSERT
(
aShape
->
Type
()
==
T_rect
||
aShape
->
Type
()
==
T_circle
||
aShape
->
Type
()
==
T_qarc
||
aShape
->
Type
()
==
T_path
wxASSERT
(
aShape
->
Type
()
==
T_rect
||
aShape
->
Type
()
==
T_circle
||
aShape
->
Type
()
==
T_qarc
||
aShape
->
Type
()
==
T_path
||
aShape
->
Type
()
==
T_polygon
);
aShape
->
SetParent
(
this
);
aShape
->
SetParent
(
this
);
}
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
out
->
Print
(
nestLevel
,
"(%s "
,
LEXER
::
GetTokenText
(
Type
()
)
);
if
(
shape
)
shape
->
Format
(
out
,
0
);
if
(
net_id
.
size
()
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
net_id
.
c_str
()
);
out
->
Print
(
0
,
"(net %s%s%s)"
,
out
->
Print
(
0
,
"(net %s%s%s)"
,
quote
,
net_id
.
c_str
(),
quote
);
}
if
(
turret
>=
0
)
out
->
Print
(
0
,
"(turrent %d)"
,
turret
);
if
(
wire_type
!=
T_NONE
)
out
->
Print
(
0
,
"(type %s)"
,
LEXER
::
GetTokenText
(
wire_type
)
);
if
(
attr
!=
T_NONE
)
out
->
Print
(
0
,
"(attr %s)"
,
LEXER
::
GetTokenText
(
attr
)
);
if
(
shield
.
size
()
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
shield
.
c_str
()
);
out
->
Print
(
0
,
"(shield %s%s%s)"
,
out
->
Print
(
0
,
"(shield %s%s%s)"
,
quote
,
shield
.
c_str
(),
quote
);
}
if
(
windows
.
size
()
)
{
out
->
Print
(
0
,
"
\n
"
);
for
(
WINDOWS
::
iterator
i
=
windows
.
begin
();
i
!=
windows
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
+
1
);
}
if
(
connect
)
connect
->
Format
(
out
,
0
);
if
(
supply
)
out
->
Print
(
0
,
"(supply)"
);
out
->
Print
(
0
,
")
\n
"
);
}
};
...
...
@@ -2878,7 +2877,7 @@ class WIRE_VIA : public ELEM
STRINGS
contact_layers
;
bool
supply
;
public
:
WIRE_VIA
(
ELEM
*
aParent
)
:
ELEM
(
T_via
,
aParent
)
...
...
@@ -2892,9 +2891,9 @@ public:
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
padstack_id
.
c_str
()
);
const
int
RIGHTMARGIN
=
80
;
int
perLine
=
out
->
Print
(
nestLevel
,
"(%s %s%s%s"
,
const
int
RIGHTMARGIN
=
80
;
int
perLine
=
out
->
Print
(
nestLevel
,
"(%s %s%s%s"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
padstack_id
.
c_str
(),
quote
);
...
...
@@ -2907,13 +2906,13 @@ public:
}
else
perLine
+=
out
->
Print
(
0
,
" "
);
perLine
+=
out
->
Print
(
0
,
"%.6g %.6g"
,
i
->
x
,
i
->
y
);
perLine
+=
out
->
Print
(
0
,
"%.6g %.6g"
,
i
->
x
,
i
->
y
);
}
if
(
net_id
.
size
()
||
via_number
!=-
1
||
via_type
!=
T_NONE
||
attr
!=
T_NONE
||
supply
)
out
->
Print
(
0
,
" "
);
if
(
net_id
.
size
()
)
{
if
(
perLine
>
RIGHTMARGIN
)
...
...
@@ -2922,7 +2921,7 @@ public:
perLine
=
out
->
Print
(
nestLevel
+
1
,
"%s"
,
""
);
}
const
char
*
quote
=
out
->
GetQuoteChar
(
net_id
.
c_str
()
);
perLine
+=
out
->
Print
(
0
,
"(net %s%s%s)"
,
quote
,
net_id
.
c_str
(),
quote
);
perLine
+=
out
->
Print
(
0
,
"(net %s%s%s)"
,
quote
,
net_id
.
c_str
(),
quote
);
}
if
(
via_number
!=
-
1
)
...
...
@@ -2934,7 +2933,7 @@ public:
}
perLine
+=
out
->
Print
(
0
,
"(via_number %d)"
,
via_number
);
}
if
(
via_type
!=
T_NONE
)
{
if
(
perLine
>
RIGHTMARGIN
)
...
...
@@ -2944,7 +2943,7 @@ public:
}
perLine
+=
out
->
Print
(
0
,
"(type %s)"
,
LEXER
::
GetTokenText
(
via_type
)
);
}
if
(
attr
!=
T_NONE
)
{
if
(
perLine
>
RIGHTMARGIN
)
...
...
@@ -2971,12 +2970,12 @@ public:
}
perLine
+=
out
->
Print
(
0
,
"(supply)"
);
}
if
(
contact_layers
.
size
()
)
{
out
->
Print
(
0
,
"
\n
"
);
out
->
Print
(
nestLevel
+
1
,
"(contact
\n
"
);
for
(
STRINGS
::
iterator
i
=
contact_layers
.
begin
();
i
!=
contact_layers
.
end
();
++
i
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
i
->
c_str
()
);
...
...
@@ -2998,10 +2997,10 @@ typedef boost::ptr_vector<WIRE_VIA> WIRE_VIAS;
class
WIRING
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
UNIT_RES
*
unit
;
WIRES
wires
;
WIRE_VIAS
wire_vias
;
WIRE_VIAS
wire_vias
;
public
:
...
...
@@ -3022,16 +3021,16 @@ public:
for
(
WIRES
::
iterator
i
=
wires
.
begin
();
i
!=
wires
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
for
(
WIRE_VIAS
::
iterator
i
=
wire_vias
.
begin
();
i
!=
wire_vias
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
}
DSN_T
GetUnits
()
const
UNIT_RES
*
GetUnits
()
const
{
if
(
unit
)
return
unit
->
GetUnits
()
;
return
unit
;
return
ELEM
::
GetUnits
();
}
};
...
...
@@ -3041,7 +3040,7 @@ class PCB : public ELEM
{
friend
class
SPECCTRA_DB
;
std
::
string
pcbname
;
std
::
string
pcbname
;
PARSER
*
parser
;
UNIT_RES
*
resolution
;
UNIT_RES
*
unit
;
...
...
@@ -3050,9 +3049,9 @@ class PCB : public ELEM
LIBRARY
*
library
;
NETWORK
*
network
;
WIRING
*
wiring
;
public
:
PCB
(
ELEM
*
aParent
=
0
)
:
ELEM
(
T_pcb
,
aParent
)
{
...
...
@@ -3065,7 +3064,7 @@ public:
network
=
0
;
wiring
=
0
;
}
~
PCB
()
{
delete
parser
;
...
...
@@ -3077,17 +3076,17 @@ public:
delete
network
;
delete
wiring
;
}
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
pcbname
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s
\n
"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
pcbname
.
c_str
(),
quote
);
if
(
parser
)
parser
->
Format
(
out
,
nestLevel
+
1
);
if
(
resolution
)
resolution
->
Format
(
out
,
nestLevel
+
1
);
...
...
@@ -3096,30 +3095,30 @@ public:
if
(
structure
)
structure
->
Format
(
out
,
nestLevel
+
1
);
if
(
placement
)
placement
->
Format
(
out
,
nestLevel
+
1
);
if
(
library
)
library
->
Format
(
out
,
nestLevel
+
1
);
if
(
network
)
network
->
Format
(
out
,
nestLevel
+
1
);
if
(
wiring
)
wiring
->
Format
(
out
,
nestLevel
+
1
);
out
->
Print
(
nestLevel
,
")
\n
"
);
out
->
Print
(
nestLevel
,
")
\n
"
);
}
DSN_T
GetUnits
()
const
UNIT_RES
*
GetUnits
()
const
{
if
(
unit
)
return
unit
->
GetUnits
()
;
return
unit
;
if
(
resolution
)
return
resolution
->
GetUnits
();
return
ELEM
::
GetUnits
();
}
};
...
...
@@ -3129,11 +3128,11 @@ class ANCESTOR : public ELEM
{
friend
class
SPECCTRA_DB
;
std
::
string
filename
;
std
::
string
filename
;
std
::
string
comment
;
time_t
time_stamp
;
public
:
ANCESTOR
(
ELEM
*
aParent
)
:
ELEM
(
T_ancestor
,
aParent
)
...
...
@@ -3145,24 +3144,24 @@ public:
{
char
temp
[
80
];
struct
tm
*
tmp
;
tmp
=
localtime
(
&
time_stamp
);
strftime
(
temp
,
sizeof
(
temp
),
"%b %d %H : %M : %S %Y"
,
tmp
);
// format the time first to temp
// filename may be empty, so quote it just in case.
out
->
Print
(
nestLevel
,
"(%s
\"
%s
\"
(created_time %s)
\n
"
,
out
->
Print
(
nestLevel
,
"(%s
\"
%s
\"
(created_time %s)
\n
"
,
LEXER
::
GetTokenText
(
Type
()
),
filename
.
c_str
(),
temp
);
if
(
comment
.
size
()
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
comment
.
c_str
()
);
out
->
Print
(
nestLevel
+
1
,
"(comment %s%s%s)
\n
"
,
out
->
Print
(
nestLevel
+
1
,
"(comment %s%s%s)
\n
"
,
quote
,
comment
.
c_str
(),
quote
);
}
out
->
Print
(
nestLevel
,
")
\n
"
);
}
};
...
...
@@ -3174,9 +3173,9 @@ class HISTORY : public ELEM
friend
class
SPECCTRA_DB
;
ANCESTORS
ancestors
;
time_t
time_stamp
;
time_t
time_stamp
;
STRINGS
comments
;
public
:
HISTORY
(
ELEM
*
aParent
)
:
...
...
@@ -3184,28 +3183,28 @@ public:
{
time_stamp
=
time
(
NULL
);
}
void
FormatContents
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
for
(
ANCESTORS
::
iterator
i
=
ancestors
.
begin
();
i
!=
ancestors
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
);
char
temp
[
80
];
struct
tm
*
tmp
;
tmp
=
localtime
(
&
time_stamp
);
strftime
(
temp
,
sizeof
(
temp
),
"%b %d %H : %M : %S %Y"
,
tmp
);
// format the time first to temp
out
->
Print
(
nestLevel
,
"(self (created_time %s)
\n
"
,
temp
);
for
(
STRINGS
::
iterator
i
=
comments
.
begin
();
i
!=
comments
.
end
();
++
i
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
i
->
c_str
()
);
out
->
Print
(
nestLevel
+
1
,
"(comment %s%s%s)
\n
"
,
out
->
Print
(
nestLevel
+
1
,
"(comment %s%s%s)
\n
"
,
quote
,
i
->
c_str
(),
quote
);
}
out
->
Print
(
nestLevel
,
")
\n
"
);
}
};
...
...
@@ -3214,11 +3213,11 @@ public:
/**
* Class SUPPLY_PIN
* corresponds to the <supply_pin_descriptor> in the specctra dsn spec.
*/
*/
class
SUPPLY_PIN
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
PIN_REFS
pin_refs
;
std
::
string
net_id
;
...
...
@@ -3232,7 +3231,7 @@ public:
{
bool
singleLine
=
pin_refs
.
size
()
<=
1
;
out
->
Print
(
nestLevel
,
"(%s"
,
LEXER
::
GetTokenText
(
Type
()
)
);
if
(
singleLine
)
{
out
->
Print
(
0
,
"%s"
,
" "
);
...
...
@@ -3243,16 +3242,16 @@ public:
for
(
PIN_REFS
::
iterator
i
=
pin_refs
.
begin
();
i
!=
pin_refs
.
end
();
++
i
)
i
->
FormatIt
(
out
,
nestLevel
+
1
);
}
if
(
net_id
.
size
()
)
{
const
char
*
newline
=
singleLine
?
""
:
"
\n
"
;
const
char
*
quote
=
out
->
GetQuoteChar
(
net_id
.
c_str
()
);
out
->
Print
(
singleLine
?
0
:
nestLevel
+
1
,
" (net %s%s%s)%s"
,
quote
,
net_id
.
c_str
(),
quote
,
newline
);
out
->
Print
(
singleLine
?
0
:
nestLevel
+
1
,
" (net %s%s%s)%s"
,
quote
,
net_id
.
c_str
(),
quote
,
newline
);
}
out
->
Print
(
singleLine
?
0
:
nestLevel
,
")
\n
"
);
}
};
...
...
@@ -3266,14 +3265,14 @@ typedef boost::ptr_vector<SUPPLY_PIN> SUPPLY_PINS;
class
NET_OUT
:
public
ELEM
{
friend
class
SPECCTRA_DB
;
std
::
string
net_id
;
int
net_number
;
RULE
*
rules
;
WIRES
wires
;
WIRE_VIAS
wire_vias
;
SUPPLY_PINS
supply_pins
;
SUPPLY_PINS
supply_pins
;
public
:
NET_OUT
(
ELEM
*
aParent
)
:
...
...
@@ -3290,26 +3289,26 @@ public:
void
Format
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
const
char
*
quote
=
out
->
GetQuoteChar
(
net_id
.
c_str
()
);
// cannot use Type() here, it is T_net_out and we need "(net "
out
->
Print
(
nestLevel
,
"(net %s%s%s
\n
"
,
// cannot use Type() here, it is T_net_out and we need "(net "
out
->
Print
(
nestLevel
,
"(net %s%s%s
\n
"
,
quote
,
net_id
.
c_str
(),
quote
);
if
(
net_number
>=
0
)
out
->
Print
(
nestLevel
+
1
,
"(net_number %d)
\n
"
,
net_number
);
if
(
rules
)
rules
->
Format
(
out
,
nestLevel
+
1
);
rules
->
Format
(
out
,
nestLevel
+
1
);
for
(
WIRES
::
iterator
i
=
wires
.
begin
();
i
!=
wires
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
+
1
);
for
(
WIRE_VIAS
::
iterator
i
=
wire_vias
.
begin
();
i
!=
wire_vias
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
+
1
);
for
(
SUPPLY_PINS
::
iterator
i
=
supply_pins
.
begin
();
i
!=
supply_pins
.
end
();
++
i
)
i
->
Format
(
out
,
nestLevel
+
1
);
out
->
Print
(
nestLevel
,
")
\n
"
);
}
};
...
...
@@ -3325,10 +3324,10 @@ class ROUTE : public ELEM
STRUCTURE
*
structure
;
LIBRARY
*
library
;
NET_OUTS
net_outs
;
// TEST_POINTS* test_points;
// TEST_POINTS* test_points;
public
:
ROUTE
(
ELEM
*
aParent
)
:
ELEM
(
T_route
,
aParent
)
{
...
...
@@ -3345,21 +3344,21 @@ public:
delete
library
;
// delete test_points;
}
void
FormatContents
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
if
(
resolution
)
resolution
->
Format
(
out
,
nestLevel
);
if
(
parser
)
parser
->
Format
(
out
,
nestLevel
);
if
(
structure
)
structure
->
Format
(
out
,
nestLevel
);
if
(
library
)
library
->
Format
(
out
,
nestLevel
);
if
(
net_outs
.
size
()
)
{
out
->
Print
(
nestLevel
,
"(network_out
\n
"
);
...
...
@@ -3367,7 +3366,7 @@ public:
i
->
Format
(
out
,
nestLevel
+
1
);
out
->
Print
(
nestLevel
,
")
\n
"
);
}
// if( test_poinst )
// test_points->Format( out, nestLevel );
}
...
...
@@ -3386,7 +3385,7 @@ struct PIN_PAIR
is
(
aParent
)
{
}
PIN_REF
was
;
PIN_REF
is
;
};
...
...
@@ -3408,7 +3407,7 @@ public:
ELEM
(
T_was_is
,
aParent
)
{
}
void
FormatContents
(
OUTPUTFORMATTER
*
out
,
int
nestLevel
)
throw
(
IOError
)
{
for
(
PIN_PAIRS
::
iterator
i
=
pin_pairs
.
begin
();
i
!=
pin_pairs
.
end
();
++
i
)
...
...
@@ -3433,8 +3432,8 @@ class SESSION : public ELEM
std
::
string
session_id
;
std
::
string
base_design
;
HISTORY
*
history
;
HISTORY
*
history
;
STRUCTURE
*
structure
;
PLACEMENT
*
placement
;
WAS_IS
*
was_is
;
...
...
@@ -3447,7 +3446,7 @@ class SESSION : public ELEM
*/
public
:
SESSION
(
ELEM
*
aParent
=
0
)
:
ELEM
(
T_pcb
,
aParent
)
{
...
...
@@ -3471,24 +3470,24 @@ public:
const
char
*
quote
=
out
->
GetQuoteChar
(
session_id
.
c_str
()
);
out
->
Print
(
nestLevel
,
"(%s %s%s%s
\n
"
,
LEXER
::
GetTokenText
(
Type
()
),
quote
,
session_id
.
c_str
(),
quote
);
out
->
Print
(
nestLevel
+
1
,
"(base_design
\"
%s
\"
)
\n
"
,
base_design
.
c_str
()
);
if
(
history
)
history
->
Format
(
out
,
nestLevel
+
1
);
if
(
structure
)
structure
->
Format
(
out
,
nestLevel
+
1
);
if
(
placement
)
placement
->
Format
(
out
,
nestLevel
+
1
);
if
(
was_is
)
was_is
->
Format
(
out
,
nestLevel
+
1
);
if
(
route
)
route
->
Format
(
out
,
nestLevel
+
1
);
out
->
Print
(
nestLevel
,
")
\n
"
);
}
};
...
...
@@ -3501,15 +3500,15 @@ public:
class
SPECCTRA_DB
:
public
OUTPUTFORMATTER
{
LEXER
*
lexer
;
PCB
*
pcb
;
SESSION
*
session
;
SESSION
*
session
;
FILE
*
fp
;
wxString
filename
;
std
::
string
quote_char
;
STRINGFORMATTER
sf
;
...
...
@@ -3517,21 +3516,21 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
STRINGS
layerIds
;
///< indexed by PCB layer number
/// maps BOARD layer number to PCB layer numbers
std
::
vector
<
int
>
kicadLayer2pcb
;
std
::
vector
<
int
>
kicadLayer2pcb
;
/// maps PCB layer number to BOARD layer numbers
std
::
vector
<
int
>
pcbLayer2kicad
;
std
::
vector
<
int
>
pcbLayer2kicad
;
static
const
KICAD_T
scanPADs
[];
/**
* Function nextTok
* returns the next token from the lexer.
*/
DSN_T
nextTok
();
/**
* Function isSymbol
* tests a token to see if it is a symbol. This means it cannot be a
...
...
@@ -3540,7 +3539,7 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
*/
static
bool
isSymbol
(
DSN_T
aTok
);
/**
* Function needLEFT
* calls nextTok() and then verifies that the token read in is a T_LEFT.
...
...
@@ -3559,7 +3558,7 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
/**
* Function needSYMBOL
* calls nextTok() and then verifies that the token read in
* calls nextTok() and then verifies that the token read in
* satisfies bool isSymbol().
* If not, an IOError is thrown.
* @throw IOError, if the next token does not satisfy isSymbol()
...
...
@@ -3571,10 +3570,10 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
* reads a <pin_reference> and splits it into the two parts which are
* on either side of the hyphen. This function is specialized because
* pin_reference may or may not be using double quotes. Both of these
* are legal: U2-14 or "U2"-"14". The lexer treats the first one as a
* are legal: U2-14 or "U2"-"14". The lexer treats the first one as a
* single T_SYMBOL, so in that case we have to split it into two here.
* <p>
* The caller should have already read in the first token comprizing the
* The caller should have already read in the first token comprizing the
* pin_reference and it will be tested through lexer->CurTok().
*
* @param component_id Where to put the text preceeding the '-' hyphen.
...
...
@@ -3592,7 +3591,7 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
* This function is specialized because time_stamps occur more than
* once in a session file.
* <p>
* The caller should not have already read in the first token comprizing the
* The caller should not have already read in the first token comprizing the
* time stamp.
*
* @param time_stamp Where to put the parsed time value.
...
...
@@ -3601,7 +3600,7 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
*/
void
readTIME
(
time_t
*
time_stamp
)
throw
(
IOError
);
/**
* Function expecting
* throws an IOError exception with an input file specific error message.
...
...
@@ -3612,21 +3611,21 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
void
expecting
(
const
char
*
text
)
throw
(
IOError
);
void
unexpected
(
DSN_T
aTok
)
throw
(
IOError
);
void
unexpected
(
const
char
*
text
)
throw
(
IOError
);
void
doPCB
(
PCB
*
growth
)
throw
(
IOError
);
void
doPARSER
(
PARSER
*
growth
)
throw
(
IOError
);
void
doRESOLUTION
(
UNIT_RES
*
growth
)
throw
(
IOError
);
void
doUNIT
(
UNIT_RES
*
growth
)
throw
(
IOError
);
void
doUNIT
(
UNIT_RES
*
growth
)
throw
(
IOError
);
void
doSTRUCTURE
(
STRUCTURE
*
growth
)
throw
(
IOError
);
void
doLAYER_NOISE_WEIGHT
(
LAYER_NOISE_WEIGHT
*
growth
)
throw
(
IOError
);
void
doLAYER_PAIR
(
LAYER_PAIR
*
growth
)
throw
(
IOError
);
void
doLAYER_PAIR
(
LAYER_PAIR
*
growth
)
throw
(
IOError
);
void
doBOUNDARY
(
BOUNDARY
*
growth
)
throw
(
IOError
);
void
doRECTANGLE
(
RECTANGLE
*
growth
)
throw
(
IOError
);
void
doPATH
(
PATH
*
growth
)
throw
(
IOError
);
void
doSTRINGPROP
(
STRINGPROP
*
growth
)
throw
(
IOError
);
void
doTOKPROP
(
TOKPROP
*
growth
)
throw
(
IOError
);
void
doVIA
(
VIA
*
growth
)
throw
(
IOError
);
void
doCONTROL
(
CONTROL
*
growth
)
throw
(
IOError
);
void
doCONTROL
(
CONTROL
*
growth
)
throw
(
IOError
);
void
doLAYER
(
LAYER
*
growth
)
throw
(
IOError
);
void
doRULE
(
RULE
*
growth
)
throw
(
IOError
);
void
doKEEPOUT
(
KEEPOUT
*
growth
)
throw
(
IOError
);
...
...
@@ -3634,7 +3633,7 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
void
doQARC
(
QARC
*
growth
)
throw
(
IOError
);
void
doWINDOW
(
WINDOW
*
growth
)
throw
(
IOError
);
void
doREGION
(
REGION
*
growth
)
throw
(
IOError
);
void
doCLASS_CLASS
(
CLASS_CLASS
*
growth
)
throw
(
IOError
);
void
doCLASS_CLASS
(
CLASS_CLASS
*
growth
)
throw
(
IOError
);
void
doLAYER_RULE
(
LAYER_RULE
*
growth
)
throw
(
IOError
);
void
doCLASSES
(
CLASSES
*
growth
)
throw
(
IOError
);
void
doGRID
(
GRID
*
growth
)
throw
(
IOError
);
...
...
@@ -3662,9 +3661,9 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
void
doROUTE
(
ROUTE
*
growth
)
throw
(
IOError
);
void
doWAS_IS
(
WAS_IS
*
growth
)
throw
(
IOError
);
void
doNET_OUT
(
NET_OUT
*
growth
)
throw
(
IOError
);
void
doSUPPLY_PIN
(
SUPPLY_PIN
*
growth
)
throw
(
IOError
);
void
doSUPPLY_PIN
(
SUPPLY_PIN
*
growth
)
throw
(
IOError
);
/**
* Function makeIMAGE
* allocates an IMAGE on the heap and creates all the PINs according
...
...
@@ -3672,15 +3671,15 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
*/
IMAGE
*
makeIMAGE
(
MODULE
*
aModule
);
/**
* Function makePADSTACKs
* makes all the PADSTACKs, and marks each D_PAD with the index into the
* makes all the PADSTACKs, and marks each D_PAD with the index into the
* LIBRARY::padstacks list that it matches.
*/
void
makePADSTACKs
(
BOARD
*
aBoard
,
TYPE_COLLECTOR
&
aPads
);
/**
* Function makeVia
* makes a round through hole PADSTACK using the given Kicad diameter in deci-mils.
...
...
@@ -3689,7 +3688,7 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
* or delete it.
*/
PADSTACK
*
makeVia
(
int
aCopperDiameter
);
/**
* Function makeVia
* makes any kind of PADSTACK using the given Kicad SEGVIA.
...
...
@@ -3698,7 +3697,7 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
* or delete it.
*/
PADSTACK
*
makeVia
(
const
SEGVIA
*
aVia
);
public
:
SPECCTRA_DB
()
...
...
@@ -3715,16 +3714,16 @@ public:
delete
lexer
;
delete
pcb
;
delete
session
;
if
(
fp
)
fclose
(
fp
);
}
//-----<OUTPUTFORMATTER>-------------------------------------------------
int
PRINTF_FUNC
Print
(
int
nestLevel
,
const
char
*
fmt
,
...
)
throw
(
IOError
);
const
char
*
GetQuoteChar
(
const
char
*
wrapee
);
const
char
*
GetQuoteChar
(
const
char
*
wrapee
);
//-----</OUTPUTFORMATTER>------------------------------------------------
/**
...
...
@@ -3744,11 +3743,11 @@ public:
}
PCB
*
GetPCB
()
{
return
pcb
;
}
void
SetFILE
(
FILE
*
aFile
)
void
SetFILE
(
FILE
*
aFile
)
{
fp
=
aFile
;
}
/**
* Function SetSESSION
* deletes any existing SESSION and replaces it with the given one.
...
...
@@ -3758,48 +3757,48 @@ public:
delete
session
;
session
=
aSession
;
}
/**
* Function LoadPCB
* is a recursive descent parser for a SPECCTRA DSN "design" file.
* A design file is nearly a full description of a PCB (seems to be
* A design file is nearly a full description of a PCB (seems to be
* missing only the silkscreen stuff).
*
* @param filename The name of the dsn file to load.
* @throw IOError if there is a lexer or parser error.
* @throw IOError if there is a lexer or parser error.
*/
void
LoadPCB
(
const
wxString
&
filename
)
throw
(
IOError
);
/**
* Function LoadSESSION
* is a recursive descent parser for a SPECCTRA DSN "session" file.
* A session file is file that is fed back from the router to the layout
* tool (PCBNEW) and should be used to update a BOARD object with the new
* tracks, vias, and component locations.
* tracks, vias, and component locations.
*
* @param filename The name of the dsn file to load.
* @throw IOError if there is a lexer or parser error.
* @throw IOError if there is a lexer or parser error.
*/
void
LoadSESSION
(
const
wxString
&
filename
)
throw
(
IOError
);
void
ThrowIOError
(
const
wxChar
*
fmt
,
...
)
throw
(
IOError
);
/**
* Function ExportPCB
* writes the internal PCB instance out as a SPECTRA DSN format file.
*
* @param aFilename The file to save to.
* @param aNameChange If true, causes the pcb's name to change to "aFilename"
* @param aNameChange If true, causes the pcb's name to change to "aFilename"
* and also to to be changed in the output file.
* @throw IOError, if an i/o error occurs saving the file.
*/
void
ExportPCB
(
wxString
aFilename
,
bool
aNameChange
=
false
)
throw
(
IOError
);
/**
* Function FromBOARD
* adds the entire BOARD to the PCB but does not write it out. Note that
...
...
@@ -3807,13 +3806,13 @@ public:
* side of the BOARD.
*
* See void WinEDA_PcbFrame::ExportToSpecctra( wxCommandEvent& event )
* for how this can be done before calling this function.
* for how this can be done before calling this function.
*
* @param aBoard The BOARD to convert to a PCB.
*/
void
FromBOARD
(
BOARD
*
aBoard
);
/**
* Function FromSESSION
* adds the entire SESSION info to a BOARD but does not write it out. The
...
...
@@ -3822,9 +3821,9 @@ public:
*
* @param aBoard The BOARD to merge the SESSION information into.
*/
void
FromSESSION
(
BOARD
*
aBoard
)
throw
(
IOError
);
void
FromSESSION
(
BOARD
*
aBoard
)
throw
(
IOError
);
/**
* Function ExportSESSION
* writes the internal SESSION instance out as a SPECTRA DSN format file.
...
...
pcbnew/specctra_export.cpp
View file @
f0ba106e
...
...
@@ -3,31 +3,31 @@
*
* Copyright (C) 2007-2008 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2007 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.,
* 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
*/
/* This source is a complement to specctra.cpp and implements the export to
specctra dsn file format. The specification for the grammar of the specctra
dsn file used to develop this code is given here:
http://www.autotraxeda.com/docs/SPECCTRA/SPECCTRA.pdf
Also see the comments at the top of the specctra.cpp file itself.
*/
...
...
@@ -48,9 +48,9 @@ void WinEDA_PcbFrame::ExportToSpecctra( wxCommandEvent& event )
wxString
fullFileName
=
GetScreen
()
->
m_FileName
;
wxString
std_ext
=
wxT
(
".dsn"
);
wxString
mask
=
wxT
(
"*"
)
+
std_ext
;
ChangeFileNameExt
(
fullFileName
,
std_ext
);
fullFileName
=
EDA_FileSelector
(
_
(
"Specctra DSN file:"
),
wxEmptyString
,
/* Chemin par defaut */
fullFileName
,
/* nom fichier par defaut */
...
...
@@ -69,38 +69,38 @@ void WinEDA_PcbFrame::ExportToSpecctra( wxCommandEvent& event )
BASE_SCREEN
*
screen
=
GetScreen
();
bool
wasModified
=
screen
->
IsModify
()
&&
!
screen
->
IsSave
();
db
.
SetPCB
(
SPECCTRA_DB
::
MakePCB
()
);
setlocale
(
LC_NUMERIC
,
"C"
);
// Switch the locale to standard C
try
{
setlocale
(
LC_NUMERIC
,
"C"
);
// Switch the locale to standard C
try
{
db
.
FromBOARD
(
m_Pcb
);
db
.
ExportPCB
(
fullFileName
,
true
);
// if an exception is thrown by FromBOARD or ExportPCB(), then
// if an exception is thrown by FromBOARD or ExportPCB(), then
// ~SPECCTRA_DB() will close the file.
}
}
catch
(
IOError
ioe
)
{
ok
=
false
;
// copy the error string to safe place, ioe is in this scope only.
errorText
=
ioe
.
errorText
;
}
setlocale
(
LC_NUMERIC
,
""
);
// revert to the current
locale
// The two calls below to BOARD::Change_Side_Module(), both set the
// modified flag, yet their actions cancel each other out, so it should
setlocale
(
LC_NUMERIC
,
""
);
// revert to the current locale
// The two calls below to BOARD::Change_Side_Module(), both set the
// modified flag, yet their actions cancel each other out, so it should
// be ok to clear the modify flag.
if
(
!
wasModified
)
screen
->
ClrModify
();
if
(
ok
)
{
Affiche_Message
(
wxString
(
_
(
"BOARD exported OK."
))
);
Affiche_Message
(
wxString
(
_
(
"BOARD exported OK."
))
);
}
else
DisplayError
(
this
,
errorText
);
...
...
@@ -115,7 +115,7 @@ struct POINT_PAIR
POINT
end
;
BOARD_ITEM
*
item
;
///< the item which has these points, TRACK or DRAWSEGMENT
};
typedef
std
::
vector
<
POINT_PAIR
>
POINT_PAIRS
;
typedef
std
::
vector
<
POINT_PAIR
>
POINT_PAIRS
;
const
KICAD_T
SPECCTRA_DB
::
scanPADs
[]
=
{
TYPEPAD
,
EOT
};
...
...
@@ -178,15 +178,15 @@ static int findPOINT( const POINT& pt, const POINT_PAIR source[], int count )
{
if
(
pt
==
source
[
i
].
start
)
{
return
+
(
i
+
1
);
return
+
(
i
+
1
);
}
if
(
pt
==
source
[
i
].
end
)
{
return
-
(
i
+
1
);
return
-
(
i
+
1
);
}
}
return
0
;
}
...
...
@@ -200,7 +200,7 @@ static void swapEnds( POINT_PAIRS& aList )
{
if
(
!
aList
.
size
()
)
return
;
// do an extraction sort based on matching ends here.
POINT_PAIRS
sorted
;
POINT_PAIRS
source
(
aList
);
...
...
@@ -208,45 +208,45 @@ static void swapEnds( POINT_PAIRS& aList )
// try and start the search using a POINT which has at least one match elsewhere.
if
(
findPOINT
(
source
.
begin
()
->
start
,
&
source
[
1
],
source
.
size
()
-
1
)
!=
0
)
swap
(
*
source
.
begin
()
);
// swap start and end of first PAIR
while
(
source
.
size
()
)
{
sorted
.
push_back
(
*
source
.
begin
()
);
source
.
erase
(
source
.
begin
()
);
// keep looping through the source list looking for a match to the end of the last sorted.
// keep looping through the source list looking for a match to the end of the last sorted.
int
result
;
while
(
(
result
=
findPOINT
(
sorted
.
back
().
end
,
&
source
[
0
],
source
.
size
()
)
)
!=
0
)
{
int
ndx
=
ABS
(
result
)
-
1
;
int
ndx
=
ABS
(
result
)
-
1
;
sorted
.
push_back
(
source
[
ndx
]
);
source
.
erase
(
source
.
begin
()
+
ndx
);
if
(
result
<
0
)
swap
(
sorted
.
back
()
);
}
}
#if 0 && defined(DEBUG)
printf( "swapEnds():\n" );
for( unsigned i=0; i<sorted.size(); ++i )
{
printf( "(%.6g,%.6g) (%.6g,%.6g)\n",
sorted[i].start.x, sorted[i].start.y,
printf( "(%.6g,%.6g) (%.6g,%.6g)\n",
sorted[i].start.x, sorted[i].start.y,
sorted[i].end.x, sorted[i].end.y );
}
#endif
aList
=
sorted
;
}
/**
* Function isRectangle
* tests to see if the POINT_PAIRS list makes up a vertically/horizontally
* tests to see if the POINT_PAIRS list makes up a vertically/horizontally
* oriented rectangle.
* @return bool - true if there are 4 point pairs making a rectangle.
*/
*/
static
bool
isRectangle
(
POINT_PAIRS
&
aList
)
{
if
(
aList
.
size
()
==
4
)
...
...
@@ -256,12 +256,12 @@ static bool isRectangle( POINT_PAIRS& aList )
if
(
i
<
aList
.
size
()
-
1
)
if
(
aList
[
i
].
end
!=
aList
[
i
+
1
].
start
)
return
false
;
if
(
aList
[
i
].
start
.
x
!=
aList
[
i
].
end
.
x
if
(
aList
[
i
].
start
.
x
!=
aList
[
i
].
end
.
x
&&
aList
[
i
].
start
.
y
!=
aList
[
i
].
end
.
y
)
return
false
;
}
return
(
aList
[
0
].
start
==
aList
[
3
].
end
);
}
return
false
;
...
...
@@ -275,7 +275,7 @@ static int Pad_list_Sort_by_Shapes( const void* refptr, const void* objptr )
const
D_PAD
*
padref
=
*
(
D_PAD
**
)
refptr
;
const
D_PAD
*
padcmp
=
*
(
D_PAD
**
)
objptr
;
return
D_PAD
::
Compare
(
padref
,
padcmp
);
return
D_PAD
::
Compare
(
padref
,
padcmp
);
}
...
...
@@ -299,14 +299,14 @@ IMAGE* SPECCTRA_DB::makeIMAGE( MODULE* aModule )
PADSTACKS
&
padstacks
=
pcb
->
library
->
padstacks
;
TYPE_COLLECTOR
pads
;
// get all the MODULE's pads.
// get all the MODULE's pads.
pads
.
Collect
(
aModule
,
scanPADs
);
IMAGE
*
image
=
new
IMAGE
(
0
);
image
->
image_id
=
CONV_TO_UTF8
(
aModule
->
m_LibRef
);
// from the pads, and make an IMAGE using collated padstacks.
for
(
int
p
=
0
;
p
<
pads
.
GetCount
();
++
p
)
{
...
...
@@ -317,10 +317,10 @@ IMAGE* SPECCTRA_DB::makeIMAGE( MODULE* aModule )
{
KEEPOUT
*
keepout
=
new
KEEPOUT
(
image
,
T_keepout
);
image
->
keepouts
.
push_back
(
keepout
);
CIRCLE
*
circle
=
new
CIRCLE
(
keepout
);
keepout
->
SetShape
(
circle
);
circle
->
SetDiameter
(
scale
(
pad
->
m_Drill
.
x
)
);
circle
->
SetVertex
(
mapPt
(
pad
->
m_Pos0
)
);
circle
->
layer_id
=
"signal"
;
...
...
@@ -328,22 +328,22 @@ IMAGE* SPECCTRA_DB::makeIMAGE( MODULE* aModule )
else
{
PADSTACK
*
padstack
=
&
padstacks
[
pad
->
m_logical_connexion
];
PIN
*
pin
=
new
PIN
(
image
);
image
->
pins
.
push_back
(
pin
);
pin
->
padstack_id
=
padstack
->
padstack_id
;
pin
->
pin_id
=
CONV_TO_UTF8
(
pad
->
ReturnStringPadName
()
);
// copper shape's position is hole position + offset
wxPoint
pos
=
pad
->
m_Pos0
+
pad
->
m_Offset
;
pin
->
SetVertex
(
mapPt
(
pos
)
);
}
}
return
image
;
}
}
PADSTACK
*
SPECCTRA_DB
::
makeVia
(
const
SEGVIA
*
aVia
)
...
...
@@ -352,9 +352,9 @@ PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia )
SHAPE
*
shape
;
double
dsnDiameter
;
char
name
[
48
];
PADSTACK
*
padstack
=
new
PADSTACK
(
pcb
->
library
);
switch
(
aVia
->
Shape
()
)
{
case
VIA_THROUGH
:
...
...
@@ -363,17 +363,17 @@ PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia )
circle
=
new
CIRCLE
(
shape
);
shape
->
SetShape
(
circle
);
dsnDiameter
=
scale
(
aVia
->
m_Width
);
dsnDiameter
=
scale
(
aVia
->
m_Width
);
circle
->
SetDiameter
(
dsnDiameter
);
circle
->
SetLayerId
(
"signal"
);
snprintf
(
name
,
sizeof
(
name
),
"Via_%.6g_mil"
,
dsnDiameter
);
circle
->
SetLayerId
(
"signal"
);
snprintf
(
name
,
sizeof
(
name
),
"Via_%.6g_mil"
,
dsnDiameter
);
name
[
sizeof
(
name
)
-
1
]
=
0
;
padstack
->
SetPadstackId
(
name
);
break
;
case
VIA_BLIND_BURIED
:
case
VIA_MICROVIA
:
int
topLayer
;
...
...
@@ -384,58 +384,58 @@ PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia )
if
(
topLayer
>
botLayer
)
EXCHG
(
topLayer
,
botLayer
);
dsnDiameter
=
scale
(
aVia
->
m_Width
);
dsnDiameter
=
scale
(
aVia
->
m_Width
);
for
(
int
layer
=
topLayer
;
layer
<=
botLayer
;
++
layer
)
{
shape
=
new
SHAPE
(
padstack
);
padstack
->
Append
(
shape
);
circle
=
new
CIRCLE
(
shape
);
shape
->
SetShape
(
circle
);
circle
->
SetDiameter
(
dsnDiameter
);
circle
->
SetLayerId
(
layerIds
[
layer
].
c_str
()
);
circle
->
SetLayerId
(
layerIds
[
layer
].
c_str
()
);
}
snprintf
(
name
,
sizeof
(
name
),
"Via[%d-%d]_%.6g_mil"
,
topLayer
,
botLayer
,
dsnDiameter
);
snprintf
(
name
,
sizeof
(
name
),
"Via[%d-%d]_%.6g_mil"
,
topLayer
,
botLayer
,
dsnDiameter
);
name
[
sizeof
(
name
)
-
1
]
=
0
;
padstack
->
SetPadstackId
(
name
);
break
;
}
return
padstack
;
}
}
PADSTACK
*
SPECCTRA_DB
::
makeVia
(
int
aCopperDiameter
)
{
char
name
[
48
];
PADSTACK
*
padstack
=
new
PADSTACK
(
pcb
->
library
);
SHAPE
*
shape
=
new
SHAPE
(
padstack
);
padstack
->
Append
(
shape
);
CIRCLE
*
circle
=
new
CIRCLE
(
shape
);
shape
->
SetShape
(
circle
);
double
dsnDiameter
=
scale
(
aCopperDiameter
);
double
dsnDiameter
=
scale
(
aCopperDiameter
);
circle
->
SetDiameter
(
dsnDiameter
);
circle
->
SetLayerId
(
"signal"
);
snprintf
(
name
,
sizeof
(
name
),
"Via_%.6g_mil"
,
dsnDiameter
);
circle
->
SetLayerId
(
"signal"
);
snprintf
(
name
,
sizeof
(
name
),
"Via_%.6g_mil"
,
dsnDiameter
);
name
[
sizeof
(
name
)
-
1
]
=
0
;
padstack
->
SetPadstackId
(
name
);
return
padstack
;
}
}
void
SPECCTRA_DB
::
makePADSTACKs
(
BOARD
*
aBoard
,
TYPE_COLLECTOR
&
aPads
)
{
char
name
[
80
];
// padstack name builder
if
(
aPads
.
GetCount
()
)
{
qsort
(
(
void
*
)
aPads
.
BasePtr
(),
aPads
.
GetCount
(),
sizeof
(
D_PAD
*
),
Pad_list_Sort_by_Shapes
);
...
...
@@ -447,28 +447,28 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
{
D_PAD
*
pad
=
(
D_PAD
*
)
aPads
[
i
];
bool
doLayer
[
2
]
=
{
// top and bottom layers only
bool
doLayer
[
2
]
=
{
// top and bottom layers only
pad
->
IsOnLayer
(
LAYER_CMP_N
),
pad
->
IsOnLayer
(
COPPER_LAYER_N
)
pad
->
IsOnLayer
(
COPPER_LAYER_N
)
};
if
(
old_pad
&&
0
==
D_PAD
::
Compare
(
old_pad
,
pad
)
)
{
// padstacks.size()-1 is the index of the matching padstack in LIBRARY::padstacks
pad
->
m_logical_connexion
=
pcb
->
library
->
padstacks
.
size
()
-
1
;
// this is the same as the last pad, so do not add it to the padstack list.
continue
;
}
// if pad has no copper presence, then it will be made into
// an "image->keepout" later. No copper pad here, it is probably a hole.
if
(
(
!
doLayer
[
0
]
&&
!
doLayer
[
1
])
// an "image->keepout" later. No copper pad here, it is probably a hole.
if
(
(
!
doLayer
[
0
]
&&
!
doLayer
[
1
])
||
(
pad
->
m_PadShape
==
PAD_CIRCLE
&&
pad
->
m_Drill
.
x
>=
pad
->
m_Size
.
x
)
)
{
// padstacks.size()-1 is the index of the matching padstack in LIBRARY::padstacks
pad
->
m_logical_connexion
=
pcb
->
library
->
padstacks
.
size
()
-
1
;
continue
;
}
...
...
@@ -476,54 +476,54 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
PADSTACK
*
padstack
=
new
PADSTACK
(
pcb
->
library
);
pcb
->
library
->
AddPadstack
(
padstack
);
// padstacks.size()-1 is the index of the matching padstack in LIBRARY::padstacks
pad
->
m_logical_connexion
=
pcb
->
library
->
padstacks
.
size
()
-
1
;
// For now, we will report only one layer for the pads. SMD pads are reported on the
// top layer, and through hole are reported on <reserved_layer_name> "signal".
// We could do better if there was actually a "layer type" field within
// We could do better if there was actually a "layer type" field within
// Kicad which would hold one of: T_signal, T_power, T_mixed, T_jumper
// See bottom of page 74 of the SECCTRA Design Language Reference, May 2000.
// See bottom of page 74 of the SECCTRA Design Language Reference, May 2000.
int
reportedLayers
=
1
;
// how many layers are reported.
doLayer
[
0
]
=
true
;
const
char
*
layerName
=
(
pad
->
m_Attribut
==
PAD_SMD
)
?
layerIds
[
0
].
c_str
()
:
"signal"
;
const
char
*
layerName
=
(
pad
->
m_Attribut
==
PAD_SMD
)
?
layerIds
[
0
].
c_str
()
:
"signal"
;
int
coppers
=
0
;
// will always be one for now
switch
(
pad
->
m_PadShape
)
{
default
:
case
PAD_CIRCLE
:
{
double
diameter
=
scale
(
pad
->
m_Size
.
x
);
for
(
int
layer
=
0
;
layer
<
reportedLayers
;
++
layer
)
{
if
(
doLayer
[
layer
]
)
{
SHAPE
*
shape
=
new
SHAPE
(
padstack
);
padstack
->
Append
(
shape
);
CIRCLE
*
circle
=
new
CIRCLE
(
shape
);
shape
->
SetShape
(
circle
);
circle
->
SetLayerId
(
layerName
);
circle
->
SetDiameter
(
diameter
);
++
coppers
;
}
}
snprintf
(
name
,
sizeof
(
name
),
"Round%dPad_%.6g_mil"
,
coppers
,
scale
(
pad
->
m_Size
.
x
)
);
name
[
sizeof
(
name
)
-
1
]
=
0
;
// @todo verify that all pad names are unique, there is a chance that
// @todo verify that all pad names are unique, there is a chance that
// D_PAD::Compare() could say two pads are different, yet the get the same
// name here. If so, blend in the padNdx into the name.
padstack
->
SetPadstackId
(
name
);
}
break
;
...
...
@@ -532,7 +532,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
{
double
dx
=
scale
(
pad
->
m_Size
.
x
)
/
2.0
;
double
dy
=
scale
(
pad
->
m_Size
.
y
)
/
2.0
;
POINT
lowerLeft
(
-
dx
,
-
dy
);
POINT
upperRight
(
dx
,
dy
);
...
...
@@ -542,28 +542,28 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
{
SHAPE
*
shape
=
new
SHAPE
(
padstack
);
padstack
->
Append
(
shape
);
RECTANGLE
*
rect
=
new
RECTANGLE
(
shape
);
shape
->
SetShape
(
rect
);
rect
->
SetLayerId
(
layerName
);
rect
->
SetCorners
(
lowerLeft
,
upperRight
);
++
coppers
;
}
}
snprintf
(
name
,
sizeof
(
name
),
"Rect%dPad_%.6gx%.6g_mil"
,
snprintf
(
name
,
sizeof
(
name
),
"Rect%dPad_%.6gx%.6g_mil"
,
coppers
,
scale
(
pad
->
m_Size
.
x
),
scale
(
pad
->
m_Size
.
y
)
);
name
[
sizeof
(
name
)
-
1
]
=
0
;
// @todo verify that all pad names are unique, there is a chance that
// @todo verify that all pad names are unique, there is a chance that
// D_PAD::Compare() could say two pads are different, yet they get the same
// name here. If so, blend in the padNdx into the name.
padstack
->
SetPadstackId
(
name
);
}
break
;
case
PAD_OVAL
:
{
double
dx
=
scale
(
pad
->
m_Size
.
x
)
/
2.0
;
...
...
@@ -585,7 +585,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
padstack
->
Append
(
shape
);
path
=
makePath
(
POINT
(
-
dr
,
0.0
),
POINT
(
dr
,
0.0
),
layerName
);
shape
->
SetShape
(
path
);
path
->
aperture_width
=
2.0
*
radius
;
path
->
aperture_width
=
2.0
*
radius
;
++
coppers
;
}
}
...
...
@@ -593,7 +593,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
else
// oval is vertical
{
double
radius
=
dx
;
dr
=
-
dr
;
for
(
int
layer
=
0
;
layer
<
reportedLayers
;
++
layer
)
...
...
@@ -607,32 +607,32 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
padstack
->
Append
(
shape
);
path
=
makePath
(
POINT
(
0.0
,
-
dr
),
POINT
(
0.0
,
dr
),
layerName
);
shape
->
SetShape
(
path
);
path
->
aperture_width
=
2.0
*
radius
;
path
->
aperture_width
=
2.0
*
radius
;
++
coppers
;
}
}
}
snprintf
(
name
,
sizeof
(
name
),
"Oval%dPad_%.6gx%.6g_mil"
,
snprintf
(
name
,
sizeof
(
name
),
"Oval%dPad_%.6gx%.6g_mil"
,
coppers
,
scale
(
pad
->
m_Size
.
x
),
scale
(
pad
->
m_Size
.
y
)
);
name
[
sizeof
(
name
)
-
1
]
=
0
;
// @todo verify that all pad names are unique, there is a chance that
// @todo verify that all pad names are unique, there is a chance that
// D_PAD::Compare() could say two pads are different, yet they get the same
// name here. If so, blend in the padNdx into the name.
padstack
->
SetPadstackId
(
name
);
}
break
;
/*
/*
case PAD_TRAPEZOID:
break;
*/
*/
}
}
// unique pads are now in the padstack list.
// unique pads are now in the padstack list.
// next we add the via's which may be used.
int
defaultViaSize
=
aBoard
->
m_BoardSettings
->
m_CurrentViaSize
;
...
...
@@ -641,24 +641,24 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
PADSTACK
*
padstack
=
makeVia
(
defaultViaSize
);
pcb
->
library
->
AddPadstack
(
padstack
);
// remember this index, it is the default via and also the start of the
// remember this index, it is the default via and also the start of the
// vias within the padstack list. Before this index are the pads.
// At this index and later are the vias.
pcb
->
library
->
SetViaStartIndex
(
pcb
->
library
->
padstacks
.
size
()
-
1
);
// padstack->SetPadstackId( "Via_Default" ); I like the padstack_id with the size in it.
}
for
(
int
i
=
0
;
i
<
HISTORY_NUMBER
;
++
i
)
{
int
viaSize
=
aBoard
->
m_BoardSettings
->
m_ViaSizeHistory
[
i
];
int
viaSize
=
aBoard
->
m_BoardSettings
->
m_ViaSizeHistory
[
i
];
if
(
!
viaSize
)
break
;
if
(
viaSize
==
defaultViaSize
)
continue
;
PADSTACK
*
padstack
=
makeVia
(
viaSize
);
PADSTACK
*
padstack
=
makeVia
(
viaSize
);
pcb
->
library
->
AddPadstack
(
padstack
);
}
}
...
...
@@ -671,8 +671,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
POINT_PAIR
pair
;
static
const
KICAD_T
scanMODULEs
[]
=
{
TYPEMODULE
,
EOT
};
if
(
!
pcb
)
pcb
=
SPECCTRA_DB
::
MakePCB
();
...
...
@@ -689,16 +689,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
}
}
//pcb->placement->flip_style = T_rotate_first;
//pcb->placement->flip_style = T_rotate_first;
// Since none of these statements cause any immediate output, the order
// of them is somewhat flexible. The outputting to disk is done at the
// end. We start by gathering all the layer information from the board.
//-----<layer_descriptor>-----------------------------------------------
{
// specctra wants top physical layer first, then going down to the
// specctra wants top physical layer first, then going down to the
// bottom most physical layer in physical sequence.
// @question : why does Kicad not display layers in that order?
int
layerCount
=
aBoard
->
GetCopperLayerCount
();
...
...
@@ -706,64 +706,64 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
layerIds
.
clear
();
pcbLayer2kicad
.
resize
(
layerCount
);
kicadLayer2pcb
.
resize
(
LAYER_CMP_N
+
1
);
for
(
int
kiNdx
=
layerCount
-
1
,
pcbNdx
=
0
;
kiNdx
>=
0
;
--
kiNdx
,
++
pcbNdx
)
{
int
kilayer
=
kiNdx
>
0
&&
kiNdx
==
layerCount
-
1
?
LAYER_CMP_N
:
kiNdx
;
// establish bi-directional mapping between kicad's BOARD layer and PCB layer
// establish bi-directional mapping between kicad's BOARD layer and PCB layer
pcbLayer2kicad
[
pcbNdx
]
=
kilayer
;
kicadLayer2pcb
[
kilayer
]
=
pcbNdx
;
kicadLayer2pcb
[
kilayer
]
=
pcbNdx
;
// save the specctra layer name in SPECCTRA_DB::layerIds for later.
layerIds
.
push_back
(
CONV_TO_UTF8
(
aBoard
->
GetLayerName
(
kilayer
)
)
);
LAYER
*
layer
=
new
LAYER
(
pcb
->
structure
);
pcb
->
structure
->
layers
.
push_back
(
layer
);
layer
->
name
=
layerIds
.
back
();
layer
->
properties
.
push_back
(
PROPERTY
()
);
PROPERTY
*
property
=
&
layer
->
properties
.
back
();
property
->
name
=
"index"
;
char
temp
[
32
];
sprintf
(
temp
,
"%d"
,
pcbNdx
);
property
->
value
=
temp
;
property
->
value
=
temp
;
// layer->type = @todo need this, the export would be better.
}
}
// for now, report on only the top and bottom layers with respect to the copper
// within a pad's padstack. this is usually correct, but not rigorous.
// within a pad's padstack. this is usually correct, but not rigorous.
// a space in a quoted token is NOT a terminator, true establishes this.
pcb
->
parser
->
space_in_quoted_tokens
=
true
;
//-----<unit_descriptor> & <resolution_descriptor>--------------------
{
{
pcb
->
unit
->
units
=
T_mil
;
pcb
->
resolution
->
units
=
T_mil
;
pcb
->
resolution
->
value
=
100
;
}
//-----<boundary_descriptor>------------------------------------------
{
// get all the DRAWSEGMENTS into 'items', then look for layer == EDGE_N,
// and those segments comprise the board's perimeter.
static
const
KICAD_T
scanDRAWSEGMENTS
[]
=
{
TYPEDRAWSEGMENT
,
EOT
};
items
.
Collect
(
aBoard
,
scanDRAWSEGMENTS
);
bool
haveEdges
=
false
;
ppairs
.
clear
();
for
(
int
i
=
0
;
i
<
items
.
GetCount
();
++
i
)
{
DRAWSEGMENT
*
item
=
(
DRAWSEGMENT
*
)
items
[
i
];
wxASSERT
(
item
->
Type
()
==
TYPEDRAWSEGMENT
);
if
(
item
->
GetLayer
()
==
EDGE_N
)
{
pair
.
start
=
mapPt
(
item
->
m_Start
);
...
...
@@ -773,36 +773,36 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
haveEdges
=
true
;
}
}
if
(
haveEdges
)
{
swapEnds
(
ppairs
);
#if 0 && defined(DEBUG)
#if 0 && defined(DEBUG)
for( unsigned i=0; i<ppairs.size(); ++i )
{
POINT_PAIR* p = &ppairs[i];
p->item->Show( 0, std::cout );
}
#endif
#endif
BOUNDARY
*
boundary
=
new
BOUNDARY
(
0
);
if
(
isRectangle
(
ppairs
)
)
{
RECTANGLE
*
rect
=
new
RECTANGLE
(
boundary
);
rect
->
layer_id
=
"pcb"
;
// opposite corners
rect
->
SetCorners
(
ppairs
[
0
].
start
,
ppairs
[
2
].
start
);
boundary
->
rectangle
=
rect
;
}
else
{
PATH
*
path
=
new
PATH
(
boundary
);
boundary
->
paths
.
push_back
(
path
);
path
->
layer_id
=
"pcb"
;
for
(
unsigned
i
=
0
;
i
<
ppairs
.
size
();
++
i
)
{
...
...
@@ -811,75 +811,75 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
path
->
points
.
push_back
(
ppairs
[
i
].
start
);
}
}
pcb
->
structure
->
SetBOUNDARY
(
boundary
);
}
else
{
aBoard
->
ComputeBoundaryBox
();
BOUNDARY
*
boundary
=
new
BOUNDARY
(
0
);
RECTANGLE
*
rect
=
new
RECTANGLE
(
boundary
);
rect
->
layer_id
=
"pcb"
;
// opposite corners
wxPoint
bottomRight
;
bottomRight
.
x
=
aBoard
->
m_BoundaryBox
.
GetRight
();
bottomRight
.
y
=
aBoard
->
m_BoundaryBox
.
GetBottom
();
rect
->
SetCorners
(
mapPt
(
aBoard
->
m_BoundaryBox
.
GetOrigin
()
),
mapPt
(
bottomRight
)
);
boundary
->
rectangle
=
rect
;
pcb
->
structure
->
SetBOUNDARY
(
boundary
);
}
}
//-----<rules>--------------------------------------------------------
{
// put out these rules, the user can then edit them with a text editor
char
rule
[
80
];
// padstack name builder
int
curTrackWidth
=
aBoard
->
m_BoardSettings
->
m_CurrentTrackWidth
;
int
curTrackClear
=
aBoard
->
m_BoardSettings
->
m_TrackClearence
;
double
clearance
=
scale
(
curTrackClear
);
STRINGS
&
rules
=
pcb
->
structure
->
rules
->
rules
;
sprintf
(
rule
,
"(width %.6g)"
,
scale
(
curTrackWidth
)
);
rules
.
push_back
(
rule
);
sprintf
(
rule
,
"(clearance %.6g)"
,
clearance
);
rules
.
push_back
(
rule
);
sprintf
(
rule
,
"(clearance %.6g (type pad_to_turn_gap))"
,
clearance
);
sprintf
(
rule
,
"(clearance %.6g (type pad_to_turn_gap))"
,
clearance
);
rules
.
push_back
(
rule
);
sprintf
(
rule
,
"(clearance %.6g (type smd_to_turn_gap))"
,
clearance
);
rules
.
push_back
(
rule
);
sprintf
(
rule
,
"(clearance %.6g (type via_via))"
,
clearance
);
rules
.
push_back
(
rule
);
sprintf
(
rule
,
"(clearance %.6g (type via_smd))"
,
clearance
);
rules
.
push_back
(
rule
);
sprintf
(
rule
,
"(clearance %.6g (type via_pin))"
,
clearance
);
rules
.
push_back
(
rule
);
sprintf
(
rule
,
"(clearance %.6g (type pin_pin))"
,
clearance
);
rules
.
push_back
(
rule
);
sprintf
(
rule
,
"(clearance %.6g (type smd_pin))"
,
clearance
);
rules
.
push_back
(
rule
);
sprintf
(
rule
,
"(clearance %.6g (type smd_smd))"
,
clearance
);
sprintf
(
rule
,
"(clearance %.6g (type smd_smd))"
,
clearance
);
rules
.
push_back
(
rule
);
}
//-----<zone containers become planes>--------------------------------
{
static
const
KICAD_T
scanZONEs
[]
=
{
TYPEZONE_CONTAINER
,
EOT
};
...
...
@@ -892,12 +892,12 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
COPPER_PLANE
*
plane
=
new
COPPER_PLANE
(
pcb
->
structure
);
PATH
*
polygon
=
new
PATH
(
plane
,
T_polygon
);
plane
->
SetShape
(
polygon
);
plane
->
name
=
CONV_TO_UTF8
(
item
->
m_Netname
);
wxString
layerName
=
aBoard
->
GetLayerName
(
item
->
GetLayer
()
);
polygon
->
layer_id
=
CONV_TO_UTF8
(
layerName
);
int
count
=
item
->
m_Poly
->
corner
.
size
();
for
(
int
j
=
0
;
j
<
count
;
++
j
)
{
...
...
@@ -905,7 +905,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
polygon
->
points
.
push_back
(
mapPt
(
point
)
);
}
pcb
->
structure
->
planes
.
push_back
(
plane
);
}
}
...
...
@@ -914,34 +914,34 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
// although COPPER_PLANEs probably will need them for the thru holes, etc.
// but in that case they are WINDOWs within the COPPER_PLANEs.
//-----<build the initial padstack list>--------------------------------
{
TYPE_COLLECTOR
pads
;
// get all the D_PADs into 'pads'.
// get all the D_PADs into 'pads'.
pads
.
Collect
(
aBoard
,
scanPADs
);
makePADSTACKs
(
aBoard
,
pads
);
#if 0 && defined(DEBUG)
for( int p=0; p<pads.GetCount(); ++p )
pads[p]->Show( 0, std::cout );
#endif
#endif
}
//-----<build the images and components>---------------------------------
{
items
.
Collect
(
aBoard
,
scanMODULEs
);
for
(
int
m
=
0
;
m
<
items
.
GetCount
();
++
m
)
{
MODULE
*
module
=
(
MODULE
*
)
items
[
m
];
IMAGE
*
image
=
makeIMAGE
(
module
);
IMAGE
*
registered
=
pcb
->
library
->
LookupIMAGE
(
image
);
IMAGE
*
registered
=
pcb
->
library
->
LookupIMAGE
(
image
);
if
(
registered
!=
image
)
{
// If our new 'image' is not a unique IMAGE, delete it.
...
...
@@ -952,56 +952,56 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
// @todo: this only works if the user has not modified the MODULE within the PCB
// and made it different from what is in the PCBNEW library. Need to test
// each image for uniqueness, not just based on name as is done here:
COMPONENT
*
comp
=
pcb
->
placement
->
LookupCOMPONENT
(
registered
->
GetImageId
()
);
PLACE
*
place
=
new
PLACE
(
comp
);
comp
->
places
.
push_back
(
place
);
place
->
SetRotation
(
module
->
m_Orient
/
10.0
);
place
->
SetVertex
(
mapPt
(
module
->
m_Pos
)
);
place
->
component_id
=
CONV_TO_UTF8
(
module
->
GetReference
()
);
place
->
part_number
=
CONV_TO_UTF8
(
module
->
GetValue
()
);
// module is flipped from bottom side, set side to T_back
if
(
module
->
flag
)
{
int
angle
=
1800
-
module
->
m_Orient
;
NORMALIZE_ANGLE_POS
(
angle
);
place
->
SetRotation
(
angle
/
10.0
);
place
->
side
=
T_back
;
}
}
}
//-----<create the nets>------------------------------------------------
{
NETWORK
*
network
=
pcb
->
network
;
TYPE_COLLECTOR
nets
;
TYPE_COLLECTOR
pads
;
static
const
KICAD_T
scanNETs
[]
=
{
PCB_EQUIPOT_STRUCT_TYPE
,
EOT
};
nets
.
Collect
(
aBoard
,
scanNETs
);
items
.
Collect
(
aBoard
,
scanMODULEs
);
PIN_REF
emptypin
(
0
);
for
(
int
n
=
0
;
n
<
nets
.
GetCount
();
++
n
)
{
EQUIPOT
*
kinet
=
(
EQUIPOT
*
)
nets
[
n
];
if
(
kinet
->
GetNet
()
==
0
)
continue
;
NET
*
net
=
new
NET
(
network
);
network
->
nets
.
push_back
(
net
);
net
->
net_id
=
CONV_TO_UTF8
(
kinet
->
m_Netname
);
net
->
net_number
=
kinet
->
GetNet
();
...
...
@@ -1010,17 +1010,17 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
MODULE
*
module
=
(
MODULE
*
)
items
[
m
];
pads
.
Collect
(
module
,
scanPADs
);
for
(
int
p
=
0
;
p
<
pads
.
GetCount
();
++
p
)
{
D_PAD
*
pad
=
(
D_PAD
*
)
pads
[
p
];
if
(
pad
->
GetNet
()
==
kinet
->
GetNet
()
)
{
// push on an empty one, then fill it via 'pin_ref'
net
->
pins
.
push_back
(
emptypin
);
PIN_REF
*
pin_ref
=
&
net
->
pins
.
back
();
pin_ref
->
SetParent
(
net
);
pin_ref
->
component_id
=
CONV_TO_UTF8
(
module
->
GetReference
()
);
pin_ref
->
pin_id
=
CONV_TO_UTF8
(
pad
->
ReturnStringPadName
()
);
...
...
@@ -1037,35 +1037,35 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
// export all of them for now, later we'll decide what controls we need
// on this.
static
const
KICAD_T
scanTRACKs
[]
=
{
TYPETRACK
,
EOT
};
items
.
Collect
(
aBoard
,
scanTRACKs
);
/*
/*
if( items.GetCount() )
qsort( (void*) items.BasePtr(), items.GetCount(),
qsort( (void*) items.BasePtr(), items.GetCount(),
sizeof(TRACK*), Track_list_Sort_by_Netcode );
*/
*/
std
::
string
netname
;
std
::
string
netname
;
WIRING
*
wiring
=
pcb
->
wiring
;
PATH
*
path
=
0
;
int
old_netcode
=
-
1
;
int
old_width
=
-
1
;
int
old_layer
=
-
1
;
int
old_netcode
=
-
1
;
int
old_width
=
-
1
;
int
old_layer
=
-
1
;
for
(
int
i
=
0
;
i
<
items
.
GetCount
();
++
i
)
{
TRACK
*
track
=
(
TRACK
*
)
items
[
i
];
if
(
track
->
GetNet
()
==
0
)
continue
;
if
(
old_netcode
!=
track
->
GetNet
()
||
old_width
!=
track
->
m_Width
||
old_width
!=
track
->
m_Width
||
old_layer
!=
track
->
GetLayer
()
||
(
path
&&
path
->
points
.
back
()
!=
mapPt
(
track
->
m_Start
)
)
)
||
(
path
&&
path
->
points
.
back
()
!=
mapPt
(
track
->
m_Start
)
)
)
{
old_width
=
track
->
m_Width
;
old_layer
=
track
->
GetLayer
();
...
...
@@ -1081,39 +1081,39 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
WIRE
*
wire
=
new
WIRE
(
wiring
);
wiring
->
wires
.
push_back
(
wire
);
wire
->
net_id
=
netname
;
wire
->
wire_type
=
T_normal
;
// @todo, this should be configurable
int
kiLayer
=
track
->
GetLayer
();
int
pcbLayer
=
kicadLayer2pcb
[
kiLayer
];
path
=
new
PATH
(
wire
);
wire
->
SetShape
(
path
);
path
->
layer_id
=
layerIds
[
pcbLayer
];
path
->
aperture_width
=
scale
(
old_width
);
path
->
AppendPoint
(
mapPt
(
track
->
m_Start
)
);
}
path
->
AppendPoint
(
mapPt
(
track
->
m_End
)
);
}
}
//-----<export the existing real instantiated vias>---------------------
{
// export all of them for now, later we'll decide what controls we need
// on this.
static
const
KICAD_T
scanVIAs
[]
=
{
TYPEVIA
,
EOT
};
items
.
Collect
(
aBoard
,
scanVIAs
);
for
(
int
i
=
0
;
i
<
items
.
GetCount
();
++
i
)
{
SEGVIA
*
via
=
(
SEGVIA
*
)
items
[
i
];
wxASSERT
(
via
->
Type
()
==
TYPEVIA
);
PADSTACK
*
padstack
=
makeVia
(
via
);
PADSTACK
*
registered
=
pcb
->
library
->
LookupVia
(
padstack
);
if
(
padstack
!=
registered
)
...
...
@@ -1123,22 +1123,22 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
WIRE_VIA
*
dsnVia
=
new
WIRE_VIA
(
pcb
->
wiring
);
pcb
->
wiring
->
wire_vias
.
push_back
(
dsnVia
);
dsnVia
->
padstack_id
=
registered
->
padstack_id
;
dsnVia
->
vertexes
.
push_back
(
mapPt
(
via
->
GetPosition
()
)
);
int
netcode
=
via
->
GetNet
();
EQUIPOT
*
equipot
=
aBoard
->
FindNet
(
netcode
);
wxASSERT
(
equipot
);
dsnVia
->
net_id
=
CONV_TO_UTF8
(
equipot
->
m_Netname
);
dsnVia
->
via_type
=
T_normal
;
// @todo, this should be configurable
}
}
#endif // do existing wires and vias
#endif // do existing wires and vias
//-----<via_descriptor>-------------------------------------------------
{
// Output the vias in the padstack list here, by name. This must
...
...
@@ -1156,9 +1156,9 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
}
}
//-----<restore MODULEs>------------------------------------------------
// DSN Images (=Kicad MODULES and pads) must be presented from the
// top view. Restore those that were flipped.
for
(
MODULE
*
module
=
aBoard
->
m_Modules
;
module
;
module
=
module
->
Next
()
)
...
...
@@ -1171,5 +1171,5 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
}
}
}
// namespace DSN
pcbnew/specctra_import.cpp
View file @
f0ba106e
...
...
@@ -3,32 +3,32 @@
*
* Copyright (C) 2007-2008 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2007 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.,
* 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
*/
/* This source is a complement to specctra.cpp and implements the import of
a specctra session file (*.ses), and import of a specctra design file
(*.dsn) file. The specification for the grammar of the specctra dsn file
a specctra session file (*.ses), and import of a specctra design file
(*.dsn) file. The specification for the grammar of the specctra dsn file
used to develop this code is given here:
http://www.autotraxeda.com/docs/SPECCTRA/SPECCTRA.pdf
Also see the comments at the top of the specctra.cpp file itself.
*/
...
...
@@ -42,25 +42,30 @@ using namespace DSN;
void
WinEDA_PcbFrame
::
ImportSpecctraDesign
(
wxCommandEvent
&
event
)
{
/* @todo write this someday
if( !Clear_Pcb( true ) )
return;
*/
}
void
WinEDA_PcbFrame
::
ImportSpecctraSession
(
wxCommandEvent
&
event
)
{
/*
if( GetScreen()->IsModify() )
{
if( !IsOK( this, _( "Board Modified: Continue ?" ) ) )
return;
}
*/
wxString
sessionExt
(
wxT
(
".ses"
)
);
wxString
fileName
=
GetScreen
()
->
m_FileName
;
wxString
mask
=
wxT
(
"*"
)
+
sessionExt
;
ChangeFileNameExt
(
fileName
,
sessionExt
);
fileName
=
EDA_FileSelector
(
_
(
"Merge Specctra Session file:"
),
wxEmptyString
,
fileName
,
...
...
@@ -69,58 +74,83 @@ void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event )
this
,
wxFD_OPEN
,
FALSE
);
if
(
fileName
==
wxEmptyString
)
return
;
SPECCTRA_DB
db
;
setlocale
(
LC_NUMERIC
,
"C"
);
// Switch the locale to standard C
try
{
setlocale
(
LC_NUMERIC
,
"C"
);
// Switch the locale to standard C
try
{
db
.
LoadSESSION
(
fileName
);
db
.
FromSESSION
(
m_Pcb
);
}
catch
(
IOError
ioe
)
{
setlocale
(
LC_NUMERIC
,
""
);
//
Switch the locale to standard C
setlocale
(
LC_NUMERIC
,
""
);
//
revert to the current locale
DisplayError
(
this
,
ioe
.
errorText
);
return
;
}
setlocale
(
LC_NUMERIC
,
""
);
//
Switch the locale to standard C
setlocale
(
LC_NUMERIC
,
""
);
//
revert to the current locale
m_SelTrackWidthBox_Changed
=
TRUE
;
m_SelViaSizeBox_Changed
=
TRUE
;
GetScreen
()
->
SetModify
();
m_Pcb
->
m_Status_Pcb
=
0
;
Affiche_Message
(
wxString
(
_
(
"Session file imported and merged OK."
))
);
DrawPanel
->
Refresh
(
TRUE
);
}
namespace
DSN
{
static
wxPoint
mapPt
(
const
POINT
&
aPoint
,
double
aResolution
)
static
wxPoint
mapPt
(
const
POINT
&
aPoint
,
UNIT_RES
*
aResolution
)
{
wxPoint
ret
;
double
resValue
=
aResolution
->
GetValue
();
double
factor
;
// multiply this times units to get mils for Kicad.
switch
(
aResolution
->
GetEngUnits
()
)
{
default
:
case
T_inch
:
factor
=
0.001
;
break
;
case
T_mil
:
factor
=
1.0
;
break
;
case
T_cm
:
factor
=
2.54
/
1000.0
;
break
;
case
T_mm
:
factor
=
25.4
/
1000.0
;
break
;
case
T_um
:
factor
=
25.4
;
break
;
}
// the factor of 10.0 is used to convert mils to deci-mils, the units
// used within Kicad.
ret
.
x
=
(
int
)
(
10.0
*
aPoint
.
x
/
aResolution
);
ret
.
y
=
(
int
)
-
(
10.0
*
aPoint
.
y
/
aResolution
);
// used within Kicad.
factor
*=
10.0
;
ret
.
x
=
(
int
)
(
factor
*
aPoint
.
x
/
resValue
);
ret
.
y
=
(
int
)
-
(
factor
*
aPoint
.
y
/
resValue
);
// negate y coord
return
ret
;
}
// no UI code in this function, throw exception to report problems to the
// no UI code in this function, throw exception to report problems to the
// UI handler: void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event )
void
SPECCTRA_DB
::
FromSESSION
(
BOARD
*
aBoard
)
throw
(
IOError
)
...
...
@@ -129,7 +159,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
if
(
!
session
)
ThrowIOError
(
_
(
"Session file is missing the
\"
session
\"
section"
)
);
if
(
!
session
->
placement
)
ThrowIOError
(
_
(
"Session file is missing the
\"
placement
\"
section"
)
);
...
...
@@ -138,16 +168,16 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
if
(
!
session
->
route
->
library
)
ThrowIOError
(
_
(
"Session file is missing the
\"
library_out
\"
section"
)
);
// delete all the old tracks and vias
aBoard
->
m_Track
->
DeleteStructList
();
aBoard
->
m_Track
=
NULL
;
aBoard
->
m_NbSegmTrack
=
0
;
aBoard
->
DeleteMARKERs
();
aBoard
->
DeleteMARKERs
();
// Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within
// each COMPONENT, reposition and re-orient each component and put on
// each COMPONENT, reposition and re-orient each component and put on
// correct side of the board.
COMPONENTS
&
components
=
session
->
placement
->
components
;
for
(
COMPONENTS
::
iterator
comp
=
components
.
begin
();
comp
!=
components
.
end
();
++
comp
)
...
...
@@ -156,51 +186,62 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
for
(
unsigned
i
=
0
;
i
<
places
.
size
();
++
i
)
{
PLACE
*
place
=
&
places
[
i
];
// '&' even though places[] holds a pointer!
wxString
reference
=
CONV_FROM_UTF8
(
place
->
component_id
.
c_str
()
);
MODULE
*
module
=
aBoard
->
FindModuleByReference
(
reference
);
if
(
!
module
)
{
wxString
errorMsg
;
errorMsg
.
Printf
(
_
(
"Session file has reference to non-existing component
\"
%s
\"
"
),
ThrowIOError
(
_
(
"Session file has 'reference' to non-existent component
\"
%s
\"
"
),
reference
.
GetData
()
);
ThrowIOError
(
errorMsg
);
}
if
(
!
place
->
hasVertex
)
continue
;
double
resolution
=
100
;
//place->GetResolution();
UNIT_RES
*
resolution
=
place
->
GetUnits
();
wxASSERT
(
resolution
);
wxPoint
newPos
=
mapPt
(
place
->
vertex
,
resolution
);
module
->
SetPosition
(
newPos
);
if
(
place
->
side
==
T_front
)
{
// convert from degrees to tenths of degrees used in Kicad.
int
orientation
=
(
int
)
(
place
->
rotation
*
10.0
);
module
->
SetOrientation
(
orientation
);
if
(
module
->
GetLayer
()
!=
CMP_N
)
{
// module is on copper layer (back)
aBoard
->
Change_Side_Module
(
module
,
0
);
}
module
->
SetOrientation
(
orientation
);
}
else
if
(
place
->
side
==
T_back
)
{
int
orientation
=
(
int
)
(
-
place
->
rotation
*
10.0
-
1800
);
module
->
SetOrientation
(
orientation
);
int
orientation
=
(
place
->
rotation
+
180.0
)
*
10.0
;
if
(
module
->
GetLayer
()
!=
COPPER_LAYER_N
)
{
// module is on component layer (front)
aBoard
->
Change_Side_Module
(
module
,
0
);
}
module
->
SetOrientation
(
orientation
);
}
else
{
// as I write this, the LEXER *is* catching this, so we should never see below:
wxFAIL_MSG
(
wxT
(
"DSN::LEXER did not catch an illegal side := 'back|front'"
)
);
}
}
}
// Walk the NET_OUTs and create tracks and vias anew.
// Walk the NET_OUTs and create tracks and vias anew.
NET_OUTS
&
net_outs
=
session
->
route
->
net_outs
;
for
(
NET_OUTS
::
iterator
i
=
net_outs
.
begin
();
i
!=
net_outs
.
end
();
++
i
)
{
// create a track or via and position it.
}
}
...
...
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