more specctra dsn work

This commit is contained in:
dickelbeck 2008-01-14 22:50:08 +00:00
parent f5f6bb6ff5
commit c72857f415
3 changed files with 521 additions and 112 deletions

View File

@ -46,11 +46,13 @@ namespace DSN {
struct KEYWORD struct KEYWORD
{ {
const char* name; const char* name;
int token; // int token;
}; };
#define TOKDEF(x) { #x, T_##x } //#define TOKDEF(x) { #x, T_##x }
#define TOKDEF(x) { #x }
// This MUST be sorted alphabetically, and also so MUST enum DSN_T {} be alphabetized. // This MUST be sorted alphabetically, and also so MUST enum DSN_T {} be alphabetized.
// These MUST all be lower case because of the conversion to lowercase in findToken(). // These MUST all be lower case because of the conversion to lowercase in findToken().
@ -123,6 +125,7 @@ const static KEYWORD tokens[] = {
TOKDEF(diagonal), TOKDEF(diagonal),
TOKDEF(direction), TOKDEF(direction),
TOKDEF(directory), TOKDEF(directory),
TOKDEF(discrete),
TOKDEF(effective_via_length), TOKDEF(effective_via_length),
TOKDEF(exclude), TOKDEF(exclude),
TOKDEF(expose), TOKDEF(expose),
@ -163,6 +166,7 @@ const static KEYWORD tokens[] = {
TOKDEF(image_image), TOKDEF(image_image),
TOKDEF(image_image_spacing), TOKDEF(image_image_spacing),
TOKDEF(image_outline_clearance), TOKDEF(image_outline_clearance),
TOKDEF(image_set),
TOKDEF(image_type), TOKDEF(image_type),
TOKDEF(inch), TOKDEF(inch),
TOKDEF(include), TOKDEF(include),
@ -310,6 +314,7 @@ const static KEYWORD tokens[] = {
TOKDEF(reorder), TOKDEF(reorder),
TOKDEF(reroute_order_viols), TOKDEF(reroute_order_viols),
TOKDEF(resistance_resolution), TOKDEF(resistance_resolution),
TOKDEF(resistor),
TOKDEF(resolution), TOKDEF(resolution),
TOKDEF(restricted_layer_length_factor), TOKDEF(restricted_layer_length_factor),
TOKDEF(room), TOKDEF(room),
@ -341,6 +346,7 @@ const static KEYWORD tokens[] = {
TOKDEF(side), TOKDEF(side),
TOKDEF(signal), TOKDEF(signal),
TOKDEF(site), TOKDEF(site),
TOKDEF(small),
TOKDEF(smd), TOKDEF(smd),
TOKDEF(snap), TOKDEF(snap),
TOKDEF(snap_angle), TOKDEF(snap_angle),
@ -420,6 +426,7 @@ const static KEYWORD tokens[] = {
TOKDEF(wiring), TOKDEF(wiring),
TOKDEF(write_resolution), TOKDEF(write_resolution),
TOKDEF(x), TOKDEF(x),
TOKDEF(xy),
TOKDEF(y), TOKDEF(y),
}; };
@ -513,7 +520,8 @@ int LEXER::findToken( const std::string& tok )
tokens, sizeof(tokens)/sizeof(tokens[0]), tokens, sizeof(tokens)/sizeof(tokens[0]),
sizeof(KEYWORD), compare ); sizeof(KEYWORD), compare );
if( findings ) if( findings )
return findings->token; // return findings->token;
return findings - tokens;
else else
return -1; return -1;
} }

View File

