diff --git a/common/scintilla_tricks.cpp b/common/scintilla_tricks.cpp index 5add388213..adae90bcf4 100644 --- a/common/scintilla_tricks.cpp +++ b/common/scintilla_tricks.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -190,7 +191,10 @@ void SCINTILLA_TRICKS::DoAutocomplete( const wxString& aPartial, const wxArraySt { // NB: tokens MUST be in alphabetical order because the Scintilla engine is going // to do a binary search on them - matchedTokens.Sort(); + matchedTokens.Sort( []( const wxString& first, const wxString& second ) -> int + { + return first.CmpNoCase( second ); + }); m_te->AutoCompShow( aPartial.size(), wxJoin( matchedTokens, ' ' ) ); } diff --git a/pcbnew/dialogs/panel_setup_rules.cpp b/pcbnew/dialogs/panel_setup_rules.cpp index 93d3393493..ad64e57b6f 100644 --- a/pcbnew/dialogs/panel_setup_rules.cpp +++ b/pcbnew/dialogs/panel_setup_rules.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -31,6 +32,7 @@ #include #include + PANEL_SETUP_RULES::PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame ) : PANEL_SETUP_RULES_BASE( aParent->GetTreebook() ), m_Parent( aParent ), @@ -46,6 +48,7 @@ PANEL_SETUP_RULES::PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFr m_textEditor->StyleSetFont( i, fixedFont ); m_textEditor->Bind( wxEVT_STC_CHARADDED, &PANEL_SETUP_RULES::onScintillaCharAdded, this ); + m_textEditor->Bind( wxEVT_STC_AUTOCOMP_CHAR_DELETED, &PANEL_SETUP_RULES::onScintillaCharAdded, this ); } @@ -205,6 +208,11 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent ) for( const wxString& propName : propNames ) tokens += " " + propName; + + PCB_EXPR_BUILTIN_FUNCTIONS& functions = PCB_EXPR_BUILTIN_FUNCTIONS::Instance(); + + for( const wxString& funcSig : functions.GetSignatures() ) + tokens += " " + funcSig; } } diff --git a/pcbnew/pcb_expr_evaluator.cpp b/pcbnew/pcb_expr_evaluator.cpp index baf5c3927d..42e9d6a7ac 100644 --- a/pcbnew/pcb_expr_evaluator.cpp +++ b/pcbnew/pcb_expr_evaluator.cpp @@ -28,91 +28,66 @@ #include "class_board.h" #include "pcb_expr_evaluator.h" -class PCB_EXPR_BUILTIN_FUNCTIONS + + +static void onLayer( LIBEVAL::UCODE* aUcode, LIBEVAL::CONTEXT* aCtx, void *self ) { -public: + LIBEVAL::VALUE* arg = aCtx->Pop(); + LIBEVAL::VALUE* result = aCtx->AllocValue(); - using FPTR = LIBEVAL::UCODE::FUNC_PTR; + result->Set( 0.0 ); + aCtx->Push( result ); - PCB_EXPR_BUILTIN_FUNCTIONS(); - - static PCB_EXPR_BUILTIN_FUNCTIONS& Instance() + if( !arg ) { - static PCB_EXPR_BUILTIN_FUNCTIONS self; - return self; + aCtx->ReportError( _( "Missing argument to 'onLayer()'" ) ); + return; } - std::string tolower( const std::string& str ) const + wxString layerName = arg->AsString(); + PCB_LAYER_ID layer = ENUM_MAP::Instance().ToEnum( layerName ); + + if( layer == UNDEFINED_LAYER ) { - std::string rv; - std::transform( str.begin(), str.end(), rv.begin(), ::tolower ); - return rv; + aCtx->ReportError( wxString::Format( _( "Unrecognized layer '%s' " ), layerName ) ); + return; } - FPTR Get( const std::string &name ) const - { - auto it = m_funcs.find( name ); + PCB_EXPR_VAR_REF* vref = static_cast( self ); + BOARD_ITEM* item = vref ? vref->GetObject( aUcode ) : nullptr; - if( it == m_funcs.end() ) - return nullptr; + if( item && item->IsOnLayer( layer ) ) + result->Set( 1.0 ); +} - return it->second; - } -private: - std::map m_funcs; +static void isPlated( LIBEVAL::UCODE* aUcode, LIBEVAL::CONTEXT* aCtx, void *self ) +{ + LIBEVAL::VALUE* result = aCtx->AllocValue(); - static void onLayer( LIBEVAL::UCODE* aUcode, LIBEVAL::CONTEXT* aCtx, void *self ) - { - LIBEVAL::VALUE* arg = aCtx->Pop(); - LIBEVAL::VALUE* result = aCtx->AllocValue(); + result->Set( 0.0 ); + aCtx->Push( result ); - result->Set( 0.0 ); - aCtx->Push( result ); + PCB_EXPR_VAR_REF* vref = static_cast( self ); + BOARD_ITEM* item = vref ? vref->GetObject( aUcode ) : nullptr; + D_PAD* pad = dynamic_cast( item ); - if( !arg ) - { - aCtx->ReportError( _( "Missing argument to 'onLayer()'" ) ); - return; - } - - wxString layerName = arg->AsString(); - PCB_LAYER_ID layer = ENUM_MAP::Instance().ToEnum( layerName ); - - if( layer == UNDEFINED_LAYER ) - { - aCtx->ReportError( wxString::Format( _( "Unrecognized layer '%s' " ), layerName ) ); - return; - } - - PCB_EXPR_VAR_REF* vref = static_cast( self ); - BOARD_ITEM* item = vref ? vref->GetObject( aUcode ) : nullptr; - - if( item && item->IsOnLayer( layer ) ) - result->Set( 1.0 ); - } - - static void isPlated( LIBEVAL::UCODE* aUcode, LIBEVAL::CONTEXT* aCtx, void *self ) - { - LIBEVAL::VALUE* result = aCtx->AllocValue(); - - result->Set( 0.0 ); - aCtx->Push( result ); - - PCB_EXPR_VAR_REF* vref = static_cast( self ); - BOARD_ITEM* item = vref ? vref->GetObject( aUcode ) : nullptr; - D_PAD* pad = dynamic_cast( item ); - - if( pad && pad->GetAttribute() == PAD_ATTRIB_STANDARD ) - result->Set( 1.0 ); - } -}; + if( pad && pad->GetAttribute() == PAD_ATTRIB_STANDARD ) + result->Set( 1.0 ); +} PCB_EXPR_BUILTIN_FUNCTIONS::PCB_EXPR_BUILTIN_FUNCTIONS() { - m_funcs[ "onlayer" ] = onLayer; - m_funcs[ "isplated" ] = isPlated; + auto registerFunc = [&]( const wxString& funcSignature, FPTR funcPtr ) + { + wxString funcName = funcSignature.BeforeFirst( '(' ); + m_funcs[ std::string( funcName.Lower() ) ] = std::move( funcPtr ); + m_funcSigs.Add( funcSignature ); + }; + + registerFunc( "onLayer('x')", onLayer ); + registerFunc( "isPlated()", isPlated ); } diff --git a/pcbnew/pcb_expr_evaluator.h b/pcbnew/pcb_expr_evaluator.h index 9fd5b442de..496b241d3b 100644 --- a/pcbnew/pcb_expr_evaluator.h +++ b/pcbnew/pcb_expr_evaluator.h @@ -41,9 +41,11 @@ class PCB_EXPR_UCODE : public LIBEVAL::UCODE { public: virtual LIBEVAL::VAR_REF* createVarRef( LIBEVAL::COMPILER *aCompiler, - const std::string& aVar, const std::string& aField ) override; + const std::string& aVar, + const std::string& aField ) override; - virtual FUNC_PTR createFuncCall( LIBEVAL::COMPILER* aCompiler, const std::string& name ) override; + virtual FUNC_PTR createFuncCall( LIBEVAL::COMPILER* aCompiler, + const std::string& name ) override; void SetItems( BOARD_ITEM* a, BOARD_ITEM* b = nullptr ) { @@ -75,24 +77,16 @@ public: void SetIsEnum( bool s ) { m_isEnum = s; } bool IsEnum() const { return m_isEnum; } - void SetType( LIBEVAL::VAR_TYPE_T type ) - { - m_type = type; - } + void SetType( LIBEVAL::VAR_TYPE_T type ) { m_type = type; } + LIBEVAL::VAR_TYPE_T GetType() override { return m_type; } void AddAllowedClass( TYPE_ID type_hash, PROPERTY_BASE* prop ) { m_matchingTypes[type_hash] = prop; } - virtual LIBEVAL::VAR_TYPE_T GetType() override - { - return m_type; - } - virtual LIBEVAL::VALUE GetValue( LIBEVAL::CONTEXT* aCtx, LIBEVAL::UCODE* aUcode ) override; - BOARD_ITEM* GetObject( LIBEVAL::UCODE* aUcode ) const; private: @@ -103,6 +97,36 @@ private: }; +class PCB_EXPR_BUILTIN_FUNCTIONS +{ +public: + using FPTR = LIBEVAL::UCODE::FUNC_PTR; + + PCB_EXPR_BUILTIN_FUNCTIONS(); + + static PCB_EXPR_BUILTIN_FUNCTIONS& Instance() + { + static PCB_EXPR_BUILTIN_FUNCTIONS self; + return self; + } + + LIBEVAL::UCODE::FUNC_PTR Get( const std::string &name ) + { + return m_funcs[ name ]; + } + + const wxArrayString GetSignatures() const + { + return m_funcSigs; + } + +private: + std::map m_funcs; + + wxArrayString m_funcSigs; +}; + + class PCB_EXPR_COMPILER : public LIBEVAL::COMPILER { public: