kicad/pcbnew/specctra.cpp

3780 lines
94 KiB
C++
Raw Normal View History

2007-12-22 07:18:20 +00:00
/*
* This program source code file is part of KiCad, a free EDA CAD application.
2007-12-22 07:18:20 +00:00
*
* Copyright (C) 2007-2011 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
2015-02-28 20:50:35 +00:00
* Copyright (C) 2007-2015 KiCad Developers, see change_log.txt for contributors.
2008-02-07 20:23:58 +00:00
*
2007-12-22 07:18:20 +00:00
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
2008-02-07 20:23:58 +00:00
*
2007-12-22 07:18:20 +00:00
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
2008-02-07 20:23:58 +00:00
*
2007-12-22 07:18:20 +00:00
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
2008-02-07 20:23:58 +00:00
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
2007-12-22 07:18:20 +00:00
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
2008-02-07 20:23:58 +00:00
/* This source file implements export and import capabilities to the
2008-01-03 22:24:17 +00:00
specctra dsn file format. The grammar for that file format is documented
fairly well. There are classes for each major type of descriptor in the
spec.
2008-02-07 20:23:58 +00:00
Since there are so many classes in here, it may be helpful to generate
2008-01-03 22:24:17 +00:00
the Doxygen directory:
2008-02-07 20:23:58 +00:00
2008-01-03 22:24:17 +00:00
$ cd <kicadSourceRoot>
$ doxygen
2008-02-07 20:23:58 +00:00
2008-01-03 22:24:17 +00:00
Then you can view the html documentation in the <kicadSourceRoot>/doxygen
2008-01-14 22:50:08 +00:00
directory. The main class in this file is SPECCTRA_DB and its main
2008-01-20 00:34:21 +00:00
functions are LoadPCB(), LoadSESSION(), and ExportPCB().
2008-02-07 20:23:58 +00:00
2008-01-20 00:34:21 +00:00
Wide use is made of boost::ptr_vector<> and std::vector<> template classes.
If the contained object is small, then std::vector tends to be used.
If the contained object is large, variable size, or would require writing
2008-02-01 20:32:18 +00:00
an assignment operator() or copy constructor, then boost::ptr_vector
2008-01-20 00:34:21 +00:00
cannot be beat.
2008-02-07 20:23:58 +00:00
*/
2008-01-03 22:24:17 +00:00
2007-12-23 06:10:51 +00:00
#include <cstdarg>
#include <cstdio>
#include <build_version.h>
#include <class_board.h>
#include <class_track.h>
#include <specctra.h>
#include <macros.h>
2010-08-08 00:31:07 +00:00
2008-01-01 08:45:47 +00:00
namespace DSN {
2008-01-20 00:34:21 +00:00
2008-02-07 20:23:58 +00:00
#define NESTWIDTH 2 ///< how many spaces per nestLevel
2008-01-20 00:34:21 +00:00
2008-01-03 06:33:28 +00:00
//-----<SPECCTRA_DB>-------------------------------------------------
const char* GetTokenText( T aTok )
{
return SPECCTRA_LEXER::TokenName( aTok );
}
void SPECCTRA_DB::buildLayerMaps( BOARD* aBoard )
{
// specctra wants top physical layer first, then going down to the
// bottom most physical layer in physical sequence.
// Same as KiCad now except for B_Cu
unsigned layerCount = aBoard->GetCopperLayerCount();
layerIds.clear();
pcbLayer2kicad.resize( layerCount );
kicadLayer2pcb.resize( B_Cu + 1 );
#if 0 // was:
for( LAYER_NUM kiNdx = layerCount - 1, pcbNdx=FIRST_LAYER;
kiNdx >= 0; --kiNdx, ++pcbNdx )
{
LAYER_NUM kilayer = (kiNdx>0 && kiNdx==layerCount-1) ? F_Cu : kiNdx;
// establish bi-directional mapping between KiCad's BOARD layer and PCB layer
pcbLayer2kicad[pcbNdx] = kilayer;
kicadLayer2pcb[kilayer] = pcbNdx;
// save the specctra layer name in SPECCTRA_DB::layerIds for later.
2014-06-29 13:05:51 +00:00
layerIds.push_back( TO_UTF8( aBoard->GetLayerName( ToLAYER_ID( kilayer ) ) ) );
}
#else
// establish bi-directional mapping between KiCad's BOARD layer and PCB layer
for( unsigned i = 0; i < kicadLayer2pcb.size(); ++i )
{
if( i < layerCount-1 )
kicadLayer2pcb[i] = i;
else
kicadLayer2pcb[i] = layerCount - 1;
}
for( unsigned i = 0; i < pcbLayer2kicad.size(); ++i )
{
LAYER_ID id = ( i < layerCount-1 ) ? ToLAYER_ID( i ) : B_Cu;
pcbLayer2kicad[i] = id;
// save the specctra layer name in SPECCTRA_DB::layerIds for later.
layerIds.push_back( TO_UTF8( aBoard->GetLayerName( id ) ) );
}
#endif
}
int SPECCTRA_DB::findLayerName( const std::string& aLayerName ) const
{
for( int i=0; i < int(layerIds.size()); ++i )
{
if( 0 == aLayerName.compare( layerIds[i] ) )
return i;
}
return -1;
}
void SPECCTRA_DB::readCOMPnPIN( std::string* component_id, std::string* pin_id ) throw( IO_ERROR )
2008-01-18 22:41:16 +00:00
{
T tok;
2008-02-07 20:23:58 +00:00
static const char pin_def[] = "<pin_reference>::=<component_id>-<pin_id>";
if( !IsSymbol( (T) CurTok() ) )
Expecting( pin_def );
2008-01-18 22:41:16 +00:00
// case for: A12-14, i.e. no wrapping quotes. This should be a single
2008-02-07 20:23:58 +00:00
// token, so split it.
if( CurTok() != T_STRING )
2008-01-18 22:41:16 +00:00
{
const char* toktext = CurText();
2008-01-18 22:41:16 +00:00
const char* dash = strchr( toktext, '-' );
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
if( !dash )
Expecting( pin_def );
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
while( toktext != dash )
*component_id += *toktext++;
++toktext; // skip the dash
while( *toktext )
*pin_id += *toktext++;
}
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
// quoted string: "U12"-"14" or "U12"-14, 3 tokens in either case
else
{
*component_id = CurText();
2008-01-18 22:41:16 +00:00
tok = NextTok();
2008-01-18 22:41:16 +00:00
if( tok!=T_DASH )
Expecting( pin_def );
2008-02-07 20:23:58 +00:00
NextTok(); // accept anything after the dash.
*pin_id = CurText();
2008-01-18 22:41:16 +00:00
}
}
void SPECCTRA_DB::readTIME( time_t* time_stamp ) throw( IO_ERROR )
2008-01-20 00:34:21 +00:00
{
T tok;
2008-02-07 20:23:58 +00:00
2008-01-23 22:38:16 +00:00
struct tm mytime;
2008-02-07 20:23:58 +00:00
static const char time_toks[] = "<month> <day> <hour> : <minute> : <second> <year>";
2008-01-20 00:34:21 +00:00
2008-01-23 22:38:16 +00:00
static const char* months[] = { // index 0 = Jan
2008-02-07 20:23:58 +00:00
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
2008-01-23 22:38:16 +00:00
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL
};
2008-02-07 20:23:58 +00:00
NeedSYMBOL(); // month
2008-02-07 20:23:58 +00:00
const char* ptok = CurText();
2008-01-23 22:38:16 +00:00
2008-01-24 21:47:54 +00:00
mytime.tm_mon = 0; // remains if we don't find a month match.
2008-01-23 22:38:16 +00:00
for( int m=0; months[m]; ++m )
{
if( !strcasecmp( months[m], ptok ) )
2008-01-23 22:38:16 +00:00
{
mytime.tm_mon = m;
break;
}
}
2008-02-07 20:23:58 +00:00
tok = NextTok(); // day
2008-01-20 00:34:21 +00:00
if( tok != T_NUMBER )
Expecting( time_toks );
mytime.tm_mday = atoi( CurText() );
2008-02-07 20:23:58 +00:00
tok = NextTok(); // hour
2008-01-20 00:34:21 +00:00
if( tok != T_NUMBER )
Expecting( time_toks );
mytime.tm_hour = atoi( CurText() );
2008-01-20 00:34:21 +00:00
2008-02-07 20:23:58 +00:00
// : colon
NeedSYMBOL();
if( *CurText() != ':' || strlen( CurText() )!=1 )
Expecting( time_toks );
2008-01-20 00:34:21 +00:00
tok = NextTok(); // minute
2008-01-20 00:34:21 +00:00
if( tok != T_NUMBER )
Expecting( time_toks );
mytime.tm_min = atoi( CurText() );
2008-02-07 20:23:58 +00:00
// : colon
NeedSYMBOL();
if( *CurText() != ':' || strlen( CurText() )!=1 )
Expecting( time_toks );
2008-01-20 00:34:21 +00:00
tok = NextTok(); // second
2008-01-20 00:34:21 +00:00
if( tok != T_NUMBER )
Expecting( time_toks );
mytime.tm_sec = atoi( CurText() );
2008-02-07 20:23:58 +00:00
tok = NextTok(); // year
2008-01-20 00:34:21 +00:00
if( tok != T_NUMBER )
Expecting( time_toks );
mytime.tm_year = atoi( CurText() ) - 1900;
2008-02-07 20:23:58 +00:00
*time_stamp = mktime( &mytime );
2008-01-20 00:34:21 +00:00
}
void SPECCTRA_DB::LoadPCB( const wxString& aFilename ) throw( IO_ERROR, boost::bad_pointer )
2008-01-01 08:45:47 +00:00
{
FILE_LINE_READER curr_reader( aFilename );
2008-02-07 20:23:58 +00:00
PushReader( &curr_reader );
2008-01-01 08:45:47 +00:00
if( NextTok() != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
if( NextTok() != T_pcb )
Expecting( T_pcb );
2008-01-01 08:53:12 +00:00
2008-01-02 18:18:37 +00:00
SetPCB( new PCB() );
2008-02-07 20:23:58 +00:00
2008-01-20 00:34:21 +00:00
doPCB( pcb );
PopReader();
2008-01-20 00:34:21 +00:00
}
void SPECCTRA_DB::LoadSESSION( const wxString& aFilename ) throw( IO_ERROR, boost::bad_pointer )
2008-01-20 00:34:21 +00:00
{
FILE_LINE_READER curr_reader( aFilename );
2008-01-20 00:34:21 +00:00
PushReader( &curr_reader );
2008-01-20 00:34:21 +00:00
if( NextTok() != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
if( NextTok() != T_session )
Expecting( T_session );
2008-01-20 00:34:21 +00:00
SetSESSION( new SESSION() );
2008-02-07 20:23:58 +00:00
2008-01-20 00:34:21 +00:00
doSESSION( session );
PopReader();
2008-01-01 08:45:47 +00:00
}
void SPECCTRA_DB::doPCB( PCB* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-01 08:45:47 +00:00
{
T tok;
2008-01-18 22:41:16 +00:00
/* <design_descriptor >::=
(pcb <pcb_id >
[<parser_descriptor> ]
[<capacitance_resolution_descriptor> ]
[<conductance_resolution_descriptor> ]
[<current_resolution_descriptor> ]
[<inductance_resolution_descriptor> ]
[<resistance_resolution_descriptor> ]
[<resolution_descriptor> ]
[<time_resolution_descriptor> ]
[<voltage_resolution_descriptor> ]
[<unit_descriptor> ]
[<structure_descriptor> | <file_descriptor> ]
[<placement_descriptor> | <file_descriptor> ]
[<library_descriptor> | <file_descriptor> ]
[<floor_plan_descriptor> | <file_descriptor> ]
[<part_library_descriptor> | <file_descriptor> ]
[<network_descriptor> | <file_descriptor> ]
[<wiring_descriptor> ]
[<color_descriptor> ]
)
*/
2008-02-07 20:23:58 +00:00
NeedSYMBOL();
growth->pcbname = CurText();
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-01 08:45:47 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-01 08:45:47 +00:00
switch( tok )
{
case T_parser:
2008-01-15 23:12:38 +00:00
if( growth->parser )
Unexpected( tok );
2008-01-02 18:18:37 +00:00
growth->parser = new PARSER( growth );
doPARSER( growth->parser );
2008-01-01 08:45:47 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-01 08:45:47 +00:00
case T_unit:
2008-01-15 23:12:38 +00:00
if( growth->unit )
Unexpected( tok );
2008-01-15 23:12:38 +00:00
growth->unit = new UNIT_RES( growth, tok );
2008-01-02 18:18:37 +00:00
doUNIT( growth->unit );
2008-01-01 08:45:47 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-01 08:45:47 +00:00
case T_resolution:
2008-01-15 23:12:38 +00:00
if( growth->resolution )
Unexpected( tok );
2008-01-15 23:12:38 +00:00
growth->resolution = new UNIT_RES( growth, tok );
2008-01-02 18:18:37 +00:00
doRESOLUTION( growth->resolution );
2008-01-01 08:45:47 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-01 08:45:47 +00:00
case T_structure:
2008-01-15 23:12:38 +00:00
if( growth->structure )
Unexpected( tok );
2008-01-03 06:33:28 +00:00
growth->structure = new STRUCTURE( growth );
doSTRUCTURE( growth->structure );
break;
2008-01-05 17:24:56 +00:00
2008-01-01 08:45:47 +00:00
case T_placement:
2008-01-15 23:12:38 +00:00
if( growth->placement )
Unexpected( tok );
2008-01-15 23:12:38 +00:00
growth->placement = new PLACEMENT( growth );
doPLACEMENT( growth->placement );
break;
2008-02-07 20:23:58 +00:00
2008-01-01 08:45:47 +00:00
case T_library:
2008-01-15 23:12:38 +00:00
if( growth->library )
Unexpected( tok );
2008-01-15 23:12:38 +00:00
growth->library = new LIBRARY( growth );
doLIBRARY( growth->library );
2008-01-01 08:45:47 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-16 23:08:22 +00:00
case T_network:
if( growth->network )
Unexpected( tok );
2008-01-16 23:08:22 +00:00
growth->network = new NETWORK( growth );
doNETWORK( growth->network );
break;
2008-01-18 22:41:16 +00:00
case T_wiring:
if( growth->wiring )
Unexpected( tok );
2008-01-18 22:41:16 +00:00
growth->wiring = new WIRING( growth );
doWIRING( growth->wiring );
break;
2008-02-07 20:23:58 +00:00
2008-01-01 08:45:47 +00:00
default:
Unexpected( CurText() );
2008-01-01 08:45:47 +00:00
}
}
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-01 08:53:12 +00:00
if( tok != T_EOF )
Expecting( T_EOF );
2008-01-01 08:45:47 +00:00
}
void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IO_ERROR )
2008-01-01 08:45:47 +00:00
{
T tok;
2008-02-14 01:07:52 +00:00
std::string const1;
std::string const2;
2008-02-07 20:23:58 +00:00
/* <parser_descriptor >::=
(parser
[(string_quote <quote_char >)]
(space_in_quoted_tokens [on | off])
[(host_cad <id >)]
[(host_version <id >)]
[{(constant <id > <id >)}]
[(write_resolution] {<character> <positive_integer >})]
[(routes_include {[testpoint | guides |
image_conductor]})]
[(wires_include testpoint)]
[(case_sensitive [on | off])]
[(via_rotate_first [on | off])]
)
*/
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-01 08:45:47 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-01 08:45:47 +00:00
switch( tok )
{
case T_STRING_QUOTE:
tok = NextTok();
2008-01-01 08:45:47 +00:00
if( tok != T_QUOTE_DEF )
Expecting( T_QUOTE_DEF );
SetStringDelimiter( (unsigned char) *CurText() );
growth->string_quote = *CurText();
quote_char = CurText();
NeedRIGHT();
2008-01-01 08:45:47 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-01 08:45:47 +00:00
case T_space_in_quoted_tokens:
tok = NextTok();
2008-01-01 08:45:47 +00:00
if( tok!=T_on && tok!=T_off )
Expecting( "on|off" );
SetSpaceInQuotedTokens( tok==T_on );
2008-01-02 18:18:37 +00:00
growth->space_in_quoted_tokens = (tok==T_on);
NeedRIGHT();
2008-01-01 08:45:47 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-01 08:45:47 +00:00
case T_host_cad:
NeedSYMBOL();
growth->host_cad = CurText();
NeedRIGHT();
2008-01-01 08:45:47 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-01 08:45:47 +00:00
case T_host_version:
NeedSYMBOLorNUMBER();
growth->host_version = CurText();
NeedRIGHT();
2008-01-01 08:45:47 +00:00
break;
case T_constant:
NeedSYMBOLorNUMBER();
const1 = CurText();
NeedSYMBOLorNUMBER();
const2 = CurText();
NeedRIGHT();
2008-02-14 01:07:52 +00:00
growth->constants.push_back( const1 );
growth->constants.push_back( const2 );
2008-01-01 08:45:47 +00:00
break;
case T_write_resolution: // [(writee_resolution {<character> <positive_integer >})]
while( (tok = NextTok()) != T_RIGHT )
2008-01-01 08:45:47 +00:00
{
if( tok!=T_SYMBOL )
Expecting( T_SYMBOL );
tok = NextTok();
2008-01-01 08:45:47 +00:00
if( tok!=T_NUMBER )
Expecting( T_NUMBER );
2008-01-01 08:45:47 +00:00
// @todo
}
break;
2008-01-01 08:45:47 +00:00
case T_routes_include: // [(routes_include {[testpoint | guides | image_conductor]})]
while( (tok = NextTok()) != T_RIGHT )
2008-01-01 08:45:47 +00:00
{
switch( tok )
{
case T_testpoint:
2008-01-03 06:33:28 +00:00
growth->routes_include_testpoint = true;
break;
2008-01-01 08:45:47 +00:00
case T_guide:
2008-01-03 06:33:28 +00:00
growth->routes_include_guides = true;
break;
2008-01-01 08:45:47 +00:00
case T_image_conductor:
2008-01-03 06:33:28 +00:00
growth->routes_include_image_conductor = true;
2008-01-01 08:45:47 +00:00
break;
default:
Expecting( "testpoint|guides|image_conductor" );
2008-01-01 08:45:47 +00:00
}
}
break;
2008-01-01 08:45:47 +00:00
case T_wires_include: // [(wires_include testpoint)]
tok = NextTok();
2008-01-01 08:45:47 +00:00
if( tok != T_testpoint )
Expecting( T_testpoint );
2008-01-03 06:33:28 +00:00
growth->routes_include_testpoint = true;
NeedRIGHT();
2008-01-01 08:45:47 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-01 08:45:47 +00:00
case T_case_sensitive:
tok = NextTok();
2008-01-01 08:45:47 +00:00
if( tok!=T_on && tok!=T_off )
Expecting( "on|off" );
2008-01-02 18:18:37 +00:00
growth->case_sensitive = (tok==T_on);
NeedRIGHT();
2008-01-01 08:45:47 +00:00
break;
case T_via_rotate_first: // [(via_rotate_first [on | off])]
tok = NextTok();
2008-01-01 08:45:47 +00:00
if( tok!=T_on && tok!=T_off )
Expecting( "on|off" );
2008-01-03 06:33:28 +00:00
growth->via_rotate_first = (tok==T_on);
NeedRIGHT();
2008-01-01 08:45:47 +00:00
break;
2008-01-20 12:58:55 +00:00
case T_generated_by_freeroute:
growth->generated_by_freeroute = true;
NeedRIGHT();
2008-01-20 12:58:55 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-01 08:45:47 +00:00
default:
Unexpected( CurText() );
2008-01-01 08:45:47 +00:00
}
}
}
2008-01-05 17:24:56 +00:00
void SPECCTRA_DB::doRESOLUTION( UNIT_RES* growth ) throw( IO_ERROR )
2008-01-01 08:45:47 +00:00
{
T tok = NextTok();
2008-01-01 08:45:47 +00:00
switch( tok )
{
case T_inch:
case T_mil:
case T_cm:
case T_mm:
case T_um:
2008-01-02 18:18:37 +00:00
growth->units = tok;
2008-01-01 08:45:47 +00:00
break;
default:
Expecting( "inch|mil|cm|mm|um" );
2008-01-01 08:45:47 +00:00
}
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-01 08:45:47 +00:00
if( tok != T_NUMBER )
Expecting( T_NUMBER );
2008-01-02 18:18:37 +00:00
growth->value = atoi( CurText() );
2008-02-07 20:23:58 +00:00
NeedRIGHT();
2008-01-01 08:45:47 +00:00
}
2008-01-05 17:24:56 +00:00
void SPECCTRA_DB::doUNIT( UNIT_RES* growth ) throw( IO_ERROR )
2008-01-02 18:18:37 +00:00
{
T tok = NextTok();
2007-12-22 07:18:20 +00:00
2008-01-02 18:18:37 +00:00
switch( tok )
{
case T_inch:
case T_mil:
case T_cm:
case T_mm:
case T_um:
growth->units = tok;
break;
default:
Expecting( "inch|mil|cm|mm|um" );
2008-01-02 18:18:37 +00:00
}
2008-02-07 20:23:58 +00:00
NeedRIGHT();
2008-01-02 18:18:37 +00:00
}
2008-01-06 01:24:36 +00:00
void SPECCTRA_DB::doLAYER_PAIR( LAYER_PAIR* growth ) throw( IO_ERROR )
2008-01-06 01:24:36 +00:00
{
NeedSYMBOL();
growth->layer_id0 = CurText();
2008-01-06 01:24:36 +00:00
NeedSYMBOL();
growth->layer_id1 = CurText();
2008-02-07 20:23:58 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->layer_weight = strtod( CurText(), 0 );
2008-01-06 01:24:36 +00:00
NeedRIGHT();
2008-01-06 01:24:36 +00:00
}
void SPECCTRA_DB::doLAYER_NOISE_WEIGHT( LAYER_NOISE_WEIGHT* growth )
throw( IO_ERROR, boost::bad_pointer )
2008-01-06 01:24:36 +00:00
{
T tok;
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-06 01:24:36 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
if( NextTok() != T_layer_pair )
Expecting( T_layer_pair );
2008-02-07 20:23:58 +00:00
2008-01-06 01:24:36 +00:00
LAYER_PAIR* layer_pair = new LAYER_PAIR( growth );
growth->layer_pairs.push_back( layer_pair );
doLAYER_PAIR( layer_pair );
}
}
2008-01-11 20:25:52 +00:00
2015-02-28 20:50:35 +00:00
void SPECCTRA_DB::doSTRUCTURE( STRUCTURE* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-03 06:33:28 +00:00
{
T tok;
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-03 06:33:28 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-03 06:33:28 +00:00
switch( tok )
{
case T_unit:
2008-01-15 23:12:38 +00:00
if( growth->unit )
Unexpected( tok );
2008-01-15 23:12:38 +00:00
growth->unit = new UNIT_RES( growth, tok );
2008-01-03 06:33:28 +00:00
doUNIT( growth->unit );
break;
2008-02-07 20:23:58 +00:00
2008-01-06 01:24:36 +00:00
case T_resolution:
2008-01-15 23:12:38 +00:00
if( growth->unit )
Unexpected( tok );
2008-01-15 23:12:38 +00:00
growth->unit = new UNIT_RES( growth, tok );
doRESOLUTION( growth->unit );
2008-01-06 01:24:36 +00:00
break;
2008-01-03 06:33:28 +00:00
2008-01-06 01:24:36 +00:00
case T_layer_noise_weight:
2008-02-14 01:07:52 +00:00
if( growth->layer_noise_weight )
Unexpected( tok );
2008-01-06 01:24:36 +00:00
growth->layer_noise_weight = new LAYER_NOISE_WEIGHT( growth );
doLAYER_NOISE_WEIGHT( growth->layer_noise_weight );
2008-02-07 20:23:58 +00:00
break;
2008-01-03 06:33:28 +00:00
case T_place_boundary:
2008-02-07 20:23:58 +00:00
L_place:
2008-01-03 06:33:28 +00:00
if( growth->place_boundary )
Unexpected( tok );
2008-01-03 06:33:28 +00:00
growth->place_boundary = new BOUNDARY( growth, T_place_boundary );
doBOUNDARY( growth->place_boundary );
break;
2008-02-07 20:23:58 +00:00
2008-01-03 06:33:28 +00:00
case T_boundary:
if( growth->boundary )
{
if( growth->place_boundary )
Unexpected( tok );
2008-01-03 06:33:28 +00:00
goto L_place;
}
growth->boundary = new BOUNDARY( growth );
doBOUNDARY( growth->boundary );
break;
2008-01-03 15:53:45 +00:00
2008-01-07 07:43:23 +00:00
case T_plane:
2008-01-23 22:38:16 +00:00
COPPER_PLANE* plane;
plane = new COPPER_PLANE( growth );
2008-01-07 07:43:23 +00:00
growth->planes.push_back( plane );
doKEEPOUT( plane );
break;
case T_region:
REGION* region;
region = new REGION( growth );
growth->regions.push_back( region );
doREGION( region );
break;
2008-02-07 20:23:58 +00:00
2008-01-03 15:53:45 +00:00
case T_snap_angle:
STRINGPROP* stringprop;
2008-02-07 20:23:58 +00:00
stringprop = new STRINGPROP( growth, T_snap_angle );
2008-01-03 22:24:17 +00:00
growth->Append( stringprop );
2008-01-03 15:53:45 +00:00
doSTRINGPROP( stringprop );
break;
case T_via:
2008-02-14 01:07:52 +00:00
if( growth->via )
Unexpected( tok );
2008-01-03 15:53:45 +00:00
growth->via = new VIA( growth );
doVIA( growth->via );
break;
2008-02-07 20:23:58 +00:00
2008-01-03 15:53:45 +00:00
case T_control:
2008-02-14 01:07:52 +00:00
if( growth->control )
Unexpected( tok );
2008-01-03 15:53:45 +00:00
growth->control = new CONTROL( growth );
doCONTROL( growth->control );
break;
2008-01-03 22:24:17 +00:00
case T_layer:
LAYER* layer;
layer = new LAYER( growth );
growth->layers.push_back( layer );
doLAYER( layer );
break;
2008-01-04 08:28:16 +00:00
case T_rule:
2008-02-14 01:07:52 +00:00
if( growth->rules )
Unexpected( tok );
2008-01-14 22:50:08 +00:00
growth->rules = new RULE( growth, T_rule );
doRULE( growth->rules );
2008-01-04 08:28:16 +00:00
break;
2008-01-05 17:24:56 +00:00
2008-01-14 22:50:08 +00:00
case T_place_rule:
2008-02-14 01:07:52 +00:00
if( growth->place_rules )
Unexpected( tok );
2008-01-14 22:50:08 +00:00
growth->place_rules = new RULE( growth, T_place_rule );
doRULE( growth->place_rules );
2008-02-07 20:23:58 +00:00
break;
2008-01-05 17:24:56 +00:00
case T_keepout:
case T_place_keepout:
case T_via_keepout:
case T_wire_keepout:
case T_bend_keepout:
case T_elongate_keepout:
2008-01-06 01:24:36 +00:00
KEEPOUT* keepout;
keepout = new KEEPOUT( growth, tok );
growth->keepouts.push_back( keepout );
doKEEPOUT( keepout );
break;
2008-01-11 20:25:52 +00:00
case T_grid:
GRID* grid;
grid = new GRID( growth );
growth->grids.push_back( grid );
doGRID( grid );
break;
2008-02-07 20:23:58 +00:00
2008-01-06 01:24:36 +00:00
default:
Unexpected( CurText() );
2008-01-06 01:24:36 +00:00
}
}
}
void SPECCTRA_DB::doSTRUCTURE_OUT( STRUCTURE_OUT* growth ) throw( IO_ERROR, boost::bad_pointer )
2009-07-13 22:59:56 +00:00
{
/*
<structure_out_descriptor >::=
(structure_out
{<layer_descriptor> }
[<rule_descriptor> ]
)
*/
T tok = NextTok();
2009-07-13 22:59:56 +00:00
while( tok != T_RIGHT )
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2009-07-13 22:59:56 +00:00
tok = NextTok();
2009-07-13 22:59:56 +00:00
switch( tok )
{
case T_layer:
LAYER* layer;
layer = new LAYER( growth );
growth->layers.push_back( layer );
doLAYER( layer );
break;
case T_rule:
if( growth->rules )
Unexpected( tok );
2009-07-13 22:59:56 +00:00
growth->rules = new RULE( growth, T_rule );
doRULE( growth->rules );
break;
default:
Unexpected( CurText() );
2009-07-13 22:59:56 +00:00
}
tok = NextTok();
2009-07-13 22:59:56 +00:00
}
}
void SPECCTRA_DB::doKEEPOUT( KEEPOUT* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-06 01:24:36 +00:00
{
T tok = NextTok();
2008-02-07 20:23:58 +00:00
if( IsSymbol(tok) )
2008-01-06 01:24:36 +00:00
{
growth->name = CurText();
tok = NextTok();
2008-01-06 01:24:36 +00:00
}
2008-02-07 20:23:58 +00:00
if( tok!=T_LEFT )
Expecting( T_LEFT );
2008-01-06 01:24:36 +00:00
while( tok != T_RIGHT )
{
if( tok!=T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-06 01:24:36 +00:00
switch( tok )
{
case T_sequence_number:
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->sequence_number = atoi( CurText() );
NeedRIGHT();
2008-01-06 01:24:36 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-06 01:24:36 +00:00
case T_rule:
2008-01-11 20:25:52 +00:00
if( growth->rules )
Unexpected( tok );
2008-01-14 22:50:08 +00:00
growth->rules = new RULE( growth, T_rule );
doRULE( growth->rules );
2008-01-06 01:24:36 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-06 01:24:36 +00:00
case T_place_rule:
2008-01-11 20:25:52 +00:00
if( growth->place_rules )
Unexpected( tok );
2008-01-14 22:50:08 +00:00
growth->place_rules = new RULE( growth, T_place_rule );
doRULE( growth->place_rules );
2008-01-06 01:24:36 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-06 01:24:36 +00:00
case T_rect:
2008-01-30 19:16:46 +00:00
if( growth->shape )
Unexpected( tok );
2008-01-30 19:16:46 +00:00
growth->shape = new RECTANGLE( growth );
doRECTANGLE( (RECTANGLE*) growth->shape );
2008-01-06 01:24:36 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-06 01:24:36 +00:00
case T_circle:
2008-01-30 19:16:46 +00:00
if( growth->shape )
Unexpected( tok );
2008-01-30 19:16:46 +00:00
growth->shape = new CIRCLE( growth );
doCIRCLE( (CIRCLE*) growth->shape );
2008-01-06 01:24:36 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-02-01 01:09:39 +00:00
case T_polyline_path:
tok = T_path;
2008-01-06 01:24:36 +00:00
case T_path:
case T_polygon:
2008-01-30 19:16:46 +00:00
if( growth->shape )
Unexpected( tok );
2008-01-30 19:16:46 +00:00
growth->shape = new PATH( growth, tok );
doPATH( (PATH*) growth->shape );
2008-01-06 01:24:36 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-06 01:24:36 +00:00
case T_qarc:
2008-01-30 19:16:46 +00:00
if( growth->shape )
Unexpected( tok );
2008-01-30 19:16:46 +00:00
growth->shape = new QARC( growth );
doQARC( (QARC*) growth->shape );
2008-01-06 01:24:36 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-06 01:24:36 +00:00
case T_window:
WINDOW* window;
window = new WINDOW( growth );
growth->windows.push_back( window );
doWINDOW( window );
break;
default:
Unexpected( CurText() );
2008-01-06 01:24:36 +00:00
}
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-06 01:24:36 +00:00
}
}
2012-01-16 21:43:07 +00:00
void SPECCTRA_DB::doCONNECT( CONNECT* growth ) throw( IO_ERROR )
{
/* from page 143 of specctra spec:
(connect
{(terminal <object_type> [<pin_reference> ])}
)
*/
T tok = NextTok();
while( tok != T_RIGHT )
{
if( tok!=T_LEFT )
Expecting( T_LEFT );
tok = NextTok();
switch( tok )
{
case T_terminal:
// since we do not use the terminal information, simlpy toss it.
while( ( tok = NextTok() ) != T_RIGHT && tok != T_EOF )
;
break;
default:
Unexpected( CurText() );
}
tok = NextTok();
}
}
void SPECCTRA_DB::doWINDOW( WINDOW* growth ) throw( IO_ERROR )
2008-01-06 01:24:36 +00:00
{
T tok = NextTok();
2008-02-07 20:23:58 +00:00
2008-01-06 01:24:36 +00:00
while( tok != T_RIGHT )
{
if( tok!=T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-06 01:24:36 +00:00
switch( tok )
{
case T_rect:
2008-01-29 16:45:14 +00:00
if( growth->shape )
Unexpected( tok );
2008-01-29 16:45:14 +00:00
growth->shape = new RECTANGLE( growth );
doRECTANGLE( (RECTANGLE*) growth->shape );
2008-01-06 01:24:36 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-06 01:24:36 +00:00
case T_circle:
2008-01-29 16:45:14 +00:00
if( growth->shape )
Unexpected( tok );
2008-01-29 16:45:14 +00:00
growth->shape = new CIRCLE( growth );
doCIRCLE( (CIRCLE*) growth->shape );
2008-01-06 01:24:36 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-02-01 01:09:39 +00:00
case T_polyline_path:
tok = T_path;
2008-01-06 01:24:36 +00:00
case T_path:
case T_polygon:
2008-01-29 16:45:14 +00:00
if( growth->shape )
Unexpected( tok );
2008-01-29 16:45:14 +00:00
growth->shape = new PATH( growth, tok );
doPATH( (PATH*) growth->shape );
2008-01-06 01:24:36 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-06 01:24:36 +00:00
case T_qarc:
2008-01-29 16:45:14 +00:00
if( growth->shape )
Unexpected( tok );
2008-01-29 16:45:14 +00:00
growth->shape = new QARC( growth );
doQARC( (QARC*) growth->shape );
2008-01-05 17:24:56 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-03 06:33:28 +00:00
default:
Unexpected( CurText() );
2008-01-03 06:33:28 +00:00
}
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-03 06:33:28 +00:00
}
}
void SPECCTRA_DB::doBOUNDARY( BOUNDARY* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-03 06:33:28 +00:00
{
T tok = NextTok();
2008-02-07 20:23:58 +00:00
2008-01-03 06:33:28 +00:00
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-03 06:33:28 +00:00
if( tok == T_rect )
{
2008-01-05 17:24:56 +00:00
if( growth->paths.size() )
Unexpected( "rect when path already encountered" );
2008-02-07 20:23:58 +00:00
2008-01-03 06:33:28 +00:00
growth->rectangle = new RECTANGLE( growth );
doRECTANGLE( growth->rectangle );
NeedRIGHT();
2008-01-03 06:33:28 +00:00
}
else if( tok == T_path )
{
2008-01-05 17:24:56 +00:00
if( growth->rectangle )
Unexpected( "path when rect already encountered" );
2008-01-05 17:24:56 +00:00
2008-01-03 06:33:28 +00:00
for(;;)
{
if( tok != T_path )
Expecting( T_path );
2008-02-07 20:23:58 +00:00
2008-01-05 17:24:56 +00:00
PATH* path = new PATH( growth, T_path ) ;
2008-01-03 06:33:28 +00:00
growth->paths.push_back( path );
2008-02-07 20:23:58 +00:00
2008-01-03 06:33:28 +00:00
doPATH( path );
tok = NextTok();
2008-01-03 06:33:28 +00:00
if( tok == T_RIGHT )
break;
if( tok != T_LEFT )
Expecting(T_LEFT);
2008-01-03 06:33:28 +00:00
tok = NextTok();
2008-01-03 06:33:28 +00:00
}
}
else
Expecting( "rect|path" );
2008-01-03 06:33:28 +00:00
}
2008-01-05 17:24:56 +00:00
void SPECCTRA_DB::doPATH( PATH* growth ) throw( IO_ERROR )
2008-01-03 06:33:28 +00:00
{
T tok = NextTok();
2008-01-03 06:33:28 +00:00
if( !IsSymbol( tok ) )
Expecting( "layer_id" );
2008-02-07 20:23:58 +00:00
growth->layer_id = CurText();
2008-01-03 06:33:28 +00:00
if( NextTok() != T_NUMBER )
Expecting( "aperture_width" );
2008-02-07 20:23:58 +00:00
growth->aperture_width = strtod( CurText(), NULL );
2008-01-03 06:33:28 +00:00
POINT ptTemp;
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-02-07 20:23:58 +00:00
2008-01-03 06:33:28 +00:00
do
{
if( tok != T_NUMBER )
Expecting( T_NUMBER );
ptTemp.x = strtod( CurText(), NULL );
2008-02-07 20:23:58 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
ptTemp.y = strtod( CurText(), NULL );
2008-02-07 20:23:58 +00:00
2008-01-03 06:33:28 +00:00
growth->points.push_back( ptTemp );
2008-02-07 20:23:58 +00:00
} while( (tok = NextTok())!=T_RIGHT && tok!=T_LEFT );
2008-02-07 20:23:58 +00:00
2008-01-03 06:33:28 +00:00
if( tok == T_LEFT )
{
if( NextTok() != T_aperture_type )
Expecting( T_aperture_type );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-03 06:33:28 +00:00
if( tok!=T_round && tok!=T_square )
Expecting( "round|square" );
2008-01-03 06:33:28 +00:00
growth->aperture_type = tok;
2008-02-07 20:23:58 +00:00
NeedRIGHT();
2008-01-03 06:33:28 +00:00
}
}
void SPECCTRA_DB::doRECTANGLE( RECTANGLE* growth ) throw( IO_ERROR )
2008-01-03 06:33:28 +00:00
{
NeedSYMBOL();
growth->layer_id = CurText();
2008-02-07 20:23:58 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->point0.x = strtod( CurText(), NULL );
2008-01-03 06:33:28 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->point0.y = strtod( CurText(), NULL );
2008-01-03 06:33:28 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->point1.x = strtod( CurText(), NULL );
2008-01-03 06:33:28 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->point1.y = strtod( CurText(), NULL );
2008-01-03 06:33:28 +00:00
NeedRIGHT();
2008-01-03 06:33:28 +00:00
}
2008-01-02 18:18:37 +00:00
2008-01-03 15:53:45 +00:00
void SPECCTRA_DB::doCIRCLE( CIRCLE* growth ) throw( IO_ERROR )
2008-01-06 01:24:36 +00:00
{
T tok;
2008-02-07 20:23:58 +00:00
NeedSYMBOL();
growth->layer_id = CurText();
2008-02-07 20:23:58 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->diameter = strtod( CurText(), 0 );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-06 01:24:36 +00:00
if( tok == T_NUMBER )
{
growth->vertex.x = strtod( CurText(), 0 );
2008-02-07 20:23:58 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->vertex.y = strtod( CurText(), 0 );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-06 01:24:36 +00:00
}
2008-01-17 22:51:09 +00:00
2008-01-06 01:24:36 +00:00
if( tok != T_RIGHT )
Expecting( T_RIGHT );
2008-01-06 01:24:36 +00:00
}
void SPECCTRA_DB::doQARC( QARC* growth ) throw( IO_ERROR )
2008-01-06 01:24:36 +00:00
{
NeedSYMBOL();
growth->layer_id = CurText();
2008-02-07 20:23:58 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->aperture_width = strtod( CurText(), 0 );
2008-02-07 20:23:58 +00:00
2008-01-06 01:24:36 +00:00
for( int i=0; i<3; ++i )
{
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->vertex[i].x = strtod( CurText(), 0 );
2008-02-07 20:23:58 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->vertex[i].y = strtod( CurText(), 0 );
2008-01-06 01:24:36 +00:00
}
2008-01-17 22:51:09 +00:00
NeedRIGHT();
2008-01-06 01:24:36 +00:00
}
void SPECCTRA_DB::doSTRINGPROP( STRINGPROP* growth ) throw( IO_ERROR )
2008-01-03 15:53:45 +00:00
{
NeedSYMBOL();
growth->value = CurText();
NeedRIGHT();
2008-01-03 15:53:45 +00:00
}
void SPECCTRA_DB::doTOKPROP( TOKPROP* growth ) throw( IO_ERROR )
2008-01-03 15:53:45 +00:00
{
T tok = NextTok();
2008-02-07 20:23:58 +00:00
2008-01-03 22:24:17 +00:00
if( tok<0 )
Unexpected( CurText() );
2008-01-03 15:53:45 +00:00
2008-01-03 22:24:17 +00:00
growth->value = tok;
2008-01-17 22:51:09 +00:00
NeedRIGHT();
2008-01-03 15:53:45 +00:00
}
void SPECCTRA_DB::doVIA( VIA* growth ) throw( IO_ERROR )
2008-01-03 15:53:45 +00:00
{
T tok;
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-03 15:53:45 +00:00
{
if( tok == T_LEFT )
{
if( NextTok() != T_spare )
Expecting( T_spare );
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-03 15:53:45 +00:00
{
if( !IsSymbol( tok ) )
Expecting( T_SYMBOL );
2008-02-07 20:23:58 +00:00
growth->spares.push_back( CurText() );
2008-01-03 15:53:45 +00:00
}
}
else if( IsSymbol( tok ) )
2008-01-03 15:53:45 +00:00
{
growth->padstacks.push_back( CurText() );
2008-01-03 15:53:45 +00:00
}
else
Unexpected( CurText() );
2008-01-03 15:53:45 +00:00
}
}
void SPECCTRA_DB::doCONTROL( CONTROL* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-03 15:53:45 +00:00
{
T tok;
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-03 15:53:45 +00:00
{
2008-01-03 22:24:17 +00:00
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-01-03 22:24:17 +00:00
tok = NextTok();
2008-01-03 22:24:17 +00:00
switch( tok )
{
case T_via_at_smd:
tok = NextTok();
2008-01-03 22:24:17 +00:00
if( tok!=T_on && tok!=T_off )
Expecting( "on|off" );
2008-01-03 22:24:17 +00:00
growth->via_at_smd = (tok==T_on);
NeedRIGHT();
2008-01-03 22:24:17 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-03 22:24:17 +00:00
case T_off_grid:
case T_route_to_fanout_only:
case T_force_to_terminal_point:
case T_same_net_checking:
case T_checking_trim_by_pin:
case T_noise_calculation:
case T_noise_accumulation:
case T_include_pins_in_crosstalk:
case T_bbv_ctr2ctr:
case T_average_pair_length:
case T_crosstalk_model:
case T_roundoff_rotation:
case T_microvia:
case T_reroute_order_viols:
TOKPROP* tokprop;
tokprop = new TOKPROP( growth, tok ) ;
growth->Append( tokprop );
doTOKPROP( tokprop );
break;
2008-02-07 20:23:58 +00:00
2008-01-03 22:24:17 +00:00
default:
Unexpected( CurText() );
2008-01-03 22:24:17 +00:00
}
}
}
void SPECCTRA_DB::doPROPERTIES( PROPERTIES* growth ) throw( IO_ERROR )
2008-01-15 23:12:38 +00:00
{
T tok;
2008-01-15 23:12:38 +00:00
PROPERTY property; // construct it once here, append multiple times.
while( (tok = NextTok()) != T_RIGHT )
2008-01-15 23:12:38 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
NeedSYMBOLorNUMBER();
property.name = CurText();
2008-01-17 22:51:09 +00:00
NeedSYMBOLorNUMBER();
property.value = CurText();
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
growth->push_back( property );
2008-01-17 22:51:09 +00:00
NeedRIGHT();
2008-01-15 23:12:38 +00:00
}
}
void SPECCTRA_DB::doLAYER( LAYER* growth ) throw( IO_ERROR )
2008-01-03 22:24:17 +00:00
{
T tok = NextTok();
2008-02-07 20:23:58 +00:00
if( !IsSymbol(tok) )
Expecting(T_SYMBOL);
2008-01-03 22:24:17 +00:00
growth->name = CurText();
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-03 22:24:17 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-01-03 22:24:17 +00:00
tok = NextTok();
2008-01-03 22:24:17 +00:00
switch( tok )
2008-01-03 15:53:45 +00:00
{
2008-01-03 22:24:17 +00:00
case T_type:
tok = NextTok();
2008-01-03 22:24:17 +00:00
if( tok!=T_signal && tok!=T_power && tok!=T_mixed && tok!=T_jumper )
Expecting( "signal|power|mixed|jumper" );
2008-01-03 22:24:17 +00:00
growth->layer_type = tok;
if( NextTok()!=T_RIGHT )
Expecting(T_RIGHT);
2008-01-03 22:24:17 +00:00
break;
case T_rule:
2008-01-14 22:50:08 +00:00
growth->rules = new RULE( growth, T_rule );
doRULE( growth->rules );
2008-01-03 22:24:17 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-03 22:24:17 +00:00
case T_property:
2008-01-15 23:12:38 +00:00
doPROPERTIES( &growth->properties );
2008-01-03 22:24:17 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-03 22:24:17 +00:00
case T_direction:
tok = NextTok();
2008-01-03 15:53:45 +00:00
switch( tok )
{
2008-01-03 22:24:17 +00:00
case T_horizontal:
case T_vertical:
case T_orthogonal:
case T_positive_diagonal:
case T_negative_diagonal:
case T_diagonal:
case T_off:
growth->direction = tok;
2008-01-03 15:53:45 +00:00
break;
default:
2008-01-23 22:38:16 +00:00
// the spec has an example show an abbreviation of the "horizontal" keyword. Ouch.
if( !strcmp( "hori", CurText() ) )
2008-01-23 22:38:16 +00:00
{
growth->direction = T_horizontal;
break;
}
else if( !strcmp( "vert", CurText() ) )
2008-01-23 22:38:16 +00:00
{
growth->direction = T_vertical;
break;
}
Expecting( "horizontal|vertical|orthogonal|positive_diagonal|negative_diagonal|diagonal|off" );
2008-01-03 15:53:45 +00:00
}
if( NextTok()!=T_RIGHT )
Expecting(T_RIGHT);
2008-01-03 22:24:17 +00:00
break;
case T_cost:
tok = NextTok();
2008-01-03 22:24:17 +00:00
switch( tok )
{
case T_forbidden:
case T_high:
case T_medium:
case T_low:
case T_free:
growth->cost = tok;
break;
case T_NUMBER:
2008-02-07 20:23:58 +00:00
// store as negative so we can differentiate between
// T (positive) and T_NUMBER (negative)
growth->cost = -atoi( CurText() );
2008-01-03 22:24:17 +00:00
break;
default:
Expecting( "forbidden|high|medium|low|free|<positive_integer>|-1" );
2008-01-03 22:24:17 +00:00
}
tok = NextTok();
2008-01-03 22:24:17 +00:00
if( tok == T_LEFT )
{
if( NextTok() != T_type )
Unexpected( CurText() );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-03 22:24:17 +00:00
if( tok!=T_length && tok!=T_way )
Expecting( "length|way" );
2008-02-07 20:23:58 +00:00
2008-01-03 22:24:17 +00:00
growth->cost_type = tok;
if( NextTok()!=T_RIGHT )
Expecting(T_RIGHT);
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-03 22:24:17 +00:00
}
if( tok!=T_RIGHT )
Expecting(T_RIGHT);
2008-01-03 22:24:17 +00:00
break;
case T_use_net:
while( (tok = NextTok()) != T_RIGHT )
2008-01-03 22:24:17 +00:00
{
if( !IsSymbol(tok) )
Expecting( T_SYMBOL );
2008-02-07 20:23:58 +00:00
growth->use_net.push_back( CurText() );
2008-01-03 22:24:17 +00:00
}
break;
2008-02-07 20:23:58 +00:00
2008-01-03 22:24:17 +00:00
default:
Unexpected( CurText() );
2008-01-03 15:53:45 +00:00
}
}
}
void SPECCTRA_DB::doRULE( RULE* growth ) throw( IO_ERROR )
2008-01-04 08:28:16 +00:00
{
std::string builder;
int bracketNesting = 1; // we already saw the opening T_LEFT
T tok = T_NONE;
2008-01-04 08:28:16 +00:00
2008-01-05 17:24:56 +00:00
while( bracketNesting!=0 && tok!=T_EOF )
2008-01-04 08:28:16 +00:00
{
tok = NextTok();
2008-02-07 20:23:58 +00:00
2008-01-05 17:24:56 +00:00
if( tok==T_LEFT)
++bracketNesting;
2008-02-07 20:23:58 +00:00
2008-01-05 17:24:56 +00:00
else if( tok==T_RIGHT )
--bracketNesting;
2008-01-04 08:28:16 +00:00
if( bracketNesting >= 1 )
{
if( PrevTok()!=T_LEFT && tok!=T_RIGHT && (tok!=T_LEFT || bracketNesting>2) )
2008-01-04 08:28:16 +00:00
builder += ' ';
2008-01-05 17:24:56 +00:00
if( tok==T_STRING )
builder += quote_char;
2008-02-07 20:23:58 +00:00
builder += CurText();
2008-02-07 20:23:58 +00:00
2008-01-05 17:24:56 +00:00
if( tok==T_STRING )
builder += quote_char;
2008-01-04 08:28:16 +00:00
}
2008-01-05 17:24:56 +00:00
2008-01-14 22:50:08 +00:00
// When the nested rule is closed with a T_RIGHT and we are back down
2008-01-05 17:24:56 +00:00
// to bracketNesting == 1, (inside the <rule_descriptor> but outside
2008-01-14 22:50:08 +00:00
// the last rule). Then save the last rule and clear the string builder.
2008-01-04 08:28:16 +00:00
if( bracketNesting == 1 )
{
growth->rules.push_back( builder );
builder.clear();
}
}
2008-02-07 20:23:58 +00:00
2008-01-05 17:24:56 +00:00
if( tok==T_EOF )
Unexpected( T_EOF );
2008-01-04 08:28:16 +00:00
}
2008-01-07 07:43:23 +00:00
2008-01-14 22:50:08 +00:00
#if 0
void SPECCTRA_DB::doPLACE_RULE( PLACE_RULE* growth, bool expect_object_type ) throw( IO_ERROR )
2008-01-14 22:50:08 +00:00
{
/* (place_rule [<structure_place_rule_object> ]
{[<spacing_descriptor> |
<permit_orient_descriptor> |
<permit_side_descriptor> |
<opposite_side_descriptor> ]}
)
*/
2008-02-07 20:23:58 +00:00
T tok = NextTok();
2008-02-07 20:23:58 +00:00
2008-01-14 22:50:08 +00:00
if( tok!=T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-14 22:50:08 +00:00
if( tok==T_object_type )
{
if( !expect_object_type )
Unexpected( tok );
2008-02-07 20:23:58 +00:00
2008-01-14 22:50:08 +00:00
/* [(object_type
[pcb |
image_set [large | small | discrete | capacitor | resistor]
[(image_type [smd | pin])]]
)]
*/
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-14 22:50:08 +00:00
switch( tok )
{
case T_pcb:
growth->object_type = tok;
break;
2008-02-07 20:23:58 +00:00
2008-01-14 22:50:08 +00:00
case T_image_set:
tok = NextTok();
2008-01-14 22:50:08 +00:00
switch( tok )
{
case T_large:
case T_small:
case T_discrete:
case T_capacitor:
case T_resistor:
growth->object_type = tok;
break;
default:
Unexpected( CurText() );
2008-01-14 22:50:08 +00:00
}
break;
2008-02-07 20:23:58 +00:00
2008-01-14 22:50:08 +00:00
default:
Unexpected( CurText() );
2008-01-14 22:50:08 +00:00
}
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-14 22:50:08 +00:00
if( tok == T_LEFT )
{
tok = NextTok();
2008-01-14 22:50:08 +00:00
if( tok != T_image_type )
Expecting( T_image_type );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-14 22:50:08 +00:00
if( tok!=T_smd && tok!=T_pin )
Expecting( "smd|pin" );
2008-02-07 20:23:58 +00:00
NeedRIGHT();
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-14 22:50:08 +00:00
}
2008-02-07 20:23:58 +00:00
2008-01-14 22:50:08 +00:00
if( tok != T_RIGHT )
Expecting( T_RIGHT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-14 22:50:08 +00:00
}
2008-02-07 20:23:58 +00:00
/* {[<spacing_descriptor> |
<permit_orient_descriptor> |
2008-01-14 22:50:08 +00:00
<permit_side_descriptor> | <opposite_side_descriptor> ]}
*/
doRULE( growth );
}
#endif
void SPECCTRA_DB::doREGION( REGION* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-07 07:43:23 +00:00
{
T tok = NextTok();
2008-02-07 20:23:58 +00:00
if( IsSymbol(tok) )
2008-01-07 07:43:23 +00:00
{
growth->region_id = CurText();
tok = NextTok();
2008-01-07 07:43:23 +00:00
}
2008-01-11 20:25:52 +00:00
for(;;)
2008-01-07 07:43:23 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-01-07 07:43:23 +00:00
tok = NextTok();
2008-01-07 07:43:23 +00:00
switch( tok )
{
case T_rect:
2008-01-23 22:38:16 +00:00
if( growth->rectangle )
Unexpected( tok );
2008-01-07 07:43:23 +00:00
growth->rectangle = new RECTANGLE( growth );
doRECTANGLE( growth->rectangle );
break;
2008-02-07 20:23:58 +00:00
2008-01-07 07:43:23 +00:00
case T_polygon:
2008-01-23 22:38:16 +00:00
if( growth->polygon )
Unexpected( tok );
2008-01-07 07:43:23 +00:00
growth->polygon = new PATH( growth, T_polygon );
doPATH( growth->polygon );
break;
2008-02-07 20:23:58 +00:00
2008-01-07 07:43:23 +00:00
case T_region_net:
case T_region_class:
2008-01-11 20:25:52 +00:00
STRINGPROP* stringprop;
stringprop = new STRINGPROP( growth, tok );
growth->Append( stringprop );
doSTRINGPROP( stringprop );
2008-02-07 20:23:58 +00:00
break;
2008-01-07 07:43:23 +00:00
2008-01-11 20:25:52 +00:00
case T_region_class_class:
CLASS_CLASS* class_class;
class_class = new CLASS_CLASS( growth, tok );
growth->Append( class_class );
2008-02-07 20:23:58 +00:00
doCLASS_CLASS( class_class );
2008-01-07 07:43:23 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-07 07:43:23 +00:00
case T_rule:
2008-01-23 22:38:16 +00:00
if( growth->rules )
Unexpected( tok );
2008-01-14 22:50:08 +00:00
growth->rules = new RULE( growth, T_rule );
doRULE( growth->rules );
2008-01-07 07:43:23 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-07 07:43:23 +00:00
default:
Unexpected( CurText() );
2008-01-07 07:43:23 +00:00
}
2008-01-11 20:25:52 +00:00
tok = NextTok();
2008-01-11 20:25:52 +00:00
if( tok == T_RIGHT )
{
if( !growth->rules )
Expecting( T_rule );
2008-01-11 20:25:52 +00:00
break;
}
}
}
void SPECCTRA_DB::doCLASS_CLASS( CLASS_CLASS* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-11 20:25:52 +00:00
{
T tok = NextTok();
2008-02-07 20:23:58 +00:00
2008-01-11 20:25:52 +00:00
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-11 20:25:52 +00:00
{
switch( tok )
{
case T_classes:
if( growth->classes )
Unexpected( tok );
2008-01-11 20:25:52 +00:00
growth->classes = new CLASSES( growth );
doCLASSES( growth->classes );
break;
2008-02-07 20:23:58 +00:00
2008-01-11 20:25:52 +00:00
case T_rule:
2008-01-14 22:50:08 +00:00
// only T_class_class takes a T_rule
2008-01-11 20:25:52 +00:00
if( growth->Type() == T_region_class_class )
Unexpected( tok );
2008-01-14 22:50:08 +00:00
RULE* rule;
rule = new RULE( growth, T_rule );
2008-01-11 20:25:52 +00:00
growth->Append( rule );
2008-01-14 22:50:08 +00:00
doRULE( rule );
2008-01-11 20:25:52 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-11 20:25:52 +00:00
case T_layer_rule:
2008-01-14 22:50:08 +00:00
// only T_class_class takes a T_layer_rule
2008-01-11 20:25:52 +00:00
if( growth->Type() == T_region_class_class )
Unexpected( tok );
2008-01-14 22:50:08 +00:00
LAYER_RULE* layer_rule;
layer_rule = new LAYER_RULE( growth );
2008-01-11 20:25:52 +00:00
growth->Append( layer_rule );
2008-01-14 22:50:08 +00:00
doLAYER_RULE( layer_rule );
2008-01-11 20:25:52 +00:00
break;
2008-02-07 20:23:58 +00:00
default:
Unexpected( tok );
2008-01-11 20:25:52 +00:00
}
}
}
void SPECCTRA_DB::doCLASSES( CLASSES* growth ) throw( IO_ERROR )
2008-01-11 20:25:52 +00:00
{
T tok = NextTok();
2008-01-11 20:25:52 +00:00
// require at least 2 class_ids
2008-02-07 20:23:58 +00:00
if( !IsSymbol( tok ) )
Expecting( "class_id" );
2008-02-07 20:23:58 +00:00
growth->class_ids.push_back( CurText() );
2008-02-07 20:23:58 +00:00
2008-01-11 20:25:52 +00:00
do
{
tok = NextTok();
if( !IsSymbol( tok ) )
Expecting( "class_id" );
2008-02-07 20:23:58 +00:00
growth->class_ids.push_back( CurText() );
2008-02-07 20:23:58 +00:00
} while( (tok = NextTok()) != T_RIGHT );
2008-01-11 20:25:52 +00:00
}
void SPECCTRA_DB::doGRID( GRID* growth ) throw( IO_ERROR )
2008-01-11 20:25:52 +00:00
{
T tok = NextTok();
2008-02-07 20:23:58 +00:00
2008-01-11 20:25:52 +00:00
switch( tok )
{
case T_via:
case T_wire:
case T_via_keepout:
case T_snap:
case T_place:
growth->grid_type = tok;
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->dimension = strtod( CurText(), 0 );
tok = NextTok();
2008-01-11 20:25:52 +00:00
if( tok == T_LEFT )
{
while( (tok=NextTok()) != T_RIGHT )
2008-01-11 20:25:52 +00:00
{
if( tok==T_direction )
{
if( growth->grid_type == T_place )
Unexpected( tok );
tok = NextTok();
2008-01-11 20:25:52 +00:00
if( tok!=T_x && tok!=T_y )
Unexpected( CurText() );
2008-01-11 20:25:52 +00:00
growth->direction = tok;
if( NextTok() != T_RIGHT )
Expecting(T_RIGHT);
2008-01-11 20:25:52 +00:00
}
else if( tok==T_offset )
{
if( growth->grid_type == T_place )
Unexpected( tok );
2008-02-07 20:23:58 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
2008-02-07 20:23:58 +00:00
growth->offset = strtod( CurText(), 0 );
2008-02-07 20:23:58 +00:00
if( NextTok() != T_RIGHT )
Expecting(T_RIGHT);
2008-01-11 20:25:52 +00:00
}
else if( tok==T_image_type )
{
if( growth->grid_type != T_place )
Unexpected( tok );
tok = NextTok();
2008-01-11 20:25:52 +00:00
if( tok!=T_smd && tok!=T_pin )
Unexpected( CurText() );
2008-01-11 20:25:52 +00:00
growth->image_type = tok;
if( NextTok() != T_RIGHT )
Expecting(T_RIGHT);
2008-01-11 20:25:52 +00:00
}
}
}
break;
default:
Unexpected( tok );
2008-01-11 20:25:52 +00:00
}
2008-01-07 07:43:23 +00:00
}
void SPECCTRA_DB::doLAYER_RULE( LAYER_RULE* growth ) throw( IO_ERROR )
2008-01-14 22:50:08 +00:00
{
T tok;
2008-02-07 20:23:58 +00:00
NeedSYMBOL();
2008-02-07 20:23:58 +00:00
2008-01-14 22:50:08 +00:00
do
{
growth->layer_ids.push_back( CurText() );
2008-02-07 20:23:58 +00:00
} while( IsSymbol(tok = NextTok()) );
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
if( NextTok() != T_rule )
Expecting( T_rule );
2008-02-07 20:23:58 +00:00
2008-01-14 22:50:08 +00:00
growth->rule = new RULE( growth, T_rule );
doRULE( growth->rule );
2008-02-07 20:23:58 +00:00
NeedRIGHT();
2008-01-14 22:50:08 +00:00
}
2015-02-21 00:41:10 +00:00
void SPECCTRA_DB::doPLACE( PLACE* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-15 23:12:38 +00:00
{
T tok = NextTok();
2008-02-07 20:23:58 +00:00
if( !IsSymbol( tok ) )
Expecting( "component_id" );
2008-02-07 20:23:58 +00:00
growth->component_id = CurText();
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-15 23:12:38 +00:00
if( tok == T_NUMBER )
{
POINT point;
2008-02-07 20:23:58 +00:00
point.x = strtod( CurText(), 0 );
2008-02-07 20:23:58 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
point.y = strtod( CurText(), 0 );
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
growth->SetVertex( point );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-15 23:12:38 +00:00
if( tok!=T_front && tok!=T_back )
Expecting( "front|back" );
2008-01-15 23:12:38 +00:00
growth->side = tok;
2008-02-07 20:23:58 +00:00
if( NextTok() != T_NUMBER )
Expecting( "rotation" );
growth->SetRotation( strtod( CurText(), 0) );
2008-01-15 23:12:38 +00:00
}
while( (tok = NextTok()) != T_RIGHT )
2008-01-15 23:12:38 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-15 23:12:38 +00:00
switch( tok )
{
case T_mirror:
tok = NextTok();
2008-01-15 23:12:38 +00:00
if( tok==T_x || tok==T_y || tok==T_xy || tok==T_off )
growth->mirror = tok;
else
Expecting("x|y|xy|off");
2008-01-15 23:12:38 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
case T_status:
tok = NextTok();
2008-01-15 23:12:38 +00:00
if( tok==T_added || tok==T_deleted || tok==T_substituted )
growth->status = tok;
else
Expecting("added|deleted|substituted");
2008-01-15 23:12:38 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
case T_logical_part:
if( growth->logical_part.size() )
Unexpected( tok );
tok = NextTok();
if( !IsSymbol( tok ) )
Expecting( "logical_part_id");
growth->logical_part = CurText();
2008-01-15 23:12:38 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
case T_place_rule:
if( growth->place_rules )
Unexpected( tok );
2008-01-15 23:12:38 +00:00
growth->place_rules = new RULE( growth, T_place_rule );
doRULE( growth->place_rules );
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
case T_property:
if( growth->properties.size() )
Unexpected( tok );
2008-01-15 23:12:38 +00:00
doPROPERTIES( &growth->properties );
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
case T_lock_type:
tok = NextTok();
2008-01-15 23:12:38 +00:00
if( tok==T_position || tok==T_gate || tok==T_subgate || tok==T_pin )
growth->lock_type = tok;
else
Expecting("position|gate|subgate|pin");
2008-01-15 23:12:38 +00:00
break;
case T_rule:
if( growth->rules || growth->region )
Unexpected( tok );
2008-01-15 23:12:38 +00:00
growth->rules = new RULE( growth, T_rule );
doRULE( growth->rules );
break;
case T_region:
if( growth->rules || growth->region )
Unexpected( tok );
2008-01-15 23:12:38 +00:00
growth->region = new REGION( growth );
doREGION( growth->region );
break;
case T_pn:
if( growth->part_number.size() )
Unexpected( tok );
NeedSYMBOLorNUMBER();
growth->part_number = CurText();
NeedRIGHT();
2008-01-15 23:12:38 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
default:
Unexpected( tok );
2008-01-15 23:12:38 +00:00
}
}
}
void SPECCTRA_DB::doCOMPONENT( COMPONENT* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-15 23:12:38 +00:00
{
T tok = NextTok();
2008-02-07 20:23:58 +00:00
if( !IsSymbol( tok ) && tok != T_NUMBER )
Expecting( "image_id" );
growth->image_id = CurText();
2008-01-15 23:12:38 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-15 23:12:38 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-15 23:12:38 +00:00
switch( tok )
{
case T_place:
PLACE* place;
place = new PLACE( growth );
growth->places.push_back( place );
doPLACE( place );
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
default:
Unexpected(tok);
2008-01-15 23:12:38 +00:00
}
}
}
void SPECCTRA_DB::doPLACEMENT( PLACEMENT* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-15 23:12:38 +00:00
{
T tok;
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-15 23:12:38 +00:00
{
if( tok == T_EOF )
Unexpected( T_EOF );
2008-02-07 20:23:58 +00:00
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-02-07 20:23:58 +00:00
switch( tok )
{
case T_unit:
case T_resolution:
growth->unit = new UNIT_RES( growth, tok );
if( tok==T_resolution )
doRESOLUTION( growth->unit );
else
doUNIT( growth->unit );
break;
2008-01-15 23:12:38 +00:00
case T_place_control:
NeedRIGHT();
tok = NextTok();
if( tok != T_flip_style )
Expecting( T_flip_style );
2008-01-15 23:12:38 +00:00
tok = NextTok();
if( tok==T_mirror_first || tok==T_rotate_first )
growth->flip_style = tok;
else
Expecting( "mirror_first|rotate_first" );
2008-02-07 20:23:58 +00:00
NeedRIGHT();
NeedRIGHT();
break;
2008-01-15 23:12:38 +00:00
case T_component:
COMPONENT* component;
component = new COMPONENT( growth );
growth->components.push_back( component );
doCOMPONENT( component );
break;
2008-02-07 20:23:58 +00:00
default:
Unexpected( tok );
}
}
2008-01-15 23:12:38 +00:00
}
void SPECCTRA_DB::doPADSTACK( PADSTACK* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-15 23:12:38 +00:00
{
T tok = NextTok();
2008-01-16 23:08:22 +00:00
/* (padstack <padstack_id >
[<unit_descriptor> ]
{(shape <shape_descriptor>
[<reduced_shape_descriptor> ]
[(connect [on | off])]
[{<window_descriptor> }]
)}
[<attach_descriptor> ]
[{<pad_via_site_descriptor> }]
[(rotate [on | off])]
[(absolute [on | off])]
[(rule <clearance_descriptor> )])
*/
2008-02-07 20:23:58 +00:00
2008-01-23 22:38:16 +00:00
// padstack_id may be a number
if( !IsSymbol( tok ) && tok!=T_NUMBER )
Expecting( "padstack_id" );
2008-02-07 20:23:58 +00:00
growth->padstack_id = CurText();
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-15 23:12:38 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-15 23:12:38 +00:00
switch( tok )
{
case T_unit:
if( growth->unit )
Unexpected( tok );
2008-01-15 23:12:38 +00:00
growth->unit = new UNIT_RES( growth, tok );
doUNIT( growth->unit );
break;
case T_rotate:
tok = NextTok();
2008-01-15 23:12:38 +00:00
if( tok!=T_on && tok!=T_off )
Expecting( "on|off" );
2008-01-15 23:12:38 +00:00
growth->rotate = tok;
NeedRIGHT();
2008-01-15 23:12:38 +00:00
break;
case T_absolute:
tok = NextTok();
2008-01-15 23:12:38 +00:00
if( tok!=T_on && tok!=T_off )
Expecting( "on|off" );
2008-01-15 23:12:38 +00:00
growth->absolute = tok;
NeedRIGHT();
2008-01-15 23:12:38 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
case T_shape:
SHAPE* shape;
shape = new SHAPE( growth );
growth->Append( shape );
doSHAPE( shape );
break;
2008-01-16 23:08:22 +00:00
case T_attach:
tok = NextTok();
2008-01-16 23:08:22 +00:00
if( tok!=T_off && tok!=T_on )
Expecting( "off|on" );
2008-01-16 23:08:22 +00:00
growth->attach = tok;
tok = NextTok();
2008-01-16 23:08:22 +00:00
if( tok == T_LEFT )
{
if( NextTok() != T_use_via )
Expecting( T_use_via );
2008-02-07 20:23:58 +00:00
NeedSYMBOL();
growth->via_id = CurText();
2008-01-17 22:51:09 +00:00
NeedRIGHT();
NeedRIGHT();
2008-01-16 23:08:22 +00:00
}
break;
2008-02-07 20:23:58 +00:00
2008-01-16 23:08:22 +00:00
/*
case T_via_site: not supported
break;
2008-02-07 20:23:58 +00:00
*/
2008-01-16 23:08:22 +00:00
case T_rule:
if( growth->rules )
Unexpected( tok );
2008-01-16 23:08:22 +00:00
growth->rules = new RULE( growth, T_rule );
doRULE( growth->rules );
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
default:
Unexpected( CurText() );
2008-01-15 23:12:38 +00:00
}
}
}
void SPECCTRA_DB::doSHAPE( SHAPE* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-15 23:12:38 +00:00
{
T tok;
2008-01-16 23:08:22 +00:00
/* (shape <shape_descriptor>
[<reduced_shape_descriptor> ]
[(connect [on | off])]
[{<window_descriptor> }])
*/
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-15 23:12:38 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-16 23:08:22 +00:00
switch( tok )
{
2008-02-01 01:09:39 +00:00
case T_polyline_path:
tok = T_path;
2008-01-16 23:08:22 +00:00
case T_rect:
case T_circle:
case T_path:
case T_polygon:
case T_qarc:
2008-02-07 20:23:58 +00:00
L_done_that:
2008-01-25 22:03:36 +00:00
if( growth->shape )
Unexpected( tok );
2008-01-23 22:38:16 +00:00
break;
default:
// the example in the spec uses "circ" instead of "circle". Bad!
if( !strcmp( "circ", CurText() ) )
2008-01-23 22:38:16 +00:00
{
tok = T_circle;
goto L_done_that;
}
2008-01-16 23:08:22 +00:00
}
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
switch( tok )
{
case T_rect:
2008-01-25 22:03:36 +00:00
growth->shape = new RECTANGLE( growth );
doRECTANGLE( (RECTANGLE*) growth->shape );
2008-01-15 23:12:38 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
case T_circle:
2008-01-25 22:03:36 +00:00
growth->shape = new CIRCLE( growth );
doCIRCLE( (CIRCLE*)growth->shape );
2008-01-15 23:12:38 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
case T_path:
case T_polygon:
2008-01-25 22:03:36 +00:00
growth->shape = new PATH( growth, tok );
doPATH( (PATH*)growth->shape );
2008-01-15 23:12:38 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
case T_qarc:
2008-01-25 22:03:36 +00:00
growth->shape = new QARC( growth );
doQARC( (QARC*)growth->shape );
2008-01-15 23:12:38 +00:00
break;
case T_connect:
tok = NextTok();
2008-01-15 23:12:38 +00:00
if( tok!=T_on && tok!=T_off )
Expecting( "on|off" );
2008-01-15 23:12:38 +00:00
growth->connect = tok;
NeedRIGHT();
2008-01-15 23:12:38 +00:00
break;
case T_window:
WINDOW* window;
window = new WINDOW( growth );
growth->windows.push_back( window );
doWINDOW( window );
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
default:
Unexpected( CurText() );
2008-01-15 23:12:38 +00:00
}
}
}
void SPECCTRA_DB::doIMAGE( IMAGE* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-16 23:08:22 +00:00
{
T tok = NextTok();
2008-01-16 23:08:22 +00:00
/* <image_descriptor >::=
(image <image_id >
[(side [front | back | both])]
[<unit_descriptor> ]
[<outline_descriptor> ]
{(pin <padstack_id > [(rotate <rotation> )]
[<reference_descriptor> | <pin_array_descriptor> ]
[<user_property_descriptor> ])}
[{<conductor_shape_descriptor> }]
[{<conductor_via_descriptor> }]
[<rule_descriptor> ]
[<place_rule_descriptor> ]
[{<keepout_descriptor> }]
[<image_property_descriptor> ]
)
*/
if( !IsSymbol( tok ) && tok != T_NUMBER )
Expecting( "image_id" );
2008-02-07 20:23:58 +00:00
growth->image_id = CurText();
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-16 23:08:22 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-16 23:08:22 +00:00
switch( tok )
{
case T_unit:
if( growth->unit )
Unexpected( tok );
2008-01-16 23:08:22 +00:00
growth->unit = new UNIT_RES( growth, tok );
doUNIT( growth->unit );
break;
case T_side:
tok = NextTok();
2008-01-16 23:08:22 +00:00
if( tok!=T_front && tok!=T_back && tok!=T_both )
Expecting( "front|back|both" );
2008-01-16 23:08:22 +00:00
growth->side = tok;
NeedRIGHT();
2008-01-16 23:08:22 +00:00
break;
case T_outline:
SHAPE* outline;
outline = new SHAPE( growth, T_outline ); // use SHAPE for T_outline
growth->Append( outline );
doSHAPE( outline );
break;
case T_pin:
PIN* pin;
pin = new PIN( growth );
growth->pins.push_back( pin );
doPIN( pin );
break;
2008-02-07 20:23:58 +00:00
2008-01-16 23:08:22 +00:00
case T_rule:
if( growth->rules )
Unexpected( tok );
2008-01-16 23:08:22 +00:00
growth->rules = new RULE( growth, tok );
doRULE( growth->rules );
break;
case T_place_rule:
if( growth->place_rules )
Unexpected( tok );
2008-01-16 23:08:22 +00:00
growth->place_rules = new RULE( growth, tok );
doRULE( growth->place_rules );
break;
2008-01-23 22:38:16 +00:00
case T_keepout:
case T_place_keepout:
case T_via_keepout:
case T_wire_keepout:
case T_bend_keepout:
case T_elongate_keepout:
KEEPOUT* keepout;
keepout = new KEEPOUT( growth, tok );
growth->keepouts.push_back( keepout );
doKEEPOUT( keepout );
break;
2008-02-07 20:23:58 +00:00
2008-01-16 23:08:22 +00:00
default:
Unexpected( CurText() );
2008-01-16 23:08:22 +00:00
}
}
}
void SPECCTRA_DB::doPIN( PIN* growth ) throw( IO_ERROR )
2008-01-16 23:08:22 +00:00
{
T tok = NextTok();
2008-01-16 23:08:22 +00:00
/* (pin <padstack_id > [(rotate <rotation> )]
[<reference_descriptor> | <pin_array_descriptor> ]
[<user_property_descriptor> ])
*/
2008-01-23 22:38:16 +00:00
// a padstack_id may be a number
if( !IsSymbol( tok ) && tok!=T_NUMBER )
Expecting( "padstack_id" );
2008-02-07 20:23:58 +00:00
growth->padstack_id = CurText();
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-16 23:08:22 +00:00
{
2008-02-14 01:07:52 +00:00
if( tok == T_LEFT )
{
tok = NextTok();
2008-02-14 01:07:52 +00:00
if( tok != T_rotate )
Expecting( T_rotate );
2008-01-16 23:08:22 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->SetRotation( strtod( CurText(), 0 ) );
NeedRIGHT();
2008-02-14 01:07:52 +00:00
}
else
{
if( !IsSymbol(tok) && tok!=T_NUMBER )
Expecting( "pin_id" );
2008-01-16 23:08:22 +00:00
growth->pin_id = CurText();
2008-02-07 20:23:58 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->vertex.x = strtod( CurText(), 0 );
2008-01-16 23:08:22 +00:00
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->vertex.y = strtod( CurText(), 0 );
2008-02-14 01:07:52 +00:00
}
}
2008-01-16 23:08:22 +00:00
}
void SPECCTRA_DB::doLIBRARY( LIBRARY* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-15 23:12:38 +00:00
{
T tok;
2008-01-16 23:08:22 +00:00
/* <library_descriptor >::=
(library
[<unit_descriptor> ]
{<image_descriptor> }
[{<jumper_descriptor> }]
{<padstack_descriptor> }
{<via_array_template_descriptor> }
[<directory_descriptor> ]
[<extra_image_directory_descriptor> ]
[{<family_family_descriptor> }]
[{<image_image_descriptor> }]
)
*/
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-15 23:12:38 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-15 23:12:38 +00:00
switch( tok )
{
case T_unit:
2008-01-16 23:08:22 +00:00
if( growth->unit )
Unexpected( tok );
2008-01-15 23:12:38 +00:00
growth->unit = new UNIT_RES( growth, tok );
doUNIT( growth->unit );
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
case T_padstack:
PADSTACK* padstack;
2008-02-14 01:07:52 +00:00
padstack = new PADSTACK();
growth->AddPadstack( padstack );
2008-01-15 23:12:38 +00:00
doPADSTACK( padstack );
break;
case T_image:
2008-01-16 23:08:22 +00:00
IMAGE* image;
image = new IMAGE( growth );
growth->images.push_back( image );
doIMAGE( image );
2008-01-15 23:12:38 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
default:
Unexpected( CurText() );
2008-01-15 23:12:38 +00:00
}
2008-01-16 23:08:22 +00:00
}
}
void SPECCTRA_DB::doNET( NET* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-16 23:08:22 +00:00
{
T tok = NextTok();
2008-02-14 01:07:52 +00:00
PIN_REFS* pin_refs;
2008-01-16 23:08:22 +00:00
/* <net_descriptor >::=
(net <net_id >
[(unassigned)]
[(net_number <integer >)]
[(pins {<pin_reference> }) | (order {<pin_reference> })]
[<component_order_descriptor> ]
[(type [fix | normal])]
[<user_property_descriptor> ]
[<circuit_descriptor> ]
[<rule_descriptor> ]
[{<layer_rule_descriptor> }]
[<fromto_descriptor> ]
[(expose {<pin_reference> })]
[(noexpose {<pin_reference> })]
[(source {<pin_reference> })]
[(load {<pin_reference> })]
[(terminator {<pin_reference> })]
[(supply [power | ground])]
)
*/
if( !IsSymbol( tok ) )
Expecting( "net_id" );
2008-02-07 20:23:58 +00:00
growth->net_id = CurText();
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-16 23:08:22 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-16 23:08:22 +00:00
switch( tok )
{
case T_unassigned:
growth->unassigned = true;
NeedRIGHT();
2008-01-16 23:08:22 +00:00
break;
case T_net_number:
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->net_number = atoi( CurText() );
NeedRIGHT();
2008-01-16 23:08:22 +00:00
break;
case T_pins:
case T_order:
growth->pins_type = tok;
2008-02-14 01:07:52 +00:00
pin_refs = &growth->pins;
goto L_pins;
case T_expose:
pin_refs = &growth->expose;
goto L_pins;
case T_noexpose:
pin_refs = &growth->noexpose;
goto L_pins;
case T_source:
pin_refs = &growth->source;
goto L_pins;
case T_load:
pin_refs = &growth->load;
goto L_pins;
case T_terminator:
pin_refs = &growth->terminator;
//goto L_pins;
L_pins:
2008-01-16 23:08:22 +00:00
{
PIN_REF empty( growth );
while( (tok = NextTok()) != T_RIGHT )
2008-01-16 23:08:22 +00:00
{
2008-02-07 20:23:58 +00:00
// copy the empty one, then fill its copy later thru pin_ref.
2008-02-14 01:07:52 +00:00
pin_refs->push_back( empty );
2008-01-18 22:41:16 +00:00
2008-02-14 01:07:52 +00:00
PIN_REF* pin_ref = &pin_refs->back();
2008-01-18 22:41:16 +00:00
readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
2008-01-16 23:08:22 +00:00
}
}
break;
2008-01-18 22:41:16 +00:00
case T_comp_order:
if( growth->comp_order )
Unexpected( tok );
2008-01-18 22:41:16 +00:00
growth->comp_order = new COMP_ORDER( growth );
doCOMP_ORDER( growth->comp_order );
break;
2008-02-07 20:23:58 +00:00
2008-01-23 22:38:16 +00:00
case T_type:
tok = NextTok();
2008-01-23 22:38:16 +00:00
if( tok!=T_fix && tok!=T_normal )
Expecting( "fix|normal" );
2008-01-23 22:38:16 +00:00
growth->type = tok;
NeedRIGHT();
2008-01-23 22:38:16 +00:00
break;
2008-02-07 20:23:58 +00:00
/* @todo
2008-01-23 22:38:16 +00:00
case T_circuit:
break;
*/
case T_rule:
if( growth->rules )
Unexpected( tok );
2008-01-23 22:38:16 +00:00
growth->rules = new RULE( growth, T_rule );
doRULE( growth->rules );
break;
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
case T_layer_rule:
LAYER_RULE* layer_rule;
layer_rule = new LAYER_RULE( growth );
growth->layer_rules.push_back( layer_rule );
doLAYER_RULE( layer_rule );
break;
2008-02-07 20:23:58 +00:00
2008-01-23 22:38:16 +00:00
case T_fromto:
FROMTO* fromto;
fromto = new FROMTO( growth );
growth->fromtos.push_back( fromto );
doFROMTO( fromto );
break;
2008-01-16 23:08:22 +00:00
default:
Unexpected( CurText() );
2008-01-16 23:08:22 +00:00
}
}
}
void SPECCTRA_DB::doTOPOLOGY( TOPOLOGY* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-17 22:51:09 +00:00
{
T tok;
2008-01-17 22:51:09 +00:00
/* <topology_descriptor >::=
(topology {[<fromto_descriptor> |
<component_order_descriptor> ]})
*/
while( (tok = NextTok()) != T_RIGHT )
2008-01-17 22:51:09 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-17 22:51:09 +00:00
switch( tok )
{
case T_fromto:
FROMTO* fromto;
fromto = new FROMTO( growth );
growth->fromtos.push_back( fromto );
2008-01-18 22:41:16 +00:00
doFROMTO( fromto );
2008-01-17 22:51:09 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
case T_comp_order:
COMP_ORDER* comp_order;
comp_order = new COMP_ORDER( growth );
growth->comp_orders.push_back( comp_order );
2008-01-18 22:41:16 +00:00
doCOMP_ORDER( comp_order );
2008-01-17 22:51:09 +00:00
break;
default:
Unexpected( CurText() );
2008-01-17 22:51:09 +00:00
}
}
}
void SPECCTRA_DB::doCLASS( CLASS* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-17 22:51:09 +00:00
{
T tok;
2008-01-17 22:51:09 +00:00
/* <class_descriptor >::=
(class
<class_id > {[{<net_id >} | {<composite_name_list> }]}
[<circuit_descriptor> ]
[<rule_descriptor> ]
[{<layer_rule_descriptor> }]
[<topology_descriptor> ]
)
*/
NeedSYMBOL();
2008-02-07 20:23:58 +00:00
growth->class_id = CurText();
2008-01-17 22:51:09 +00:00
// do net_ids, do not support <composite_name_list>s at this time
while( IsSymbol(tok = NextTok()) )
2008-01-17 22:51:09 +00:00
{
growth->net_ids.push_back( CurText() );
2008-01-17 22:51:09 +00:00
}
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
while( tok != T_RIGHT )
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-17 22:51:09 +00:00
switch( tok )
{
case T_rule:
if( growth->rules )
Unexpected( tok );
2008-01-17 22:51:09 +00:00
growth->rules = new RULE( growth, T_rule );
doRULE( growth->rules );
break;
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
case T_layer_rule:
LAYER_RULE* layer_rule;
layer_rule = new LAYER_RULE( growth );
growth->layer_rules.push_back( layer_rule );
doLAYER_RULE( layer_rule );
break;
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
case T_topology:
if( growth->topology )
Unexpected( tok );
2008-01-17 22:51:09 +00:00
growth->topology = new TOPOLOGY( growth );
doTOPOLOGY( growth->topology );
break;
2008-02-07 20:23:58 +00:00
2008-02-29 06:49:34 +00:00
case T_circuit: // handle all the circuit_descriptor here as strings
2008-01-17 22:51:09 +00:00
{
std::string builder;
int bracketNesting = 1; // we already saw the opening T_LEFT
T tok = T_NONE;
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
while( bracketNesting!=0 && tok!=T_EOF )
{
tok = NextTok();
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
if( tok==T_LEFT)
++bracketNesting;
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
else if( tok==T_RIGHT )
--bracketNesting;
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
if( bracketNesting >= 1 )
{
T prevTok = (T) PrevTok();
if( prevTok!=T_LEFT && prevTok!=T_circuit && tok!=T_RIGHT )
2008-01-17 22:51:09 +00:00
builder += ' ';
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
if( tok==T_STRING )
builder += quote_char;
2008-02-07 20:23:58 +00:00
builder += CurText();
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
if( tok==T_STRING )
builder += quote_char;
}
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
// When the nested rule is closed with a T_RIGHT and we are back down
// to bracketNesting == 0, then save the builder and break;
if( bracketNesting == 0 )
{
growth->circuit.push_back( builder );
break;
2008-01-17 22:51:09 +00:00
}
}
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
if( tok==T_EOF )
Unexpected( T_EOF );
2008-01-17 22:51:09 +00:00
} // scope bracket
2008-02-29 06:49:34 +00:00
break;
default:
Unexpected( CurText() );
2008-01-17 22:51:09 +00:00
} // switch
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
} // while
}
void SPECCTRA_DB::doNETWORK( NETWORK* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-16 23:08:22 +00:00
{
T tok;
2008-01-16 23:08:22 +00:00
/* <network_descriptor >::=
(network
{<net_descriptor>}
[{<class_descriptor> }]
[{<class_class_descriptor> }]
[{<group_descriptor> }]
[{<group_set_descriptor> }]
[{<pair_descriptor> }]
[{<bundle_descriptor> }]
)
*/
while( (tok = NextTok()) != T_RIGHT )
2008-01-16 23:08:22 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-16 23:08:22 +00:00
switch( tok )
{
case T_net:
NET* net;
net = new NET( growth );
growth->nets.push_back( net );
doNET( net );
break;
2008-02-07 20:23:58 +00:00
2008-01-17 22:51:09 +00:00
case T_class:
CLASS* myclass;
myclass = new CLASS( growth );
growth->classes.push_back( myclass );
doCLASS( myclass );
break;
2008-01-16 23:08:22 +00:00
default:
Unexpected( CurText() );
2008-01-16 23:08:22 +00:00
}
2008-01-15 23:12:38 +00:00
}
}
void SPECCTRA_DB::doCOMP_ORDER( COMP_ORDER* growth ) throw( IO_ERROR )
2008-01-18 22:41:16 +00:00
{
T tok;
2008-01-18 22:41:16 +00:00
/* <component_order_descriptor >::=
(comp_order {<placement_id> })
*/
while( IsSymbol(tok = NextTok()) )
2008-01-18 22:41:16 +00:00
{
growth->placement_ids.push_back( CurText() );
2008-01-18 22:41:16 +00:00
}
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
if( tok != T_RIGHT )
Expecting( T_RIGHT );
2008-01-18 22:41:16 +00:00
}
void SPECCTRA_DB::doFROMTO( FROMTO* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-18 22:41:16 +00:00
{
T tok;
2008-01-18 22:41:16 +00:00
/* <fromto_descriptor >::=
{(fromto
[<pin_reference> | <virtual_pin_descriptor> ] | <component_id >]
[<pin_reference> | <virtual_pin_descriptor> | <component_id >]
[(type [fix | normal | soft])]
[(net <net_id >)]
[<rule_descriptor> ]
[<circuit_descriptor> ]
[{<layer_rule_descriptor> }]
)}
*/
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
// read the first two grammar items in as 2 single tokens, i.e. do not
// split apart the <pin_reference>s into 3 separate tokens. Do this by
// turning off the string delimiter in the lexer.
2008-02-07 20:23:58 +00:00
char old = SetStringDelimiter( 0 );
2008-02-07 20:23:58 +00:00
if( !IsSymbol(NextTok() ) )
2008-01-18 22:41:16 +00:00
{
SetStringDelimiter( old );
Expecting( T_SYMBOL );
2008-01-18 22:41:16 +00:00
}
growth->fromText = CurText();
2008-02-07 20:23:58 +00:00
if( !IsSymbol(NextTok() ) )
2008-01-18 22:41:16 +00:00
{
SetStringDelimiter( old );
Expecting( T_SYMBOL );
2008-01-18 22:41:16 +00:00
}
growth->toText = CurText();
2008-01-18 22:41:16 +00:00
SetStringDelimiter( old );
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-18 22:41:16 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-18 22:41:16 +00:00
switch( tok )
{
case T_type:
tok = NextTok();
2008-01-18 22:41:16 +00:00
if( tok!=T_fix && tok!=T_normal && tok!=T_soft )
Expecting( "fix|normal|soft" );
2008-01-18 22:41:16 +00:00
growth->fromto_type = tok;
NeedRIGHT();
2008-01-18 22:41:16 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
case T_rule:
if( growth->rules )
Unexpected( tok );
2008-01-18 22:41:16 +00:00
growth->rules = new RULE( growth, T_rule );
doRULE( growth->rules );
break;
case T_layer_rule:
LAYER_RULE* layer_rule;
layer_rule = new LAYER_RULE( growth );
growth->layer_rules.push_back( layer_rule );
doLAYER_RULE( layer_rule );
break;
case T_net:
if( growth->net_id.size() )
Unexpected( tok );
NeedSYMBOL();
growth->net_id = CurText();
NeedRIGHT();
2008-01-18 22:41:16 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
// circuit descriptor not supported at this time
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
default:
Unexpected( CurText() );
2008-01-18 22:41:16 +00:00
}
}
}
void SPECCTRA_DB::doWIRE( WIRE* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-18 22:41:16 +00:00
{
T tok;
2008-01-18 22:41:16 +00:00
/* <wire_shape_descriptor >::=
(wire
<shape_descriptor>
[(net <net_id >)]
[(turret <turret#> )]
[(type [fix | route | normal | protect])]
[(attr [test | fanout | bus | jumper])]
[(shield <net_id >)]
[{<window_descriptor> }]
[(connect
(terminal <object_type> [<pin_reference> ])
(terminal <object_type> [<pin_reference> ])
)]
[(supply)]
)
*/
while( (tok = NextTok()) != T_RIGHT )
2008-01-18 22:41:16 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-01-18 22:41:16 +00:00
tok = NextTok();
2008-01-18 22:41:16 +00:00
switch( tok )
{
case T_rect:
2008-01-31 01:30:52 +00:00
if( growth->shape )
Unexpected( tok );
2008-01-31 01:30:52 +00:00
growth->shape = new RECTANGLE( growth );
doRECTANGLE( (RECTANGLE*) growth->shape );
2008-01-18 22:41:16 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
case T_circle:
2008-01-31 01:30:52 +00:00
if( growth->shape )
Unexpected( tok );
2008-01-31 01:30:52 +00:00
growth->shape = new CIRCLE( growth );
doCIRCLE( (CIRCLE*) growth->shape );
2008-01-18 22:41:16 +00:00
break;
2008-02-01 01:09:39 +00:00
case T_polyline_path:
tok = T_path;
2008-01-18 22:41:16 +00:00
case T_path:
case T_polygon:
2008-01-31 01:30:52 +00:00
if( growth->shape )
Unexpected( tok );
2008-01-31 01:30:52 +00:00
growth->shape = new PATH( growth, tok );
doPATH( (PATH*) growth->shape );
2008-01-18 22:41:16 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
case T_qarc:
2008-01-31 01:30:52 +00:00
if( growth->shape )
Unexpected( tok );
2008-01-31 01:30:52 +00:00
growth->shape = new QARC( growth );
doQARC( (QARC*) growth->shape );
2008-01-18 22:41:16 +00:00
break;
case T_net:
NeedSYMBOL();
growth->net_id = CurText();
NeedRIGHT();
2008-01-18 22:41:16 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
case T_turret:
if( NextTok() != T_NUMBER )
Expecting( T_NUMBER );
growth->turret = atoi( CurText() );
NeedRIGHT();
2008-01-18 22:41:16 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
case T_type:
tok = NextTok();
2008-01-18 22:41:16 +00:00
if( tok!=T_fix && tok!=T_route && tok!=T_normal && tok!=T_protect )
Expecting( "fix|route|normal|protect" );
2008-02-01 01:09:39 +00:00
growth->wire_type = tok;
NeedRIGHT();
2008-01-18 22:41:16 +00:00
break;
case T_attr:
tok = NextTok();
2008-01-18 22:41:16 +00:00
if( tok!=T_test && tok!=T_fanout && tok!=T_bus && tok!=T_jumper )
Expecting( "test|fanout|bus|jumper" );
2008-01-18 22:41:16 +00:00
growth->attr = tok;
NeedRIGHT();
2008-01-18 22:41:16 +00:00
break;
case T_shield:
NeedSYMBOL();
growth->shield = CurText();
NeedRIGHT();
2008-01-18 22:41:16 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
case T_window:
WINDOW* window;
window = new WINDOW( growth );
growth->windows.push_back( window );
doWINDOW( window );
break;
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
case T_connect:
if( growth->connect )
Unexpected( tok );
2008-01-18 22:41:16 +00:00
growth->connect = new CONNECT( growth );
doCONNECT( growth->connect );
break;
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
case T_supply:
growth->supply = true;
NeedRIGHT();
2008-01-18 22:41:16 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
default:
Unexpected( CurText() );
2008-01-18 22:41:16 +00:00
}
}
}
void SPECCTRA_DB::doWIRE_VIA( WIRE_VIA* growth ) throw( IO_ERROR )
2008-01-19 06:56:48 +00:00
{
T tok;
2008-01-19 06:56:48 +00:00
POINT point;
2008-02-07 20:23:58 +00:00
2008-01-19 06:56:48 +00:00
/* <wire_via_descriptor >::=
(via
<padstack_id > {<vertex> }
[(net <net_id >)]
[(via_number <via#> )]
[(type [fix | route | normal | protect])]
[(attr [test | fanout | jumper |
virtual_pin <virtual_pin_name> ])]
[(contact {<layer_id >})]
[(supply)]
)
(virtual_pin
<virtual_pin_name> <vertex> (net <net_id >)
)
*/
NeedSYMBOL();
growth->padstack_id = CurText();
2008-01-19 06:56:48 +00:00
while( (tok = NextTok()) == T_NUMBER )
2008-01-19 06:56:48 +00:00
{
point.x = strtod( CurText(), 0 );
2008-02-07 20:23:58 +00:00
if( NextTok() != T_NUMBER )
Expecting( "vertex.y" );
2008-02-07 20:23:58 +00:00
point.y = strtod( CurText(), 0 );
2008-02-07 20:23:58 +00:00
2008-01-19 06:56:48 +00:00
growth->vertexes.push_back( point );
}
while( tok != T_RIGHT )
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-19 06:56:48 +00:00
switch( tok )
{
case T_net:
NeedSYMBOL();
growth->net_id = CurText();
NeedRIGHT();
2008-01-19 06:56:48 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-19 06:56:48 +00:00
case T_via_number:
if( NextTok() != T_NUMBER )
Expecting( "<via#>" );
growth->via_number = atoi( CurText() );
NeedRIGHT();
2008-01-19 06:56:48 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-19 06:56:48 +00:00
case T_type:
tok = NextTok();
2008-01-19 06:56:48 +00:00
if( tok!=T_fix && tok!=T_route && tok!=T_normal && tok!=T_protect )
Expecting( "fix|route|normal|protect" );
2008-02-01 01:09:39 +00:00
growth->via_type = tok;
NeedRIGHT();
2008-01-19 06:56:48 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-19 06:56:48 +00:00
case T_attr:
tok = NextTok();
2008-01-19 06:56:48 +00:00
if( tok!=T_test && tok!=T_fanout && tok!=T_jumper && tok!=T_virtual_pin )
Expecting( "test|fanout|jumper|virtual_pin" );
2008-01-19 06:56:48 +00:00
growth->attr = tok;
if( tok == T_virtual_pin )
{
NeedSYMBOL();
growth->virtual_pin_name = CurText();
2008-01-19 06:56:48 +00:00
}
NeedRIGHT();
2008-01-19 06:56:48 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-19 06:56:48 +00:00
case T_contact:
NeedSYMBOL();
2008-01-19 06:56:48 +00:00
tok = T_SYMBOL;
while( IsSymbol(tok) )
2008-01-19 06:56:48 +00:00
{
growth->contact_layers.push_back( CurText() );
tok = NextTok();
2008-01-19 06:56:48 +00:00
}
if( tok != T_RIGHT )
Expecting( T_RIGHT );
2008-01-19 06:56:48 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-19 06:56:48 +00:00
case T_supply:
growth->supply = true;
NeedRIGHT();
2008-01-19 06:56:48 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-19 06:56:48 +00:00
default:
Unexpected( CurText() );
2008-01-19 06:56:48 +00:00
}
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-19 06:56:48 +00:00
}
}
void SPECCTRA_DB::doWIRING( WIRING* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-18 22:41:16 +00:00
{
T tok;
2008-01-18 22:41:16 +00:00
/* <wiring_descriptor >::=
(wiring
[<unit_descriptor> | <resolution_descriptor> | null]
{<wire_descriptor> }
[<test_points_descriptor> ]
{[<supply_pin_descriptor> ]}
)
*/
while( (tok = NextTok()) != T_RIGHT )
2008-01-18 22:41:16 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-18 22:41:16 +00:00
switch( tok )
{
2008-01-23 22:38:16 +00:00
case T_unit:
if( growth->unit )
Unexpected( tok );
2008-01-23 22:38:16 +00:00
growth->unit = new UNIT_RES( growth, tok );
doUNIT( growth->unit );
break;
2008-02-07 20:23:58 +00:00
2008-01-23 22:38:16 +00:00
case T_resolution:
if( growth->unit )
Unexpected( tok );
2008-01-23 22:38:16 +00:00
growth->unit = new UNIT_RES( growth, tok );
doRESOLUTION( growth->unit );
break;
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
case T_wire:
WIRE* wire;
wire = new WIRE( growth );
growth->wires.push_back( wire );
doWIRE( wire );
break;
2008-01-19 06:56:48 +00:00
case T_via:
WIRE_VIA* wire_via;
wire_via = new WIRE_VIA( growth );
growth->wire_vias.push_back( wire_via );
doWIRE_VIA( wire_via );
break;
2008-02-07 20:23:58 +00:00
2008-01-18 22:41:16 +00:00
default:
Unexpected( CurText() );
2008-01-18 22:41:16 +00:00
}
}
}
void SPECCTRA_DB::doANCESTOR( ANCESTOR* growth ) throw( IO_ERROR )
2008-01-20 00:34:21 +00:00
{
T tok;
2008-01-20 00:34:21 +00:00
/* <ancestor_file_descriptor >::=
(ancestor <file_path_name> (created_time <time_stamp> )
[(comment <comment_string> )])
*/
2008-02-07 20:23:58 +00:00
NeedSYMBOL();
growth->filename = CurText();
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-20 00:34:21 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-20 00:34:21 +00:00
switch( tok )
{
case T_created_time:
readTIME( &growth->time_stamp );
NeedRIGHT();
2008-01-20 00:34:21 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-20 00:34:21 +00:00
case T_comment:
NeedSYMBOL();
growth->comment = CurText();
NeedRIGHT();
2008-01-20 00:34:21 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-20 00:34:21 +00:00
default:
Unexpected( CurText() );
2008-01-20 00:34:21 +00:00
}
}
}
void SPECCTRA_DB::doHISTORY( HISTORY* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-20 00:34:21 +00:00
{
T tok;
2008-01-20 00:34:21 +00:00
/* <history_descriptor >::=
(history [{<ancestor_file_descriptor> }] <self_descriptor> )
*/
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-20 00:34:21 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-20 00:34:21 +00:00
switch( tok )
{
case T_ancestor:
ANCESTOR* ancestor;
ancestor = new ANCESTOR( growth );
growth->ancestors.push_back( ancestor );
doANCESTOR( ancestor );
break;
2008-02-07 20:23:58 +00:00
2008-01-20 00:34:21 +00:00
case T_self:
while( (tok = NextTok()) != T_RIGHT )
2008-01-20 00:34:21 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-01-20 00:34:21 +00:00
tok = NextTok();
2008-01-20 00:34:21 +00:00
switch( tok )
{
case T_created_time:
readTIME( &growth->time_stamp );
NeedRIGHT();
2008-01-20 00:34:21 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-20 00:34:21 +00:00
case T_comment:
NeedSYMBOL();
growth->comments.push_back( CurText() );
NeedRIGHT();
2008-01-20 00:34:21 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-20 00:34:21 +00:00
default:
Unexpected( CurText() );
2008-01-20 00:34:21 +00:00
}
}
break;
2008-02-07 20:23:58 +00:00
2008-01-20 00:34:21 +00:00
default:
Unexpected( CurText() );
2008-01-20 00:34:21 +00:00
}
}
}
void SPECCTRA_DB::doSESSION( SESSION* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-20 00:34:21 +00:00
{
T tok;
2008-01-20 00:34:21 +00:00
/* <session_file_descriptor >::=
(session <session_id >
(base_design <path/filename >)
[<history_descriptor> ]
[<session_structure_descriptor> ]
[<placement_descriptor> ]
[<floor_plan_descriptor> ]
[<net_pin_changes_descriptor> ]
[<was_is_descriptor> ]
<swap_history_descriptor> ]
[<route_descriptor> ]
)
*/
2008-02-07 20:23:58 +00:00
NeedSYMBOL();
growth->session_id = CurText();
2008-01-20 00:34:21 +00:00
while( (tok = NextTok()) != T_RIGHT )
2008-01-20 00:34:21 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-20 00:34:21 +00:00
switch( tok )
{
case T_base_design:
NeedSYMBOL();
growth->base_design = CurText();
NeedRIGHT();
2008-01-20 00:34:21 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-20 00:34:21 +00:00
case T_history:
if( growth->history )
Unexpected( tok );
2008-01-20 00:34:21 +00:00
growth->history = new HISTORY( growth );
doHISTORY( growth->history );
break;
2008-02-07 20:23:58 +00:00
2008-01-20 00:34:21 +00:00
case T_structure:
if( growth->structure )
Unexpected( tok );
2008-01-20 00:34:21 +00:00
growth->structure = new STRUCTURE( growth );
doSTRUCTURE( growth->structure );
break;
2008-02-07 20:23:58 +00:00
2008-01-20 00:34:21 +00:00
case T_placement:
if( growth->placement )
Unexpected( tok );
2008-01-20 00:34:21 +00:00
growth->placement = new PLACEMENT( growth );
doPLACEMENT( growth->placement );
break;
2008-02-07 20:23:58 +00:00
2008-01-20 12:58:55 +00:00
case T_was_is:
if( growth->was_is )
Unexpected( tok );
2008-01-20 12:58:55 +00:00
growth->was_is = new WAS_IS( growth );
doWAS_IS( growth->was_is );
break;
2008-01-20 00:34:21 +00:00
2008-01-20 12:58:55 +00:00
case T_routes:
2008-01-20 00:34:21 +00:00
if( growth->route )
Unexpected( tok );
2008-01-20 00:34:21 +00:00
growth->route = new ROUTE( growth );
doROUTE( growth->route );
break;
2008-02-07 20:23:58 +00:00
2008-01-20 12:58:55 +00:00
default:
Unexpected( CurText() );
2008-01-20 12:58:55 +00:00
}
}
}
void SPECCTRA_DB::doWAS_IS( WAS_IS* growth ) throw( IO_ERROR )
2008-01-20 12:58:55 +00:00
{
T tok;
2008-01-20 12:58:55 +00:00
PIN_PAIR empty( growth );
PIN_PAIR* pin_pair;
/* <was_is_descriptor >::=
(was_is {(pins <pin_reference> <pin_reference> )})
*/
// none of the pins is ok too
while( (tok = NextTok()) != T_RIGHT )
2008-01-20 12:58:55 +00:00
{
2008-02-07 20:23:58 +00:00
2008-01-20 12:58:55 +00:00
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-20 12:58:55 +00:00
switch( tok )
{
case T_pins:
2008-02-07 20:23:58 +00:00
// copy the empty one, then fill its copy later thru pin_pair.
2008-01-20 12:58:55 +00:00
growth->pin_pairs.push_back( empty );
pin_pair= &growth->pin_pairs.back();
2008-02-07 20:23:58 +00:00
NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
2008-01-20 12:58:55 +00:00
readCOMPnPIN( &pin_pair->was.component_id, &pin_pair->was.pin_id );
2008-02-07 20:23:58 +00:00
NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
2008-01-20 12:58:55 +00:00
readCOMPnPIN( &pin_pair->is.component_id, &pin_pair->is.pin_id );
2008-02-07 20:23:58 +00:00
NeedRIGHT();
2008-01-20 12:58:55 +00:00
break;
2008-02-07 20:23:58 +00:00
2008-01-20 12:58:55 +00:00
default:
Unexpected( CurText() );
2008-01-20 12:58:55 +00:00
}
}
}
void SPECCTRA_DB::doROUTE( ROUTE* growth ) throw( IO_ERROR, boost::bad_pointer )
2008-01-20 12:58:55 +00:00
{
T tok;
2008-01-20 12:58:55 +00:00
/* <route_descriptor >::=
(routes
<resolution_descriptor>
<parser_descriptor>
<structure_out_descriptor>
<library_out_descriptor>
<network_out_descriptor>
<test_points_descriptor>
)
*/
while( (tok = NextTok()) != T_RIGHT )
2008-01-20 12:58:55 +00:00
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
2008-01-20 12:58:55 +00:00
switch( tok )
{
case T_resolution:
if( growth->resolution )
Unexpected( tok );
2008-01-20 12:58:55 +00:00
growth->resolution = new UNIT_RES( growth, tok );
doRESOLUTION( growth->resolution );
break;
case T_parser:
if( growth->parser )
2012-01-16 21:43:07 +00:00
{
#if 0 // Electra 2.9.1 emits two (parser ) elements in a row.
// Work around their bug for now.
Unexpected( tok );
2012-01-16 21:43:07 +00:00
#else
delete growth->parser;
#endif
}
2008-01-20 12:58:55 +00:00
growth->parser = new PARSER( growth );
doPARSER( growth->parser );
break;
2009-07-13 22:59:56 +00:00
case T_structure_out:
if( growth->structure_out )
Unexpected( tok );
2009-07-13 22:59:56 +00:00
growth->structure_out = new STRUCTURE_OUT( growth );
doSTRUCTURE_OUT( growth->structure_out );
2008-01-20 12:58:55 +00:00
break;
case T_library_out:
2008-01-20 12:58:55 +00:00
if( growth->library )
Unexpected( tok );
2008-01-23 22:38:16 +00:00
growth->library = new LIBRARY( growth, tok );
2008-01-20 12:58:55 +00:00
doLIBRARY( growth->library );
break;
2008-02-07 20:23:58 +00:00
case T_network_out:
while( (tok = NextTok()) != T_RIGHT )
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
if( tok != T_net ) // it is class NET_OUT, but token T_net
Unexpected( CurText() );
2008-02-07 20:23:58 +00:00
NET_OUT* net_out;
net_out = new NET_OUT( growth );
2008-02-07 20:23:58 +00:00
growth->net_outs.push_back( net_out );
doNET_OUT( net_out );
}
break;
default:
Unexpected( CurText() );
}
}
}
void SPECCTRA_DB::doNET_OUT( NET_OUT* growth ) throw( IO_ERROR, boost::bad_pointer )
{
T tok;
/* <net_out_descriptor >::=
(net <net_id >
[(net_number <integer >)]
[<rule_descriptor> ]
{[<wire_shape_descriptor> | <wire_guide_descriptor> |
<wire_via_descriptor> | <bond_shape_descriptor> ]}
{[<supply_pin_descriptor> ]}
)
*/
2008-02-07 20:23:58 +00:00
NeedSYMBOLorNUMBER();
growth->net_id = CurText();
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
{
if( tok != T_LEFT )
Expecting( T_LEFT );
2008-02-07 20:23:58 +00:00
tok = NextTok();
switch( tok )
{
case T_net_number:
tok = NextTok();
if( tok!= T_NUMBER )
Expecting( T_NUMBER );
growth->net_number = atoi( CurText() );
NeedRIGHT();
break;
case T_rule:
if( growth->rules )
Unexpected( tok );
growth->rules = new RULE( growth, tok );
doRULE( growth->rules );
break;
case T_wire:
WIRE* wire;
wire = new WIRE( growth );
growth->wires.push_back( wire );
doWIRE( wire );
break;
case T_via:
WIRE_VIA* wire_via;
wire_via = new WIRE_VIA( growth );
growth->wire_vias.push_back( wire_via );
doWIRE_VIA( wire_via );
break;
2008-02-07 20:23:58 +00:00
case T_supply_pin:
SUPPLY_PIN* supply_pin;
supply_pin = new SUPPLY_PIN( growth );
growth->supply_pins.push_back( supply_pin );
doSUPPLY_PIN( supply_pin );
2008-01-20 12:58:55 +00:00
break;
2008-01-20 00:34:21 +00:00
default:
Unexpected( CurText() );
2008-01-20 00:34:21 +00:00
}
}
}
void SPECCTRA_DB::doSUPPLY_PIN( SUPPLY_PIN* growth ) throw( IO_ERROR )
{
T tok;
PIN_REF empty(growth);
/* <supply_pin_descriptor >::=
(supply_pin {<pin_reference> } [(net <net_id >)])
*/
2008-02-07 20:23:58 +00:00
NeedSYMBOL();
growth->net_id = CurText();
2008-02-07 20:23:58 +00:00
while( (tok = NextTok()) != T_RIGHT )
{
if( IsSymbol(tok) )
{
growth->pin_refs.push_back( empty );
2008-02-07 20:23:58 +00:00
PIN_REF* pin_ref = &growth->pin_refs.back();
2008-02-07 20:23:58 +00:00
readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
}
else if( tok == T_LEFT )
{
tok = NextTok();
if( tok != T_net )
Expecting( T_net );
growth->net_id = CurText();
NeedRIGHT();
}
else
Unexpected( CurText() );
}
}
void SPECCTRA_DB::ExportPCB( wxString aFilename, bool aNameChange ) throw( IO_ERROR )
2007-12-22 07:18:20 +00:00
{
2010-08-08 00:31:07 +00:00
if( pcb )
2009-04-16 15:50:55 +00:00
{
FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), quote_char[0] );
2008-01-22 20:48:02 +00:00
if( aNameChange )
pcb->pcbname = TO_UTF8( aFilename );
2008-02-07 20:23:58 +00:00
pcb->Format( &formatter, 0 );
2008-01-22 20:48:02 +00:00
}
2008-01-20 00:34:21 +00:00
}
void SPECCTRA_DB::ExportSESSION( wxString aFilename )
2008-01-20 00:34:21 +00:00
{
2010-08-08 00:31:07 +00:00
if( session )
2008-01-20 00:34:21 +00:00
{
FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), quote_char[0] );
2010-08-08 00:31:07 +00:00
session->Format( &formatter, 0 );
2010-08-08 00:31:07 +00:00
}
2008-01-02 18:18:37 +00:00
}
2007-12-23 06:10:51 +00:00
2008-01-02 18:18:37 +00:00
PCB* SPECCTRA_DB::MakePCB()
2007-12-22 07:18:20 +00:00
{
2008-01-02 18:18:37 +00:00
PCB* pcb = new PCB();
2008-02-07 20:23:58 +00:00
2008-01-02 18:18:37 +00:00
pcb->parser = new PARSER( pcb );
2008-01-21 22:16:45 +00:00
pcb->resolution = new UNIT_RES( pcb, T_resolution );
pcb->unit = new UNIT_RES( pcb, T_unit );
2008-02-07 20:23:58 +00:00
2008-01-21 22:16:45 +00:00
pcb->structure = new STRUCTURE( pcb );
2008-01-22 20:48:02 +00:00
pcb->structure->boundary = new BOUNDARY( pcb->structure );
2008-01-29 16:45:14 +00:00
pcb->structure->via = new VIA( pcb->structure );
pcb->structure->rules = new RULE( pcb->structure, T_rule );
2008-02-07 20:23:58 +00:00
2008-01-21 22:16:45 +00:00
pcb->placement = new PLACEMENT( pcb );
2008-02-07 20:23:58 +00:00
2008-01-21 22:16:45 +00:00
pcb->library = new LIBRARY( pcb );
2008-02-07 20:23:58 +00:00
2008-01-21 22:16:45 +00:00
pcb->network = new NETWORK( pcb );
2008-02-07 20:23:58 +00:00
2008-01-21 22:16:45 +00:00
pcb->wiring = new WIRING( pcb );
2008-01-02 18:18:37 +00:00
return pcb;
2007-12-22 07:18:20 +00:00
}
2008-01-03 06:33:28 +00:00
//-----<ELEM>---------------------------------------------------------------
ELEM::ELEM( T aType, ELEM* aParent ) :
2008-01-03 06:33:28 +00:00
type( aType ),
parent( aParent )
{
}
ELEM::~ELEM()
{
}
const char* ELEM::Name() const
{
return SPECCTRA_DB::TokenName( type );
}
2008-01-03 06:33:28 +00:00
2008-02-07 20:23:58 +00:00
UNIT_RES* ELEM::GetUnits() const
{
if( parent )
return parent->GetUnits();
return &UNIT_RES::Default;
}
void ELEM::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
2008-01-03 06:33:28 +00:00
{
out->Print( nestLevel, "(%s\n", Name() );
2008-01-11 20:25:52 +00:00
FormatContents( out, nestLevel+1 );
2008-02-07 20:23:58 +00:00
out->Print( nestLevel, ")\n" );
2008-01-11 20:25:52 +00:00
}
void ELEM_HOLDER::FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
2008-01-11 20:25:52 +00:00
{
2008-01-03 06:33:28 +00:00
for( int i=0; i<Length(); ++i )
{
2008-01-11 20:25:52 +00:00
At(i)->Format( out, nestLevel );
2008-01-03 06:33:28 +00:00
}
}
int ELEM_HOLDER::FindElem( T aType, int instanceNum )
2008-01-03 06:33:28 +00:00
{
int repeats=0;
for( unsigned i=0; i<kids.size(); ++i )
{
if( kids[i].Type() == aType )
{
if( repeats == instanceNum )
return i;
++repeats;
}
}
return -1;
}
2008-02-14 01:07:52 +00:00
// a reasonably small memory price to pay for improved performance
STRING_FORMATTER ELEM::sf;
2008-02-14 01:07:52 +00:00
2008-02-07 20:23:58 +00:00
//-----<UNIT_RES>---------------------------------------------------------
UNIT_RES UNIT_RES::Default( NULL, T_resolution );
2008-01-03 06:33:28 +00:00
2008-01-29 16:45:14 +00:00
//-----<PADSTACK>---------------------------------------------------------
int PADSTACK::Compare( PADSTACK* lhs, PADSTACK* rhs )
{
2008-02-14 01:07:52 +00:00
// printf( "PADSTACK::Compare( %p, %p)\n", lhs, rhs );
2008-01-29 16:45:14 +00:00
if( !lhs->hash.size() )
lhs->hash = lhs->makeHash();
2008-02-07 20:23:58 +00:00
2008-01-29 16:45:14 +00:00
if( !rhs->hash.size() )
rhs->hash = rhs->makeHash();
2008-02-07 20:23:58 +00:00
2008-01-29 16:45:14 +00:00
int result = lhs->hash.compare( rhs->hash );
if( result )
return result;
// Via names hold the drill diameters, so we have to include those to discern
// between two vias with same copper size but with different drill sizes.
result = lhs->padstack_id.compare( rhs->padstack_id );
2008-01-29 16:45:14 +00:00
return result;
}
//-----<IMAGE>------------------------------------------------------------
int IMAGE::Compare( IMAGE* lhs, IMAGE* rhs )
{
if( !lhs->hash.size() )
lhs->hash = lhs->makeHash();
2008-02-07 20:23:58 +00:00
2008-01-29 16:45:14 +00:00
if( !rhs->hash.size() )
rhs->hash = rhs->makeHash();
2008-01-03 06:33:28 +00:00
2008-01-29 16:45:14 +00:00
int result = lhs->hash.compare( rhs->hash );
2008-02-07 20:23:58 +00:00
2008-01-29 16:45:14 +00:00
// printf("\"%s\" \"%s\" ret=%d\n", lhs->hash.c_str(), rhs->hash.c_str(), result );
2008-02-07 20:23:58 +00:00
2008-01-29 16:45:14 +00:00
return result;
}
//-----<COMPONENT>--------------------------------------------------------
/*
int COMPONENT::Compare( COMPONENT* lhs, COMPONENT* rhs )
{
if( !lhs->hash.size() )
lhs->hash = lhs->makeHash();
2008-02-07 20:23:58 +00:00
if( !rhs->hash.size() )
rhs->hash = rhs->makeHash();
int result = lhs->hash.compare( rhs->hash );
return result;
}
*/
2008-01-29 16:45:14 +00:00
//-----<PARSER>-----------------------------------------------------------
PARSER::PARSER( ELEM* aParent ) :
ELEM( T_parser, aParent )
{
string_quote = '"';
space_in_quoted_tokens = false;
case_sensitive = false;
wires_include_testpoint = false;
routes_include_testpoint = false;
routes_include_guides = false;
routes_include_image_conductor = false;
via_rotate_first = true;
generated_by_freeroute = false;
2008-02-07 20:23:58 +00:00
host_cad = "KiCad's Pcbnew";
wxString msg = GetBuildVersion();
host_version = TO_UTF8(msg);
}
void PARSER::FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
2008-01-03 06:33:28 +00:00
{
2008-01-14 22:50:08 +00:00
out->Print( nestLevel, "(string_quote %c)\n", string_quote );
out->Print( nestLevel, "(space_in_quoted_tokens %s)\n", space_in_quoted_tokens ? "on" : "off" );
2008-02-07 20:23:58 +00:00
out->Print( nestLevel, "(host_cad \"%s\")\n", host_cad.c_str() );
2008-01-14 22:50:08 +00:00
out->Print( nestLevel, "(host_version \"%s\")\n", host_version.c_str() );
2008-02-07 20:23:58 +00:00
2008-02-14 01:07:52 +00:00
for( STRINGS::iterator i=constants.begin(); i!=constants.end(); )
{
const std::string& s1 = *i++;
const std::string& s2 = *i++;
const char* q1 = out->GetQuoteChar( s1.c_str() );
const char* q2 = out->GetQuoteChar( s2.c_str() );
out->Print( nestLevel, "(constant %s%s%s %s%s%s)\n",
q1, s1.c_str(), q1,
q2, s2.c_str(), q2 );
}
2008-01-03 06:33:28 +00:00
if( routes_include_testpoint || routes_include_guides || routes_include_image_conductor )
2008-01-14 22:50:08 +00:00
out->Print( nestLevel, "(routes_include%s%s%s)\n",
2008-01-03 06:33:28 +00:00
routes_include_testpoint ? " testpoint" : "",
routes_include_guides ? " guides" : "",
routes_include_image_conductor ? " image_conductor" : "");
2008-02-07 20:23:58 +00:00
2008-01-03 06:33:28 +00:00
if( wires_include_testpoint )
2008-01-14 22:50:08 +00:00
out->Print( nestLevel, "(wires_include testpoint)\n" );
2008-02-07 20:23:58 +00:00
2008-01-03 06:33:28 +00:00
if( !via_rotate_first )
2008-01-14 22:50:08 +00:00
out->Print( nestLevel, "(via_rotate_first off)\n" );
2008-01-30 19:16:46 +00:00
2008-02-07 20:23:58 +00:00
if( case_sensitive )
2008-01-30 19:16:46 +00:00
out->Print( nestLevel, "(case_sensitive %s)\n", case_sensitive ? "on" : "off" );
2008-01-14 22:50:08 +00:00
}
void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IO_ERROR )
2008-01-14 22:50:08 +00:00
{
2008-01-15 23:12:38 +00:00
bool useMultiLine;
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
const char* quote = out->GetQuoteChar( component_id.c_str() );
2008-01-14 22:50:08 +00:00
if( place_rules || properties.size() || rules || region )
2008-01-15 23:12:38 +00:00
{
useMultiLine = true;
2008-02-07 20:23:58 +00:00
out->Print( nestLevel, "(%s %s%s%s\n", Name(),
2008-01-15 23:12:38 +00:00
quote, component_id.c_str(), quote );
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
out->Print( nestLevel+1, "%s", "" );
}
else
{
useMultiLine = false;
2008-02-07 20:23:58 +00:00
out->Print( nestLevel, "(%s %s%s%s", Name(),
2008-01-15 23:12:38 +00:00
quote, component_id.c_str(), quote );
}
2008-01-14 22:50:08 +00:00
if( hasVertex )
2008-01-23 22:38:16 +00:00
{
2008-01-22 20:48:02 +00:00
out->Print( 0, " %.6g %.6g", vertex.x, vertex.y );
2008-02-07 20:23:58 +00:00
out->Print( 0, " %s", GetTokenText( side ) );
2008-02-07 20:23:58 +00:00
2008-01-22 20:48:02 +00:00
out->Print( 0, " %.6g", rotation );
2008-01-23 22:38:16 +00:00
}
2008-01-30 19:16:46 +00:00
const char* space = " "; // one space, as c string.
2008-02-07 20:23:58 +00:00
2008-01-14 22:50:08 +00:00
if( mirror != T_NONE )
2008-01-30 19:16:46 +00:00
{
out->Print( 0, "%s(mirror %s)", space, GetTokenText( mirror ) );
2008-01-30 19:16:46 +00:00
space = "";
}
2008-02-07 20:23:58 +00:00
2008-01-14 22:50:08 +00:00
if( status != T_NONE )
2008-01-30 19:16:46 +00:00
{
out->Print( 0, "%s(status %s)", space, GetTokenText( status ) );
2008-01-30 19:16:46 +00:00
space = "";
}
2008-02-07 20:23:58 +00:00
2008-01-14 22:50:08 +00:00
if( logical_part.size() )
{
quote = out->GetQuoteChar( logical_part.c_str() );
2008-02-07 20:23:58 +00:00
out->Print( 0, "%s(logical_part %s%s%s)", space,
2008-01-14 22:50:08 +00:00
quote, logical_part.c_str(), quote );
2008-01-30 19:16:46 +00:00
space = "";
2008-01-14 22:50:08 +00:00
}
2008-01-15 23:12:38 +00:00
if( useMultiLine )
2008-01-14 22:50:08 +00:00
{
out->Print( 0, "\n" );
if( place_rules )
{
place_rules->Format( out, nestLevel+1 );
}
2008-02-07 20:23:58 +00:00
2008-01-14 22:50:08 +00:00
if( properties.size() )
{
out->Print( nestLevel+1, "(property \n" );
2008-02-07 20:23:58 +00:00
2008-01-15 23:12:38 +00:00
for( PROPERTIES::const_iterator i = properties.begin();
2008-01-14 22:50:08 +00:00
i != properties.end(); ++i )
{
i->Format( out, nestLevel+2 );
}
out->Print( nestLevel+1, ")\n" );
}
if( lock_type != T_NONE )
out->Print( nestLevel+1, "(lock_type %s)\n", GetTokenText(lock_type) );
2008-01-14 22:50:08 +00:00
if( rules )
rules->Format( out, nestLevel+1 );
2008-02-07 20:23:58 +00:00
2008-01-14 22:50:08 +00:00
if( region )
region->Format( out, nestLevel+1 );
2008-02-07 20:23:58 +00:00
2008-01-14 22:50:08 +00:00
if( part_number.size() )
{
quote = out->GetQuoteChar( part_number.c_str() );
2008-01-14 22:50:08 +00:00
out->Print( nestLevel+1, "(PN %s%s%s)\n",
quote, part_number.c_str(), quote );
}
}
else
{
if( lock_type != T_NONE )
2008-01-30 19:16:46 +00:00
{
out->Print( 0, "%s(lock_type %s)", space, GetTokenText(lock_type) );
2008-01-30 19:16:46 +00:00
space = "";
}
if( part_number.size() )
{
quote = out->GetQuoteChar( part_number.c_str() );
2008-01-30 19:16:46 +00:00
out->Print( 0, "%s(PN %s%s%s)", space,
quote, part_number.c_str(), quote );
}
}
2008-02-07 20:23:58 +00:00
out->Print( 0, ")\n" );
2008-01-03 06:33:28 +00:00
}
2007-12-23 06:10:51 +00:00
} // namespace DSN
2007-12-22 07:18:20 +00:00
//EOF