mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-13 17:53:11 +02:00
ADDED: text variable processing in DRC rules.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/11231
This commit is contained in:
parent
38f4a21b96
commit
89fcd3134e
@ -543,6 +543,7 @@ int DSNLEXER::NextTok()
|
||||
const char* head = cur;
|
||||
|
||||
prevTok = curTok;
|
||||
curSeparator.clear();
|
||||
|
||||
if( curTok == DSN_EOF )
|
||||
goto exit;
|
||||
@ -565,7 +566,10 @@ L_read:
|
||||
|
||||
// skip leading whitespace
|
||||
while( cur < limit && isSpace( *cur ) )
|
||||
{
|
||||
curSeparator += *cur;
|
||||
++cur;
|
||||
}
|
||||
|
||||
// If the first non-blank character is #, this line is a comment.
|
||||
// Comments cannot follow any other token on the same line.
|
||||
@ -597,7 +601,10 @@ L_read:
|
||||
{
|
||||
// skip leading whitespace
|
||||
while( cur < limit && isSpace( *cur ) )
|
||||
{
|
||||
curSeparator += *cur;
|
||||
++cur;
|
||||
}
|
||||
}
|
||||
|
||||
if( cur >= limit )
|
||||
|
@ -586,7 +586,10 @@ bool COMPILER::lexDefault( T_TOKEN& aToken )
|
||||
case ',': retval.token = G_COMMA; break;
|
||||
|
||||
default:
|
||||
reportError( CST_PARSE, wxString::Format( _( "Unrecognized character '%c'" ), (char) ch ) );
|
||||
if( m_tokenizer.MatchAhead( "${", []( int c ) -> bool { return c != '{'; } ) )
|
||||
reportError( CST_PARSE, _( "Unresolved text variable reference" ), m_sourcePos + 2 );
|
||||
else
|
||||
reportError( CST_PARSE, wxString::Format( _( "Unrecognized character '%c'" ), (char) ch ) );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -427,6 +427,11 @@ public:
|
||||
return curText;
|
||||
}
|
||||
|
||||
const std::string& CurSeparator() const
|
||||
{
|
||||
return curSeparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current token text as a wxString, assuming that the input byte stream
|
||||
* is UTF8 encoded.
|
||||
@ -572,6 +577,7 @@ protected:
|
||||
|
||||
int curTok; ///< The current token obtained on last NextTok().
|
||||
std::string curText; ///< The text of the current token.
|
||||
std::string curSeparator; ///< The text of the separator preceeding the current text.
|
||||
|
||||
const KEYWORD* keywords; ///< Table sorted by CMake for bsearch().
|
||||
unsigned keywordCount; ///< Count of keywords table.
|
||||
|
@ -708,7 +708,18 @@ void PANEL_SETUP_RULES::OnCompile( wxCommandEvent& event )
|
||||
{
|
||||
std::vector<std::shared_ptr<DRC_RULE>> dummyRules;
|
||||
|
||||
DRC_RULES_PARSER parser( m_textEditor->GetText(), _( "DRC rules" ) );
|
||||
std::function<bool( wxString* )> resolver =
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
if( m_frame->Prj().TextVarResolver( token ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
wxString rulesText = ExpandTextVars( m_textEditor->GetText(), &resolver );
|
||||
|
||||
DRC_RULES_PARSER parser( rulesText, _( "DRC rules" ) );
|
||||
|
||||
parser.Parse( dummyRules, m_errorsReport );
|
||||
}
|
||||
|
@ -494,11 +494,24 @@ void DRC_ENGINE::loadRules( const wxFileName& aPath )
|
||||
{
|
||||
std::vector<std::shared_ptr<DRC_RULE>> rules;
|
||||
|
||||
FILE* fp = wxFopen( aPath.GetFullPath(), wxT( "rt" ) );
|
||||
|
||||
if( fp )
|
||||
if( FILE* fp = wxFopen( aPath.GetFullPath(), wxT( "rt" ) ) )
|
||||
{
|
||||
DRC_RULES_PARSER parser( fp, aPath.GetFullPath() );
|
||||
FILE_LINE_READER lineReader( fp, aPath.GetFullPath() ); // Will close rules file
|
||||
wxString rulesText;
|
||||
|
||||
std::function<bool( wxString* )> resolver =
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
if( m_board && m_board->GetProject() )
|
||||
return m_board->GetProject()->TextVarResolver( token );
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
while( char* line = lineReader.ReadLine() )
|
||||
rulesText << ExpandTextVars( line, &resolver ) << '\n';
|
||||
|
||||
DRC_RULES_PARSER parser( rulesText, aPath.GetFullPath() );
|
||||
parser.Parse( rules, m_logReporter );
|
||||
}
|
||||
|
||||
|
@ -43,15 +43,6 @@ DRC_RULES_PARSER::DRC_RULES_PARSER( const wxString& aSource, const wxString& aSo
|
||||
}
|
||||
|
||||
|
||||
DRC_RULES_PARSER::DRC_RULES_PARSER( FILE* aFile, const wxString& aFilename ) :
|
||||
DRC_RULES_LEXER( aFile, aFilename ),
|
||||
m_requiredVersion( 0 ),
|
||||
m_tooRecent( false ),
|
||||
m_reporter( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DRC_RULES_PARSER::reportError( const wxString& aMessage )
|
||||
{
|
||||
wxString rest;
|
||||
@ -121,6 +112,9 @@ wxString DRC_RULES_PARSER::parseExpression()
|
||||
break;
|
||||
}
|
||||
|
||||
if( !expr.IsEmpty() )
|
||||
expr += CurSeparator();
|
||||
|
||||
expr += FromUTF8();
|
||||
}
|
||||
|
||||
@ -720,6 +714,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
|
||||
|
||||
case T_min:
|
||||
{
|
||||
size_t offset = CurOffset() + GetTokenString( token ).length();
|
||||
wxString expr = parseExpression();
|
||||
|
||||
if( expr.IsEmpty() )
|
||||
@ -728,7 +723,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
|
||||
break;
|
||||
}
|
||||
|
||||
parseValueWithUnits( expr, value, units, unitless );
|
||||
parseValueWithUnits( offset, expr, value, units, unitless );
|
||||
validateAndSetValueWithUnits( value, units,
|
||||
[&c]( const int aValue )
|
||||
{
|
||||
@ -740,6 +735,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
|
||||
|
||||
case T_max:
|
||||
{
|
||||
size_t offset = CurOffset() + GetTokenString( token ).length();
|
||||
wxString expr = parseExpression();
|
||||
|
||||
if( expr.IsEmpty() )
|
||||
@ -748,7 +744,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
|
||||
break;
|
||||
}
|
||||
|
||||
parseValueWithUnits( expr, value, units, unitless );
|
||||
parseValueWithUnits( offset, expr, value, units, unitless );
|
||||
validateAndSetValueWithUnits( value, units,
|
||||
[&c]( const int aValue )
|
||||
{
|
||||
@ -760,6 +756,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
|
||||
|
||||
case T_opt:
|
||||
{
|
||||
size_t offset = CurOffset() + GetTokenString( token ).length();
|
||||
wxString expr = parseExpression();
|
||||
|
||||
if( expr.IsEmpty() )
|
||||
@ -768,7 +765,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
|
||||
break;
|
||||
}
|
||||
|
||||
parseValueWithUnits( expr, value, units, unitless );
|
||||
parseValueWithUnits( offset, expr, value, units, unitless );
|
||||
validateAndSetValueWithUnits( value, units,
|
||||
[&c]( const int aValue )
|
||||
{
|
||||
@ -798,21 +795,22 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
|
||||
}
|
||||
|
||||
|
||||
void DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult, EDA_UNITS& aUnits, bool aUnitless )
|
||||
void DRC_RULES_PARSER::parseValueWithUnits( int aOffset, const wxString& aExpr, int& aResult,
|
||||
EDA_UNITS& aUnits, bool aUnitless )
|
||||
{
|
||||
aResult = 0.0;
|
||||
aUnits = EDA_UNITS::UNSCALED;
|
||||
|
||||
auto errorHandler =
|
||||
[&]( const wxString& aMessage, int aOffset )
|
||||
[&]( const wxString& message, int offset )
|
||||
{
|
||||
wxString rest;
|
||||
wxString first = aMessage.BeforeFirst( '|', &rest );
|
||||
wxString first = message.BeforeFirst( '|', &rest );
|
||||
|
||||
if( m_reporter )
|
||||
{
|
||||
wxString msg = wxString::Format( _( "ERROR: <a href='%d:%d'>%s</a>%s" ),
|
||||
CurLineNumber(), CurOffset() + aOffset, first, rest );
|
||||
CurLineNumber(), aOffset + offset, first, rest );
|
||||
|
||||
m_reporter->Report( msg, RPT_SEVERITY_ERROR );
|
||||
}
|
||||
@ -826,7 +824,7 @@ void DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult,
|
||||
};
|
||||
|
||||
PCBEXPR_EVALUATOR evaluator( aUnitless ? (LIBEVAL::UNIT_RESOLVER*) new PCBEXPR_UNITLESS_RESOLVER()
|
||||
: (LIBEVAL::UNIT_RESOLVER*) new PCBEXPR_UNIT_RESOLVER() );
|
||||
: (LIBEVAL::UNIT_RESOLVER*) new PCBEXPR_UNIT_RESOLVER() );
|
||||
evaluator.SetErrorCallback( errorHandler );
|
||||
|
||||
if( evaluator.Evaluate( aExpr ) )
|
||||
|
@ -41,7 +41,6 @@ class DRC_RULES_PARSER : public DRC_RULES_LEXER
|
||||
{
|
||||
public:
|
||||
DRC_RULES_PARSER( const wxString& aSource, const wxString& aSourceDescr );
|
||||
DRC_RULES_PARSER( FILE* aFile, const wxString& aFilename );
|
||||
|
||||
void Parse( std::vector<std::shared_ptr<DRC_RULE>>& aRules, REPORTER* aReporter );
|
||||
|
||||
@ -55,7 +54,8 @@ private:
|
||||
std::shared_ptr<COMPONENT_CLASS_ASSIGNMENT_RULE> parseComponentClassAssignment();
|
||||
|
||||
void parseConstraint( DRC_RULE* aRule );
|
||||
void parseValueWithUnits( const wxString& aExpr, int& aResult, EDA_UNITS& aUnits, bool aUnitless = false );
|
||||
void parseValueWithUnits( int aOffset, const wxString& aExpr, int& aResult, EDA_UNITS& aUnits,
|
||||
bool aUnitless = false );
|
||||
LSET parseLayer( wxString* aSource );
|
||||
SEVERITY parseSeverity();
|
||||
void parseUnknown();
|
||||
|
Loading…
x
Reference in New Issue
Block a user