SST  13.1.0
Structural Simulation Toolkit
stringize.h
1 // Copyright 2009-2023 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-2023, 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 ) { s.replace(s.begin(), s.begin() + (start), ""); }
44  auto end = s.find_last_not_of(" \t\n\r\v\f");
45  if ( end != s.size() - 1 ) { s.replace(s.begin() + end + 1, s.end(), ""); }
46 }
47 
48 inline void
49 tokenize(std::vector<std::string>& output, const std::string& input, const std::string& delim, bool trim_ws = false)
50 {
51  size_t start = 0;
52  size_t end = input.find(delim);
53 
54  std::string token;
55  while ( end != std::string::npos ) {
56  token = input.substr(start, end - start);
57  if ( trim_ws ) trim(token);
58  output.push_back(token);
59  start = end + delim.length();
60  end = input.find(delim, start);
61  }
62 
63  token = input.substr(start, end);
64  if ( trim_ws ) trim(token);
65  output.push_back(token);
66 }
67 
69 {
70  typedef std::string::const_iterator iter;
71  const std::string delim;
72  char_delimiter(const std::string& delim = " \t\v\f\n\r") : delim(delim) {}
73 
74  /**
75  * @return pair<iter, iter> = <tok_end, next_tok>
76  */
77  void operator()(iter& first, iter last, std::string& token)
78  {
79  token.clear();
80 
81  /* Skip any leading separators */
82  while ( first != last && delim.find(*first) != std::string::npos )
83  ++first;
84 
85  while ( first != last && delim.find(*first) == std::string::npos )
86  token += *first++;
87  }
88 };
89 
91 {
92  typedef std::string::const_iterator iter;
93  std::string e;
94  std::string q;
95  std::string s;
96 
98  const std::string& esc = "\\", const std::string& sep = ",", const std::string& quote = "\"") :
99  e(esc),
100  q(quote),
101  s(sep)
102  {}
103 
104  /**
105  * @return pair<iter, iter> = <tok_end, next_tok>
106  */
107  void operator()(iter& first, iter last, std::string& token)
108  {
109  token.clear();
110 
111  bool inside_quotes = false;
112  bool in_escape = false;
113  while ( first != last ) {
114  char c = *first++;
115 
116  if ( in_escape ) {
117  token += c;
118  in_escape = false;
119  }
120  else if ( s.find(c) != std::string::npos && !inside_quotes ) {
121  /* Separator found */
122  break;
123  }
124  else if ( q.find(c) != std::string::npos ) {
125  inside_quotes = !inside_quotes;
126  }
127  else if ( e.find(c) != std::string::npos ) {
128  in_escape = true;
129  }
130  else {
131  token += c;
132  }
133  }
134  }
135 };
136 
137 template <typename TokenizerFunc = char_delimiter>
139 {
140 
141  template <typename Func>
142  struct token_iter
143  {
144  Func& f;
145  std::string::const_iterator first;
146  std::string::const_iterator last;
147  std::string token;
148 
149  public:
150  explicit token_iter(Func& f_, std::string::const_iterator& first_, std::string::const_iterator& last_) :
151  f(f_),
152  first(first_),
153  last(last_)
154  {
155  f(first, last, token);
156  }
157  token_iter& operator++()
158  {
159  f(first, last, token);
160  return *this;
161  }
162  token_iter operator++(int)
163  {
164  token_iter retval = *this;
165  ++(*this);
166  return retval;
167  }
168  bool operator==(token_iter other) const
169  {
170  return (first == other.first) && (last == other.last) && (token == other.token);
171  }
172  bool operator!=(token_iter other) const { return !(*this == other); }
173  const std::string& operator*() const { return token; }
174  const std::string& operator->() const { return token; }
175 
176  using difference_type = std::ptrdiff_t;
177  using value_type = std::string;
178  using pointer = const std::string*;
179  using reference = const std::string&;
180  using iterator_category = std::input_iterator_tag;
181  };
182 
183  typedef token_iter<TokenizerFunc> iter;
184 
185 public:
186  typedef iter iterator;
187  typedef iter const_iterator;
188  typedef std::string value_type;
189 
190  iter begin() { return iter(f, first, last); }
191  iter end() { return iter(f, last, last); }
192 
193  Tokenizer(const std::string& s, const TokenizerFunc& f = TokenizerFunc()) : first(s.begin()), last(s.end()), f(f) {}
194 
195 private:
196  std::string::const_iterator first, last;
197  TokenizerFunc f;
198 };
199 
200 
201 /**
202  Creates a string using a vprintf like function call. This function
203  uses a dynamically allocated char array of size max_length to
204  create the buffer to intialize the string.
205 
206  @param max_length Maximum length of string. Anything past
207  max_length will be truncated (null terminator is included in the
208  length)
209 
210  @param format printf-like format string
211 
212  @param args va_list containing variable length argument list
213 
214  @return formatted string, potentially truncated at length max_length - 1
215  */
216 std::string vformat_string(size_t max_length, const char* format, va_list args);
217 
218 /**
219  Creates a string using a printf like function call. This function
220  uses a compile time allocated char array of length 256 to create
221  the buffer to intialize the string. If this is not long enough, it
222  will dynamically allocate an array that is just big enough to
223  create the buffer to initialize the string. No truncation will
224  occur.
225 
226  @param format printf-like format string
227 
228  @param args va_list containing variable length argument list
229 
230  @return formatted string
231  */
232 std::string vformat_string(const char* format, va_list args);
233 
234 /**
235  Creates a string using a printf like function call. This function
236  uses a dynamically allocated char array of size max_length to
237  create the buffer to intialize the string.
238 
239  @param max_length Maximum length of string. Anything past
240  max_length will be truncated (null terminator is included in the
241  length)
242 
243  @param format printf-like format string
244 
245  @param ... arguments for format string
246 
247  @return formatted string, potentially truncated at length max_length - 1
248  */
249 std::string format_string(size_t max_length, const char* format, ...) __attribute__((format(printf, 2, 3)));
250 
251 /**
252  Creates a string using a printf like function call. This function
253  uses a compile time allocated char array of length 256 to create
254  the buffer to intialize the string. If this is not long enough, it
255  will dynamically allocate an array that is just big enough to
256  create the buffer to initialize the string. No truncation will
257  occur.
258 
259  @param format printf-like format string
260 
261  @param ... arguments for format string
262 
263  @return formatted string
264  */
265 std::string format_string(const char* format, ...) __attribute__((format(printf, 1, 2)));
266 
267 } // namespace SST
268 
269 #endif // SST_CORE_STRINGIZE_H
Definition: stringize.h:139
Definition: stringize.h:69
void operator()(iter &first, iter last, std::string &token)
Definition: stringize.h:77
Definition: stringize.h:91
void operator()(iter &first, iter last, std::string &token)
Definition: stringize.h:107