Commit f0ba106e authored by dickelbeck's avatar dickelbeck

more amazing free software

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