diff options
| author | Neil <nyamatongwe@gmail.com> | 2019-12-13 11:29:26 +1100 | 
|---|---|---|
| committer | Neil <nyamatongwe@gmail.com> | 2019-12-13 11:29:26 +1100 | 
| commit | 952cd885fb6055c1e133ca53e3348d0e0b9d6cab (patch) | |
| tree | 5566ed4368ad2b8f195d6b1c46787b2517d4720d /src/ExternalLexer.cxx | |
| parent | 8f1cccd456144fcab0a004afe08aeabfcf2c7357 (diff) | |
| download | scintilla-mirror-952cd885fb6055c1e133ca53e3348d0e0b9d6cab.tar.gz | |
Use safe mechanism to convert to function pointers.
Mark noexcept where reasonable. Check that functions are available.
Diffstat (limited to 'src/ExternalLexer.cxx')
| -rw-r--r-- | src/ExternalLexer.cxx | 33 | 
1 files changed, 23 insertions, 10 deletions
| diff --git a/src/ExternalLexer.cxx b/src/ExternalLexer.cxx index 308846628..495b8a867 100644 --- a/src/ExternalLexer.cxx +++ b/src/ExternalLexer.cxx @@ -39,6 +39,16 @@ typedef int (EXT_LEXER_DECL *GetLexerCountFn)();  typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, int buflength);  typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned int Index); +/// Generic function to convert from a void* to a function pointer. +/// This avoids undefined and conditionally defined behaviour. +template<typename T> +T FunctionPointer(void *function) noexcept { +	static_assert(sizeof(T) == sizeof(function)); +	T fp; +	memcpy(&fp, &function, sizeof(T)); +	return fp; +} +  /// Sub-class of LexerModule to use an external lexer.  class ExternalLexerModule : public LexerModule {  protected: @@ -51,7 +61,7 @@ public:  		fneFactory(nullptr), name(languageName_){  		languageName = name.c_str();  	} -	virtual void SetExternal(GetLexerFactoryFunction fFactory, int index); +	void SetExternal(GetLexerFactoryFunction fFactory, int index) noexcept;  };  /// LexerLibrary exists for every External Lexer DLL, contains ExternalLexerModules. @@ -71,10 +81,10 @@ public:  	~LexerManager();  	static LexerManager *GetInstance(); -	static void DeleteInstance(); +	static void DeleteInstance() noexcept;  	void Load(const char *path); -	void Clear(); +	void Clear() noexcept;  private:  	LexerManager(); @@ -95,7 +105,7 @@ std::unique_ptr<LexerManager> LexerManager::theInstance;  //  //------------------------------------------ -void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) { +void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) noexcept {  	fneFactory = fFactory;  	fnFactory = fFactory(index);  } @@ -111,13 +121,16 @@ LexerLibrary::LexerLibrary(const char *moduleName_) {  	lib.reset(DynamicLibrary::Load(moduleName_));  	if (lib->IsValid()) {  		moduleName = moduleName_; -		//Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects -		GetLexerCountFn GetLexerCount = (GetLexerCountFn)(sptr_t)lib->FindFunction("GetLexerCount"); +		GetLexerCountFn GetLexerCount = FunctionPointer<GetLexerCountFn>(lib->FindFunction("GetLexerCount"));  		if (GetLexerCount) {  			// Find functions in the DLL -			GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName"); -			GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory"); +			GetLexerNameFn GetLexerName = FunctionPointer<GetLexerNameFn>(lib->FindFunction("GetLexerName")); +			GetLexerFactoryFunction fnFactory = FunctionPointer<GetLexerFactoryFunction>(lib->FindFunction("GetLexerFactory")); + +			if (!GetLexerName || !fnFactory) { +				return; +			}  			const int nl = GetLexerCount(); @@ -158,7 +171,7 @@ LexerManager *LexerManager::GetInstance() {  }  /// Delete any LexerManager instance... -void LexerManager::DeleteInstance() { +void LexerManager::DeleteInstance() noexcept {  	theInstance.reset();  } @@ -178,7 +191,7 @@ void LexerManager::Load(const char *path) {  	libraries.push_back(std::make_unique<LexerLibrary>(path));  } -void LexerManager::Clear() { +void LexerManager::Clear() noexcept {  	libraries.clear();  } | 
