Commit 36f6103b authored by dickelbeck's avatar dickelbeck

more specctra dsn work

parent ba762faf
......@@ -120,6 +120,7 @@ const static KEYWORD tokens[] = {
TOKDEF(deleted_keepout),
TOKDEF(delete_pins),
TOKDEF(delta),
TOKDEF(diagonal),
TOKDEF(direction),
TOKDEF(directory),
TOKDEF(effective_via_length),
......@@ -139,6 +140,7 @@ const static KEYWORD tokens[] = {
TOKDEF(forbidden),
TOKDEF(force_to_terminal_point),
TOKDEF(forgotten),
TOKDEF(free),
TOKDEF(fromto),
TOKDEF(front),
TOKDEF(front_only),
......@@ -151,6 +153,7 @@ const static KEYWORD tokens[] = {
TOKDEF(guide),
TOKDEF(hard),
TOKDEF(height),
TOKDEF(high),
TOKDEF(history),
TOKDEF(horizontal),
TOKDEF(host_cad),
......@@ -197,6 +200,7 @@ const static KEYWORD tokens[] = {
TOKDEF(lock_type),
TOKDEF(logical_part),
TOKDEF(logical_part_mapping),
TOKDEF(low),
TOKDEF(match_fromto_delay),
TOKDEF(match_fromto_length),
TOKDEF(match_group_delay),
......@@ -213,6 +217,7 @@ const static KEYWORD tokens[] = {
TOKDEF(max_total_delay),
TOKDEF(max_total_length),
TOKDEF(max_total_vias),
TOKDEF(medium),
TOKDEF(mhenry),
TOKDEF(mho),
TOKDEF(microvia),
......@@ -221,7 +226,9 @@ const static KEYWORD tokens[] = {
TOKDEF(min_gap),
TOKDEF(mirror),
TOKDEF(mirror_first),
TOKDEF(mixed),
TOKDEF(mm),
TOKDEF(negative_diagonal),
TOKDEF(net),
TOKDEF(net_number),
TOKDEF(net_pin_changes),
......@@ -240,6 +247,7 @@ const static KEYWORD tokens[] = {
TOKDEF(open),
TOKDEF(opposite_side),
TOKDEF(order),
TOKDEF(orthogonal),
TOKDEF(outline),
TOKDEF(overlap),
TOKDEF(pad),
......@@ -276,6 +284,7 @@ const static KEYWORD tokens[] = {
TOKDEF(point),
TOKDEF(polygon),
TOKDEF(position),
TOKDEF(positive_diagonal),
TOKDEF(power),
TOKDEF(power_dissipation),
TOKDEF(power_fanout),
......@@ -387,6 +396,7 @@ const static KEYWORD tokens[] = {
TOKDEF(use_net),
TOKDEF(use_via),
TOKDEF(value),
TOKDEF(vertical),
TOKDEF(via),
TOKDEF(via_array_template),
TOKDEF(via_at_smd),
......
......@@ -120,6 +120,7 @@ enum DSN_T {
T_deleted_keepout,
T_delete_pins,
T_delta,
T_diagonal,
T_direction,
T_directory,
T_effective_via_length,
......@@ -138,6 +139,7 @@ enum DSN_T {
T_footprint,
T_forbidden,
T_force_to_terminal_point,
T_free,
T_forgotten,
T_fromto,
T_front,
......@@ -151,6 +153,7 @@ enum DSN_T {
T_guide,
T_hard,
T_height,
T_high,
T_history,
T_horizontal,
T_host_cad,
......@@ -197,6 +200,7 @@ enum DSN_T {
T_lock_type,
T_logical_part,
T_logical_part_mapping,
T_low,
T_match_fromto_delay,
T_match_fromto_length,
T_match_group_delay,
......@@ -213,6 +217,7 @@ enum DSN_T {
T_max_total_delay,
T_max_total_length,
T_max_total_vias,
T_medium,
T_mhenry,
T_mho,
T_microvia,
......@@ -221,7 +226,9 @@ enum DSN_T {
T_min_gap,
T_mirror,
T_mirror_first,
T_mixed,
T_mm,
T_negative_diagonal,
T_net,
T_net_number,
T_net_pin_changes,
......@@ -240,6 +247,7 @@ enum DSN_T {
T_open,
T_opposite_side,
T_order,
T_orthogonal,
T_outline,
T_overlap,
T_pad,
......@@ -276,6 +284,7 @@ enum DSN_T {
T_point,
T_polygon,
T_position,
T_positive_diagonal,
T_power,
T_power_dissipation,
T_power_fanout,
......@@ -387,6 +396,7 @@ enum DSN_T {
T_use_net,
T_use_via,
T_value,
T_vertical,
T_via,
T_via_array_template,
T_via_at_smd,
......
......@@ -23,6 +23,21 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* This source file implements export and import capabilities to the
specctra dsn file format. The grammar for that file format is documented
fairly well. There are classes for each major type of descriptor in the
spec.
Since there are so many classes in here, it may be helpful to generate
the Doxygen directory:
$ cd <kicadSourceRoot>
$ doxygen
Then you can view the html documentation in the <kicadSourceRoot>/doxygen
directory.
*/
#include <cstdarg>
#include <cstdio>
......@@ -91,6 +106,8 @@ struct POINT
POINT() { x=0.0; y=0.0; }
};
typedef std::vector<std::string> STRINGS;
/**
......@@ -435,8 +452,6 @@ class VIA : public ELEM
{
friend class SPECCTRA_DB;
typedef std::vector<std::string> STRINGS;
STRINGS padstacks;
STRINGS spares;
......@@ -509,6 +524,135 @@ public:
out->Print( nestLevel+1, "(via_at_smd %s", via_at_smd ? "on" : "off" );
if( via_at_smd_grid_on )
out->Print( 0, " grid %s", via_at_smd_grid_on ? "on" : "off" );
out->Print( 0, ")\n" );
}
for( int i=0; i<Length(); ++i )
{
At(i)->Save( out, nestLevel+1 );
}
out->Print( nestLevel, ")\n" );
}
};
/**
* Class RULE
* holds a single rule and corresponds to <rule_descriptors>
*/
class RULE : public ELEM
{
};
/**
* Class RULES
* corresponds to the <rule_descriptor> in the specctra dsn spec.
*/
class RULES : public ELEM
{
;
};
class LAYER : public ELEM
{
friend class SPECCTRA_DB;
std::string name;
DSN_T layer_type; ///< one of: T_signal, T_power, T_mixed, T_jumper
int direction;
int cost; ///< [forbidden | high | medium | low | free | <positive_integer > | -1]
int cost_type; ///< T_length | T_way
RULES* rules;
STRINGS use_net;
struct PROPERTY
{
std::string name;
std::string value;
};
typedef std::vector<PROPERTY> PROPERTYS;
PROPERTYS propertys;
public:
LAYER( ELEM* aParent ) :
ELEM( T_layer, aParent )
{
layer_type = T_signal;
direction = -1;
cost = -1;
cost_type = -1;
rules = 0;
}
~LAYER()
{
delete rules;
}
void Save( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
const char* quote = out->GetQuoteChar( name.c_str() );
out->Print( nestLevel, "(%s %s%s%s\n", LEXER::GetTokenText( Type() ),
quote, name.c_str(), quote );
out->Print( nestLevel+1, "(type %s)\n", LEXER::GetTokenText( layer_type ) );
if( propertys.size() )
{
out->Print( nestLevel+1, "(property \n" );
for( PROPERTYS::const_iterator i = propertys.begin();
i != propertys.end(); ++i )
{
const char* quoteName = out->GetQuoteChar( i->name.c_str() );
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" );
}
if( direction != -1 )
out->Print( nestLevel+1, "(direction %s)\n",
LEXER::GetTokenText( (DSN_T)direction ) );
if( rules )
rules->Save( out, nestLevel+1 );
if( cost != -1 )
{
if( cost < 0 )
out->Print( nestLevel+1, "(cost %d", -cost ); // positive integer, stored as negative
else
out->Print( nestLevel+1, "(cost %s", LEXER::GetTokenText( (DSN_T)cost ) );
if( cost_type != -1 )
out->Print( 0, " (type %s)", LEXER::GetTokenText( (DSN_T)cost_type ) );
out->Print( 0, ")\n" );
}
if( use_net.size() )
{
out->Print( nestLevel+1, "(use_net" );
for( STRINGS::const_iterator i = use_net.begin(); i!=use_net.end(); ++i )
{
const char* quote = out->GetQuoteChar( i->c_str() );
out->Print( 0, " %s%s%s",
quote, i->c_str(), quote );
}
out->Print( 0, ")\n" );
}
......@@ -527,6 +671,9 @@ class STRUCTURE : public ELEM
VIA* via;
CONTROL* control;
typedef boost::ptr_vector<LAYER> LAYERS;
LAYERS layers;
public:
STRUCTURE( ELEM* aParent ) :
......@@ -555,6 +702,9 @@ public:
if( unit )
unit->Save( out, nestLevel+1 );
for( unsigned i=0; i<layers.size(); ++i )
layers[i].Save( out, nestLevel+1 );
if( boundary )
boundary->Save( out, nestLevel+1 );
......@@ -586,19 +736,19 @@ public:
/**
* Class BOOLPROP
* is a container for a single property whose value is a boolean (on|off).
* The name of the property is obtained from the DSN_T.
* Class TOKPROP
* is a container for a single property whose value is another token.
* The name of the property is obtained from the DSN_T Type().
*/
class BOOLPROP : public ELEM
class TOKPROP : public ELEM
{
friend class SPECCTRA_DB;
bool value;
DSN_T value;
public:
BOOLPROP( ELEM* aParent, DSN_T aType ) :
TOKPROP( ELEM* aParent, DSN_T aType ) :
ELEM( aType, aParent )
{
}
......@@ -606,7 +756,7 @@ public:
void Save( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{
out->Print( nestLevel, "(%s %s)\n", LEXER::GetTokenText( Type() ),
value ? "on" : "off" );
LEXER::GetTokenText( value ) );
}
};
......@@ -756,10 +906,10 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
void doRECTANGLE( RECTANGLE* growth ) throw( IOError );
void doPATH( PATH* growth ) throw( IOError );
void doSTRINGPROP( STRINGPROP* growth ) throw( IOError );
void doBOOLPROP( STRINGPROP* growth ) throw( IOError );
void doTOKPROP( TOKPROP* growth ) throw( IOError );
void doVIA( VIA* growth ) throw( IOError );
void doCONTROL( CONTROL* growth ) throw( IOError );
void doLAYER( LAYER* growth ) throw( IOError );
public:
......@@ -1167,7 +1317,8 @@ L_place:
case T_snap_angle:
STRINGPROP* stringprop;
growth->Append( stringprop = new STRINGPROP( growth, T_snap_angle ) );
stringprop = new STRINGPROP( growth, T_snap_angle );
growth->Append( stringprop );
doSTRINGPROP( stringprop );
break;
......@@ -1180,6 +1331,13 @@ L_place:
growth->control = new CONTROL( growth );
doCONTROL( growth->control );
break;
case T_layer:
LAYER* layer;
layer = new LAYER( growth );
growth->layers.push_back( layer );
doLAYER( layer );
break;
default:
unexpected( lexer->CurText() );
......@@ -1332,14 +1490,14 @@ void SPECCTRA_DB::doSTRINGPROP( STRINGPROP* growth ) throw( IOError )
}
void SPECCTRA_DB::doBOOLPROP( STRINGPROP* growth ) throw( IOError )
void SPECCTRA_DB::doTOKPROP( TOKPROP* growth ) throw( IOError )
{
DSN_T tok = nextTok();
if( tok!=T_on && tok!=T_off )
expecting( wxT("on|off") );
if( tok<0 )
unexpected( lexer->CurText() );
growth->value = (tok==T_on);
growth->value = tok;
if( nextTok() != T_RIGHT )
expecting( T_RIGHT );
......@@ -1381,22 +1539,176 @@ void SPECCTRA_DB::doCONTROL( CONTROL* growth ) throw( IOError )
while( (tok = nextTok()) != T_RIGHT )
{
if( tok == T_LEFT )
if( tok != T_LEFT )
expecting( T_LEFT );
tok = nextTok();
switch( tok )
{
case T_via_at_smd:
tok = nextTok();
if( tok!=T_on && tok!=T_off )
expecting( wxT("on|off") );
growth->via_at_smd = (tok==T_on);
if( nextTok() != T_RIGHT )
expecting( T_RIGHT );
break;
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;
default:
unexpected( lexer->CurText() );
}
}
}
void SPECCTRA_DB::doLAYER( LAYER* growth ) throw( IOError )
{
DSN_T tok = nextTok();
if( !isSymbol(tok) )
expecting(T_SYMBOL);
growth->name = lexer->CurText();
while( (tok = nextTok()) != T_RIGHT )
{
if( tok != T_LEFT )
expecting( T_LEFT );
tok = nextTok();
switch( tok )
{
case T_type:
tok = nextTok();
if( tok!=T_signal && tok!=T_power && tok!=T_mixed && tok!=T_jumper )
expecting( wxT("signal|power|mixed|jumper") );
growth->layer_type = tok;
if( nextTok()!=T_RIGHT )
expecting(T_RIGHT);
break;
case T_rule:
// @todo
break;
case T_property:
{
LAYER::PROPERTY property; // construct it once here, append multiple times.
while( (tok = nextTok()) != T_RIGHT )
{
if( tok != T_LEFT )
expecting( T_LEFT );
tok = nextTok();
if( !isSymbol(tok) )
expecting( T_SYMBOL );
property.name = lexer->CurText();
tok = nextTok();
if( !isSymbol(tok) )
expecting( T_SYMBOL );
property.value = lexer->CurText();
growth->propertys.push_back( property );
if( nextTok() != T_RIGHT )
expecting( T_RIGHT );
}
}
break;
case T_direction:
tok = nextTok();
switch( tok )
{
case T_via_at_smd:
tok = nextTok();
if( tok!=T_on && tok!=T_off )
expecting( wxT("on|off") );
growth->via_at_smd = (tok==T_on);
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;
break;
default:
unexpected( lexer->CurText() );
expecting( wxT("horizontal|vertical|orthogonal|positive_diagonal|negative_diagonal|diagonal|off") );
}
if( nextTok()!=T_RIGHT )
expecting(T_RIGHT);
break;
case T_cost:
tok = nextTok();
switch( tok )
{
case T_forbidden:
case T_high:
case T_medium:
case T_low:
case T_free:
growth->cost = tok;
break;
case T_NUMBER:
// store as negative so we can differentiate between
// DSN_T (positive) and T_NUMBER (negative)
growth->cost = -atoi( lexer->CurText() );
break;
default:
expecting( wxT("forbidden|high|medium|low|free|<positive_integer>|-1") );
}
tok = nextTok();
if( tok == T_LEFT )
{
if( nextTok() != T_type )
unexpected( lexer->CurText() );
tok = nextTok();
if( tok!=T_length && tok!=T_way )
expecting( wxT("length|way") );
growth->cost_type = tok;
if( nextTok()!=T_RIGHT )
expecting(T_RIGHT);
tok = nextTok();
}
if( tok!=T_RIGHT )
expecting(T_RIGHT);
break;
case T_use_net:
while( (tok = nextTok()) != T_RIGHT )
{
if( !isSymbol(tok) )
expecting( T_SYMBOL );
growth->use_net.push_back( lexer->CurText() );
}
break;
default:
unexpected( lexer->CurText() );
}
}
}
......@@ -1428,12 +1740,12 @@ const char* SPECCTRA_DB::GetQuoteChar( const char* wrapee )
{
while( *wrapee )
{
// if the string to be wrapped, the wrapee has a delimiter in it,
// use the quote_char
// if the string to be wrapped (wrapee) has a delimiter in it,
// return the quote_char so caller wraps the wrapee.
if( strchr( "\t ()", *wrapee++ ) )
return quote_char.c_str();
}
return ""; // can use and unwrapped string.
return ""; // can use an unwrapped string.
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment