diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e6af150cbf4cebb493e667c134adc13f322240eb..c53d6f5ad168101bf718b47951d8a11705d41e76 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,7 +14,7 @@ before_script: esac - export JOBS=$(grep -c processor /proc/cpuinfo) - apk add --no-cache build-base bash libexecinfo-dev - cppunit-dev libxml2-dev tclap-dev $EXTRA_PKGS + cppunit-dev libxml2-dev tclap-dev readline-dev $EXTRA_PKGS - case "$CI_BUILD_NAME" in *-clang) ln -s /usr/lib/llvm4/lib/LLVMgold.so /usr/lib/LLVMgold.so;; *) ;; diff --git a/aql2/makefile.conf b/aql2/makefile.conf index 4556c5f00da4df610b4a4f9f0215e8579c70abe2..29eb6afc9426066de4aa1be41f114f88170db798 100644 --- a/aql2/makefile.conf +++ b/aql2/makefile.conf @@ -1,4 +1,4 @@ EXECUTABLE:=aql2 LINK_PATHS=../alib2cli/ ../alib2elgo/ ../alib2algo/ ../alib2raw/ ../alib2str/ ../alib2data/ ../alib2common/ ../alib2std/ -LINK_LIBRARIES=alib2cli alib2elgo alib2algo alib2raw alib2str alib2data alib2common alib2std xml2 +LINK_LIBRARIES=alib2cli alib2elgo alib2algo alib2raw alib2str alib2data alib2common alib2std xml2 readline INCLUDE_PATHS=\$$(SOURCES_BASE_DIR)/../../alib2cli/src/ \$$(SOURCES_BASE_DIR)/../../alib2data/src/ \$$(SOURCES_BASE_DIR)/../../alib2common/src/ \$$(SOURCES_BASE_DIR)/../../alib2std/src/ /usr/include/libxml2/ diff --git a/aql2/src/aql.cpp b/aql2/src/aql.cpp index e899dc450664baed063d8e92bd76b0470c467363..cdfe7d1decf90fd18e5f13e3ed6a66d579c92e79 100644 --- a/aql2/src/aql.cpp +++ b/aql2/src/aql.cpp @@ -1,11 +1,10 @@ /* * aql.cpp * - * Created on: 26. 3. 2014 + * Created on: 1. 7. 2017 * Author: Jan Travnicek */ -#include <measure> #include <istream> #include <iostream> @@ -27,11 +26,13 @@ std::istream& operator>> ( std::istream & in, std::pair < T, U > & value ) { return in; } +#include <string> + +#include <measure> #include <tclap/CmdLine.h> #include <global/GlobalData.h> -#include <lexer/Lexer.h> -#include <parser/Parser.h> +#include "prompt/Prompt.h" namespace TCLAP { @@ -50,7 +51,7 @@ int main ( int argc, char * argv[] ) { TCLAP::CmdLine cmd ( "Algorithms query language binary", ' ', "0.01" ); - TCLAP::ValueArg < std::string > query ( "q", "query", "Query index", true, "", "query" ); + TCLAP::ValueArg < std::string > query ( "q", "query", "Query index", false, "", "query" ); cmd.add ( query ); TCLAP::SwitchArg measure ( "m", "measure", "Measure times", false ); @@ -79,15 +80,20 @@ int main ( int argc, char * argv[] ) { environment.set ( param.first, param.second ); } - cli::Parser parser ( cli::Lexer ( query.getValue ( ) ) ); - parser.execute ( )->translateAndEval ( nullptr, environment ); + Prompt p ( std::move ( environment ) ); + + int result = 0; + if ( query.isSet ( ) ) + result = p.execute_line ( query.getValue ( ) ); + else + result = p.run ( ); measurements::end ( ); if ( measure.getValue ( ) ) std::cmeasure << measurements::results ( ) << std::endl; - return 0; + return result; } catch ( const exception::CommonException & exception ) { alib::XmlDataFactory::toStdout ( exception ); return 1; diff --git a/aql2/src/prompt/Prompt.cpp b/aql2/src/prompt/Prompt.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8d98c9c6ae75beca050998d8e0f5c462ee4d8113 --- /dev/null +++ b/aql2/src/prompt/Prompt.cpp @@ -0,0 +1,65 @@ +/* + * Prompt.cpp + * + * Created on: 20. 7. 2017 + * Author: Jan Travnicek + */ + +#include "Prompt.h" + +#include <cstdlib> +#include <cctype> +#include <cstring> + +#include <readline/readline.h> +#include <readline/history.h> + +#include <lexer/Lexer.h> +#include <parser/Parser.h> + +char * Prompt::stripwhite ( char * begin ) { + while ( isspace ( * begin ) ) + ++ begin; + + char * end = begin + strlen ( begin ) - 1; + while ( end >= begin && isspace ( * end ) ) + -- end; + + if ( end >= begin ) + * ++ end = '\0'; + + return begin; +} + +Prompt::Prompt ( cli::Environment environment ) : m_prefix ( "> " ), m_active ( true ), m_exec_result ( 0 ), m_environment ( std::move ( environment ) ) { +} + +int Prompt::run ( ) { + while ( m_active ) { + char * line = readline ( m_prefix.c_str ( ) ); + + if ( ! line ) + continue; + + char * s = stripwhite ( line ); + + if ( * s ) { + add_history ( s ); + execute_line ( std::string ( s ) ); + } + + free ( line ); + } + return m_exec_result; +} + +int Prompt::execute_line ( std::string line ) { + if ( line == "quit" ) { + m_active = false; + m_exec_result = 0; + } else { + cli::Parser parser = cli::Parser ( cli::Lexer ( line ) ); + parser.execute ( )->translateAndEval ( nullptr, m_environment ); + } + return m_exec_result; +} diff --git a/aql2/src/prompt/Prompt.h b/aql2/src/prompt/Prompt.h new file mode 100644 index 0000000000000000000000000000000000000000..db0341300c5c7d7e0960ebf960f699119b6d8d5a --- /dev/null +++ b/aql2/src/prompt/Prompt.h @@ -0,0 +1,35 @@ +/* + * Prompt.h + * + * Created on: 20. 3. 2017 + * Author: Jan Travnicek + */ + +#ifndef _AQL_PROMPT_H_ +#define _AQL_PROMPT_H_ + +#include <string> +#include <parser/Parser.h> + +class Prompt { + Prompt ( const Prompt & ) = delete; + Prompt ( Prompt && ) = delete; + Prompt & operator = ( const Prompt & ) = delete; + Prompt & operator = ( Prompt && ) = delete; + + std::string m_prefix; + bool m_active; + int m_exec_result; + + cli::Environment m_environment; + + char * stripwhite ( char * begin ); + +public: + Prompt ( cli::Environment environment ); + + int run ( ); + int execute_line ( std::string line ); +}; + +#endif /* _AQL_PROMPT_H_ */