From c4a6034d69ba326f91d8956c4df58e9865ee2c95 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Wed, 3 Jan 2018 17:09:44 +0100 Subject: [PATCH] introduce load cli command to load library --- alib2cli/makefile.conf | 2 +- alib2cli/src/command/LoadCommand.h | 26 ++++++++++ alib2cli/src/common/LibraryLoader.cpp | 23 +++++++++ alib2cli/src/common/LibraryLoader.h | 72 +++++++++++++++++++++++++++ alib2cli/src/parser/Parser.cpp | 7 +++ alib2cli/src/parser/Parser.h | 2 +- 6 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 alib2cli/src/command/LoadCommand.h create mode 100644 alib2cli/src/common/LibraryLoader.cpp create mode 100644 alib2cli/src/common/LibraryLoader.h diff --git a/alib2cli/makefile.conf b/alib2cli/makefile.conf index 5f6fbb956f..f6fc9bd373 100644 --- a/alib2cli/makefile.conf +++ b/alib2cli/makefile.conf @@ -1,5 +1,5 @@ LIBRARY:=alib2cli TESTBIN:=alib2test LINK_PATHS=../alib2xml/ ../alib2common/ ../alib2abstraction/ ../alib2measure/ ../alib2std/ -LINK_LIBRARIES=alib2xml alib2common alib2abstraction alib2measure alib2std xml2 +LINK_LIBRARIES=alib2xml alib2common alib2abstraction alib2measure alib2std xml2 stdc++fs INCLUDE_PATHS=\$$(SOURCES_BASE_DIR)/../../alib2xml/src/ \$$(SOURCES_BASE_DIR)/../../alib2common/src/ \$$(SOURCES_BASE_DIR)/../../alib2abstraction/src/ \$$(SOURCES_BASE_DIR)/../../alib2measure/src/ \$$(SOURCES_BASE_DIR)/../../alib2std/src/ /usr/include/libxml2/ diff --git a/alib2cli/src/command/LoadCommand.h b/alib2cli/src/command/LoadCommand.h new file mode 100644 index 0000000000..db42419791 --- /dev/null +++ b/alib2cli/src/command/LoadCommand.h @@ -0,0 +1,26 @@ +#ifndef _CLI_LOAD_COMMAND_H_ +#define _CLI_LOAD_COMMAND_H_ + +#include <command/Command.h> +#include <environment/Environment.h> + +#include <common/LibraryLoader.h> + +namespace cli { + +class LoadCommand : public Command { + std::string m_libraryName; + +public: + LoadCommand ( std::string libraryName ) : m_libraryName ( std::move ( libraryName ) ) { + } + + virtual Command::Result run ( Environment & ) const override { + cli::LibraryLoader::load ( m_libraryName ); + return Command::Result::OK; + } +}; + +} /* namespace cli */ + +#endif /* _CLI_LOAD_COMMAND_H_ */ diff --git a/alib2cli/src/common/LibraryLoader.cpp b/alib2cli/src/common/LibraryLoader.cpp new file mode 100644 index 0000000000..0b0ba38f81 --- /dev/null +++ b/alib2cli/src/common/LibraryLoader.cpp @@ -0,0 +1,23 @@ +#include "LibraryLoader.h" + +namespace cli { + +std::list < LibraryLoader::Library >::iterator LibraryLoader::find ( const std::string name ) { + for ( std::list < LibraryLoader::Library >::iterator iter = libraries.begin ( ); iter != libraries.end ( ); ++ iter ) { + if ( iter->path ( ) == name ) + return iter; + } + + return libraries.end ( ); +} + +std::list < LibraryLoader::Library > LibraryLoader::libraries; + +void LibraryLoader::load ( const std::string & name ) { + std::list < LibraryLoader::Library >::iterator iter = find ( name ); + if ( iter == libraries.end ( ) ) + iter = libraries.emplace ( libraries.end ( ), std::move ( name ) ); + iter->load ( ); +} + +} /* namespace cli */ diff --git a/alib2cli/src/common/LibraryLoader.h b/alib2cli/src/common/LibraryLoader.h new file mode 100644 index 0000000000..fbcfded963 --- /dev/null +++ b/alib2cli/src/common/LibraryLoader.h @@ -0,0 +1,72 @@ +#ifndef _CLI_LIBRARY_LOADER_H_ +#define _CLI_LIBRARY_LOADER_H_ + +#include <command/Command.h> +#include <environment/Environment.h> + +#include <dlfcn.h> + +#include <experimental/filesystem> +#include <alib/list> + +#include <exception/CommonException.h> + +namespace cli { + +class LibraryLoader { + class Library { + std::string m_path; + void * m_handle; + + public: + Library ( const std::string & path ) : m_path ( path ), m_handle ( NULL ) { + } + + Library ( const Library & ) = delete; + + Library ( Library && other ) : m_path ( std::move ( other.m_path ) ), m_handle ( other.m_handle ) { + other.m_handle = NULL; + } + + Library & operator = ( const Library & ) = delete; + Library & operator = ( Library && other ) = delete; + + ~Library ( ) { + unload ( ); + } + + void load ( ) { + if ( ! loaded ( ) ) + m_handle = dlopen ( m_path.c_str ( ), RTLD_NOW ); + if ( ! loaded ( ) ) + throw exception::CommonException ( std::string ( dlerror ( ) ) ); + } + + void unload ( ) { + if ( loaded ( ) ) { + dlclose ( m_handle ); + m_handle = NULL; + } + } + + const std::string & path ( ) const { + return m_path; + } + + bool loaded ( ) const { + return m_handle != NULL; + } + + }; + + static std::list < Library >::iterator find ( const std::string name ); + + static std::list < Library > libraries; + +public: + static void load ( const std::string & name ); +}; + +} /* namespace cli */ + +#endif /* _CLI_LIBRARY_LOADER_H_ */ diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp index 10cbcd4866..3d5fec731b 100644 --- a/alib2cli/src/parser/Parser.cpp +++ b/alib2cli/src/parser/Parser.cpp @@ -30,6 +30,7 @@ #include <command/DataTypesIntrospectionCommand.h> #include <command/CastsIntrospectionCommand.h> #include <command/SetCommand.h> +#include <command/LoadCommand.h> #include <primitive/Integer.h> #include <primitive/String.h> @@ -358,6 +359,12 @@ std::unique_ptr < Command > Parser::parse ( ) { match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER, cli::Lexer::TokenType::STRING ); match ( cli::Lexer::TokenType::END ); return std::make_unique < SetCommand > ( std::move ( param ), std::move ( value ) ); + } else if ( check_nonreserved_kw ( "load" ) ) { + match_nonreserved_kw ( "load" ); + std::string libraryName = getTokenValue ( ); + match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER, cli::Lexer::TokenType::STRING ); + match ( cli::Lexer::TokenType::END ); + return std::make_unique < LoadCommand > ( std::move ( libraryName ) ); } else { throw exception::CommonException ( "Mismatched set while expanding parse rule." ); } diff --git a/alib2cli/src/parser/Parser.h b/alib2cli/src/parser/Parser.h index 64d3268898..1db21e5e5c 100644 --- a/alib2cli/src/parser/Parser.h +++ b/alib2cli/src/parser/Parser.h @@ -95,7 +95,7 @@ public: std::unique_ptr < Param > in_redirect_param ( ); std::unique_ptr < Param > param ( ); - + std::unique_ptr < Arg > template_param ( ); std::unique_ptr < Param > move_param ( ); -- GitLab