@ -42,6 +42,7 @@ namespace DSN {
enum DSN_T { enum DSN_T {
// the first few are special (the uppercase ones) // the first few are special (the uppercase ones)
T_NONE = -9,
T_QUOTE_DEF = -8, T_QUOTE_DEF = -8,
T_DASH = -7, T_DASH = -7,
T_SYMBOL = -6, T_SYMBOL = -6,
@ -123,6 +124,7 @@ enum DSN_T {
T_diagonal, T_diagonal,
T_direction, T_direction,
T_directory, T_directory,
T_discrete,
T_effective_via_length, T_effective_via_length,
T_exclude, T_exclude,
T_expose, T_expose,
@ -163,6 +165,7 @@ enum DSN_T {
T_image_image, T_image_image,
T_image_image_spacing, T_image_image_spacing,
T_image_outline_clearance, T_image_outline_clearance,
T_image_set,
T_image_type, T_image_type,
T_inch, T_inch,
T_include, T_include,
@ -310,6 +313,7 @@ enum DSN_T {
T_reorder, T_reorder,
T_reroute_order_viols, T_reroute_order_viols,
T_resistance_resolution, T_resistance_resolution,
T_resistor,
T_resolution, T_resolution,
T_restricted_layer_length_factor, T_restricted_layer_length_factor,
T_room, T_room,
@ -341,6 +345,7 @@ enum DSN_T {
T_side, T_side,
T_signal, T_signal,
T_site, T_site,
T_small,
T_smd, T_smd,
T_snap, T_snap,
T_snap_angle, T_snap_angle,
@ -420,6 +425,7 @@ enum DSN_T {
T_wiring, T_wiring,
T_write_resolution, T_write_resolution,
T_x, T_x,
T_xy,
T_y, T_y,
T_END // just a sentinel, not a token T_END // just a sentinel, not a token
}; };

View File

@ -34,8 +34,10 @@
$ cd <kicadSourceRoot> $ cd <kicadSourceRoot>
$ doxygen $ doxygen
Then you can view the html documentation in the <kicadSourceRoot>/doxygen Then you can view the html documentation in the <kicadSourceRoot>/doxygen
directory. directory. The main class in this file is SPECCTRA_DB and its main
functions are Load() and Export().
*/ */
@ -113,11 +115,49 @@ struct POINT
float y; float y;
POINT() { x=0.0; y=0.0; } POINT() { x=0.0; y=0.0; }
/**
* Function Format
* writes this object as ASCII out to an OUTPUTFORMATTER according to the
* SPECCTRA DSN format.
* @param out The formatter to write to.
* @param nestLevel A multiple of the number of spaces to preceed the output with.
* @throw IOError if a system error writing the output, such as a full disk.
*/
void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IOError )
{
out->Print( nestLevel, " %f %f", x, y );
}
}; };
typedef std::vector<std::string> STRINGS; typedef std::vector<std::string> STRINGS;
typedef std::vector<POINT> POINTS; typedef std::vector<POINT> POINTS;
struct PROPERTY
{
std::string name;
std::string value;
/**
* Function Format
* writes this object as ASCII out to an OUTPUTFORMATTER according to the
* SPECCTRA DSN format.
* @param out The formatter to write to.
* @param nestLevel A multiple of the number of spaces to preceed the output with.
* @throw IOError if a system error writing the output, such as a full disk.
*/
void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IOError )
{
const char* quoteName = out->GetQuoteChar( name.c_str() );
const char* quoteValue = out->GetQuoteChar( value.c_str() );
out->Print( nestLevel, "(%s%s%s %s%s%s)\n",
quoteName, name.c_str(), quoteName,
quoteValue, value.c_str(), quoteValue );
}
};
typedef std::vector<PROPERTY> PROPERTYS;
/** /**
* Class ELEM * Class ELEM
@ -290,7 +330,7 @@ public:
host_version = CONV_TO_UTF8(g_BuildVersion); host_version = CONV_TO_UTF8(g_BuildVersion);
} }
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ); void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError );
}; };
@ -378,71 +418,102 @@ public:
/** /**
* Class RULES * Class RULE
* corresponds to the <rule_descriptor> in the specctra dsn spec. * corresponds to the <rule_descriptor> in the specctra dsn spec.
*/ */
class RULES : public ELEM class RULE : public ELEM
{ {
friend class SPECCTRA_DB; friend class SPECCTRA_DB;
STRINGS rules; ///< rules are saved in std::string form. STRINGS rules; ///< rules are saved in std::string form.
public: public:
RULES( ELEM* aParent, DSN_T aType ) : RULE( ELEM* aParent, DSN_T aType ) :
ELEM( aType, aParent ) ELEM( aType, aParent )
{ {
} }
~RULES()
{
}
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) );
void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
for( STRINGS::const_iterator i = rules.begin(); i!=rules.end(); ++i ) for( STRINGS::const_iterator i = rules.begin(); i!=rules.end(); ++i )
out->Print( nestLevel+1, "%s\n", i->c_str() ); out->Print( nestLevel, "%s\n", i->c_str() );
}
out->Print( nestLevel, ")\n" );
}
}; };
class LAYER_RULES : public ELEM #if 0
class PLACE_RULE : public RULE
{
friend class SPECCTRA_DB;
DSN_T object_type;
DSN_T image_type;
/* T_spacing, T_permit_orient, T_permit_side & T_opposite_side are
all stored in the kids list.
*/
public:
PLACE_RULE( ELEM* aParent ) :
RULE( aParent, T_place_rule )
{
object_type = T_NONE;
image_type = T_NONE;
}
void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
if( object_type != T_NONE )
{
if( object_type == T_pcb )
out->Print( nestLevel, "(object_type %s",
LEXER::GetTokenText( object_type ) );
else
out->Print( nestLevel, "(object_type image_set %s",
LEXER::GetTokenText( object_type ) );
if( image_type != T_NONE )
out->Print( 0, " (image_type %s)", LEXER::GetTokenText( image_type ) );
out->Print( 0, ")\n" );
}
RULE::FormatContents( out, nestLevel );
}
};
#endif
class LAYER_RULE : public ELEM
{ {
friend class SPECCTRA_DB; friend class SPECCTRA_DB;
STRINGS layer_ids; STRINGS layer_ids;
RULES* rules; RULE* rule;
public: public:
LAYER_RULES( ELEM* aParent ) : LAYER_RULE( ELEM* aParent ) :
ELEM( T_layer_rule, aParent ) ELEM( T_layer_rule, aParent )
{ {
rules = 0; rule = 0;
} }
~LAYER_RULES() ~LAYER_RULE()
{ {
delete rules; delete rule;
} }
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void FormatContent( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{ {
out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) );
for( STRINGS::const_iterator i=layer_ids.begin(); i!=layer_ids.end(); ++i ) for( STRINGS::const_iterator i=layer_ids.begin(); i!=layer_ids.end(); ++i )
{ {
const char* quote = out->GetQuoteChar( i->c_str() ); const char* quote = out->GetQuoteChar( i->c_str() );
out->Print( nestLevel, "%s%s%s\n", quote, i->c_str(), quote ); out->Print( nestLevel, "%s%s%s\n", quote, i->c_str(), quote );
} }
if( rules ) if( rule )
rules->Format( out, nestLevel+1 ); rule->Format( out, nestLevel );
out->Print( nestLevel, ")\n" );
} }
}; };
@ -660,8 +731,8 @@ class KEEPOUT : public ELEM
protected: protected:
std::string name; std::string name;
int sequence_number; int sequence_number;
RULES* rules; RULE* rules;
RULES* place_rules; RULE* place_rules;
typedef boost::ptr_vector<WINDOW> WINDOWS; typedef boost::ptr_vector<WINDOW> WINDOWS;
WINDOWS windows; WINDOWS windows;
@ -905,18 +976,10 @@ class LAYER : public ELEM
int direction; int direction;
int cost; ///< [forbidden | high | medium | low | free | <positive_integer > | -1] int cost; ///< [forbidden | high | medium | low | free | <positive_integer > | -1]
int cost_type; ///< T_length | T_way int cost_type; ///< T_length | T_way
RULES* rules; RULE* rules;
STRINGS use_net; STRINGS use_net;
struct PROPERTY PROPERTYS properties;
{
std::string name;
std::string value;
};
typedef std::vector<PROPERTY> PROPERTYS;
PROPERTYS propertys;
public: public:
@ -945,19 +1008,14 @@ public:
out->Print( nestLevel+1, "(type %s)\n", LEXER::GetTokenText( layer_type ) ); out->Print( nestLevel+1, "(type %s)\n", LEXER::GetTokenText( layer_type ) );
if( propertys.size() ) if( properties.size() )
{ {
out->Print( nestLevel+1, "(property \n" ); out->Print( nestLevel+1, "(property \n" );
for( PROPERTYS::const_iterator i = propertys.begin(); for( PROPERTYS::const_iterator i = properties.begin();
i != propertys.end(); ++i ) i != properties.end(); ++i )
{ {
const char* quoteName = out->GetQuoteChar( i->name.c_str() ); i->Format( out, nestLevel+2 );
const char* quoteValue = out->GetQuoteChar( i->value.c_str() );
out->Print( nestLevel+2, "(%s%s%s %s%s%s)\n",
quoteName, i->name.c_str(), quoteName,
quoteValue, i->value.c_str(), quoteValue );
} }
out->Print( nestLevel+1, ")\n" ); out->Print( nestLevel+1, ")\n" );
} }
@ -1133,7 +1191,7 @@ class REGION : public ELEM
exclusive and are put into the kids container. exclusive and are put into the kids container.
*/ */
RULES* rules; RULE* rules;
public: public:
REGION( ELEM* aParent ) : REGION( ELEM* aParent ) :
@ -1193,10 +1251,10 @@ public:
ELEM( T_grid, aParent ) ELEM( T_grid, aParent )
{ {
grid_type = T_via; grid_type = T_via;
direction = (DSN_T) -1; direction = T_NONE;
dimension = 0.0; dimension = 0.0;
offset = 0.0; offset = 0.0;
image_type= (DSN_T) -1; image_type= T_NONE;
} }
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
@ -1240,7 +1298,7 @@ class STRUCTURE : public ELEM
BOUNDARY* place_boundary; BOUNDARY* place_boundary;
VIA* via; VIA* via;
CONTROL* control; CONTROL* control;
RULES* rules; RULE* rules;
typedef boost::ptr_vector<KEEPOUT> KEEPOUTS; typedef boost::ptr_vector<KEEPOUT> KEEPOUTS;
KEEPOUTS keepouts; KEEPOUTS keepouts;
@ -1251,6 +1309,8 @@ class STRUCTURE : public ELEM
typedef boost::ptr_vector<REGION> REGIONS; typedef boost::ptr_vector<REGION> REGIONS;
REGIONS regions; REGIONS regions;
RULE* place_rules;
typedef boost::ptr_vector<GRID> GRIDS; typedef boost::ptr_vector<GRID> GRIDS;
GRIDS grids; GRIDS grids;
@ -1267,6 +1327,7 @@ public:
via = 0; via = 0;
control = 0; control = 0;
rules = 0; rules = 0;
place_rules = 0;
} }
~STRUCTURE() ~STRUCTURE()
@ -1279,6 +1340,7 @@ public:
delete via; delete via;
delete control; delete control;
delete rules; delete rules;
delete place_rules;
} }
void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
@ -1323,6 +1385,9 @@ public:
if( rules ) if( rules )
rules->Format( out, nestLevel ); rules->Format( out, nestLevel );
if( place_rules )
place_rules->Format( out, nestLevel );
for( unsigned i=0; i<grids.size(); ++i ) for( unsigned i=0; i<grids.size(); ++i )
grids[i].Format( out, nestLevel ); grids[i].Format( out, nestLevel );
@ -1338,6 +1403,155 @@ public:
}; };
class PLACE : public ELEM
{
friend class SPECCTRA_DB;
std::string component_id; ///< reference designator
DSN_T side;
bool isRotated;
float rotation;
bool hasVertex;
POINT vertex;
DSN_T mirror;
DSN_T status;
std::string logical_part;
RULE* place_rules;
PROPERTYS properties;
DSN_T lock_type;
//-----<mutually exclusive>--------------
RULE* rules;
REGION* region;
//-----</mutually exclusive>-------------
std::string part_number;
public:
PLACE( ELEM* aParent ) :
ELEM( T_place, aParent )
{
side = T_NONE;
isRotated = false;
hasVertex = false;
mirror = T_NONE;
status = T_NONE;
place_rules = 0;
lock_type = T_NONE;
rules = 0;
region = 0;
}
~PLACE()
{
delete place_rules;
delete rules;
delete region;
}
void SetVertext( const POINT& aVertex )
{
vertex = aVertex;
hasVertex = true;
}
void SetRotation( float aRotation )
{
rotation = aRotation;
isRotated = true;
}
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError );
};
class COMPONENT : public ELEM
{
friend class SPECCTRA_DB;
std::string image_id;
typedef boost::ptr_vector<PLACE> PLACES;
PLACES places;
public:
COMPONENT( ELEM* aParent ) :
ELEM( T_component, aParent )
{
}
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
const char* quote = out->GetQuoteChar( image_id.c_str() );
out->Print( nestLevel, "(%s %s%s%s\n", LEXER::GetTokenText( Type() ),
quote, image_id.c_str(), quote );
for( unsigned i=0; i<places.size(); ++i )
places[i].Format( out, nestLevel+1 );
out->Print( nestLevel, ")\n" );
}
};
class PLACEMENT : public ELEM
{
friend class SPECCTRA_DB;
DSN_T unit;
int resolution;
DSN_T flip_style;
typedef boost::ptr_vector<COMPONENT> COMPONENTS;
COMPONENTS components;
public:
PLACEMENT( ELEM* aParent ) :
ELEM( T_placement, aParent )
{
unit = T_NONE;
resolution = -1;
flip_style = T_NONE;
}
void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
if( unit != T_NONE )
{
if( resolution >= 0 )
out->Print( nestLevel, "(resolution %s %d)\n",
LEXER::GetTokenText( unit ),
resolution );
else
out->Print( nestLevel, "(unit %s)\n",
LEXER::GetTokenText( unit ) );
}
if( flip_style != T_NONE )
{
out->Print( nestLevel, "(place_control (flip_style %s))\n",
LEXER::GetTokenText( flip_style ) );
}
for( unsigned i=0; i<components.size(); ++i )
components[i].Format( out, nestLevel );
}
};
class PCB : public ELEM class PCB : public ELEM
{ {
friend class SPECCTRA_DB; friend class SPECCTRA_DB;
@ -1347,6 +1561,7 @@ class PCB : public ELEM
RESOLUTION* resolution; RESOLUTION* resolution;
UNIT* unit; UNIT* unit;
STRUCTURE* structure; STRUCTURE* structure;
PLACEMENT* placement;
public: public:
@ -1357,6 +1572,7 @@ public:
resolution = 0; resolution = 0;
unit = 0; unit = 0;
structure = 0; structure = 0;
placement = 0;
} }
~PCB() ~PCB()
@ -1365,6 +1581,7 @@ public:
delete resolution; delete resolution;
delete unit; delete unit;
delete structure; delete structure;
delete placement;
} }
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
@ -1386,6 +1603,9 @@ public:
if( structure ) if( structure )
structure->Format( out, nestLevel+1 ); structure->Format( out, nestLevel+1 );
if( placement )
placement->Format( out, nestLevel+1 );
out->Print( nestLevel, ")\n" ); out->Print( nestLevel, ")\n" );
} }
@ -1460,16 +1680,17 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
void doVIA( VIA* growth ) throw( IOError ); void doVIA( VIA* growth ) throw( IOError );
void doCONTROL( CONTROL* growth ) throw( IOError ); void doCONTROL( CONTROL* growth ) throw( IOError );
void doLAYER( LAYER* growth ) throw( IOError ); void doLAYER( LAYER* growth ) throw( IOError );
void doRULES( RULES* growth ) throw( IOError ); void doRULE( RULE* growth ) throw( IOError );
void doKEEPOUT( KEEPOUT* growth ) throw( IOError ); void doKEEPOUT( KEEPOUT* growth ) throw( IOError );
void doCIRCLE( CIRCLE* growth ) throw( IOError ); void doCIRCLE( CIRCLE* growth ) throw( IOError );
void doQARC( QARC* growth ) throw( IOError ); void doQARC( QARC* growth ) throw( IOError );
void doWINDOW( WINDOW* growth ) throw( IOError ); void doWINDOW( WINDOW* growth ) throw( IOError );
void doREGION( REGION* growth ) throw( IOError ); void doREGION( REGION* growth ) throw( IOError );
void doCLASS_CLASS( CLASS_CLASS* growth ) throw( IOError ); void doCLASS_CLASS( CLASS_CLASS* growth ) throw( IOError );
void doLAYER_RULES( LAYER_RULES* growth ) throw( IOError ); void doLAYER_RULE( LAYER_RULE* growth ) throw( IOError );
void doCLASSES( CLASSES* growth ) throw( IOError ); void doCLASSES( CLASSES* growth ) throw( IOError );
void doGRID( GRID* growth ) throw( IOError ); void doGRID( GRID* growth ) throw( IOError );
// void doPLACE_RULE( PLACE_RULE* growth, bool expect_object_type = false ) throw( IOError );
public: public:
@ -1974,10 +2195,15 @@ L_place:
break; break;
case T_rule: case T_rule:
growth->rules = new RULES( growth, T_rule ); growth->rules = new RULE( growth, T_rule );
doRULES( growth->rules ); doRULE( growth->rules );
break; break;
case T_place_rule:
growth->place_rules = new RULE( growth, T_place_rule );
doRULE( growth->place_rules );
break;
case T_keepout: case T_keepout:
/* @todo /* @todo
case T_place_keepout: case T_place_keepout:
@ -2039,15 +2265,15 @@ void SPECCTRA_DB::doKEEPOUT( KEEPOUT* growth ) throw( IOError )
case T_rule: case T_rule:
if( growth->rules ) if( growth->rules )
unexpected( tok ); unexpected( tok );
growth->rules = new RULES( growth, T_rule ); growth->rules = new RULE( growth, T_rule );
doRULES( growth->rules ); doRULE( growth->rules );
break; break;
case T_place_rule: case T_place_rule:
if( growth->place_rules ) if( growth->place_rules )
unexpected( tok ); unexpected( tok );
growth->place_rules = new RULES( growth, T_place_rule ); growth->place_rules = new RULE( growth, T_place_rule );
doRULES( growth->place_rules ); doRULE( growth->place_rules );
break; break;
case T_rect: case T_rect:
@ -2447,13 +2673,13 @@ void SPECCTRA_DB::doLAYER( LAYER* growth ) throw( IOError )
break; break;
case T_rule: case T_rule:
growth->rules = new RULES( growth, T_rule ); growth->rules = new RULE( growth, T_rule );
doRULES( growth->rules ); doRULE( growth->rules );
break; break;
case T_property: case T_property:
{ {
LAYER::PROPERTY property; // construct it once here, append multiple times. PROPERTY property; // construct it once here, append multiple times.
while( (tok = nextTok()) != T_RIGHT ) while( (tok = nextTok()) != T_RIGHT )
{ {
@ -2470,7 +2696,7 @@ void SPECCTRA_DB::doLAYER( LAYER* growth ) throw( IOError )
expecting( T_SYMBOL ); expecting( T_SYMBOL );
property.value = lexer->CurText(); property.value = lexer->CurText();
growth->propertys.push_back( property ); growth->properties.push_back( property );
if( nextTok() != T_RIGHT ) if( nextTok() != T_RIGHT )
expecting( T_RIGHT ); expecting( T_RIGHT );
@ -2554,11 +2780,11 @@ void SPECCTRA_DB::doLAYER( LAYER* growth ) throw( IOError )
} }
void SPECCTRA_DB::doRULES( RULES* growth ) throw( IOError ) void SPECCTRA_DB::doRULE( RULE* growth ) throw( IOError )
{ {
std::string builder; std::string builder;
int bracketNesting = 1; // we already saw the opening T_LEFT int bracketNesting = 1; // we already saw the opening T_LEFT
DSN_T tok = T_END; DSN_T tok = T_NONE;
while( bracketNesting!=0 && tok!=T_EOF ) while( bracketNesting!=0 && tok!=T_EOF )
{ {
@ -2584,9 +2810,9 @@ void SPECCTRA_DB::doRULES( RULES* growth ) throw( IOError )
builder += quote_char; builder += quote_char;
} }
// when the nested rule is closed with a T_RIGHT and we are back down // When the nested rule is closed with a T_RIGHT and we are back down
// to bracketNesting == 1, (inside the <rule_descriptor> but outside // to bracketNesting == 1, (inside the <rule_descriptor> but outside
// the last rule) then save the last rule and clear the string builder. // the last rule). Then save the last rule and clear the string builder.
if( bracketNesting == 1 ) if( bracketNesting == 1 )
{ {
growth->rules.push_back( builder ); growth->rules.push_back( builder );
@ -2599,6 +2825,94 @@ void SPECCTRA_DB::doRULES( RULES* growth ) throw( IOError )
} }
#if 0
void SPECCTRA_DB::doPLACE_RULE( PLACE_RULE* growth, bool expect_object_type ) throw( IOError )
{
/* (place_rule [<structure_place_rule_object> ]
{[<spacing_descriptor> |
<permit_orient_descriptor> |
<permit_side_descriptor> |
<opposite_side_descriptor> ]}
)
*/
DSN_T tok = nextTok();
if( tok!=T_LEFT )
expecting( T_LEFT );
tok = nextTok();
if( tok==T_object_type )
{
if( !expect_object_type )
unexpected( tok );
/* [(object_type
[pcb |
image_set [large | small | discrete | capacitor | resistor]
[(image_type [smd | pin])]]
)]
*/
tok = nextTok();
switch( tok )
{
case T_pcb:
growth->object_type = tok;
break;
case T_image_set:
tok = nextTok();
switch( tok )
{
case T_large:
case T_small:
case T_discrete:
case T_capacitor:
case T_resistor:
growth->object_type = tok;
break;
default:
unexpected( lexer->CurText() );
}
break;
default:
unexpected( lexer->CurText() );
}
tok = nextTok();
if( tok == T_LEFT )
{
tok = nextTok();
if( tok != T_image_type )
expecting( T_image_type );
tok = nextTok();
if( tok!=T_smd && tok!=T_pin )
expecting( wxT("smd|pin") );
if( nextTok() != T_RIGHT )
expecting( T_RIGHT );
tok = nextTok();
}
if( tok != T_RIGHT )
expecting( T_RIGHT );
tok = nextTok();
}
/* {[<spacing_descriptor> |
<permit_orient_descriptor> |
<permit_side_descriptor> | <opposite_side_descriptor> ]}
*/
doRULE( growth );
}
#endif
void SPECCTRA_DB::doREGION( REGION* growth ) throw( IOError ) void SPECCTRA_DB::doREGION( REGION* growth ) throw( IOError )
{ {
DSN_T tok = nextTok(); DSN_T tok = nextTok();
@ -2643,8 +2957,8 @@ void SPECCTRA_DB::doREGION( REGION* growth ) throw( IOError )
break; break;
case T_rule: case T_rule:
growth->rules = new RULES( growth, T_rule ); growth->rules = new RULE( growth, T_rule );
doRULES( growth->rules ); doRULE( growth->rules );
break; break;
default: default:
@ -2681,22 +2995,23 @@ void SPECCTRA_DB::doCLASS_CLASS( CLASS_CLASS* growth ) throw( IOError )
break; break;
case T_rule: case T_rule:
// only T_class_class takes a T_rule
if( growth->Type() == T_region_class_class ) if( growth->Type() == T_region_class_class )
unexpected( tok ); unexpected( tok );
RULES* rule; RULE* rule;
rule = new RULES( growth, T_rule ); rule = new RULE( growth, T_rule );
growth->Append( rule ); growth->Append( rule );
doRULES( rule ); doRULE( rule );
break; break;
case T_layer_rule: case T_layer_rule:
// only T_class_class takes a T_layer_rule
if( growth->Type() == T_region_class_class ) if( growth->Type() == T_region_class_class )
unexpected( tok ); unexpected( tok );
LAYER_RULES* layer_rule; LAYER_RULE* layer_rule;
layer_rule = new LAYER_RULES( growth ); layer_rule = new LAYER_RULE( growth );
growth->Append( layer_rule ); growth->Append( layer_rule );
// doLAYER_RULES( layer_rule ); doLAYER_RULE( layer_rule );
// @todo
break; break;
default: default:
@ -2726,7 +3041,6 @@ void SPECCTRA_DB::doCLASSES( CLASSES* growth ) throw( IOError )
growth->class_ids.push_back( lexer->CurText() ); growth->class_ids.push_back( lexer->CurText() );
} while( (tok = nextTok()) != T_RIGHT ); } while( (tok = nextTok()) != T_RIGHT );
} }
@ -2795,6 +3109,33 @@ void SPECCTRA_DB::doGRID( GRID* growth ) throw( IOError )
} }
void SPECCTRA_DB::doLAYER_RULE( LAYER_RULE* growth ) throw( IOError )
{
DSN_T tok = nextTok();
if( !isSymbol(tok ) )
expecting( wxT("<layer_id>") );
do
{
growth->layer_ids.push_back( lexer->CurText() );
} while( isSymbol(tok = nextTok()) );
if( nextTok() != T_LEFT )
expecting( T_LEFT );
if( nextTok() != T_rule )
expecting( T_rule );
growth->rule = new RULE( growth, T_rule );
doRULE( growth->rule );
if( nextTok() != T_RIGHT )
expecting( T_RIGHT );
}
void SPECCTRA_DB::Print( int nestLevel, const char* fmt, ... ) throw( IOError ) void SPECCTRA_DB::Print( int nestLevel, const char* fmt, ... ) throw( IOError )
{ {
va_list args; va_list args;
@ -2911,33 +3252,101 @@ int ELEM::FindElem( DSN_T aType, int instanceNum )
//-----<PARSER>----------------------------------------------------------- //-----<PARSER>-----------------------------------------------------------
void PARSER::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void PARSER::FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{ {
out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) ); out->Print( nestLevel, "(string_quote %c)\n", string_quote );
out->Print( nestLevel+1, "(string_quote %c)\n", string_quote ); out->Print( nestLevel, "(space_in_quoted_tokens %s)\n", space_in_quoted_tokens ? "on" : "off" );
out->Print( nestLevel+1, "(space_in_quoted_tokens %s)\n", space_in_quoted_tokens ? "on" : "off" ); out->Print( nestLevel, "(host_cad \"%s\")\n", host_cad.c_str() );
out->Print( nestLevel+1, "(host_cad \"%s\")\n", host_cad.c_str() ); out->Print( nestLevel, "(host_version \"%s\")\n", host_version.c_str() );
out->Print( nestLevel+1, "(host_version \"%s\")\n", host_version.c_str() );
if( const_id1.length()>0 || const_id2.length()>0 ) if( const_id1.length()>0 || const_id2.length()>0 )
out->Print( nestLevel+1, "(constant %c%s%c %c%s%c)\n", out->Print( nestLevel, "(constant %c%s%c %c%s%c)\n",
string_quote, const_id1.c_str(), string_quote, string_quote, const_id1.c_str(), string_quote,
string_quote, const_id2.c_str(), string_quote ); string_quote, const_id2.c_str(), string_quote );
if( routes_include_testpoint || routes_include_guides || routes_include_image_conductor ) if( routes_include_testpoint || routes_include_guides || routes_include_image_conductor )
out->Print( nestLevel+1, "(routes_include%s%s%s)\n", out->Print( nestLevel, "(routes_include%s%s%s)\n",
routes_include_testpoint ? " testpoint" : "", routes_include_testpoint ? " testpoint" : "",
routes_include_guides ? " guides" : "", routes_include_guides ? " guides" : "",
routes_include_image_conductor ? " image_conductor" : ""); routes_include_image_conductor ? " image_conductor" : "");
if( wires_include_testpoint ) if( wires_include_testpoint )
out->Print( nestLevel+1, "(wires_include testpoint)\n" ); out->Print( nestLevel, "(wires_include testpoint)\n" );
if( !via_rotate_first ) if( !via_rotate_first )
out->Print( nestLevel+1, "(via_rotate_first off)\n" ); out->Print( nestLevel, "(via_rotate_first off)\n" );
out->Print( nestLevel+1, "(case_sensitive %s)\n", case_sensitive ? "on" : "off" ); out->Print( nestLevel, "(case_sensitive %s)\n", case_sensitive ? "on" : "off" );
out->Print( nestLevel, ")\n" ); }
void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
const char* quote = out->GetQuoteChar( component_id.c_str() );
out->Print( nestLevel, "(%s %s%s%s\n", LEXER::GetTokenText( Type() ),
quote, component_id.c_str(), quote );
out->Print( nestLevel+1, "%s", "" );
if( hasVertex )
out->Print( 0, "%f %f ", vertex.x, vertex.y );
if( side != T_NONE )
out->Print( 0, "%s ", LEXER::GetTokenText( side ) );
if( isRotated )
out->Print( 0, "%f ", rotation );
if( mirror != T_NONE )
out->Print( 0, "(mirror %s)", LEXER::GetTokenText( mirror ) );
if( status != T_NONE )
out->Print( 0, "(status %s)", LEXER::GetTokenText( status ) );
if( logical_part.size() )
{
quote = out->GetQuoteChar( logical_part.c_str() );
out->Print( 0, "(logical_part %s%s%s)",
quote, logical_part.c_str(), quote );
}
if( place_rules || properties.size() || lock_type!=T_NONE || rules || region || part_number.size() )
{
out->Print( 0, "\n" );
if( place_rules )
{
place_rules->Format( out, nestLevel+1 );
}
if( properties.size() )
{
out->Print( nestLevel+1, "(property \n" );
for( PROPERTYS::const_iterator i = properties.begin();
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",
LEXER::GetTokenText(lock_type) );
if( rules )
rules->Format( out, nestLevel+1 );
if( region )
region->Format( out, nestLevel+1 );
if( part_number.size() )
{
const char* quote = out->GetQuoteChar( part_number.c_str() );
out->Print( nestLevel+1, "(PN %s%s%s)\n",
quote, part_number.c_str(), quote );
}
}
else
out->Print( 0, ")\n" );
} }
@ -2946,22 +3355,10 @@ void PARSER::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
using namespace DSN; using namespace DSN;
// a test to verify some of the list management functions. // unit test this source file
int main( int argc, char** argv ) int main( int argc, char** argv )
{ {
#if 0
ELEM parent( T_pcb );
ELEM* child = new ELEM( T_absolute );
parent.Append( child );
parent[0]->Test();
child->Append( new ELEM( T_absolute ) );
#else
wxString filename( wxT("/tmp/fpcroute/Sample_1sided/demo_1sided.dsn") ); wxString filename( wxT("/tmp/fpcroute/Sample_1sided/demo_1sided.dsn") );
// wxString filename( wxT("/tmp/testdesigns/test.dsn") ); // wxString filename( wxT("/tmp/testdesigns/test.dsn") );
@ -2985,8 +3382,6 @@ int main( int argc, char** argv )
db.Export( wxT("/tmp/export.dsn"), 0 ); db.Export( wxT("/tmp/export.dsn"), 0 );
#endif
} }