35#include <wx/stc/stc.h>
39 wxWindow* aParent, std::shared_ptr<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA> aConstraintData ) :
45 wxBoxSizer* sizer =
new wxBoxSizer( wxVERTICAL );
47 m_textCtrl =
new wxStyledTextCtrl(
this, wxID_ANY );
48 sizer->Add(
m_textCtrl, 1, wxEXPAND | wxALL, 5 );
58 []( wxKeyEvent& aEvent )
63 [
this]( wxStyledTextEvent& aEvent )
87 text = wxS(
" (constraint clearance (min 0.2mm))" );
109 (void) aValidationMessage;
123 if( body.Trim().IsEmpty() )
124 return wxEmptyString;
126 wxString ruleName = aContext.
ruleName;
127 ruleName.Replace( wxS(
"\"" ), wxS(
"\\\"" ) );
130 rule << wxS(
"(rule \"" ) << ruleName << wxS(
"\"\n" );
132 if( !aContext.
comment.IsEmpty() )
134 wxArrayString lines = wxSplit( aContext.
comment,
'\n',
'\0' );
136 for(
const wxString& line : lines )
141 rule << wxS(
"\t# " ) << line << wxS(
"\n" );
145 rule << body << wxS(
")" );
160 if( aEvent.GetModifiers() == wxMOD_CONTROL && aEvent.GetKey() ==
' ' )
171 enum class EXPR_CONTEXT_T :
int
179 std::stack<wxString> sexprs;
181 EXPR_CONTEXT_T context = EXPR_CONTEXT_T::NONE;
183 for(
int i = startPos; i < currentPos; ++i )
191 else if( context == EXPR_CONTEXT_T::STRING )
194 context = EXPR_CONTEXT_T::NONE;
198 partial = wxEmptyString;
199 context = EXPR_CONTEXT_T::STRING;
203 if( context == EXPR_CONTEXT_T::SEXPR_OPEN && !partial.IsEmpty() )
206 sexprs.push( partial );
209 partial = wxEmptyString;
210 context = EXPR_CONTEXT_T::SEXPR_OPEN;
214 if( !sexprs.empty() )
217 context = EXPR_CONTEXT_T::NONE;
221 if( context == EXPR_CONTEXT_T::SEXPR_OPEN && !partial.IsEmpty() )
224 sexprs.push( partial );
225 context = EXPR_CONTEXT_T::SEXPR_TOKEN;
226 partial = wxEmptyString;
230 context = EXPR_CONTEXT_T::NONE;
240 if( context == EXPR_CONTEXT_T::SEXPR_OPEN )
244 tokens = wxT(
"condition|constraint|layer|severity" );
246 else if( sexprs.top() == wxT(
"rule" ) )
249 tokens = wxT(
"condition|constraint|layer|severity" );
251 else if( sexprs.top() == wxT(
"constraint" ) )
254 tokens = wxT(
"min|max|opt" );
257 else if( context == EXPR_CONTEXT_T::SEXPR_TOKEN )
259 if( !sexprs.empty() && sexprs.top() == wxT(
"constraint" ) )
262 tokens = wxT(
"annular_width|"
266 "courtyard_clearance|"
269 "diff_pair_uncoupled|"
277 "min_resolved_spokes|"
278 "physical_clearance|"
279 "physical_hole_clearance|"
284 "thermal_relief_gap|"
285 "thermal_spoke_width|"
287 "track_segment_length|"
293 else if( !sexprs.empty() && sexprs.top() == wxT(
"layer" ) )
296 tokens = wxT(
"inner|outer" );
298 else if( !sexprs.empty() && sexprs.top() == wxT(
"severity" ) )
301 tokens = wxT(
"error|warning|ignore|exclusion" );
305 if( !tokens.IsEmpty() )
321 ruleName.Replace( wxS(
"\"" ), wxS(
"\\\"" ) );
322 wxString rulesText = wxString::Format( wxS(
"(version 1)\n(rule \"%s\"\n%s)" ), ruleName, body );
324 if( body.Trim().IsEmpty() )
326#if wxCHECK_VERSION( 3, 3, 2 )
327 m_tipWindow = wxTipWindow::New(
this,
_(
"No rule text to check." ) );
329 m_tipWindow =
new wxTipWindow(
this,
_(
"No rule text to check." ) );
339 std::vector<std::shared_ptr<DRC_RULE>> dummyRules;
342 parser.
Parse( dummyRules, &reporter );
346 reporter.
Report( wxString::Format(
_(
"ERROR at line %d, column %d: %s" ),
361 message =
_(
"Syntax check passed with warnings:\n" ) + reporter.
GetMessages();
365 message =
_(
"Syntax OK" );
368#if wxCHECK_VERSION( 3, 3, 2 )
bool TransferDataFromWindow() override
wxStyledTextCtrl * m_textCtrl
bool TransferDataToWindow() override
wxTipWindow * m_tipWindow
~DRC_RE_CUSTOM_RULE_PANEL() override
void UpdateRuleName(const wxString &aName)
void onScintillaCharAdded(wxStyledTextEvent &aEvent)
bool ValidateInputs(int *aErrorCount, wxString *aValidationMessage) override
wxString GenerateRule(const RULE_GENERATION_CONTEXT &aContext) override
std::shared_ptr< DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA > m_constraintData
std::unique_ptr< SCINTILLA_TRICKS > m_scintillaTricks
wxButton * m_checkSyntaxBtn
DRC_RE_CUSTOM_RULE_PANEL(wxWindow *aParent, std::shared_ptr< DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA > aConstraintData)
void onCheckSyntax(wxCommandEvent &aEvent)
void Parse(std::vector< std::shared_ptr< DRC_RULE > > &aRules, REPORTER *aReporter)
virtual bool HasMessageOfSeverity(int aSeverityMask) const
Returns true if the reporter has one or more messages matching the specified severity mask.
virtual bool HasMessage() const
Returns true if any messages were reported.
A wrapper for reporting to a wxString object.
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
const wxString & GetMessages() const
A filename or source description, a problem input line, a line number, a byte offset,...
int lineNumber
at which line number, 1 based index.
const wxString ParseProblem()
int byteIndex
at which byte offset within the line, 1 based index