diff --git a/pcbnew/dsn.cpp b/pcbnew/dsn.cpp index 7d4bfbd9d0..c7097d48f2 100644 --- a/pcbnew/dsn.cpp +++ b/pcbnew/dsn.cpp @@ -588,7 +588,7 @@ DSN_T LEXER::NextTok() throw (IOError) char* cur = next; char* head = cur; - lastTok = curTok; + prevTok = curTok; if( curTok != T_EOF ) { @@ -613,7 +613,7 @@ L_read: goto L_read; // switching the string_quote character - if( lastTok == T_string_quote ) + if( prevTok == T_string_quote ) { static const wxString errtxt( _("String delimiter must be a single character of ', \", or $")); diff --git a/pcbnew/dsn.h b/pcbnew/dsn.h index 3e703ef8e0..2516f5cd79 100644 --- a/pcbnew/dsn.h +++ b/pcbnew/dsn.h @@ -527,7 +527,7 @@ class LEXER bool space_in_quoted_tokens; ///< blank spaces within quoted strings wxString filename; - int lastTok; ///< curTok from previous NextTok() call. + DSN_T prevTok; ///< curTok from previous NextTok() call. int curOffset; ///< offset within current line of the current token DSN_T curTok; ///< the current token obtained on last NextTok() @@ -640,7 +640,6 @@ public: return curText.c_str(); } - /** * Function CurTok * returns whatever NextTok() returned the last time it was called. @@ -650,6 +649,15 @@ public: return curTok; } + /** + * Function PrevTok + * returns whatever NextTok() returned the 2nd to last time it was called. + */ + DSN_T PrevTok() + { + return prevTok; + } + /** * Function CurOffset * returns the char offset within the current line, using a 1 based index. diff --git a/pcbnew/specctra.cpp b/pcbnew/specctra.cpp index d9e332e888..afaf0d4218 100644 --- a/pcbnew/specctra.cpp +++ b/pcbnew/specctra.cpp @@ -538,23 +538,36 @@ public: }; -/** - * Class RULE - * holds a single rule and corresponds to - */ -class RULE : public ELEM -{ - -}; - - /** * Class RULES * corresponds to the in the specctra dsn spec. */ class RULES : public ELEM { - ; + friend class SPECCTRA_DB; + + STRINGS rules; ///< rules are saved in std::string form. + +public: + + RULES( ELEM* aParent ) : + ELEM( T_rule, aParent ) + { + } + + ~RULES() + { + } + + void Save( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) + { + out->Print( nestLevel, "(%s\n", LEXER::GetTokenText( Type() ) ); + + for( STRINGS::const_iterator i = rules.begin(); i!=rules.end(); ++i ) + out->Print( nestLevel+1, "%s\n", i->c_str() ); + + out->Print( nestLevel, ")\n" ); + } }; @@ -670,6 +683,7 @@ class STRUCTURE : public ELEM BOUNDARY* place_boundary; VIA* via; CONTROL* control; + RULES* rules; typedef boost::ptr_vector LAYERS; LAYERS layers; @@ -684,6 +698,7 @@ public: place_boundary = 0; via = 0; control = 0; + rules = 0; } ~STRUCTURE() @@ -693,6 +708,7 @@ public: delete place_boundary; delete via; delete control; + delete rules; } void Save( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) @@ -722,6 +738,9 @@ public: At(i)->Save( out, nestLevel+1 ); } + if( rules ) + rules->Save( out, nestLevel+1 ); + out->Print( nestLevel, ")\n" ); } @@ -910,6 +929,7 @@ class SPECCTRA_DB : public OUTPUTFORMATTER void doVIA( VIA* growth ) throw( IOError ); void doCONTROL( CONTROL* growth ) throw( IOError ); void doLAYER( LAYER* growth ) throw( IOError ); + void doRULES( RULES* growth ) throw( IOError ); public: @@ -1338,6 +1358,11 @@ L_place: growth->layers.push_back( layer ); doLAYER( layer ); break; + + case T_rule: + growth->rules = new RULES( growth ); + doRULES( growth->rules ); + break; default: unexpected( lexer->CurText() ); @@ -1608,7 +1633,8 @@ void SPECCTRA_DB::doLAYER( LAYER* growth ) throw( IOError ) break; case T_rule: - // @todo + growth->rules = new RULES( growth ); + doRULES( growth->rules ); break; case T_property: @@ -1714,6 +1740,39 @@ void SPECCTRA_DB::doLAYER( LAYER* growth ) throw( IOError ) } +void SPECCTRA_DB::doRULES( RULES* growth ) throw( IOError ) +{ + std::string builder; + int bracketNesting = 1; // we already saw the opening T_LEFT + + while( bracketNesting != 0 ) + { + DSN_T tok = nextTok(); + + switch( tok ) + { + case T_LEFT: ++bracketNesting; break; + case T_RIGHT: --bracketNesting; break; + default: + ; + } + + if( bracketNesting >= 1 ) + { + if( lexer->PrevTok() != T_LEFT && tok!=T_RIGHT ) + builder += ' '; + + builder += lexer->CurText(); + } + + if( bracketNesting == 1 ) + { + growth->rules.push_back( builder ); + builder.clear(); + } + } +} + void SPECCTRA_DB::Print( int nestLevel, const char* fmt, ... ) throw( IOError ) { va_list args;