src/AwkHandler.h
branchv_0
changeset 25 13a1e1134797
parent 24 c805c968b7ed
child 26 cf57e8c78492
equal deleted inserted replaced
24:c805c968b7ed 25:13a1e1134797
    67 	std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings
    67 	std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings
    68 
    68 
    69 	int awkInputWriterFD = -1;
    69 	int awkInputWriterFD = -1;
    70 	RelationConfiguration* currentRelationConfiguration = nullptr;
    70 	RelationConfiguration* currentRelationConfiguration = nullptr;
    71 	std::vector<AttributeMetadata> currentReaderMetadata;
    71 	std::vector<AttributeMetadata> currentReaderMetadata;
    72 	vector<writer::AttributeMetadata> currentWriterMetadata;
    72 	std::vector<writer::AttributeMetadata> currentWriterMetadata;
       
    73 	std::map<string_t, string_t> currenVariablesMapping;
    73 	integer_t currentAttributeIndex = 0;
    74 	integer_t currentAttributeIndex = 0;
    74 
    75 
    75 	void createPipe(int& readerFD, int& writerFD) {
    76 	void createPipe(int& readerFD, int& writerFD) {
    76 		int fds[2];
    77 		int fds[2];
    77 		int result = pipe(fds);
    78 		int result = pipe(fds);
   139 		}
   140 		}
   140 
   141 
   141 		currentAttributeIndex = 0;
   142 		currentAttributeIndex = 0;
   142 		currentReaderMetadata.clear();
   143 		currentReaderMetadata.clear();
   143 		currentWriterMetadata.clear();
   144 		currentWriterMetadata.clear();
       
   145 		currenVariablesMapping.clear();
   144 		currentRelationConfiguration = nullptr;
   146 		currentRelationConfiguration = nullptr;
   145 	}
   147 	}
   146 
   148 
       
   149 	void generateVariableMappings() {
       
   150 		for (AttributeMetadata m : currentReaderMetadata) currenVariablesMapping[m.getAttributeName()] = L"";
       
   151 		for (writer::AttributeMetadata m : currentWriterMetadata) currenVariablesMapping[m.attributeName] = L"";
       
   152 		for (DefinitionRecipe d : configuration.definitions) currenVariablesMapping[d.name] = L"";
       
   153 		for (DefinitionRecipe d : currentRelationConfiguration->definitions) currenVariablesMapping[d.name] = L"";
       
   154 
       
   155 		for (std::pair<string_t, string_t> m : currenVariablesMapping) {
       
   156 			currenVariablesMapping[m.first] = escapeAwkVariableName(m.first);
       
   157 		}
       
   158 	}
       
   159 
   147 	string_t a2v(const string_t& attributeName) {
   160 	string_t a2v(const string_t& attributeName) {
       
   161 		if (currenVariablesMapping.find(attributeName) != currenVariablesMapping.end()) return currenVariablesMapping[attributeName];
       
   162 		else throw cli::RelpipeCLIException(L"Unable to find value in currenVariablesMapping", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions?
       
   163 	}
       
   164 
       
   165 	template <typename K, typename V> bool containsValue(std::map<K, V> map, V value) {
       
   166 		for (std::pair<K, V> p : map) if (p.second == value) return true;
       
   167 		return false;
       
   168 	}
       
   169 
       
   170 	string_t escapeAwkVariableName(const string_t& attributeName) {
   148 		// cat awkgram.y | awk -v FS='\\{"|",' -v ORS='|' '/static const struct token tokentab/, /\};/ { if (/^\{/) { print $2} }'
   171 		// cat awkgram.y | awk -v FS='\\{"|",' -v ORS='|' '/static const struct token tokentab/, /\};/ { if (/^\{/) { print $2} }'
       
   172 		// cat AwkHandler.h | awk -v FS=' |\\(' -v ORS='|' '/awkScript.*"function/ { print $4; }'
   149 		std::wregex awkReservedNames(L"BEGIN|BEGINFILE|END|ENDFILE|adump|and|asort|asorti|atan2|bindtextdomain|break|case|close|compl|continue|cos|dcgettext|dcngettext|default|delete|do|else|eval|exit|exp|fflush|for|func|function|gensub|getline|gsub|if|in|include|index|int|intdiv0|isarray|length|load|log|lshift|match|mktime|namespace|next|nextfile|or|patsplit|print|printf|rand|return|rshift|sin|split|sprintf|sqrt|srand|stopme|strftime|strtonum|sub|substr|switch|system|systime|tolower|toupper|typeof|while|xor");
   173 		std::wregex awkReservedNames(L"BEGIN|BEGINFILE|END|ENDFILE|adump|and|asort|asorti|atan2|bindtextdomain|break|case|close|compl|continue|cos|dcgettext|dcngettext|default|delete|do|else|eval|exit|exp|fflush|for|func|function|gensub|getline|gsub|if|in|include|index|int|intdiv0|isarray|length|load|log|lshift|match|mktime|namespace|next|nextfile|or|patsplit|print|printf|rand|return|rshift|sin|split|sprintf|sqrt|srand|stopme|strftime|strtonum|sub|substr|switch|system|systime|tolower|toupper|typeof|while|xor");
   150 		std::wregex trReservedNames(L"_escape|_unescape|_readVariables|_writeVariables|record");
   174 		std::wregex trReservedNames(L"_escape|_unescape|_readVariables|_writeVariables|record");
   151 		if (regex_match(attributeName, awkReservedNames) || regex_match(attributeName, trReservedNames)) return a2v(L"_" + attributeName);
   175 		std::wregex badCharacters(L"[^a-zA-Z0-9_]|^([0-9])");
   152 		else return attributeName;
   176 
       
   177 		const string_t& name = std::regex_replace(attributeName, badCharacters, L"_$1");
       
   178 
       
   179 		bool badName = false;
       
   180 		badName |= regex_match(name, awkReservedNames);
       
   181 		badName |= regex_match(name, trReservedNames);
       
   182 		badName |= containsValue(currenVariablesMapping, name);
       
   183 
       
   184 		if (badName) return escapeAwkVariableName(L"_" + name);
       
   185 		else return name;
   153 	}
   186 	}
   154 
   187 
   155 	string_t escapeAwkValue(const string_t& value) {
   188 	string_t escapeAwkValue(const string_t& value) {
   156 		std::wstringstream escaped;
   189 		std::wstringstream escaped;
   157 		for (wchar_t ch : value) {
   190 		for (wchar_t ch : value) {
   226 		} else {
   259 		} else {
   227 			add(currentReaderMetadata, currentWriterMetadata);
   260 			add(currentReaderMetadata, currentWriterMetadata);
   228 		}
   261 		}
   229 
   262 
   230 		if (currentRelationConfiguration) {
   263 		if (currentRelationConfiguration) {
       
   264 			generateVariableMappings();
       
   265 
   231 			int awkInputReaderFD;
   266 			int awkInputReaderFD;
   232 			int awkOutputReaderFD;
   267 			int awkOutputReaderFD;
   233 			int awkOutputWriterFD;
   268 			int awkOutputWriterFD;
   234 
   269 
   235 			createPipe(awkInputReaderFD, awkInputWriterFD);
   270 			createPipe(awkInputReaderFD, awkInputWriterFD);