SST  15.1.0
StructuralSimulationToolkit
stringize.h
1 // Copyright 2009-2025 NTESS. Under the terms
2 // of Contract DE-NA0003525 with NTESS, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2025, NTESS
6 // All rights reserved.
7 //
8 // This file is part of the SST software package. For license
9 // information, see the LICENSE file in the top level directory of the
10 // distribution.
11 
12 #ifndef SST_CORE_STRINGIZE_H
13 #define SST_CORE_STRINGIZE_H
14 
15 #include <cctype>
16 #include <cinttypes>
17 #include <cstdarg>
18 #include <cstdio>
19 #include <string>
20 #include <strings.h>
21 #include <vector>
22 
23 namespace SST {
24 
25 inline bool
26 strcasecmp(const std::string& s1, const std::string& s2)
27 {
28  return !::strcasecmp(s1.c_str(), s2.c_str());
29 }
30 
31 inline void
32 to_lower(std::string& s)
33 {
34  for ( size_t i = 0; i < s.size(); i++ ) {
35  s[i] = std::tolower(s[i]);
36  }
37 }
38 
39 inline void
40 trim(std::string& s)
41 {
42  auto start = s.find_first_not_of(" \t\n\r\v\f");
43  if ( start != 0 ) {
44  s.replace(s.begin(), s.begin() + (start), "");
45  }
46  auto end = s.find_last_not_of(" \t\n\r\v\f");
47  if ( end != s.size() - 1 ) {
48  s.replace(s.begin() + end + 1, s.end(), "");
49  }
50 }
51 
52 inline void
53 tokenize(std::vector<std::string>& output, const std::string& input, const std::string& delim, bool trim_ws = false)
54 {
55  size_t start = 0;
56  size_t end = input.find(delim);
57 
58  std::string token;
59  while ( end != std::string::npos ) {
60  token = input.substr(start, end - start);
61  if ( trim_ws ) trim(token);
62  output.push_back(token);
63  start = end + delim.length();
64  end = input.find(delim, start);
65  }
66 
67  if ( input.empty() ) {
68  return;
69  }
70 
71  token = input.substr(start, end);
72  if ( trim_ws ) trim(token);
73  output.push_back(token);
74 }
75 
77 {
78  using iter = std::string::const_iterator;
79  const std::string delim;
80  explicit char_delimiter(const std::string& delim = " \t\v\f\n\r") :
81  delim(delim)
82  {}
83 
84  /**
85  * @return pair<iter, iter> = <tok_end, next_tok>
86  */
87  void operator()(iter& first, iter last, std::string& token)
88  {
89  token.clear();
90 
91  /* Skip any leading separators */
92  while ( first != last && delim.find(*first) != std::string::npos )
93  ++first;
94 
95  while ( first != last && delim.find(*first) == std::string::npos )
96  token += *first++;
97  }
98 };
99 
101 {
102  using iter = std::string::const_iterator;
103  std::string e, q, s;
104 
106  const std::string& esc = "\\", const std::string& sep = ",", const std::string& quote = "\"") :
107  e(esc),
108  q(quote),
109  s(sep)
110  {}
111 
112  /**
113  * Sets pair<iter, iter> = <tok_end, next_tok>
114  */
115  void operator()(iter& first, iter last, std::string& token)
116  {
117  token.clear();
118 
119  bool inside_quotes = false;
120  bool in_escape = false;
121  while ( first != last ) {
122  char c = *first++;
123 
124  if ( in_escape ) {
125  token += c;
126  in_escape = false;
127  }
128  else if ( s.find(c) != std::string::npos && !inside_quotes ) {
129  /* Separator found */
130  break;
131  }
132  else if ( q.find(c) != std::string::npos ) {
133  inside_quotes = !inside_quotes;
134  }
135  else if ( e.find(c) != std::string::npos ) {
136  in_escape = true;
137  }
138  else {
139  token += c;
140  }
141  }
142  }
143 };
144 
145 template <typename TokenizerFunc = char_delimiter>
147 {
148 
149  template <typename Func>
150  struct token_iter
151  {
152  Func& f;
153  std::string::const_iterator first;
154  std::string::const_iterator last;
155  std::string token;
156 
157  public:
158  explicit token_iter(Func& f_, std::string::const_iterator& first_, std::string::const_iterator& last_) :
159  f(f_),
160  first(first_),
161  last(last_)
162  {
163  f(first, last, token);
164  }
165  token_iter& operator++()
166  {
167  f(first, last, token);
168  return *this;
169  }
170  token_iter operator++(int)
171  {
172  token_iter retval = *this;
173  ++(*this);
174  return retval;
175  }
176  bool operator==(token_iter other) const
177  {
178  return (first == other.first) && (last == other.last) && (token == other.token);
179  }
180  bool operator!=(token_iter other) const { return !(*this == other); }
181  const std::string& operator*() const { return token; }
182  const std::string& operator->() const { return token; }
183 
184  using difference_type = std::ptrdiff_t;
185  using value_type = std::string;
186  using pointer = const std::string*;
187  using reference = const std::string&;
188  using iterator_category = std::input_iterator_tag;
189  };
190 
191  using iter = token_iter<TokenizerFunc>;
192 
193 public:
194  using iterator = iter;
195  using const_iterator = iter;
196  using value_type = std::string;
197 
198  iter begin() { return iter(f, first, last); }
199  iter end() { return iter(f, last, last); }
200 
201  Tokenizer(const std::string& s, const TokenizerFunc& f = TokenizerFunc()) :
202  first(s.begin()),
203  last(s.end()),
204  f(f)
205  {}
206 
207 private:
208  std::string::const_iterator first, last;
209  TokenizerFunc f;
210 };
211 
212 
213 /**
214  Creates a string using a vprintf like function call. This function
215  uses a dynamically allocated char array of size max_length to
216  create the buffer to intialize the string.
217 
218  @param max_length Maximum length of string. Anything past
219  max_length will be truncated (null terminator is included in the
220  length)
221 
222  @param format printf-like format string
223 
224  @param args va_list containing variable length argument list
225 
226  @return formatted string, potentially truncated at length max_length - 1
227  */
228 std::string vformat_string(size_t max_length, const char* format, va_list args) __attribute__((format(printf, 2, 0)));
229 
230 /**
231  Creates a string using a printf like function call. This function
232  uses a compile time allocated char array of length 256 to create
233  the buffer to intialize the string. If this is not long enough, it
234  will dynamically allocate an array that is just big enough to
235  create the buffer to initialize the string. No truncation will
236  occur.
237 
238  @param format printf-like format string
239 
240  @param args va_list containing variable length argument list
241 
242  @return formatted string
243  */
244 std::string vformat_string(const char* format, va_list args) __attribute__((format(printf, 1, 0)));
245 
246 /**
247  Creates a string using a printf like function call. This function
248  uses a dynamically allocated char array of size max_length to
249  create the buffer to intialize the string.
250 
251  @param max_length Maximum length of string. Anything past
252  max_length will be truncated (null terminator is included in the
253  length)
254 
255  @param format printf-like format string
256 
257  @param ... arguments for format string
258 
259  @return formatted string, potentially truncated at length max_length - 1
260  */
261 std::string format_string(size_t max_length, const char* format, ...) __attribute__((format(printf, 2, 3)));
262 
263 /**
264  Creates a string using a printf like function call. This function
265  uses a compile time allocated char array of length 256 to create
266  the buffer to intialize the string. If this is not long enough, it
267  will dynamically allocate an array that is just big enough to
268  create the buffer to initialize the string. No truncation will
269  occur.
270 
271  @param format printf-like format string
272 
273  @param ... arguments for format string
274 
275  @return formatted string
276  */
277 std::string format_string(const char* format, ...) __attribute__((format(printf, 1, 2)));
278 
279 } // namespace SST
280 
281 #endif // SST_CORE_STRINGIZE_H
Definition: stringize.h:100
Definition: action.cc:18
void operator()(iter &first, iter last, std::string &token)
Sets pair<iter, iter> = <tok_end, next_tok>
Definition: stringize.h:115
Definition: stringize.h:146
Definition: stringize.h:76
void operator()(iter &first, iter last, std::string &token)
Definition: stringize.h:87