link to the Guile library and add some Guile demo code – evaluate code from CLI argument v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Sun, 20 Jan 2019 01:02:40 +0100
branchv_0
changeset 1 9179406ab3b3
parent 0 f36bf14d45cb
child 2 7fb4d2c70e8c
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
nbproject/configurations.xml
src/CMakeLists.txt
src/GuileHandler.h
src/relpipe-tr-guile.cpp
--- 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 @@
               <pElem>../relpipe-lib-reader.cpp/include</pElem>
               <pElem>../relpipe-lib-writer.cpp/include</pElem>
               <pElem>../relpipe-lib-cli.cpp/include</pElem>
+              <pElem>/usr/include/guile/2.2</pElem>
               <pElem>build/Debug/src</pElem>
             </incDir>
           </ccTool>
--- 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})
 
--- 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 <codecvt>
 #include <regex>
 
+#include <libguile.h>
+
 #include <relpipe/reader/typedefs.h>
 #include <relpipe/reader/TypeId.h>
 #include <relpipe/reader/handlers/RelationalReaderStringHandler.h>
@@ -46,6 +48,8 @@
 
 class GuileHandler : public RelationalReaderStringHadler {
 private:
+	std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings.
+
 	shared_ptr<writer::RelationalWriter> 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 <relationNameRegExp>", 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<writer::AttributeMetadata> 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);
 		}
 	}
--- 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
+}