1 #include "otsdaq/Macros/StringMacros.h"
9 std::map<std::string , std::string >>
10 StringMacros::systemVariables_;
11 const std::string StringMacros::TBD =
"To-be-defined";
25 const std::string& haystack,
26 unsigned int* priorityIndex)
34 if(needle.size() == 0)
50 if(needle == haystack)
58 if(needle[needle.size() - 1] ==
'*' &&
59 needle.substr(0, needle.size() - 1) == haystack.substr(0, needle.size() - 1))
67 if(needle[0] ==
'*' &&
68 needle.substr(1) == haystack.substr(haystack.size() - (needle.size() - 1)))
76 if(needle[0] ==
'*' && needle[needle.size() - 1] ==
'*' &&
77 std::string::npos != haystack.find(needle.substr(1, needle.size() - 2)))
101 const std::set<std::string>& haystack)
103 for(
const auto& haystackString : haystack)
106 if(haystackString.size() && haystackString[0] ==
'!')
123 std::string decodeURIString(data.size(), 0);
125 for(
unsigned int i = 0; i < data.size(); ++i, ++j)
130 if(data[i + 1] >
'9')
131 decodeURIString[j] += (data[i + 1] - 55) * 16;
133 decodeURIString[j] += (data[i + 1] - 48) * 16;
136 if(data[i + 2] >
'9')
137 decodeURIString[j] += (data[i + 2] - 55);
139 decodeURIString[j] += (data[i + 2] - 48);
144 decodeURIString[j] = data[i];
146 decodeURIString.resize(j);
147 return decodeURIString;
151 std::string StringMacros::encodeURIComponent(
const std::string& sourceStr)
153 std::string retStr =
"";
155 for(
const auto& c : sourceStr)
156 if((c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z') || (c >=
'0' && c <=
'9'))
160 sprintf(encodeStr,
"%%%2.2X", (uint8_t)c);
170 std::map<char, std::string> replacements = {
178 while(pos < str.size())
180 auto it = replacements.find(str[pos]);
181 if(it != replacements.end())
183 str.replace(pos, 1, it->second);
184 pos += it->second.size();
203 bool allowWhiteSpace )
205 unsigned int ws = -1;
208 __COUTVS__(30, allowWhiteSpace);
210 for(
unsigned int i = 0; i < inString.length(); i++)
211 if(inString[i] !=
' ')
213 __COUTS__(30) << i <<
". " << inString[i] <<
":" << (int)inString[i]
217 if(inString[i] ==
'\r' || inString[i] ==
'\n' ||
218 inString[i] ==
'\t' ||
221 (inString[i] >
char(126) &&
222 inString[i] <
char(161)))
229 if(i + 2 < inString.size() && inString[i] == char(0xE2) &&
230 inString[i + 1] == char(0x80) &&
249 if(inString[i] ==
'\n')
253 sprintf(htmlTmp,
"&#%3.3d", inString[i]);
255 i, std::string(htmlTmp));
264 else if(inString[i] ==
'\t')
272 "        ");
274 i, std::string(htmlTmp));
282 sprintf(htmlTmp,
"	");
284 i, std::string(htmlTmp));
296 inString.erase(i, 1);
299 __COUTS__(31) << inString << std::endl;
303 __COUTS__(31) << inString << std::endl;
306 if(inString[i] ==
'\"' || inString[i] ==
'\'')
309 (inString[i] ==
'\'')
312 inString.replace(i + 5, 1, 1,
';');
316 else if(inString[i] ==
'&')
318 inString.insert(i,
"&");
319 inString.replace(i + 4, 1, 1,
';');
322 else if(inString[i] ==
'<' || inString[i] ==
'>')
329 inString.replace(i + 3, 1, 1,
';');
332 else if(inString[i] >=
char(161) &&
333 inString[i] <=
char(255))
335 sprintf(htmlTmp,
"&#%3.3d", inString[i]);
336 inString.insert(i, std::string(htmlTmp));
337 inString.replace(i + 5, 1, 1,
';');
341 __COUTS__(30) << inString << std::endl;
345 else if(allowWhiteSpace)
353 inString.insert(i,
" ");
356 inString.insert(i,
" ");
357 inString.replace(i + 5, 1, 1,
';');
362 __COUTS__(30) << inString.size() <<
" " << ws << std::endl;
366 __COUTS__(30) << inString.size() <<
" " << inString << std::endl;
372 if(ws == (
unsigned int)-1)
374 return inString.substr(0, ws + 1);
384 unsigned int sz = str.size();
388 std::string retStr =
"";
389 retStr.reserve(str.size() * 2);
390 for(
unsigned int i = 0; i < sz; ++i)
422 unsigned int sz = str.size();
426 std::string retStr =
"";
427 retStr.reserve(str.size());
429 for(; i < sz - 1; ++i)
461 retStr += str[sz - 1];
472 s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](
unsigned char ch) {
473 return !std::isspace(ch);
477 s.erase(std::find_if(
478 s.rbegin(), s.rend(), [](
unsigned char ch) { return !std::isspace(ch); })
497 size_t begin = data.find(
"$");
498 if(begin != std::string::npos)
501 std::string envVariable;
502 std::string converted = data;
504 while(begin && begin != std::string::npos &&
505 converted[begin - 1] ==
508 converted.replace(begin - 1, 1,
"");
509 begin = data.find(
"$", begin + 1);
510 if(begin == std::string::npos)
512 __COUTS__(50) <<
"Only found escaped $'s that will not be converted: "
513 << converted << __E__;
518 if(data[begin + 1] ==
'{')
520 end = data.find(
"}", begin + 2);
521 envVariable = data.substr(begin + 2, end - begin - 2);
527 for(end = begin + 1; end < data.size(); ++end)
528 if(!((data[end] >=
'0' && data[end] <=
'9') ||
529 (data[end] >=
'A' && data[end] <=
'Z') ||
530 (data[end] >=
'a' && data[end] <=
'z') || data[end] ==
'-' ||
531 data[end] ==
'_' || data[end] ==
'.' || data[end] ==
':'))
533 envVariable = data.substr(begin + 1, end - begin - 1);
535 __COUTVS__(50, data);
536 __COUTVS__(50, envVariable);
537 if(envVariable.starts_with(
"OTS."))
539 __COUT__ <<
"OTS system variable detected!" << __E__;
543 if(sysVarSplit.size() != 3 ||
544 systemVariables_.find(sysVarSplit[1]) == systemVariables_.end() ||
545 systemVariables_.at(sysVarSplit[1]).find(sysVarSplit[2]) ==
546 systemVariables_.at(sysVarSplit[1]).end())
548 __SS__ <<
"System variable ${" << envVariable
549 <<
"} is not valid or was not found!" << __E__;
557 systemVariables_.at(sysVarSplit[1]).at(sysVarSplit[2])));
561 char* envResult = __ENV__(envVariable.c_str());
567 converted.replace(begin, end - begin, envResult));
571 __SS__ << (
"The environmental variable '" + envVariable +
572 "' is not set! Please make sure you set it before continuing!")
579 __COUTS__(50) <<
"Result: " << data << __E__;
591 std::vector<std::string> numbers;
592 std::vector<char> ops;
600 std::set<char>({
'+',
'-',
'*',
'/'}),
601 std::set<char>({
' ',
'\t',
'\n',
'\r'}),
607 for(
const auto& number : numbers)
609 if(number.size() == 0)
612 if(number.find(
"0x") == 0)
615 for(
unsigned int i = 2; i < number.size(); ++i)
617 if(!((number[i] >=
'0' && number[i] <=
'9') ||
618 (number[i] >=
'A' && number[i] <=
'F') ||
619 (number[i] >=
'a' && number[i] <=
'f')))
627 else if(number[0] ==
'b')
631 for(
unsigned int i = 1; i < number.size(); ++i)
633 if(!((number[i] >=
'0' && number[i] <=
'1')))
643 for(
unsigned int i = 0; i < number.size(); ++i)
644 if(!((number[i] >=
'0' && number[i] <=
'9') || number[i] ==
'.' ||
645 number[i] ==
'+' || number[i] ==
'-'))
668 std::vector<std::string> numbers;
669 std::vector<char> ops;
671 bool hasDecimal =
false;
676 std::set<char>({
'+',
'-',
'*',
'/'}),
677 std::set<char>({
' ',
'\t',
'\n',
'\r'}),
683 for(
const auto& number : numbers)
685 if(number.size() == 0)
688 if(number.find(
"0x") == 0)
691 for(
unsigned int i = 2; i < number.size(); ++i)
693 if(!((number[i] >=
'0' && number[i] <=
'9') ||
694 (number[i] >=
'A' && number[i] <=
'F') ||
695 (number[i] >=
'a' && number[i] <=
'f')))
703 else if(number[0] ==
'b')
707 for(
unsigned int i = 1; i < number.size(); ++i)
709 if(!((number[i] >=
'0' && number[i] <=
'1')))
719 for(
unsigned int i = 0; i < number.size(); ++i)
720 if(!((number[i] >=
'0' && number[i] <=
'9') || number[i] ==
'.' ||
721 number[i] ==
'+' || number[i] ==
'-'))
723 else if(number[i] ==
'.')
736 return "unsigned long long";
749 __COUT_ERR__ <<
"Invalid empty bool string " << s << __E__;
754 if(s.find(
"1") != std::string::npos || s ==
"true" || s ==
"True" || s ==
"TRUE")
761 if(s.find(
"0") != std::string::npos || s ==
"false" || s ==
"False" || s ==
"FALSE")
767 __COUT_ERR__ <<
"Invalid bool string " << s << __E__;
778 time_t timestamp(strtol(linuxTimeInSeconds.c_str(), 0, 10));
788 std::string retValue(30,
'\0');
791 ::localtime_r(&linuxTimeInSeconds, &tmstruct);
792 ::strftime(&retValue[0], 30,
"%c %Z", &tmstruct);
793 retValue.resize(strlen(retValue.c_str()));
805 std::stringstream ss;
806 int days = t / 60 / 60 / 24;
809 ss << days <<
" day" << (days > 1 ?
"s" :
"") <<
", ";
810 t -= days * 60 * 60 * 24;
814 ss << std::setw(2) << std::setfill(
'0') << (t / 60 / 60) <<
":" << std::setw(2)
815 << std::setfill(
'0') << ((t % (60 * 60)) / 60) <<
":" << std::setw(2)
816 << std::setfill(
'0') << (t % 60);
824 const std::string& value,
bool doConvertEnvironmentVariables)
827 return doConvertEnvironmentVariables
831 catch(
const std::runtime_error& e)
833 __SS__ <<
"Failed to validate value for default string data type. " << __E__
834 << e.what() << __E__;
843 std::set<std::string>& setToReturn,
844 const std::set<char>& delimiter,
845 const std::set<char>& whitespace)
852 for(; j < inputString.size(); ++j)
853 if((whitespace.find(inputString[j]) !=
855 delimiter.find(inputString[j]) != delimiter.end()) &&
858 else if((whitespace.find(inputString[j]) !=
861 delimiter.find(inputString[j]) != delimiter.end()) &&
867 setToReturn.emplace(inputString.substr(i, j - i));
874 setToReturn.emplace(inputString.substr(i, j - i));
890 std::vector<std::string>& listToReturn,
891 const std::set<char>& delimiter,
892 const std::set<char>& whitespace,
893 std::vector<char>* listOfDelimiters,
894 bool decodeURIComponents)
899 std::set<char>::iterator delimeterSearchIt;
900 char lastDelimiter = 0;
909 for(; c < inputString.size(); ++c)
913 delimeterSearchIt = delimiter.find(inputString[c]);
914 isDelimiter = delimeterSearchIt != delimiter.end();
919 if(whitespace.find(inputString[c]) !=
928 else if(whitespace.find(inputString[c]) != whitespace.end() &&
938 if(listOfDelimiters && listToReturn.size())
945 listOfDelimiters->push_back(lastDelimiter);
948 inputString.substr(i, j - i))
949 : inputString.substr(i, j - i));
959 lastDelimiter = *delimeterSearchIt;
968 if(listOfDelimiters && listToReturn.size())
974 listOfDelimiters->push_back(lastDelimiter);
977 inputString.substr(i, j - i))
978 : inputString.substr(i, j - i));
982 if(listOfDelimiters && listToReturn.size() - 1 != listOfDelimiters->size() &&
983 listToReturn.size() != listOfDelimiters->size())
985 __SS__ <<
"There is a mismatch in delimiters to entries (should be equal or one "
987 << listOfDelimiters->size() <<
" vs " << listToReturn.size() << __E__
1009 const std::string& inputString,
1010 const std::set<char>& delimiter,
1011 const std::set<char>& whitespace,
1012 std::vector<char>* listOfDelimiters,
1013 bool decodeURIComponents)
1015 std::vector<std::string> listToReturn;
1022 decodeURIComponents);
1023 return listToReturn;
1031 std::map<std::string, std::string>& mapToReturn,
1032 const std::set<char>& pairPairDelimiter,
1033 const std::set<char>& nameValueDelimiter,
1034 const std::set<char>& whitespace)
1040 bool needValue =
false;
1044 for(; j < inputString.size(); ++j)
1047 if((whitespace.find(inputString[j]) !=
1049 pairPairDelimiter.find(inputString[j]) != pairPairDelimiter.end()) &&
1052 else if((whitespace.find(inputString[j]) !=
1055 nameValueDelimiter.find(inputString[j]) !=
1056 nameValueDelimiter.end()) &&
1062 name = inputString.substr(i, j - i);
1072 if((whitespace.find(inputString[j]) !=
1074 nameValueDelimiter.find(inputString[j]) != nameValueDelimiter.end()) &&
1077 else if(whitespace.find(inputString[j]) !=
1080 pairPairDelimiter.find(inputString[j]) !=
1081 pairPairDelimiter.end())
1087 auto emplaceReturn =
1088 mapToReturn.emplace(std::pair<std::string, std::string>(
1091 inputString.substr(i, j - i))
1094 if(!emplaceReturn.second)
1096 __COUT__ <<
"Ignoring repetitive value ('"
1097 << inputString.substr(i, j - i)
1098 <<
"') and keeping current value ('"
1099 << emplaceReturn.first->second <<
"'). " << __E__;
1111 auto emplaceReturn =
1112 mapToReturn.emplace(std::pair<std::string, std::string>(
1115 inputString.substr(i, j - i))
1118 if(!emplaceReturn.second)
1120 __COUT__ <<
"Ignoring repetitive value ('" << inputString.substr(i, j - i)
1121 <<
"') and keeping current value ('" << emplaceReturn.first->second
1126 catch(
const std::runtime_error& e)
1128 __SS__ <<
"Error while extracting a map from the string '" << inputString
1129 <<
"'... is it a valid map?" << __E__ << e.what() << __E__;
1136 const std::string& primaryDelimeter,
1137 const std::string& secondaryDelimeter)
1139 std::stringstream ss;
1141 for(
auto& mapPair : mapToReturn)
1146 ss << primaryDelimeter;
1147 ss << mapPair.first << secondaryDelimeter << (
unsigned int)mapPair.second;
1155 const std::string& delimeter)
1157 std::stringstream ss;
1159 for(
auto& setValue : setToReturn)
1165 ss << (
unsigned int)setValue;
1173 const std::string& delimeter)
1175 std::stringstream ss;
1177 if(delimeter ==
"\n")
1179 for(
auto& setValue : setToReturn)
1185 ss << (
unsigned int)setValue;
1201 std::vector<std::string>& commonChunksToReturn,
1202 std::vector<std::string>& wildcardStringsToReturn,
1203 unsigned int& fixedWildcardLength)
1205 fixedWildcardLength = 0;
1230 std::pair<
unsigned int ,
unsigned int > wildcardBounds(
1231 std::make_pair(-1, 0));
1234 for(
unsigned int n = 1; n < haystack.size(); ++n)
1235 for(
unsigned int i = 0, j = 0;
1236 i < haystack[0].length() && j < haystack[n].length();
1239 if(i < wildcardBounds.first)
1241 if(haystack[0][i] != haystack[n][j])
1243 wildcardBounds.first = i;
1250 __COUTS__(3) <<
"Low side = " << wildcardBounds.first <<
" "
1251 << haystack[0].substr(0, wildcardBounds.first) << __E__;
1254 for(
unsigned int n = 1; n < haystack.size(); ++n)
1255 for(
int i = haystack[0].length() - 1, j = haystack[n].length() - 1;
1256 i >= (int)wildcardBounds.first && j >= (
int)wildcardBounds.first;
1259 if(i > (
int)wildcardBounds.second)
1261 if(haystack[0][i] != haystack[n][j])
1263 wildcardBounds.second = i + 1;
1271 __COUTS__(3) <<
"High side = " << wildcardBounds.second <<
" "
1272 << haystack[0].substr(wildcardBounds.second) << __E__;
1275 commonChunksToReturn.push_back(haystack[0].substr(0, wildcardBounds.first));
1277 if(wildcardBounds.first != (
unsigned int)-1)
1280 for(
int i = (wildcardBounds.first + wildcardBounds.second) / 2 + 1;
1281 i < (
int)wildcardBounds.second;
1283 if(haystack[0][wildcardBounds.first] == haystack[0][i] &&
1284 haystack[0].substr(wildcardBounds.first, wildcardBounds.second - i) ==
1285 haystack[0].substr(i, wildcardBounds.second - i))
1287 std::string multiWildcardString =
1288 haystack[0].substr(i, wildcardBounds.second - i);
1289 __COUT__ <<
"Potential multi-wildcard found: " << multiWildcardString
1290 <<
" at position i=" << i << __E__;
1292 std::vector<
unsigned int > wildCardInstances;
1294 wildCardInstances.push_back(wildcardBounds.first);
1296 unsigned int offset =
1297 wildCardInstances[0] + multiWildcardString.size() + 1;
1298 std::string middleString = haystack[0].substr(offset, (i - 1) - offset);
1299 __COUTV__(middleString);
1303 while((k = middleString.find(multiWildcardString)) != std::string::npos)
1305 __COUT__ <<
"Multi-wildcard found at " << k << __E__;
1307 wildCardInstances.push_back(offset + k);
1310 middleString.substr(k + multiWildcardString.size() + 1);
1311 offset += k + multiWildcardString.size() + 1;
1312 __COUTV__(middleString);
1316 wildCardInstances.push_back(i);
1318 for(
unsigned int w = 0; w < wildCardInstances.size() - 1; ++w)
1320 __COUTV__(wildCardInstances[w]);
1321 __COUTV__(wildCardInstances[w + 1]);
1322 __COUTV__(wildCardInstances.size());
1323 commonChunksToReturn.push_back(haystack[0].substr(
1324 wildCardInstances[w] + multiWildcardString.size(),
1325 wildCardInstances[w + 1] -
1326 (wildCardInstances[w] + multiWildcardString.size())));
1332 for(
unsigned int c = 1; c < commonChunksToReturn.size(); ++c)
1334 __COUT__ <<
"Checking [" << c <<
"]: " << commonChunksToReturn[c] << __E__;
1335 for(
unsigned int n = 1; n < haystack.size(); ++n)
1337 __COUT__ <<
"Checking chunks work with haystack [" << n
1338 <<
"]: " << haystack[n] << __E__;
1339 __COUTV__(commonChunksToReturn[0].size());
1340 std::string wildCardValue = haystack[n].substr(
1341 commonChunksToReturn[0].size(),
1342 haystack[n].find(commonChunksToReturn[1],
1343 commonChunksToReturn[0].size() + 1) -
1344 commonChunksToReturn[0].size());
1345 __COUTTV__(wildCardValue);
1347 std::string builtString =
"";
1348 for(
unsigned int cc = 0; cc < commonChunksToReturn.size(); ++cc)
1349 builtString += commonChunksToReturn[cc] + wildCardValue;
1350 __COUTTV__(builtString);
1351 __COUTTV__(wildCardValue);
1353 if(haystack[n].find(builtString) != 0)
1355 __COUT__ <<
"Dropping common chunk " << commonChunksToReturn[c]
1356 <<
", built '" << builtString <<
"' not found in "
1357 << haystack[n] << __E__;
1358 commonChunksToReturn.erase(commonChunksToReturn.begin() + c);
1363 __COUTT__ <<
"Found built '" << builtString <<
"' in " << haystack[n]
1369 __COUTTV__(commonChunksToReturn[0].size());
1371 __COUTTV__(fixedWildcardLength);
1373 for(
unsigned int i = 0; i < commonChunksToReturn[0].size(); ++i)
1374 if(commonChunksToReturn[0][commonChunksToReturn[0].size() - 1 - i] ==
'0')
1376 ++fixedWildcardLength;
1377 __COUTT__ <<
"Trying for added fixed length +1 to " << fixedWildcardLength
1384 for(
unsigned int c = 0; c < commonChunksToReturn.size(); ++c)
1386 unsigned int cnt = 0;
1387 for(
unsigned int i = 0; i < commonChunksToReturn[c].size(); ++i)
1388 if(commonChunksToReturn[c][commonChunksToReturn[c].size() - 1 - i] ==
'0')
1393 if(fixedWildcardLength < cnt)
1394 fixedWildcardLength = cnt;
1395 else if(fixedWildcardLength > cnt)
1397 __SS__ <<
"Invalid fixed length found, please simplify indexing between "
1398 "these common chunks: "
1403 __COUTTV__(fixedWildcardLength);
1405 if(fixedWildcardLength)
1406 for(
unsigned int c = 0; c < commonChunksToReturn.size(); ++c)
1407 commonChunksToReturn[c] = commonChunksToReturn[c].substr(
1408 0, commonChunksToReturn[c].size() - fixedWildcardLength);
1411 commonChunksToReturn.push_back(haystack[0].substr(wildcardBounds.second));
1418 unsigned int ioff = fixedWildcardLength;
1419 bool wildcardsNeeded =
false;
1420 bool someLeadingZeros =
false;
1421 bool allWildcardsSameSize =
true;
1423 for(
unsigned int n = 0; n < haystack.size(); ++n)
1425 std::string wildcard =
"";
1427 i = ioff + commonChunksToReturn[0].size();
1429 if(commonChunksToReturn.size() == 1)
1430 wildcard = haystack[n].substr(i);
1432 for(
unsigned int c = 1; c < commonChunksToReturn.size(); ++c)
1434 if(c == commonChunksToReturn.size() - 1)
1435 k = haystack[n].rfind(commonChunksToReturn[c]);
1437 k = haystack[n].find(commonChunksToReturn[c], i + 1);
1444 __COUTVS__(3, k - i);
1446 wildcard = haystack[n].substr(i, k - i);
1447 if(fixedWildcardLength && n == 0)
1448 fixedWildcardLength += wildcard.size();
1450 __COUTS__(3) <<
"name[" << n <<
"] = " << wildcard <<
" fixed @ "
1451 << fixedWildcardLength << __E__;
1456 wildcard != haystack[n].substr(i, k - i))
1458 __SS__ <<
"Invalid wildcard! for name[" << n <<
"] = " << haystack[n]
1459 <<
" - the extraction algorithm is confused, please simplify "
1460 "your naming convention."
1470 wildcardsNeeded =
true;
1473 if(wildcard[0] ==
'0' && !fixedWildcardLength)
1475 someLeadingZeros =
true;
1476 if(wildcardStringsToReturn.size() &&
1477 wildcard.size() != wildcardStringsToReturn[0].size())
1478 allWildcardsSameSize =
false;
1481 wildcardStringsToReturn.push_back(wildcard);
1488 if(someLeadingZeros && allWildcardsSameSize)
1490 __COUTTV__(fixedWildcardLength);
1491 fixedWildcardLength = wildcardStringsToReturn[0].size();
1492 __COUT__ <<
"Enforce wildcard size of " << fixedWildcardLength << __E__;
1495 if(wildcardStringsToReturn.size() != haystack.size())
1497 __SS__ <<
"There was a problem during common chunk extraction!" << __E__;
1501 return wildcardsNeeded;
1510 const std::string& rhs)
const
1516 for(
unsigned int i = 0; i < lhs.size() && i < rhs.size(); ++i)
1519 if((lhs[i] >=
'A' && lhs[i] <=
'Z' && rhs[i] >=
'A' && rhs[i] <=
'Z') ||
1520 (lhs[i] >=
'a' && lhs[i] <=
'z' && rhs[i] >=
'a' && rhs[i] <=
'z'))
1522 if(lhs[i] == rhs[i])
1524 return (lhs[i] < rhs[i]);
1527 else if(lhs[i] >=
'A' && lhs[i] <=
'Z')
1529 if(lhs[i] + 32 == rhs[i])
1531 return (lhs[i] + 32 < rhs[i]);
1533 else if(rhs[i] >=
'A' && rhs[i] <=
'Z')
1535 if(lhs[i] == rhs[i] + 32)
1537 return (lhs[i] < rhs[i] + 32);
1541 if(lhs[i] == rhs[i])
1543 return (lhs[i] < rhs[i]);
1548 return lhs.size() < rhs.size();
1558 std::array<char, 128> buffer;
1560 std::shared_ptr<FILE> pipe(popen(cmd,
"r"), pclose);
1562 __THROW__(
"popen() failed!");
1563 while(!feof(pipe.get()))
1565 if(fgets(buffer.data(), 128, pipe.get()) !=
nullptr)
1566 result += buffer.data();
1577 #include <execinfo.h>
1581 __SS__ <<
"ots::stackTrace:\n";
1587 size = backtrace(array, 10);
1591 char** messages = backtrace_symbols(array, size);
1595 for(
unsigned int i = 1; i < size && messages != NULL; ++i)
1608 char *mangled_name = 0, *offset_begin = 0, *offset_end = 0;
1611 for(
char* p = messages[i]; *p; ++p)
1629 if(mangled_name && offset_begin && offset_end && mangled_name < offset_begin)
1631 *mangled_name++ =
'\0';
1632 *offset_begin++ =
'\0';
1633 *offset_end++ =
'\0';
1636 char* real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
1641 ss <<
"[" << i <<
"] " << messages[i] <<
" : " << real_name <<
"+"
1642 << offset_begin << offset_end << std::endl;
1647 ss <<
"[" << i <<
"] " << messages[i] <<
" : " << mangled_name <<
"+"
1648 << offset_begin << offset_end << std::endl;
1655 ss <<
"[" << i <<
"] " << messages[i] << std::endl;
1674 const std::string& location,
1675 const unsigned int& line)
1677 char* environmentVariablePtr = getenv(name);
1678 if(!environmentVariablePtr)
1680 __SS__ <<
"Environment variable '$" << name <<
"' not defined at " << location
1681 <<
":" << line << __E__;
1685 return environmentVariablePtr;
1692 const std::string& field,
1693 uint32_t occurrence,
1695 size_t* returnFindPos ,
1696 const std::string& valueField ,
1697 const std::string& quoteType )
1700 *returnFindPos = std::string::npos;
1702 __COUTVS__(41, xml);
1704 size_t lo, findpos = after, hi;
1705 for(uint32_t i = 0; i <= occurrence; ++i)
1707 bool anyFound =
false;
1709 xml.find(
"<" + field,
1710 findpos)) != std::string::npos &&
1711 findpos + 1 + field.size() < xml.size())
1713 __COUTS__(40) <<
"find: ---- '<" << field <<
" findpos=" << findpos
1714 <<
"findpos " << findpos <<
" " << xml[findpos] <<
" "
1715 << xml[findpos + 1 + field.size()] <<
" "
1716 << (int)xml[findpos + 1 + field.size()] << __E__;
1724 if((quoteType ==
">" && xml[findpos] ==
'>') || xml[findpos] ==
' ' ||
1725 xml[findpos] ==
'\n' || xml[findpos] ==
'\t')
1734 __COUTS__(40) <<
"Field '" << field <<
"' not found" << __E__;
1739 lo = xml.find(valueField + quoteType, findpos) + valueField.size() + quoteType.size();
1741 if(TTEST(40) && quoteType.size())
1743 __COUTS__(40) <<
"Neighbors of field '" << field <<
"' and value '" << valueField
1744 <<
"' w/quote = " << quoteType << __E__;
1745 for(
size_t i = lo - valueField.size(); i < lo + 10 && i < xml.size(); ++i)
1746 __COUTS__(40) <<
"xml[" << i <<
"] " << xml[i] <<
" vs " << quoteType <<
" ? "
1747 << (int)xml[i] <<
" vs " << (
int)quoteType[0] << __E__;
1751 quoteType ==
">" ?
"<" : quoteType,
1752 lo)) == std::string::npos)
1754 __COUTS__(40) <<
"Value closing not found" << __E__;
1759 *returnFindPos = findpos - (1 + field.size());
1761 __COUTS__(40) <<
"after: " << after <<
", findpos: " << findpos <<
", hi/lo: " << hi
1762 <<
"/" << lo <<
", size: " << xml.size() << __E__;
1763 __COUTVS__(40, xml.substr(lo, hi - lo));
1764 return xml.substr(lo, hi - lo);
1771 const std::string& field,
1772 uint32_t occurrence,
1774 size_t* returnFindPos ,
1775 const std::string& valueField ,
1776 const std::string& quoteType )
1779 *returnFindPos = std::string::npos;
1781 __COUTVS__(41, xml);
1783 size_t lo = 0, hi, findpos = before;
1784 for(uint32_t i = 0; i <= occurrence; ++i)
1786 bool anyFound =
false;
1788 xml.rfind(
"<" + field,
1789 findpos)) != std::string::npos &&
1790 findpos + 1 + field.size() < xml.size())
1792 __COUTS__(40) <<
"rfind: ---- '<" << field <<
" findpos=" << findpos <<
" "
1793 << xml[findpos] <<
" " << xml[findpos + 1 + field.size()] <<
" "
1794 << (int)xml[findpos + 1 + field.size()] << __E__;
1796 findpos += 1 + field.size();
1799 if((quoteType ==
">" && xml[findpos] ==
'>') || xml[findpos] ==
' ' ||
1800 xml[findpos] ==
'\n' || xml[findpos] ==
'\t')
1806 findpos -= 1 + field.size() + 1;
1810 __COUTS__(40) <<
"Field '" << field <<
"' not found" << __E__;
1815 lo = xml.find(valueField + quoteType, findpos) + valueField.size() + quoteType.size();
1817 if(TTEST(40) && quoteType.size())
1819 __COUTS__(40) <<
"Neighbors?" << __E__;
1820 for(
size_t i = findpos; i < lo + 10 && i < xml.size(); ++i)
1821 __COUTS__(40) <<
"xml[" << i <<
"] " << xml[i] <<
" vs " << quoteType <<
" ? "
1822 << (int)xml[i] <<
" vs " << (
int)quoteType[0] << __E__;
1826 quoteType ==
">" ?
"<" : quoteType,
1827 lo)) == std::string::npos)
1829 __COUTS__(40) <<
"Value closing not found" << __E__;
1835 findpos - (1 + field.size());
1837 __COUTS__(40) <<
"before: " << before <<
", findpos: " << findpos <<
", hi/lo: " << hi
1838 <<
"/" << lo <<
", size: " << xml.size() << __E__;
1839 __COUTVS__(40, xml.substr(lo, hi - lo));
1840 return xml.substr(lo, hi - lo);
1848 const std::set<char>& delimiter )
1852 for(
const auto& split : splitArr)
1853 __COUTS__(lvl) << split;
1868 std::unique_ptr<char, void (*)(
void*)> res{
1869 abi::__cxa_demangle(name, NULL, NULL, &status), std::free};
1871 return (status == 0) ? res.get() : name;
defines used also by OtsConfigurationWizardSupervisor
bool operator()(const std::string &lhs, const std::string &rhs) const
<get string in order ignoring letter case
static std::string getTimestampString(const std::string &linuxTimeInSeconds)
static const std::string & trim(std::string &s)
static std::string extractXmlField(const std::string &xml, const std::string &field, uint32_t occurrence, size_t after, size_t *returnFindPos=nullptr, const std::string &valueField="value=", const std::string "eType="'")
static void getVectorFromString(const std::string &inputString, std::vector< std::string > &listToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'}, std::vector< char > *listOfDelimiters=0, bool decodeURIComponents=false)
static std::string exec(const char *cmd)
static void getSetFromString(const std::string &inputString, std::set< std::string > &setToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'})
static std::string setToString(const std::set< T > &setToReturn, const std::string &delimeter=", ")
setToString ~
static T validateValueForDefaultStringDataType(const std::string &value, bool doConvertEnvironmentVariables=true)
static char * otsGetEnvironmentVarable(const char *name, const std::string &location, const unsigned int &line)
static std::string escapeString(std::string inString, bool allowWhiteSpace=false)
static void sanitizeForSQL(std::string &data)
StringMacros::sanitizeForSQL.
static void coutSplit(const std::string &str, uint8_t traceLevel=TLVL_DEBUG, const std::set< char > &delimiter={',', '\n', ';'})
static std::string vectorToString(const std::vector< T > &setToReturn, const std::string &delimeter=", ")
vectorToString ~
static std::string convertEnvironmentVariables(const std::string &data)
static std::string getNumberType(const std::string &stringToCheck)
Note: before call consider use of stringToCheck = StringMacros::convertEnvironmentVariables(stringToC...
static std::string escapeJSONStringEntities(const std::string &str)
static std::string demangleTypeName(const char *name)
static std::string rextractXmlField(const std::string &xml, const std::string &field, uint32_t occurrence, size_t before, size_t *returnFindPos=nullptr, const std::string &valueField="value=", const std::string "eType="'")
static bool extractCommonChunks(const std::vector< std::string > &haystack, std::vector< std::string > &commonChunksToReturn, std::vector< std::string > &wildcardStrings, unsigned int &fixedWildcardLength)
static bool inWildCardSet(const std::string &needle, const std::set< std::string > &haystack)
static bool isNumber(const std::string &stringToCheck)
Note: before call consider use of stringToCheck = StringMacros::convertEnvironmentVariables(stringToC...
static std::string mapToString(const std::map< std::string, T > &mapToReturn, const std::string &primaryDelimeter=", ", const std::string &secondaryDelimeter=": ")
static void getMapFromString(const std::string &inputString, std::map< S, T > &mapToReturn, const std::set< char > &pairPairDelimiter={',', '|', '&'}, const std::set< char > &nameValueDelimiter={'=', ':'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'})
getMapFromString ~
static std::string restoreJSONStringEntities(const std::string &str)
static std::string getTimeDurationString(const time_t durationInSeconds=time(0))
static bool wildCardMatch(const std::string &needle, const std::string &haystack, unsigned int *priorityIndex=0)
static std::string decodeURIComponent(const std::string &data)
static std::string stackTrace(void)
static bool getNumber(const std::string &s, T &retValue)