more specctra dsn work

This commit is contained in:
dickelbeck 2008-01-03 06:33:28 +00:00
parent d7a85428fa
commit a8eed789e0
3 changed files with 511 additions and 93 deletions

View File

@ -339,6 +339,7 @@ const static KEYWORD tokens[] = {
TOKDEF(spacing),
TOKDEF(spare),
TOKDEF(spiral_via),
TOKDEF(square),
TOKDEF(stack_via),
TOKDEF(stack_via_depth),
TOKDEF(standard),
@ -553,7 +554,9 @@ const char* LEXER::GetTokenText( DSN_T aTok )
wxString LEXER::GetTokenString( DSN_T aTok )
{
wxString ret = CONV_FROM_UTF8( GetTokenText(aTok) );
wxString ret;
ret << wxT("'") << CONV_FROM_UTF8( GetTokenText(aTok) ) << wxT("'");
return ret;
}

View File

@ -339,6 +339,7 @@ enum DSN_T {
T_spacing,
T_spare,
T_spiral_via,
T_square,
T_stack_via,
T_stack_via_depth,
T_standard,

View File

@ -49,32 +49,6 @@ class SPECCTRA_DB;
class PCB;
/**
* Class ELEM
* is a base class for any DSN element. It is not a parent node so it
* cannot contain other elements but it can be extended to hold fields
* for any DSN element which contains no other elements, only fields.
class ELEM
{
protected:
DSN_T type;
public:
ELEM( DSN_T aType ) :
type( aType )
{
}
virtual ~ELEM()
{
// printf("~ELEM(%p %d)\n", this, Type() );
}
};
*/
/**
* Class OUTPUTFORMATTER
* is an interface (abstract class) used to output ASCII text.
@ -94,9 +68,20 @@ public:
* @throw IOError if there is a problem outputting, such as a full disk.
*/
virtual void Print( int nestLevel, const char* fmt, ... ) throw( IOError ) = 0;
virtual char GetQuoteChar() = 0;
};
struct POINT
{
float x;
float y;
POINT() { x=0.0; y=0.0; }
};
/**
* Class ELEM
@ -212,48 +197,6 @@ public:
};
ELEM::ELEM( DSN_T aType, ELEM* aParent ) :
type( aType ),
parent( aParent )
{
}
ELEM::~ELEM()
{
}
void ELEM::Save( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) );
for( int i=0; i<Length(); ++i )
{
At(i)->Save( out, nestLevel+1 );
}
out->Print( nestLevel, ")\n" );
}
int ELEM::FindElem( DSN_T aType, int instanceNum )
{
int repeats=0;
for( unsigned i=0; i<kids.size(); ++i )
{
if( kids[i].Type() == aType )
{
if( repeats == instanceNum )
return i;
++repeats;
}
}
return -1;
}
/**
* Class PARSER
* is simply a configuration record per the SPECCTRA DSN file spec.
@ -298,17 +241,7 @@ public:
host_version = CONV_TO_UTF8(g_BuildVersion);
}
void Save( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) );
out->Print( nestLevel+1, "(string_quote %c)\n", string_quote );
out->Print( nestLevel+1, "(space_in_quoted_tokens %s)\n", space_in_quoted_tokens ? "on" : "off" );
out->Print( nestLevel+1, "(host_cad \"%s\")\n", host_cad.c_str() );
out->Print( nestLevel+1, "(host_version \"%s\")\n", host_version.c_str() );
out->Print( nestLevel+1, "(case_sensitive %s)\n", case_sensitive ? "on" : "off" );
out->Print( nestLevel, ")\n" );
}
void Save( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError );
};
@ -366,6 +299,179 @@ public:
};
class RECTANGLE : public ELEM
{
friend class SPECCTRA_DB;
std::string layer_id;
POINT point0;
POINT point1;
public:
RECTANGLE( ELEM* aParent ) :
ELEM( T_rect, aParent )
{
}
~RECTANGLE()
{
}
void Save( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
char quote = out->GetQuoteChar();
out->Print( nestLevel, "(%s %c%s%c %f %f %f %f)\n",
LEXER::GetTokenText( Type() ),
quote, layer_id.c_str(), quote,
point0.x, point0.y,
point1.x, point1.y );
}
};
class PATH : public ELEM
{
friend class SPECCTRA_DB;
std::string layer_id;
double aperture_width;
typedef std::vector<POINT> POINTS;
POINTS points;
DSN_T aperture_type;
public:
PATH( ELEM* aParent ) :
ELEM( T_path, aParent )
{
aperture_width = 0.0;
aperture_type = T_round;
}
~PATH()
{
}
void Save( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
char quote = out->GetQuoteChar();
out->Print( nestLevel, "(%s %c%s%c %f\n", LEXER::GetTokenText( Type() ),
quote, layer_id.c_str(), quote,
aperture_width );
for( unsigned i=0; i<points.size(); ++i )
{
out->Print( nestLevel+1, "%f %f\n", points[i].x, points[i].y );
}
if( aperture_type == T_square )
out->Print( nestLevel+1, "(aperture_type square)\n" );
out->Print( nestLevel, ")\n" );
}
};
class BOUNDARY : public ELEM
{
friend class SPECCTRA_DB;
// see http://www.boost.org/libs/ptr_container/doc/ptr_sequence_adapter.html
typedef boost::ptr_vector<PATH> PATHS;
PATHS paths;
RECTANGLE* rectangle;
public:
BOUNDARY( ELEM* aParent, DSN_T aType = T_boundary ) :
ELEM( aType, aParent )
{
rectangle = 0;
}
~BOUNDARY()
{
delete rectangle;
}
void Save( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) );
if( rectangle )
rectangle->Save( out, nestLevel+1 );
else
{
for( unsigned i=0; i<paths.size(); ++i )
{
paths[i].Save( out, nestLevel+1 );
}
}
out->Print( nestLevel, ")\n" );
}
};
class STRUCTURE : public ELEM
{
friend class SPECCTRA_DB;
UNIT* unit;
BOUNDARY* boundary;
BOUNDARY* place_boundary;
public:
STRUCTURE( ELEM* aParent ) :
ELEM( T_structure, aParent )
{
unit = 0;
boundary = 0;
place_boundary = 0;
}
~STRUCTURE()
{
delete unit;
delete boundary;
delete place_boundary;
}
void Save( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) );
if( unit )
unit->Save( out, nestLevel+1 );
if( boundary )
boundary->Save( out, nestLevel+1 );
if( place_boundary )
place_boundary->Save( out, nestLevel+1 );
out->Print( nestLevel, ")\n" );
}
DSN_T GetUnits()
{
if( unit )
return unit->GetUnits();
return ELEM::GetUnits();
}
};
class PCB : public ELEM
{
friend class SPECCTRA_DB;
@ -373,6 +479,7 @@ class PCB : public ELEM
PARSER* parser;
RESOLUTION* resolution;
UNIT* unit;
STRUCTURE* structure;
public:
@ -382,6 +489,7 @@ public:
parser = 0;
resolution = 0;
unit = 0;
structure = 0;
}
~PCB()
@ -389,6 +497,7 @@ public:
delete parser;
delete resolution;
delete unit;
delete structure;
}
void Save( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
@ -403,6 +512,9 @@ public:
if( unit )
unit->Save( out, nestLevel+1 );
if( structure )
structure->Save( out, nestLevel+1 );
out->Print( nestLevel, ")\n" );
}
@ -436,6 +548,8 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
wxString filename;
char quote_char;
/**
* Function nextTok
@ -443,13 +557,26 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
*/
DSN_T nextTok();
/**
* Function expecting
* throws an IOError exception with an input file specific error message.
* @param DSN_T The token type which was expected at the current input location.
* @throw IOError with the location within the input file of the problem.
*/
void expecting( DSN_T ) throw( IOError );
void expecting( const wxChar* text ) throw( IOError );
void unexpected( DSN_T aTok ) throw( IOError );
void unexpected( const char* text ) throw( IOError );
void doPCB( PCB* growth ) throw(IOError);
void doPARSER( PARSER* growth ) throw(IOError);
void doRESOLUTION( RESOLUTION* growth ) throw(IOError);
void doUNIT( UNIT* growth ) throw( IOError );
void doSTRUCTURE( STRUCTURE* growth ) throw( IOError );
void doBOUNDARY( BOUNDARY* growth ) throw( IOError );
void doRECTANGLE( RECTANGLE* growth ) throw( IOError );
void doPATH( PATH* growth ) throw( IOError );
public:
@ -458,6 +585,7 @@ public:
lexer = 0;
tree = 0;
fp = 0;
quote_char = '"';
}
~SPECCTRA_DB()
@ -472,11 +600,14 @@ public:
//-----<OUTPUTFORMATTER>-------------------------------------------------
void Print( int nestLevel, const char* fmt, ... ) throw( IOError );
char GetQuoteChar() { return quote_char; }
//-----</OUTPUTFORMATTER>------------------------------------------------
/**
* Function MakePCB
* makes PCB with all the default ELEMs and parts on the heap.
* makes a PCB with all the default ELEMs and parts on the heap.
*/
static PCB* MakePCB();
@ -512,6 +643,9 @@ public:
};
//-----<SPECCTRA_DB>-------------------------------------------------
void SPECCTRA_DB::ThrowIOError( const wxChar* fmt, ... ) throw( IOError )
{
wxString errText;
@ -528,9 +662,7 @@ void SPECCTRA_DB::ThrowIOError( const wxChar* fmt, ... ) throw( IOError )
void SPECCTRA_DB::expecting( DSN_T aTok ) throw( IOError )
{
wxString errText( _("Expecting") );
errText << wxT(" ") << LEXER::GetTokenString( aTok );
lexer->ThrowIOError( errText, lexer->CurOffset() );
}
@ -543,10 +675,25 @@ void SPECCTRA_DB::expecting( const wxChar* text ) throw( IOError )
lexer->ThrowIOError( errText, lexer->CurOffset() );
}
void SPECCTRA_DB::unexpected( DSN_T aTok ) throw( IOError )
{
wxString errText( _("Unexpected") );
errText << wxT(" ") << LEXER::GetTokenString( aTok );
lexer->ThrowIOError( errText, lexer->CurOffset() );
}
void SPECCTRA_DB::unexpected( const char* text ) throw( IOError )
{
wxString errText( _("Unexpected") );
errText << wxT(" '") << CONV_FROM_UTF8(text) << wxT("'");
lexer->ThrowIOError( errText, lexer->CurOffset() );
}
DSN_T SPECCTRA_DB::nextTok()
{
return lexer->NextTok();
DSN_T ret = lexer->NextTok();
return ret;
}
@ -611,12 +758,15 @@ void SPECCTRA_DB::doPCB( PCB* growth ) throw( IOError )
break;
case T_structure:
growth->structure = new STRUCTURE( growth );
doSTRUCTURE( growth->structure );
break;
case T_placement:
case T_library:
break;
default:
expecting( wxT("parser|unit|resolution|structure|placement|library") );
unexpected( lexer->CurText() );
}
}
@ -643,6 +793,8 @@ void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IOError )
if( tok != T_QUOTE_DEF )
expecting( T_QUOTE_DEF );
lexer->SetStringDelimiter( (unsigned char) *lexer->CurText() );
growth->string_quote = *lexer->CurText();
quote_char = *lexer->CurText();
break;
case T_space_in_quoted_tokens:
@ -671,10 +823,11 @@ void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IOError )
tok = nextTok();
if( tok!=T_STRING && tok!=T_SYMBOL )
expecting( T_SYMBOL );
growth->const_id1 = lexer->CurText();
tok = nextTok();
if( tok!=T_STRING && tok!=T_SYMBOL )
expecting( T_SYMBOL );
// @todo
growth->const_id2 = lexer->CurText();
break;
case T_write_resolution: // [(writee_resolution {<character> <positive_integer >})]
@ -695,12 +848,16 @@ void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IOError )
switch( tok )
{
case T_testpoint:
growth->routes_include_testpoint = true;
break;
case T_guide:
growth->routes_include_guides = true;
break;
case T_image_conductor:
// @todo
growth->routes_include_image_conductor = true;
break;
default:
expecting( _("testpoint, guides, or image_conductor") );
expecting( wxT("testpoint|guides|image_conductor") );
}
}
continue; // we ate the T_RIGHT
@ -709,7 +866,7 @@ void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IOError )
tok = nextTok();
if( tok != T_testpoint )
expecting( T_testpoint );
// @todo
growth->routes_include_testpoint = true;
break;
case T_case_sensitive:
@ -723,12 +880,11 @@ void SPECCTRA_DB::doPARSER( PARSER* growth ) throw( IOError )
tok = nextTok();
if( tok!=T_on && tok!=T_off )
expecting( wxT("on|off") );
// @todo
growth->via_rotate_first = (tok==T_on);
break;
default:
expecting( wxT("parser_descriptor contents") );
unexpected( lexer->CurText() );
}
tok = nextTok();
@ -787,6 +943,189 @@ void SPECCTRA_DB::doUNIT( UNIT* growth ) throw(IOError)
expecting( T_RIGHT );
}
void SPECCTRA_DB::doSTRUCTURE( STRUCTURE* growth ) throw(IOError)
{
DSN_T tok;
while( (tok = nextTok()) != T_RIGHT )
{
if( tok != T_LEFT )
expecting( T_LEFT );
tok = nextTok();
switch( tok )
{
case T_unit:
if( growth->unit )
unexpected( T_unit );
growth->unit = new UNIT( growth );
doUNIT( growth->unit );
break;
case T_place_boundary:
L_place:
if( growth->place_boundary )
unexpected( T_place_boundary );
growth->place_boundary = new BOUNDARY( growth, T_place_boundary );
doBOUNDARY( growth->place_boundary );
break;
case T_boundary:
if( growth->boundary )
{
if( growth->place_boundary )
unexpected( T_boundary );
goto L_place;
}
growth->boundary = new BOUNDARY( growth );
doBOUNDARY( growth->boundary );
break;
default:
unexpected( lexer->CurText() );
}
}
}
void SPECCTRA_DB::doBOUNDARY( BOUNDARY* growth ) throw( IOError )
{
DSN_T tok = nextTok();
if( tok != T_LEFT )
expecting( T_LEFT );
tok = nextTok();
if( tok == T_rect )
{
growth->rectangle = new RECTANGLE( growth );
doRECTANGLE( growth->rectangle );
if( nextTok() != T_RIGHT )
expecting( T_RIGHT );
}
else if( tok == T_path )
{
for(;;)
{
if( tok != T_path )
expecting( T_path );
PATH* path = new PATH( growth ) ;
growth->paths.push_back( path );
doPATH( path );
tok = nextTok();
if( tok == T_RIGHT )
break;
if( tok != T_LEFT )
expecting(T_LEFT);
tok = nextTok();
}
}
else
expecting( wxT("rect|path") );
}
void SPECCTRA_DB::doPATH( PATH* growth ) throw( IOError )
{
DSN_T tok = nextTok();
switch( tok )
{
case T_SYMBOL:
case T_STRING:
case T_pcb: // reserved layer names
case T_power:
case T_signal:
growth->layer_id = lexer->CurText();
break;
default:
expecting( T_SYMBOL );
}
if( nextTok() != T_NUMBER )
expecting( wxT("<aperture_width>") );
growth->aperture_width = strtod( lexer->CurText(), NULL );
POINT ptTemp;
tok = nextTok();
do
{
if( tok != T_NUMBER )
expecting( T_NUMBER );
ptTemp.x = strtod( lexer->CurText(), NULL );
if( nextTok() != T_NUMBER )
expecting( T_NUMBER );
ptTemp.y = strtod( lexer->CurText(), NULL );
growth->points.push_back( ptTemp );
} while( (tok = nextTok())!=T_RIGHT && tok!=T_LEFT );
if( tok == T_LEFT )
{
if( nextTok() != T_aperture_type )
expecting( T_aperture_type );
tok = nextTok();
if( tok!=T_round && tok!=T_square )
expecting( wxT("round|square") );
growth->aperture_type = tok;
if( nextTok() != T_RIGHT )
expecting( T_RIGHT );
}
}
void SPECCTRA_DB::doRECTANGLE( RECTANGLE* growth ) throw( IOError )
{
DSN_T tok = nextTok();
switch( tok )
{
case T_SYMBOL:
case T_STRING:
case T_pcb: // reserved layer names match these tokens
case T_power:
case T_signal:
growth->layer_id = lexer->CurText();
break;
default:
expecting( T_SYMBOL );
}
if( nextTok() != T_NUMBER )
expecting( T_NUMBER );
growth->point0.x = strtod( lexer->CurText(), NULL );
if( nextTok() != T_NUMBER )
expecting( T_NUMBER );
growth->point0.y = strtod( lexer->CurText(), NULL );
if( nextTok() != T_NUMBER )
expecting( T_NUMBER );
growth->point1.x = strtod( lexer->CurText(), NULL );
if( nextTok() != T_NUMBER )
expecting( T_NUMBER );
growth->point1.y = strtod( lexer->CurText(), NULL );
if( nextTok() != T_RIGHT )
expecting( T_RIGHT );
}
void SPECCTRA_DB::Print( int nestLevel, const char* fmt, ... ) throw( IOError )
{
@ -833,6 +1172,81 @@ PCB* SPECCTRA_DB::MakePCB()
}
//-----<ELEM>---------------------------------------------------------------
ELEM::ELEM( DSN_T aType, ELEM* aParent ) :
type( aType ),
parent( aParent )
{
}
ELEM::~ELEM()
{
}
void ELEM::Save( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) );
for( int i=0; i<Length(); ++i )
{
At(i)->Save( out, nestLevel+1 );
}
out->Print( nestLevel, ")\n" );
}
int ELEM::FindElem( DSN_T aType, int instanceNum )
{
int repeats=0;
for( unsigned i=0; i<kids.size(); ++i )
{
if( kids[i].Type() == aType )
{
if( repeats == instanceNum )
return i;
++repeats;
}
}
return -1;
}
//-----<PARSER>-----------------------------------------------------------
void PARSER::Save( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) );
out->Print( nestLevel+1, "(string_quote %c)\n", string_quote );
out->Print( nestLevel+1, "(space_in_quoted_tokens %s)\n", space_in_quoted_tokens ? "on" : "off" );
out->Print( nestLevel+1, "(host_cad \"%s\")\n", host_cad.c_str() );
out->Print( nestLevel+1, "(host_version \"%s\")\n", host_version.c_str() );
if( const_id1.length()>0 || const_id2.length()>0 )
out->Print( nestLevel+1, "(constant %c%s%c %c%s%c)\n",
string_quote, const_id1.c_str(), string_quote,
string_quote, const_id2.c_str(), string_quote );
if( routes_include_testpoint || routes_include_guides || routes_include_image_conductor )
out->Print( nestLevel+1, "(routes_include%s%s%s)\n",
routes_include_testpoint ? " testpoint" : "",
routes_include_guides ? " guides" : "",
routes_include_image_conductor ? " image_conductor" : "");
if( wires_include_testpoint )
out->Print( nestLevel+1, "(wires_include testpoint)\n" );
if( !via_rotate_first )
out->Print( nestLevel+1, "(via_rotate_first off)\n" );
out->Print( nestLevel+1, "(case_sensitive %s)\n", case_sensitive ? "on" : "off" );
out->Print( nestLevel, ")\n" );
}
} // namespace DSN