--- a/ArgumentsCommand.h Mon Dec 03 16:11:40 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/**
- * Relational pipes
- * Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#pragma once
-
-#include <cstdlib>
-#include <iostream>
-#include <string>
-#include <vector>
-#include <algorithm>
-
-#include <relpipe/writer/typedefs.h>
-#include <relpipe/writer/AttributeMetadata.h>
-
-#include "Command.h"
-
-namespace relpipe {
-namespace in {
-namespace cli {
-
-class ArgumentsCommand : public Command {
-public:
-
- void process(std::istream& input, std::ostream& output, const relpipe::writer::string_t& command, const std::vector<relpipe::writer::string_t>& arguments) override {
- using namespace relpipe::writer;
-
- size_t i = 0;
- string_t relationName = arguments[i++];
- integer_t attributeCount = std::stoul(arguments[i++]); // TODO: use integer data type's method?
- boolean_t writeHeader = true; // TODO: add option for header omitting
-
- // TODO: check argument count
-
- std::shared_ptr<RelationalWriter> writer(Factory::create(output));
-
- std::vector<AttributeMetadata> attributes(attributeCount);
-
- for (size_t j = 0; j < attributeCount; j++) {
- string_t attributeName = arguments[i++];
- TypeId attributeType = writer->toTypeId(arguments[i++]);
- attributes[j] = {attributeName, attributeType};
- }
-
- writer->startRelation(relationName, attributes, writeHeader);
-
- for (; i < arguments.size(); i++) {
- writer->writeAttribute(arguments[i]);
- }
- }
-};
-
-}
-}
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CMakeLists.txt Sun Dec 09 18:33:20 2018 +0100
@@ -0,0 +1,19 @@
+# Relational pipes
+# Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+project (relpipe-in-cli.cpp)
+cmake_minimum_required(VERSION 2.8)
+add_subdirectory (src)
--- a/Command.h Mon Dec 03 16:11:40 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/**
- * Relational pipes
- * Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#pragma once
-
-#include <cstdlib>
-#include <iostream>
-#include <string>
-#include <vector>
-#include <algorithm>
-
-
-namespace relpipe {
-namespace in {
-namespace cli {
-
-class Command {
-public:
- virtual ~Command() = default;
-
- /**
- * Processes the inputs (stream + arguments) and generates output in the relational pipes format.
- *
- * @param input usually STDIN, may not be used if all data are passed as CLI arguments
- * @param output usually STDOUT, relational data is passed here
- * @param command command name, usualy not needed, may be significant if the same Command instance is used for several commands
- * @param arguments CLI arguments containing data or parameters (format is specific to each command)
- */
- virtual void process(std::istream& input, std::ostream& output, const relpipe::writer::string_t& command, const std::vector<relpipe::writer::string_t> &arguments) = 0;
-
-};
-
-}
-}
-}
--- a/DemoCommand.h Mon Dec 03 16:11:40 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/**
- * Relational pipes
- * Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#pragma once
-
-#include <cstdlib>
-#include <iostream>
-#include <string>
-#include <vector>
-#include <algorithm>
-
-#include <relpipe/writer/typedefs.h>
-
-#include "Command.h"
-
-namespace relpipe {
-namespace in {
-namespace cli {
-
-class DemoCommand : public Command {
-public:
-
- void process(std::istream& input, std::ostream& output, const relpipe::writer::string_t& command, const std::vector<relpipe::writer::string_t>& arguments) override {
- using namespace relpipe::writer;
- std::shared_ptr<RelationalWriter> writer(Factory::create(output));
-
-
- // Various data types passed as strings
- writer->startRelation(L"table_from_strings",{
- {L"s", TypeId::STRING},
- {L"i", TypeId::INTEGER},
- {L"b", TypeId::BOOLEAN}
- }, true);
-
- writer->writeAttribute(L"a");
- writer->writeAttribute(L"1");
- writer->writeAttribute(L"true");
-
- writer->writeAttribute(L"b");
- writer->writeAttribute(L"2");
- writer->writeAttribute(L"false");
-
-
- // Various data types passed as raw pointers + typeids
- writer->startRelation(L"from_raw_pointers",{
- {L"s", TypeId::STRING},
- {L"i", TypeId::INTEGER},
- {L"b", TypeId::BOOLEAN}
- }, true);
-
- string_t sValue;
- integer_t iValue;
- boolean_t bValue;
-
- for (int i = 0; i < 8; i++) {
- sValue.append(L"*");
- iValue = i + 1;
- bValue = iValue % 2 == 0;
- writer->writeAttribute(&sValue, typeid (sValue));
- writer->writeAttribute(&iValue, typeid (iValue));
- writer->writeAttribute(&bValue, typeid (bValue));
- }
- }
-};
-
-}
-}
-}
--- a/Makefile Mon Dec 03 16:11:40 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-#
-# There exist several targets which are by default empty and which can be
-# used for execution of your targets. These targets are usually executed
-# before and after some main targets. They are:
-#
-# .build-pre: called before 'build' target
-# .build-post: called after 'build' target
-# .clean-pre: called before 'clean' target
-# .clean-post: called after 'clean' target
-# .clobber-pre: called before 'clobber' target
-# .clobber-post: called after 'clobber' target
-# .all-pre: called before 'all' target
-# .all-post: called after 'all' target
-# .help-pre: called before 'help' target
-# .help-post: called after 'help' target
-#
-# Targets beginning with '.' are not intended to be called on their own.
-#
-# Main targets can be executed directly, and they are:
-#
-# build build a specific configuration
-# clean remove built files from a configuration
-# clobber remove all built files
-# all build all configurations
-# help print help mesage
-#
-# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
-# .help-impl are implemented in nbproject/makefile-impl.mk.
-#
-# Available make variables:
-#
-# CND_BASEDIR base directory for relative paths
-# CND_DISTDIR default top distribution directory (build artifacts)
-# CND_BUILDDIR default top build directory (object files, ...)
-# CONF name of current configuration
-# CND_PLATFORM_${CONF} platform name (current configuration)
-# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
-# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
-# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
-# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
-# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
-# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
-#
-# NOCDDL
-
-
-# Environment
-MKDIR=mkdir
-CP=cp
-CCADMIN=CCadmin
-
-
-# build
-build: .build-post
-
-.build-pre:
-# Add your pre 'build' code here...
-
-.build-post: .build-impl
-# Add your post 'build' code here...
-
-
-# clean
-clean: .clean-post
-
-.clean-pre:
-# Add your pre 'clean' code here...
-
-.clean-post: .clean-impl
-# Add your post 'clean' code here...
-
-
-# clobber
-clobber: .clobber-post
-
-.clobber-pre:
-# Add your pre 'clobber' code here...
-
-.clobber-post: .clobber-impl
-# Add your post 'clobber' code here...
-
-
-# all
-all: .all-post
-
-.all-pre:
-# Add your pre 'all' code here...
-
-.all-post: .all-impl
-# Add your post 'all' code here...
-
-
-# build tests
-build-tests: .build-tests-post
-
-.build-tests-pre:
-# Add your pre 'build-tests' code here...
-
-.build-tests-post: .build-tests-impl
-# Add your post 'build-tests' code here...
-
-
-# run tests
-test: .test-post
-
-.test-pre: build-tests
-# Add your pre 'test' code here...
-
-.test-post: .test-impl
-# Add your post 'test' code here...
-
-
-# help
-help: .help-post
-
-.help-pre:
-# Add your pre 'help' code here...
-
-.help-post: .help-impl
-# Add your post 'help' code here...
-
-
-
-# include project implementation makefile
-include nbproject/Makefile-impl.mk
-
-# include project make variables
-include nbproject/Makefile-variables.mk
--- a/StdInCommand.h Mon Dec 03 16:11:40 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/**
- * Relational pipes
- * Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#pragma once
-
-#include <cstdlib>
-#include <iostream>
-#include <string>
-#include <vector>
-#include <algorithm>
-#include <string>
-#include <locale>
-
-#include <relpipe/writer/typedefs.h>
-#include <relpipe/writer/AttributeMetadata.h>
-#include <relpipe/cli/CLI.h>
-#include <relpipe/cli/RelpipeCLIException.h>
-
-#include "Command.h"
-
-namespace relpipe {
-namespace in {
-namespace cli {
-
-/**
- * TODO: consider code merge with ArgumentsCommand
- */
-class StdInCommand : public Command {
-private:
- relpipe::writer::boolean_t readStdIn;
- std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings.
-
- /**
- * Reads next value from arguments and (if no arguments left) from input
- * @param input
- * @param arguments
- * @param i current index in the arguments vector
- * @param required if true, exception is thrown when no data found
- * @return
- */
- relpipe::writer::string_t readNext(std::istream& input, const std::vector<relpipe::writer::string_t>& arguments, size_t& i, relpipe::writer::boolean_t required) {
- using namespace relpipe::writer;
- using namespace relpipe::cli;
-
- if (i < arguments.size()) {
- return arguments[i++];
- } else if (readStdIn) {
- std::stringstream value;
-
- while (true) {
- char ch;
- input.get(ch);
- if (ch == 0 || input.eof() || input.fail()) break;
- else value << ch;
- }
-
- if (required && value.str().empty()) throw RelpipeCLIException(L"Missing value on STDIN.", CLI::EXIT_CODE_BAD_SYNTAX);
-
- return convertor.from_bytes(value.str());
- } else {
- if (required) throw RelpipeCLIException(L"Missing value on CLI.", CLI::EXIT_CODE_BAD_SYNTAX);
- return L"";
- }
- }
-
-
-public:
-
- StdInCommand(relpipe::writer::boolean_t readStdIn) :
- readStdIn(readStdIn) {
- }
-
- void process(std::istream& input, std::ostream& output, const relpipe::writer::string_t& command, const std::vector<relpipe::writer::string_t>& arguments) override {
- using namespace relpipe::writer;
-
- size_t i = 0;
- string_t relationName = readNext(input, arguments, i, true);
- integer_t attributeCount = std::stoul(readNext(input, arguments, i, true)); // TODO: use integer data type's method?
- boolean_t writeHeader = true; // TODO: add option for header omitting
-
- std::shared_ptr<RelationalWriter> writer(Factory::create(output));
-
- std::vector<AttributeMetadata> attributes(attributeCount);
-
- for (size_t j = 0; j < attributeCount; j++) {
- string_t attributeName = readNext(input, arguments, i, true);
- TypeId attributeType = writer->toTypeId(readNext(input, arguments, i, true));
- attributes[j] = {attributeName, attributeType};
- }
-
- writer->startRelation(relationName, attributes, writeHeader);
-
- while (true) {
- string_t value = readNext(input, arguments, i, false);
- if (value.empty() && (input.eof() || input.fail() || (!readStdIn && i >= arguments.size()))) break;
- else writer->writeAttribute(value);
- // TODO: check attribute count (avoid unfinished records)
- }
- }
-};
-
-}
-}
-}
--- a/nbproject/Makefile-Debug.mk Mon Dec 03 16:11:40 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-#
-# Generated Makefile - do not edit!
-#
-# Edit the Makefile in the project folder instead (../Makefile). Each target
-# has a -pre and a -post target defined where you can add customized code.
-#
-# This makefile implements configuration specific macros and targets.
-
-
-# Environment
-MKDIR=mkdir
-CP=cp
-GREP=grep
-NM=nm
-CCADMIN=CCadmin
-RANLIB=ranlib
-CC=gcc
-CCC=g++
-CXX=g++
-FC=gfortran
-AS=as
-
-# Macros
-CND_PLATFORM=GNU-Linux
-CND_DLIB_EXT=so
-CND_CONF=Debug
-CND_DISTDIR=dist
-CND_BUILDDIR=build
-
-# Include project Makefile
-include Makefile
-
-# Object Directory
-OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
-
-# Object Files
-OBJECTFILES= \
- ${OBJECTDIR}/relpipe-in-cli.o
-
-
-# C Compiler Flags
-CFLAGS=
-
-# CC Compiler Flags
-CCFLAGS=-fsanitize=address
-CXXFLAGS=-fsanitize=address
-
-# Fortran Compiler Flags
-FFLAGS=
-
-# Assembler Flags
-ASFLAGS=
-
-# Link Libraries and Options
-LDLIBSOPTIONS=`pkg-config --libs relpipe-lib-writer.cpp` `pkg-config --libs relpipe-lib-cli.cpp`
-
-# Build Targets
-.build-conf: ${BUILD_SUBPROJECTS}
- "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/relpipe-in-cli.cpp
-
-${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/relpipe-in-cli.cpp: ${OBJECTFILES}
- ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
- ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/relpipe-in-cli.cpp ${OBJECTFILES} ${LDLIBSOPTIONS}
-
-${OBJECTDIR}/relpipe-in-cli.o: relpipe-in-cli.cpp
- ${MKDIR} -p ${OBJECTDIR}
- ${RM} "$@.d"
- $(COMPILE.cc) -g `pkg-config --cflags relpipe-lib-writer.cpp` `pkg-config --cflags relpipe-lib-cli.cpp` -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/relpipe-in-cli.o relpipe-in-cli.cpp
-
-# Subprojects
-.build-subprojects:
-
-# Clean Targets
-.clean-conf: ${CLEAN_SUBPROJECTS}
- ${RM} -r ${CND_BUILDDIR}/${CND_CONF}
-
-# Subprojects
-.clean-subprojects:
-
-# Enable dependency checking
-.dep.inc: .depcheck-impl
-
-include .dep.inc
--- a/nbproject/Makefile-Release.mk Mon Dec 03 16:11:40 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-#
-# Generated Makefile - do not edit!
-#
-# Edit the Makefile in the project folder instead (../Makefile). Each target
-# has a -pre and a -post target defined where you can add customized code.
-#
-# This makefile implements configuration specific macros and targets.
-
-
-# Environment
-MKDIR=mkdir
-CP=cp
-GREP=grep
-NM=nm
-CCADMIN=CCadmin
-RANLIB=ranlib
-CC=gcc
-CCC=g++
-CXX=g++
-FC=gfortran
-AS=as
-
-# Macros
-CND_PLATFORM=GNU-Linux
-CND_DLIB_EXT=so
-CND_CONF=Release
-CND_DISTDIR=dist
-CND_BUILDDIR=build
-
-# Include project Makefile
-include Makefile
-
-# Object Directory
-OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
-
-# Object Files
-OBJECTFILES= \
- ${OBJECTDIR}/relpipe-in-cli.o
-
-
-# C Compiler Flags
-CFLAGS=
-
-# CC Compiler Flags
-CCFLAGS=
-CXXFLAGS=
-
-# Fortran Compiler Flags
-FFLAGS=
-
-# Assembler Flags
-ASFLAGS=
-
-# Link Libraries and Options
-LDLIBSOPTIONS=`pkg-config --libs relpipe-lib-writer.cpp` `pkg-config --libs relpipe-lib-cli.cpp`
-
-# Build Targets
-.build-conf: ${BUILD_SUBPROJECTS}
- "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/relpipe-in-cli.cpp
-
-${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/relpipe-in-cli.cpp: ${OBJECTFILES}
- ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
- ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/relpipe-in-cli.cpp ${OBJECTFILES} ${LDLIBSOPTIONS}
-
-${OBJECTDIR}/relpipe-in-cli.o: relpipe-in-cli.cpp
- ${MKDIR} -p ${OBJECTDIR}
- ${RM} "$@.d"
- $(COMPILE.cc) -O2 `pkg-config --cflags relpipe-lib-writer.cpp` `pkg-config --cflags relpipe-lib-cli.cpp` -std=c++14 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/relpipe-in-cli.o relpipe-in-cli.cpp
-
-# Subprojects
-.build-subprojects:
-
-# Clean Targets
-.clean-conf: ${CLEAN_SUBPROJECTS}
- ${RM} -r ${CND_BUILDDIR}/${CND_CONF}
-
-# Subprojects
-.clean-subprojects:
-
-# Enable dependency checking
-.dep.inc: .depcheck-impl
-
-include .dep.inc
--- a/nbproject/Makefile-impl.mk Mon Dec 03 16:11:40 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-#
-# Generated Makefile - do not edit!
-#
-# Edit the Makefile in the project folder instead (../Makefile). Each target
-# has a pre- and a post- target defined where you can add customization code.
-#
-# This makefile implements macros and targets common to all configurations.
-#
-# NOCDDL
-
-
-# Building and Cleaning subprojects are done by default, but can be controlled with the SUB
-# macro. If SUB=no, subprojects will not be built or cleaned. The following macro
-# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf
-# and .clean-reqprojects-conf unless SUB has the value 'no'
-SUB_no=NO
-SUBPROJECTS=${SUB_${SUB}}
-BUILD_SUBPROJECTS_=.build-subprojects
-BUILD_SUBPROJECTS_NO=
-BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}}
-CLEAN_SUBPROJECTS_=.clean-subprojects
-CLEAN_SUBPROJECTS_NO=
-CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}
-
-
-# Project Name
-PROJECTNAME=relpipe-in-cli.cpp
-
-# Active Configuration
-DEFAULTCONF=Debug
-CONF=${DEFAULTCONF}
-
-# All Configurations
-ALLCONFS=Debug Release
-
-
-# build
-.build-impl: .build-pre .validate-impl .depcheck-impl
- @#echo "=> Running $@... Configuration=$(CONF)"
- "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf
-
-
-# clean
-.clean-impl: .clean-pre .validate-impl .depcheck-impl
- @#echo "=> Running $@... Configuration=$(CONF)"
- "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf
-
-
-# clobber
-.clobber-impl: .clobber-pre .depcheck-impl
- @#echo "=> Running $@..."
- for CONF in ${ALLCONFS}; \
- do \
- "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \
- done
-
-# all
-.all-impl: .all-pre .depcheck-impl
- @#echo "=> Running $@..."
- for CONF in ${ALLCONFS}; \
- do \
- "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \
- done
-
-# build tests
-.build-tests-impl: .build-impl .build-tests-pre
- @#echo "=> Running $@... Configuration=$(CONF)"
- "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf
-
-# run tests
-.test-impl: .build-tests-impl .test-pre
- @#echo "=> Running $@... Configuration=$(CONF)"
- "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf
-
-# dependency checking support
-.depcheck-impl:
- @echo "# This code depends on make tool being used" >.dep.inc
- @if [ -n "${MAKE_VERSION}" ]; then \
- echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES} \$${TESTOBJECTFILES}))" >>.dep.inc; \
- echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \
- echo "include \$${DEPFILES}" >>.dep.inc; \
- echo "endif" >>.dep.inc; \
- else \
- echo ".KEEP_STATE:" >>.dep.inc; \
- echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \
- fi
-
-# configuration validation
-.validate-impl:
- @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
- then \
- echo ""; \
- echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \
- echo "See 'make help' for details."; \
- echo "Current directory: " `pwd`; \
- echo ""; \
- fi
- @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
- then \
- exit 1; \
- fi
-
-
-# help
-.help-impl: .help-pre
- @echo "This makefile supports the following configurations:"
- @echo " ${ALLCONFS}"
- @echo ""
- @echo "and the following targets:"
- @echo " build (default target)"
- @echo " clean"
- @echo " clobber"
- @echo " all"
- @echo " help"
- @echo ""
- @echo "Makefile Usage:"
- @echo " make [CONF=<CONFIGURATION>] [SUB=no] build"
- @echo " make [CONF=<CONFIGURATION>] [SUB=no] clean"
- @echo " make [SUB=no] clobber"
- @echo " make [SUB=no] all"
- @echo " make help"
- @echo ""
- @echo "Target 'build' will build a specific configuration and, unless 'SUB=no',"
- @echo " also build subprojects."
- @echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no',"
- @echo " also clean subprojects."
- @echo "Target 'clobber' will remove all built files from all configurations and,"
- @echo " unless 'SUB=no', also from subprojects."
- @echo "Target 'all' will will build all configurations and, unless 'SUB=no',"
- @echo " also build subprojects."
- @echo "Target 'help' prints this message."
- @echo ""
-
--- a/nbproject/Makefile-variables.mk Mon Dec 03 16:11:40 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-#
-# Generated - do not edit!
-#
-# NOCDDL
-#
-CND_BASEDIR=`pwd`
-CND_BUILDDIR=build
-CND_DISTDIR=dist
-# Debug configuration
-CND_PLATFORM_Debug=GNU-Linux
-CND_ARTIFACT_DIR_Debug=dist/Debug/GNU-Linux
-CND_ARTIFACT_NAME_Debug=relpipe-in-cli.cpp
-CND_ARTIFACT_PATH_Debug=dist/Debug/GNU-Linux/relpipe-in-cli.cpp
-CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux/package
-CND_PACKAGE_NAME_Debug=relpipe-in-cli.cpp.tar
-CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux/package/relpipe-in-cli.cpp.tar
-# Release configuration
-CND_PLATFORM_Release=GNU-Linux
-CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux
-CND_ARTIFACT_NAME_Release=relpipe-in-cli.cpp
-CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux/relpipe-in-cli.cpp
-CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux/package
-CND_PACKAGE_NAME_Release=relpipe-in-cli.cpp.tar
-CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux/package/relpipe-in-cli.cpp.tar
-#
-# include compiler specific variables
-#
-# dmake command
-ROOT:sh = test -f nbproject/private/Makefile-variables.mk || \
- (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk)
-#
-# gmake command
-.PHONY: $(shell test -f nbproject/private/Makefile-variables.mk || (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk))
-#
-include nbproject/private/Makefile-variables.mk
--- a/nbproject/Package-Debug.bash Mon Dec 03 16:11:40 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-#!/bin/bash -x
-
-#
-# Generated - do not edit!
-#
-
-# Macros
-TOP=`pwd`
-CND_PLATFORM=GNU-Linux
-CND_CONF=Debug
-CND_DISTDIR=dist
-CND_BUILDDIR=build
-CND_DLIB_EXT=so
-NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
-TMPDIRNAME=tmp-packaging
-OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/relpipe-in-cli.cpp
-OUTPUT_BASENAME=relpipe-in-cli.cpp
-PACKAGE_TOP_DIR=relpipe-in-cli.cpp/
-
-# Functions
-function checkReturnCode
-{
- rc=$?
- if [ $rc != 0 ]
- then
- exit $rc
- fi
-}
-function makeDirectory
-# $1 directory path
-# $2 permission (optional)
-{
- mkdir -p "$1"
- checkReturnCode
- if [ "$2" != "" ]
- then
- chmod $2 "$1"
- checkReturnCode
- fi
-}
-function copyFileToTmpDir
-# $1 from-file path
-# $2 to-file path
-# $3 permission
-{
- cp "$1" "$2"
- checkReturnCode
- if [ "$3" != "" ]
- then
- chmod $3 "$2"
- checkReturnCode
- fi
-}
-
-# Setup
-cd "${TOP}"
-mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
-rm -rf ${NBTMPDIR}
-mkdir -p ${NBTMPDIR}
-
-# Copy files and create directories and links
-cd "${TOP}"
-makeDirectory "${NBTMPDIR}/relpipe-in-cli.cpp/bin"
-copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755
-
-
-# Generate tar file
-cd "${TOP}"
-rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/relpipe-in-cli.cpp.tar
-cd ${NBTMPDIR}
-tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/relpipe-in-cli.cpp.tar *
-checkReturnCode
-
-# Cleanup
-cd "${TOP}"
-rm -rf ${NBTMPDIR}
--- a/nbproject/Package-Release.bash Mon Dec 03 16:11:40 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-#!/bin/bash -x
-
-#
-# Generated - do not edit!
-#
-
-# Macros
-TOP=`pwd`
-CND_PLATFORM=GNU-Linux
-CND_CONF=Release
-CND_DISTDIR=dist
-CND_BUILDDIR=build
-CND_DLIB_EXT=so
-NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
-TMPDIRNAME=tmp-packaging
-OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/relpipe-in-cli.cpp
-OUTPUT_BASENAME=relpipe-in-cli.cpp
-PACKAGE_TOP_DIR=relpipe-in-cli.cpp/
-
-# Functions
-function checkReturnCode
-{
- rc=$?
- if [ $rc != 0 ]
- then
- exit $rc
- fi
-}
-function makeDirectory
-# $1 directory path
-# $2 permission (optional)
-{
- mkdir -p "$1"
- checkReturnCode
- if [ "$2" != "" ]
- then
- chmod $2 "$1"
- checkReturnCode
- fi
-}
-function copyFileToTmpDir
-# $1 from-file path
-# $2 to-file path
-# $3 permission
-{
- cp "$1" "$2"
- checkReturnCode
- if [ "$3" != "" ]
- then
- chmod $3 "$2"
- checkReturnCode
- fi
-}
-
-# Setup
-cd "${TOP}"
-mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
-rm -rf ${NBTMPDIR}
-mkdir -p ${NBTMPDIR}
-
-# Copy files and create directories and links
-cd "${TOP}"
-makeDirectory "${NBTMPDIR}/relpipe-in-cli.cpp/bin"
-copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755
-
-
-# Generate tar file
-cd "${TOP}"
-rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/relpipe-in-cli.cpp.tar
-cd ${NBTMPDIR}
-tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/relpipe-in-cli.cpp.tar *
-checkReturnCode
-
-# Cleanup
-cd "${TOP}"
-rm -rf ${NBTMPDIR}
--- a/nbproject/configurations.xml Mon Dec 03 16:11:40 2018 +0100
+++ b/nbproject/configurations.xml Sun Dec 09 18:33:20 2018 +0100
@@ -1,109 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+Copyright (c) 2014, 2016 Oracle and/or its affiliates. All rights reserved.
+
+Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+Other names may be trademarks of their respective owners.
+
+The contents of this file are subject to the terms of either the GNU
+General Public License Version 2 only ("GPL") or the Common
+Development and Distribution License("CDDL") (collectively, the
+"License"). You may not use this file except in compliance with the
+License. You can obtain a copy of the License at
+http://www.netbeans.org/cddl-gplv2.html
+or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+specific language governing permissions and limitations under the
+License. When distributing the software, include this License Header
+Notice in each file and include the License file at
+nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the GPL Version 2 section of the License file that
+accompanied this code. If applicable, add the following below the
+License Header, with the fields enclosed by brackets [] replaced by
+your own identifying information:
+"Portions Copyrighted [year] [name of copyright owner]"
+
+If you wish your version of this file to be governed by only the CDDL
+or only the GPL Version 2, indicate your decision by adding
+"[Contributor] elects to include this software in this distribution
+under the [CDDL or GPL Version 2] license." If you do not indicate a
+single choice of license, a recipient has the option to distribute
+your version of this file under either the CDDL, the GPL Version 2 or
+to extend the choice of license to its licensees as provided above.
+However, if you add GPL Version 2 code and therefore, elected the GPL
+Version 2 license, then the option applies only if the new code is
+made subject to such option by the copyright holder.
+
+Contributor(s):
+-->
<configurationDescriptor version="100">
<logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
- <logicalFolder name="HeaderFiles"
- displayName="Header Files"
- projectFiles="true">
- <itemPath>ArgumentsCommand.h</itemPath>
- <itemPath>Command.h</itemPath>
- <itemPath>DemoCommand.h</itemPath>
- <itemPath>StdInCommand.h</itemPath>
- </logicalFolder>
- <logicalFolder name="ResourceFiles"
- displayName="Resource Files"
- projectFiles="true">
- </logicalFolder>
- <logicalFolder name="SourceFiles"
- displayName="Source Files"
- projectFiles="true">
- <itemPath>relpipe-in-cli.cpp</itemPath>
- </logicalFolder>
- <logicalFolder name="TestFiles"
- displayName="Test Files"
- projectFiles="false"
- kind="TEST_LOGICAL_FOLDER">
- </logicalFolder>
+ <df root="." name="0">
+ <df name="src">
+ <in>relpipe-in-cli.cpp</in>
+ </df>
+ </df>
<logicalFolder name="ExternalFiles"
displayName="Important Files"
projectFiles="false"
kind="IMPORTANT_FILES_FOLDER">
- <itemPath>Makefile</itemPath>
+ <itemPath>CMakeLists.txt</itemPath>
+ <itemPath>build/Debug/Makefile</itemPath>
+ <itemPath>build/Release/Makefile</itemPath>
</logicalFolder>
</logicalFolder>
- <projectmakefile>Makefile</projectmakefile>
+ <sourceFolderFilter>^(nbproject|build)$</sourceFolderFilter>
+ <sourceRootList>
+ <Elem>.</Elem>
+ </sourceRootList>
+ <projectmakefile>build/Debug/Makefile</projectmakefile>
<confs>
- <conf name="Debug" type="1">
+ <conf name="Debug" type="0">
<toolsSet>
<compilerSet>default</compilerSet>
- <dependencyChecking>true</dependencyChecking>
+ <dependencyChecking>false</dependencyChecking>
<rebuildPropChanged>false</rebuildPropChanged>
</toolsSet>
- <compileType>
- <cTool>
- <incFile>
- <pElem>../../src/relpipe-lib-writer.cpp/DataTypeWriter.h</pElem>
- <pElem>../../src/relpipe-lib-writer.cpp/DataTypeWriterBase.h</pElem>
- </incFile>
- </cTool>
- <ccTool>
- <standard>11</standard>
- <commandLine>-fsanitize=address</commandLine>
+ <flagsDictionary>
+ <element flagsID="0"
+ commonFlags="-mtune=generic -march=x86-64 -fsanitize=address -fstack-protector-strong"/>
+ </flagsDictionary>
+ <codeAssistance>
+ </codeAssistance>
+ <makefileType>
+ <makeTool>
+ <buildCommandWorkingDir>build/Debug</buildCommandWorkingDir>
+ <buildCommand>${MAKE} -f Makefile</buildCommand>
+ <cleanCommand>${MAKE} -f Makefile clean</cleanCommand>
+ <executablePath>build/Debug/src/relpipe-in-cli</executablePath>
+ <ccTool>
+ <incDir>
+ <pElem>../relpipe-lib-writer.cpp/include/relpipe/writer</pElem>
+ <pElem>../relpipe-lib-cli.cpp/include/relpipe/cli</pElem>
+ <pElem>src</pElem>
+ <pElem>../relpipe-lib-writer.cpp/include</pElem>
+ <pElem>../relpipe-lib-cli.cpp/include</pElem>
+ <pElem>build/Debug/src</pElem>
+ </incDir>
+ </ccTool>
+ </makeTool>
+ <preBuild>
+ <preBuildCommandWorkingDir>build/Debug</preBuildCommandWorkingDir>
+ <preBuildCommand>${CMAKE} -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=${IDE_CC} -DCMAKE_CXX_COMPILER=${IDE_CXX} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ../..</preBuildCommand>
+ <preBuildFirst>true</preBuildFirst>
+ </preBuild>
+ </makefileType>
+ <item path="src/relpipe-in-cli.cpp" ex="false" tool="1" flavor2="0">
+ <ccTool flags="0">
</ccTool>
- <linkerTool>
- <linkerLibItems>
- <linkerOptionItem>`pkg-config --libs relpipe-lib-writer.cpp`</linkerOptionItem>
- <linkerOptionItem>`pkg-config --libs relpipe-lib-cli.cpp`</linkerOptionItem>
- </linkerLibItems>
- </linkerTool>
- </compileType>
- <item path="ArgumentsCommand.h" ex="false" tool="3" flavor2="0">
- </item>
- <item path="Command.h" ex="false" tool="3" flavor2="0">
- </item>
- <item path="DemoCommand.h" ex="false" tool="3" flavor2="0">
- </item>
- <item path="StdInCommand.h" ex="false" tool="3" flavor2="0">
- </item>
- <item path="relpipe-in-cli.cpp" ex="false" tool="1" flavor2="0">
</item>
</conf>
- <conf name="Release" type="1">
+ <conf name="Release" type="0">
<toolsSet>
<compilerSet>default</compilerSet>
- <dependencyChecking>true</dependencyChecking>
+ <dependencyChecking>false</dependencyChecking>
<rebuildPropChanged>false</rebuildPropChanged>
</toolsSet>
- <compileType>
- <cTool>
- <developmentMode>5</developmentMode>
- </cTool>
- <ccTool>
- <developmentMode>5</developmentMode>
- <standard>11</standard>
- </ccTool>
- <fortranCompilerTool>
- <developmentMode>5</developmentMode>
- </fortranCompilerTool>
- <asmTool>
- <developmentMode>5</developmentMode>
- </asmTool>
- <linkerTool>
- <linkerLibItems>
- <linkerOptionItem>`pkg-config --libs relpipe-lib-writer.cpp`</linkerOptionItem>
- <linkerOptionItem>`pkg-config --libs relpipe-lib-cli.cpp`</linkerOptionItem>
- </linkerLibItems>
- </linkerTool>
- </compileType>
- <item path="ArgumentsCommand.h" ex="false" tool="3" flavor2="0">
- </item>
- <item path="Command.h" ex="false" tool="3" flavor2="0">
- </item>
- <item path="DemoCommand.h" ex="false" tool="3" flavor2="0">
- </item>
- <item path="StdInCommand.h" ex="false" tool="3" flavor2="0">
- </item>
- <item path="relpipe-in-cli.cpp" ex="false" tool="1" flavor2="0">
- </item>
+ <codeAssistance>
+ </codeAssistance>
+ <makefileType>
+ <makeTool>
+ <buildCommandWorkingDir>build/Release</buildCommandWorkingDir>
+ <buildCommand>${MAKE} -f Makefile</buildCommand>
+ <cleanCommand>${MAKE} -f Makefile clean</cleanCommand>
+ <executablePath>build/Release/src/welcome</executablePath>
+ <ccTool>
+ <incDir>
+ <pElem>src</pElem>
+ </incDir>
+ <preprocessorList>
+ <Elem>NDEBUG</Elem>
+ </preprocessorList>
+ </ccTool>
+ </makeTool>
+ <preBuild>
+ <preBuildCommandWorkingDir>build/Release</preBuildCommandWorkingDir>
+ <preBuildCommand>${CMAKE} -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=${IDE_CC} -DCMAKE_CXX_COMPILER=${IDE_CXX} -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ../..</preBuildCommand>
+ <preBuildFirst>true</preBuildFirst>
+ </preBuild>
+ </makefileType>
</conf>
</confs>
</configurationDescriptor>
--- a/nbproject/project.xml Mon Dec 03 16:11:40 2018 +0100
+++ b/nbproject/project.xml Sun Dec 09 18:33:20 2018 +0100
@@ -9,15 +9,17 @@
<header-extensions>h</header-extensions>
<sourceEncoding>UTF-8</sourceEncoding>
<make-dep-projects/>
- <sourceRootList/>
+ <sourceRootList>
+ <sourceRootElem>.</sourceRootElem>
+ </sourceRootList>
<confList>
<confElem>
<name>Debug</name>
- <type>1</type>
+ <type>0</type>
</confElem>
<confElem>
<name>Release</name>
- <type>1</type>
+ <type>0</type>
</confElem>
</confList>
<formatting>
--- a/relpipe-in-cli.cpp Mon Dec 03 16:11:40 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/**
- * Relational pipes
- * Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#include <cstdlib>
-#include <memory>
-
-#include <relpipe/writer/RelationalWriter.h>
-#include <relpipe/writer/RelpipeWriterException.h>
-#include <relpipe/writer/Factory.h>
-#include <relpipe/writer/TypeId.h>
-
-#include <relpipe/cli/CLI.h>
-#include <relpipe/cli/RelpipeCLIException.h>
-
-#include "Command.h"
-#include "ArgumentsCommand.h"
-#include "DemoCommand.h"
-#include "StdInCommand.h"
-
-using namespace relpipe::cli;
-using namespace relpipe::in::cli;
-using namespace relpipe::writer;
-
-Command* findCommand(string_t commandName) {
- // TODO: better command names
- // TODO: help command
- if (commandName == L"demo") return new DemoCommand();
- else if (commandName == L"generate") return new ArgumentsCommand();
- else if (commandName == L"generate-without-stdin") return new StdInCommand(false); // TODO: just for testing, StdInCommand(false) should work same as ArgumentsCommand()
- else if (commandName == L"generate-from-stdin") return new StdInCommand(true);
- else throw RelpipeCLIException(L"Unknown command: " + commandName, CLI::EXIT_CODE_UNKNOWN_COMMAND);
-}
-
-int main(int argc, char** argv) {
- setlocale(LC_ALL, "");
- CLI::untieStdIO();
- CLI cli(argc, argv);
-
- int resultCode = CLI::EXIT_CODE_UNEXPECTED_ERROR;
-
- try {
- if (cli.arguments().size() > 0) {
-
- const wstring commandName = cli.arguments()[0];
- vector<wstring> arguments(cli.arguments().size() - 1);
- for (int i = 1; i < cli.arguments().size(); i++) {
- arguments[i - 1] = cli.arguments()[i];
- }
-
- std::shared_ptr<Command> command(findCommand(commandName));
- command->process(cin, cout, commandName, arguments);
- resultCode = CLI::EXIT_CODE_SUCCESS;
-
- } else {
- throw RelpipeCLIException(L"Missing command…", CLI::EXIT_CODE_BAD_SYNTAX);
- }
- } catch (RelpipeCLIException e) {
- fwprintf(stderr, L"Caught CLI exception: %ls\n", e.getMessge().c_str());
- fwprintf(stderr, L"Debug: Input stream: eof=%ls, lastRead=%d\n", (cin.eof() ? L"true" : L"false"), cin.gcount());
- resultCode = e.getExitCode();
- } catch (RelpipeWriterException e) {
- fwprintf(stderr, L"Caught Writer exception: %ls\n", e.getMessge().c_str());
- fwprintf(stderr, L"Debug: Input stream: eof=%ls, lastRead=%d\n", (cin.eof() ? L"true" : L"false"), cin.gcount());
- resultCode = CLI::EXIT_CODE_DATA_ERROR;
- }
-
- return resultCode;
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ArgumentsCommand.h Sun Dec 09 18:33:20 2018 +0100
@@ -0,0 +1,68 @@
+/**
+ * Relational pipes
+ * Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <cstdlib>
+#include <iostream>
+#include <string>
+#include <vector>
+#include <algorithm>
+
+#include <relpipe/writer/typedefs.h>
+#include <relpipe/writer/AttributeMetadata.h>
+
+#include "Command.h"
+
+namespace relpipe {
+namespace in {
+namespace cli {
+
+class ArgumentsCommand : public Command {
+public:
+
+ void process(std::istream& input, std::ostream& output, const relpipe::writer::string_t& command, const std::vector<relpipe::writer::string_t>& arguments) override {
+ using namespace relpipe::writer;
+
+ size_t i = 0;
+ string_t relationName = arguments[i++];
+ integer_t attributeCount = std::stoul(arguments[i++]); // TODO: use integer data type's method?
+ boolean_t writeHeader = true; // TODO: add option for header omitting
+
+ // TODO: check argument count
+
+ std::shared_ptr<RelationalWriter> writer(Factory::create(output));
+
+ std::vector<AttributeMetadata> attributes(attributeCount);
+
+ for (size_t j = 0; j < attributeCount; j++) {
+ string_t attributeName = arguments[i++];
+ TypeId attributeType = writer->toTypeId(arguments[i++]);
+ attributes[j] = {attributeName, attributeType};
+ }
+
+ writer->startRelation(relationName, attributes, writeHeader);
+
+ for (; i < arguments.size(); i++) {
+ writer->writeAttribute(arguments[i]);
+ }
+ }
+};
+
+}
+}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/CMakeLists.txt Sun Dec 09 18:33:20 2018 +0100
@@ -0,0 +1,37 @@
+# Relational pipes
+# Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+set(EXECUTABLE_FILE "relpipe-in-cli")
+
+# Relpipe libraries:
+INCLUDE(FindPkgConfig)
+pkg_check_modules (RELPIPE_LIBS relpipe-lib-writer.cpp relpipe-lib-cli.cpp)
+include_directories(${RELPIPE_LIBS_INCLUDE_DIRS})
+link_directories(${RELPIPE_LIBS_LIBRARY_DIRS})
+
+# Add ASan AddressSanitizer
+set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
+set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
+# From ASan wiki: "To get nicer stack traces in error messages add -fno-omit-frame-pointer."
+
+# Executable output:
+add_executable(
+ ${EXECUTABLE_FILE}
+ relpipe-in-cli.cpp
+)
+
+# Link libraries:
+target_link_libraries(${EXECUTABLE_FILE} ${RELPIPE_LIBS_LIBRARIES})
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Command.h Sun Dec 09 18:33:20 2018 +0100
@@ -0,0 +1,49 @@
+/**
+ * Relational pipes
+ * Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <cstdlib>
+#include <iostream>
+#include <string>
+#include <vector>
+#include <algorithm>
+
+
+namespace relpipe {
+namespace in {
+namespace cli {
+
+class Command {
+public:
+ virtual ~Command() = default;
+
+ /**
+ * Processes the inputs (stream + arguments) and generates output in the relational pipes format.
+ *
+ * @param input usually STDIN, may not be used if all data are passed as CLI arguments
+ * @param output usually STDOUT, relational data is passed here
+ * @param command command name, usualy not needed, may be significant if the same Command instance is used for several commands
+ * @param arguments CLI arguments containing data or parameters (format is specific to each command)
+ */
+ virtual void process(std::istream& input, std::ostream& output, const relpipe::writer::string_t& command, const std::vector<relpipe::writer::string_t> &arguments) = 0;
+
+};
+
+}
+}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/DemoCommand.h Sun Dec 09 18:33:20 2018 +0100
@@ -0,0 +1,82 @@
+/**
+ * Relational pipes
+ * Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <cstdlib>
+#include <iostream>
+#include <string>
+#include <vector>
+#include <algorithm>
+
+#include <relpipe/writer/typedefs.h>
+
+#include "Command.h"
+
+namespace relpipe {
+namespace in {
+namespace cli {
+
+class DemoCommand : public Command {
+public:
+
+ void process(std::istream& input, std::ostream& output, const relpipe::writer::string_t& command, const std::vector<relpipe::writer::string_t>& arguments) override {
+ using namespace relpipe::writer;
+ std::shared_ptr<RelationalWriter> writer(Factory::create(output));
+
+
+ // Various data types passed as strings
+ writer->startRelation(L"table_from_strings",{
+ {L"s", TypeId::STRING},
+ {L"i", TypeId::INTEGER},
+ {L"b", TypeId::BOOLEAN}
+ }, true);
+
+ writer->writeAttribute(L"a");
+ writer->writeAttribute(L"1");
+ writer->writeAttribute(L"true");
+
+ writer->writeAttribute(L"b");
+ writer->writeAttribute(L"2");
+ writer->writeAttribute(L"false");
+
+
+ // Various data types passed as raw pointers + typeids
+ writer->startRelation(L"from_raw_pointers",{
+ {L"s", TypeId::STRING},
+ {L"i", TypeId::INTEGER},
+ {L"b", TypeId::BOOLEAN}
+ }, true);
+
+ string_t sValue;
+ integer_t iValue;
+ boolean_t bValue;
+
+ for (int i = 0; i < 8; i++) {
+ sValue.append(L"*");
+ iValue = i + 1;
+ bValue = iValue % 2 == 0;
+ writer->writeAttribute(&sValue, typeid (sValue));
+ writer->writeAttribute(&iValue, typeid (iValue));
+ writer->writeAttribute(&bValue, typeid (bValue));
+ }
+ }
+};
+
+}
+}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/StdInCommand.h Sun Dec 09 18:33:20 2018 +0100
@@ -0,0 +1,118 @@
+/**
+ * Relational pipes
+ * Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <cstdlib>
+#include <iostream>
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <string>
+#include <locale>
+
+#include <relpipe/writer/typedefs.h>
+#include <relpipe/writer/AttributeMetadata.h>
+#include <relpipe/cli/CLI.h>
+#include <relpipe/cli/RelpipeCLIException.h>
+
+#include "Command.h"
+
+namespace relpipe {
+namespace in {
+namespace cli {
+
+/**
+ * TODO: consider code merge with ArgumentsCommand
+ */
+class StdInCommand : public Command {
+private:
+ relpipe::writer::boolean_t readStdIn;
+ std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings.
+
+ /**
+ * Reads next value from arguments and (if no arguments left) from input
+ * @param input
+ * @param arguments
+ * @param i current index in the arguments vector
+ * @param required if true, exception is thrown when no data found
+ * @return
+ */
+ relpipe::writer::string_t readNext(std::istream& input, const std::vector<relpipe::writer::string_t>& arguments, size_t& i, relpipe::writer::boolean_t required) {
+ using namespace relpipe::writer;
+ using namespace relpipe::cli;
+
+ if (i < arguments.size()) {
+ return arguments[i++];
+ } else if (readStdIn) {
+ std::stringstream value;
+
+ while (true) {
+ char ch;
+ input.get(ch);
+ if (ch == 0 || input.eof() || input.fail()) break;
+ else value << ch;
+ }
+
+ if (required && value.str().empty()) throw RelpipeCLIException(L"Missing value on STDIN.", CLI::EXIT_CODE_BAD_SYNTAX);
+
+ return convertor.from_bytes(value.str());
+ } else {
+ if (required) throw RelpipeCLIException(L"Missing value on CLI.", CLI::EXIT_CODE_BAD_SYNTAX);
+ return L"";
+ }
+ }
+
+
+public:
+
+ StdInCommand(relpipe::writer::boolean_t readStdIn) :
+ readStdIn(readStdIn) {
+ }
+
+ void process(std::istream& input, std::ostream& output, const relpipe::writer::string_t& command, const std::vector<relpipe::writer::string_t>& arguments) override {
+ using namespace relpipe::writer;
+
+ size_t i = 0;
+ string_t relationName = readNext(input, arguments, i, true);
+ integer_t attributeCount = std::stoul(readNext(input, arguments, i, true)); // TODO: use integer data type's method?
+ boolean_t writeHeader = true; // TODO: add option for header omitting
+
+ std::shared_ptr<RelationalWriter> writer(Factory::create(output));
+
+ std::vector<AttributeMetadata> attributes(attributeCount);
+
+ for (size_t j = 0; j < attributeCount; j++) {
+ string_t attributeName = readNext(input, arguments, i, true);
+ TypeId attributeType = writer->toTypeId(readNext(input, arguments, i, true));
+ attributes[j] = {attributeName, attributeType};
+ }
+
+ writer->startRelation(relationName, attributes, writeHeader);
+
+ while (true) {
+ string_t value = readNext(input, arguments, i, false);
+ if (value.empty() && (input.eof() || input.fail() || (!readStdIn && i >= arguments.size()))) break;
+ else writer->writeAttribute(value);
+ // TODO: check attribute count (avoid unfinished records)
+ }
+ }
+};
+
+}
+}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/relpipe-in-cli.cpp Sun Dec 09 18:33:20 2018 +0100
@@ -0,0 +1,82 @@
+/**
+ * Relational pipes
+ * Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <cstdlib>
+#include <memory>
+
+#include <relpipe/writer/RelationalWriter.h>
+#include <relpipe/writer/RelpipeWriterException.h>
+#include <relpipe/writer/Factory.h>
+#include <relpipe/writer/TypeId.h>
+
+#include <relpipe/cli/CLI.h>
+#include <relpipe/cli/RelpipeCLIException.h>
+
+#include "Command.h"
+#include "ArgumentsCommand.h"
+#include "DemoCommand.h"
+#include "StdInCommand.h"
+
+using namespace relpipe::cli;
+using namespace relpipe::in::cli;
+using namespace relpipe::writer;
+
+Command* findCommand(string_t commandName) {
+ // TODO: better command names
+ // TODO: help command
+ if (commandName == L"demo") return new DemoCommand();
+ else if (commandName == L"generate") return new ArgumentsCommand();
+ else if (commandName == L"generate-without-stdin") return new StdInCommand(false); // TODO: just for testing, StdInCommand(false) should work same as ArgumentsCommand()
+ else if (commandName == L"generate-from-stdin") return new StdInCommand(true);
+ else throw RelpipeCLIException(L"Unknown command: " + commandName, CLI::EXIT_CODE_UNKNOWN_COMMAND);
+}
+
+int main(int argc, char** argv) {
+ setlocale(LC_ALL, "");
+ CLI::untieStdIO();
+ CLI cli(argc, argv);
+
+ int resultCode = CLI::EXIT_CODE_UNEXPECTED_ERROR;
+
+ try {
+ if (cli.arguments().size() > 0) {
+
+ const wstring commandName = cli.arguments()[0];
+ vector<wstring> arguments(cli.arguments().size() - 1);
+ for (int i = 1; i < cli.arguments().size(); i++) {
+ arguments[i - 1] = cli.arguments()[i];
+ }
+
+ std::shared_ptr<Command> command(findCommand(commandName));
+ command->process(cin, cout, commandName, arguments);
+ resultCode = CLI::EXIT_CODE_SUCCESS;
+
+ } else {
+ throw RelpipeCLIException(L"Missing command…", CLI::EXIT_CODE_BAD_SYNTAX);
+ }
+ } catch (RelpipeCLIException e) {
+ fwprintf(stderr, L"Caught CLI exception: %ls\n", e.getMessge().c_str());
+ fwprintf(stderr, L"Debug: Input stream: eof=%ls, lastRead=%d\n", (cin.eof() ? L"true" : L"false"), cin.gcount());
+ resultCode = e.getExitCode();
+ } catch (RelpipeWriterException e) {
+ fwprintf(stderr, L"Caught Writer exception: %ls\n", e.getMessge().c_str());
+ fwprintf(stderr, L"Debug: Input stream: eof=%ls, lastRead=%d\n", (cin.eof() ? L"true" : L"false"), cin.gcount());
+ resultCode = CLI::EXIT_CODE_DATA_ERROR;
+ }
+
+ return resultCode;
+}