# HG changeset patch # User František Kučera # Date 1547942560 -3600 # Node ID 9179406ab3b32018c33c31201517511699772425 # Parent f36bf14d45cb16090bc566b43e8208211e0d779e link to the Guile library and add some Guile demo code – evaluate code from CLI argument try: relpipe-in-fstab | relpipe-tr-guile 'fstab' '(or (= a b) (= a a) )' | relpipe-out-tabular relpipe-in-fstab | relpipe-tr-guile 'fstab' '(or (= a b) (= a 9) )' | relpipe-out-tabular diff -r f36bf14d45cb -r 9179406ab3b3 nbproject/configurations.xml --- a/nbproject/configurations.xml Sat Jan 19 16:01:08 2019 +0100 +++ b/nbproject/configurations.xml Sun Jan 20 01:02:40 2019 +0100 @@ -82,6 +82,7 @@ ../relpipe-lib-reader.cpp/include ../relpipe-lib-writer.cpp/include ../relpipe-lib-cli.cpp/include + /usr/include/guile/2.2 build/Debug/src diff -r f36bf14d45cb -r 9179406ab3b3 src/CMakeLists.txt --- a/src/CMakeLists.txt Sat Jan 19 16:01:08 2019 +0100 +++ b/src/CMakeLists.txt Sun Jan 20 01:02:40 2019 +0100 @@ -18,7 +18,7 @@ # Relpipe libraries: INCLUDE(FindPkgConfig) -pkg_check_modules (RELPIPE_LIBS relpipe-lib-reader.cpp relpipe-lib-writer.cpp relpipe-lib-cli.cpp) +pkg_check_modules (RELPIPE_LIBS relpipe-lib-reader.cpp relpipe-lib-writer.cpp relpipe-lib-cli.cpp guile-2.2) include_directories(${RELPIPE_LIBS_INCLUDE_DIRS}) link_directories(${RELPIPE_LIBS_LIBRARY_DIRS}) diff -r f36bf14d45cb -r 9179406ab3b3 src/GuileHandler.h --- a/src/GuileHandler.h Sat Jan 19 16:01:08 2019 +0100 +++ b/src/GuileHandler.h Sun Jan 20 01:02:40 2019 +0100 @@ -26,6 +26,8 @@ #include #include +#include + #include #include #include @@ -46,6 +48,8 @@ class GuileHandler : public RelationalReaderStringHadler { private: + std::wstring_convert> convertor; // TODO: support also other encodings. + shared_ptr relationalWriter; wregex relationNameRegEx; @@ -55,6 +59,44 @@ integer_t currentAttributeIndex = 0; boolean_t includeCurrentRecord = false; boolean_t filterCurrentRelation = false; + string_t guileCode; + + SCM toGuileSymbol(const string_t& name) { + return scm_string_to_symbol(scm_from_locale_string(convertor.to_bytes(name).c_str())); + } + + SCM toGuileString(const string_t& value) { + return scm_from_locale_string(convertor.to_bytes(value).c_str()); + } + + SCM toGuileInteger(const string_t& value) { + return scm_from_uint64(stoul(value)); + } + + SCM toGuileBoolean(const string_t& value) { + return value == L"true" ? SCM_BOOL_T : SCM_BOOL_F; + } + + void defineGuileVariable(const string_t& name, TypeId type, const string_t& value) { + // TODO: RelationalReaderValueHadler? + switch (type) { + case TypeId::BOOLEAN: + scm_define(toGuileSymbol(name), toGuileBoolean(value)); + break; + case TypeId::INTEGER: + scm_define(toGuileSymbol(name), toGuileInteger(value)); + break; + case TypeId::STRING: + scm_define(toGuileSymbol(name), toGuileString(value)); + break; + default: + throw cli::RelpipeCLIException(L"Unsupported type in defineGuileVariable()", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); + } + } + + void undefineGuileVariable(const string_t& name, TypeId type, const string_t& value) { + scm_define(toGuileSymbol(name), scm_make_undefined_variable()); // undefined != (define n) + } public: @@ -62,8 +104,9 @@ relationalWriter.reset(writer::Factory::create(output)); // TODO: options and parser - if (arguments.size() == 1) { + if (arguments.size() == 2) { relationNameRegEx = wregex(arguments[0]); + guileCode = arguments[1]; } else { throw cli::RelpipeCLIException(L"Usage: relpipe-tr-guile ", cli::CLI::EXIT_CODE_UNKNOWN_COMMAND); } @@ -74,9 +117,10 @@ // TODO: move to a reusable method (or use same metadata on both reader and writer side?) vector writerMetadata; for (AttributeMetadata readerMetadata : attributes) { + writerMetadata.push_back({readerMetadata.getAttributeName(), relationalWriter->toTypeId(readerMetadata.getTypeName())}); } - + currentRecord.resize(attributes.size()); filterCurrentRelation = regex_match(name, relationNameRegEx); @@ -89,6 +133,21 @@ currentRecord[currentAttributeIndex] = value; includeCurrentRecord = false; + // TODO: remove, just a demo code + defineGuileVariable(L"hello", TypeId::STRING, L"world"); + defineGuileVariable(L"a", TypeId::INTEGER, L"123"); + defineGuileVariable(L"b", TypeId::INTEGER, L"456"); + defineGuileVariable(L"tr", TypeId::BOOLEAN, L"true"); + defineGuileVariable(L"fa", TypeId::BOOLEAN, L"false"); + + //integer_t guileResult = scm_to_uint64(scm_eval_string(toGuileString(guileCode))); + //std::wcerr << "result from Guile: " << guileResult << std::endl; + + includeCurrentRecord = scm_to_bool(scm_eval_string(toGuileString(guileCode))); + //scm_shell(0, nullptr); + // -------- + + currentAttributeIndex++; if (currentAttributeIndex > 0 && currentAttributeIndex % currentMetadata.size() == 0) { @@ -98,6 +157,7 @@ currentAttributeIndex = currentAttributeIndex % currentMetadata.size(); } else { + relationalWriter->writeAttribute(value); } } diff -r f36bf14d45cb -r 9179406ab3b3 src/relpipe-tr-guile.cpp --- a/src/relpipe-tr-guile.cpp Sat Jan 19 16:01:08 2019 +0100 +++ b/src/relpipe-tr-guile.cpp Sun Jan 20 01:02:40 2019 +0100 @@ -38,7 +38,7 @@ using namespace relpipe::reader; using namespace relpipe::tr::guile; -int main(int argc, char**argv) { +static void relpipeMain(void *closure, int argc, char **argv) { setlocale(LC_ALL, ""); CLI::untieStdIO(); CLI cli(argc, argv); @@ -63,5 +63,10 @@ resultCode = CLI::EXIT_CODE_DATA_ERROR; } - return resultCode; + exit(resultCode); } + +int main(int argc, char**argv) { + scm_boot_guile(argc, argv, relpipeMain, nullptr); + return 999; // never reached – see exit(resultCode) above +}