GGS(GenericGEANT4Simulation)Software  2.7.0
 All Data Structures Namespaces Files Functions Variables Typedefs Macros
GGSStringUtils.cpp
1 /*
2  * StringUtils.cpp
3  *
4  * Created on: 10 Oct 2018
5  * Author: Nicola Mori
6  */
7 
8 #include "utils/GGSStringUtils.h"
9 
10 #include <algorithm>
11 #include <stdexcept>
12 
13 Tokens GGSStringUtils::Tokenize(const std::string &str, char delimiter) {
14  Tokens tokens;
15 
16  size_t iChar = 0;
17  char endliteralDelimiter = '\0';
18  // Discard trailing spaces and tabs
19  while (str[iChar] == ' ' || str[iChar] == '\t')
20  iChar++;
21 
22  // Tokenize the string
23  std::string token;
24  tokens.clear();
25  while (iChar < str.size()) {
26 
27  size_t iLast = 0;
28  bool quotedText = false;
29  if (str[iChar] == '\"') {
30  quotedText = true;
31  endliteralDelimiter = '\"';
32  iChar++;
33  iLast = str.find_first_of('\"', iChar);
34  } else if (str[iChar] == '{') {
35  quotedText = true;
36  endliteralDelimiter = '}';
37  iChar++;
38  iLast = str.find_first_of('}', iChar);
39  } else {
40  iLast = str.find_first_of(delimiter, iChar + 1);
41  }
42  if (iLast != std::string::npos) {
43  // Delimiter character found
44  token = str.substr(iChar, iLast - iChar);
45  if (str[iLast] == endliteralDelimiter) {
46  iLast++;
47  quotedText = false;
48  }
49  } else {
50  // Delimiter character not found.
51  if (quotedText) {
52  // Missing closing double quotation.
53  throw std::runtime_error(std::string("[GGSStringUtils::Tokenize] Missing closing ") + endliteralDelimiter);
54  } else {
55  // Take all the characters up to the end of the string
56  token = str.substr(iChar);
57  }
58  }
59  tokens.push_back(token);
60 
61  iChar = str.find_first_not_of(delimiter, iLast);
62  }
63 
64  return tokens;
65 }
66 
67 std::string GGSStringUtils::Trim(const std::string &str) {
68  std::string retStr = str;
69  retStr.erase(retStr.begin(), std::find_if(retStr.begin(), retStr.end(),
70  [](int ch) { return !(std::isblank(static_cast<unsigned int>(ch))); }));
71  retStr.erase(std::find_if(retStr.rbegin(), retStr.rend(),
72  [](int ch) { return !(std::isblank(static_cast<unsigned int>(ch))); })
73  .base(),
74  retStr.end());
75  return retStr;
76 }
77 
78 bool GGSStringUtils::IsInteger(const std::string &str) {
79  std::string trimmedStr = Trim(str);
80  if (trimmedStr.empty() || ((!isdigit(trimmedStr[0])) && (trimmedStr[0] != '-') && (trimmedStr[0] != '+')))
81  return false;
82  for (unsigned int iChar = 1; iChar < trimmedStr.size(); iChar++) {
83  if (!isdigit(trimmedStr[iChar])) {
84  return false;
85  }
86  }
87  return true;
88 }
89 
90 bool GGSStringUtils::IsReal(const std::string &str) {
91  std::string trimmedStr = Trim(str);
92  if (trimmedStr.empty() || ((!isdigit(trimmedStr[0])) && (trimmedStr[0] != '-') && (trimmedStr[0] != '+')))
93  return false;
94  bool hasPoint = false;
95  bool hase = false;
96  for (unsigned int iChar = 1; iChar < trimmedStr.size(); iChar++) {
97  if (!isdigit(trimmedStr[iChar])) {
98  if (trimmedStr[iChar] == '.') {
99  if (hasPoint) {
100  return false;
101  }
102  hasPoint = true;
103  } else if (trimmedStr[iChar] == 'e') {
104  if (hase) {
105  return false;
106  }
107  hase = true;
108  // After 'e' there must be a digit or a sign
109  ++iChar;
110  if (iChar >= trimmedStr.size() ||
111  (!isdigit(trimmedStr[iChar]) && (trimmedStr[iChar] != '-') && (trimmedStr[iChar] != '+'))) {
112  return false;
113  }
114  } else {
115  return false;
116  }
117  }
118  }
119  return true;
120 }
121 
122 bool GGSStringUtils::IsGlobExpression(const std::string &str) {
123  if (str.find('*') != std::string::npos || str.find('?') != std::string::npos) {
124  return true;
125  } else {
126  return false;
127  }
128 }
129 
130 std::string GGSStringUtils::RegexFromGlob(const std::string &str) {
131  static std::string regexStr;
132  regexStr = str;
133  std::string::size_type n = 0;
134  while ((n = regexStr.find(".", n)) != std::string::npos) {
135  regexStr.replace(n, 1, "\\.");
136  n += 2;
137  }
138  n = 0;
139  while ((n = regexStr.find("*", n)) != std::string::npos) {
140  regexStr.replace(n, 1, ".*");
141  n += 2;
142  }
143  std::replace(regexStr.begin(), regexStr.end(), '?', '.');
144  return regexStr;
145 }
std::string RegexFromGlob(const std::string &str)
Build a regex starting from a glob expression.
Tokens Tokenize(const std::string &str, char delimiter= ' ')
Extracts words from a string.
bool IsGlobExpression(const std::string &str)
Check if the given string is a glob expression.
bool IsInteger(const std::string &str)
Checks if a string is an a integer.
bool IsReal(const std::string &str)
Checks if a string is a real number.
std::string Trim(const std::string &str)
Trims a string.