src/AwkHandler.h
branchv_0
changeset 28 4fdbe30d8c58
parent 27 86d8bbc99e7b
child 29 b3d1a671315b
equal deleted inserted replaced
27:86d8bbc99e7b 28:4fdbe30d8c58
    39 #include <relpipe/writer/Factory.h>
    39 #include <relpipe/writer/Factory.h>
    40 
    40 
    41 #include <relpipe/cli/RelpipeCLIException.h>
    41 #include <relpipe/cli/RelpipeCLIException.h>
    42 
    42 
    43 #include "Configuration.h"
    43 #include "Configuration.h"
       
    44 #include "AwkException.h"
    44 
    45 
    45 namespace relpipe {
    46 namespace relpipe {
    46 namespace tr {
    47 namespace tr {
    47 namespace awk {
    48 namespace awk {
    48 
    49 
    76 	void createPipe(int& readerFD, int& writerFD) {
    77 	void createPipe(int& readerFD, int& writerFD) {
    77 		int fds[2];
    78 		int fds[2];
    78 		int result = pipe(fds);
    79 		int result = pipe(fds);
    79 		readerFD = fds[0];
    80 		readerFD = fds[0];
    80 		writerFD = fds[1];
    81 		writerFD = fds[1];
    81 		if (result < 0) throw cli::RelpipeCLIException(L"Unable to create a pipe.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions?
    82 		if (result < 0) throw AwkException(L"Unable to create a pipe.");
    82 	}
    83 	}
    83 
    84 
    84 	void redirectFD(int oldfd, int newfd) {
    85 	void redirectFD(int oldfd, int newfd) {
    85 		int result = dup2(oldfd, newfd);
    86 		int result = dup2(oldfd, newfd);
    86 		if (result < 0) throw cli::RelpipeCLIException(L"Unable redirect FD.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions?
    87 		if (result < 0) throw AwkException(L"Unable redirect FD.");
    87 	}
    88 	}
    88 
    89 
    89 	void closeOrThrow(int fd) {
    90 	void closeOrThrow(int fd) {
    90 		int error = close(fd);
    91 		int error = close(fd);
    91 		if (error) throw cli::RelpipeCLIException(L"Unable to close FD: " + to_wstring(fd) + L" from PID: " + to_wstring(getpid()), cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions?
    92 		if (error) throw AwkException(L"Unable to close FD: " + to_wstring(fd) + L" from PID: " + to_wstring(getpid()));
    92 	}
    93 	}
    93 
    94 
    94 	void execp(const std::vector<std::string>& args) {
    95 	void execp(const std::vector<std::string>& args) {
    95 		const char** a = new const char*[args.size() + 1];
    96 		const char** a = new const char*[args.size() + 1];
    96 		for (size_t i = 0; i < args.size(); i++) a[i] = args[i].c_str();
    97 		for (size_t i = 0; i < args.size(); i++) a[i] = args[i].c_str();
    97 		a[args.size()] = nullptr;
    98 		a[args.size()] = nullptr;
    98 
    99 
    99 		execvp(a[0], (char*const*) a);
   100 		execvp(a[0], (char*const*) a);
   100 
   101 
   101 		delete[] a;
   102 		delete[] a;
   102 		throw cli::RelpipeCLIException(L"Unable to do execvp().", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions?
   103 		throw AwkException(L"Unable to do execvp().");
   103 	}
   104 	}
   104 
   105 
   105 	/* TODO: move to lib-cli when stable and used in other modules */
   106 	/* TODO: move to lib-cli when stable and used in other modules */
   106 	void setEnv(const char * name, const string_t& value) {
   107 	void setEnv(const char * name, const string_t& value) {
   107 		setenv(name, convertor.to_bytes(value).c_str(), true);
   108 		setenv(name, convertor.to_bytes(value).c_str(), true);
   159 		}
   160 		}
   160 	}
   161 	}
   161 
   162 
   162 	string_t a2v(const string_t& attributeName) {
   163 	string_t a2v(const string_t& attributeName) {
   163 		if (currenVariablesMapping.find(attributeName) != currenVariablesMapping.end()) return currenVariablesMapping[attributeName];
   164 		if (currenVariablesMapping.find(attributeName) != currenVariablesMapping.end()) return currenVariablesMapping[attributeName];
   164 		else throw cli::RelpipeCLIException(L"Unable to find value in currenVariablesMapping", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions?
   165 		else throw AwkException(L"Unable to find value in currenVariablesMapping");
   165 	}
   166 	}
   166 
   167 
   167 	template <typename K, typename V> bool containsValue(std::map<K, V> map, V value) {
   168 	template <typename K, typename V> bool containsValue(std::map<K, V> map, V value) {
   168 		for (std::pair<K, V> p : map) if (p.second == value) return true;
   169 		for (std::pair<K, V> p : map) if (p.second == value) return true;
   169 		return false;
   170 		return false;
   216 				} else if (ch == '\\') {
   217 				} else if (ch == '\\') {
   217 					ch = awkOutputReader.get();
   218 					ch = awkOutputReader.get();
   218 					if (ch == 't') currentValue << L'\t';
   219 					if (ch == 't') currentValue << L'\t';
   219 					else if (ch == 'n') currentValue << L'\n';
   220 					else if (ch == 'n') currentValue << L'\n';
   220 					else if (ch == '\\') currentValue << L'\\';
   221 					else if (ch == '\\') currentValue << L'\\';
   221 					else throw cli::RelpipeCLIException(L"Unknown escape sequence. Only \\t, \\n and \\\\ are supported.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions?
   222 					else throw AwkException(L"Unknown escape sequence. Only \\t, \\n and \\\\ are supported.");
   222 				} else {
   223 				} else {
   223 					currentValue << ch;
   224 					currentValue << ch;
   224 				}
   225 				}
   225 			}
   226 			}
   226 		}
   227 		}
   286 
   287 
   287 			relationalWriterFlush();
   288 			relationalWriterFlush();
   288 			__pid_t awkPid = fork();
   289 			__pid_t awkPid = fork();
   289 
   290 
   290 			if (awkPid < 0) {
   291 			if (awkPid < 0) {
   291 				throw cli::RelpipeCLIException(L"Unable to fork AWK process.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions?
   292 				throw AwkException(L"Unable to fork AWK process.");
   292 			} else if (awkPid == 0) {
   293 			} else if (awkPid == 0) {
   293 				// AWK child process
   294 				// AWK child process
   294 				closeOrThrow(awkInputWriterFD);
   295 				closeOrThrow(awkInputWriterFD);
   295 				closeOrThrow(awkOutputReaderFD);
   296 				closeOrThrow(awkOutputReaderFD);
   296 
   297 
   377 				closeOrThrow(awkOutputWriterFD);
   378 				closeOrThrow(awkOutputWriterFD);
   378 
   379 
   379 				__pid_t writerPid = fork();
   380 				__pid_t writerPid = fork();
   380 
   381 
   381 				if (writerPid < 0) {
   382 				if (writerPid < 0) {
   382 					throw cli::RelpipeCLIException(L"Unable to fork Writer process.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions?
   383 					throw AwkException(L"Unable to fork Writer process.");
   383 				} else if (writerPid == 0) {
   384 				} else if (writerPid == 0) {
   384 					// Writer child process
   385 					// Writer child process
   385 					closeOrThrow(awkInputWriterFD);
   386 					closeOrThrow(awkInputWriterFD);
   386 
   387 
   387 					if (currentRelationConfiguration->debugVariableMapping) debugVariableMapping(name);
   388 					if (currentRelationConfiguration->debugVariableMapping) debugVariableMapping(name);