SST 16.0.0
Structural Simulation Toolkit
stringize.h
1// Copyright 2009-2026 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-2026, 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
23namespace SST {
24
25inline bool
26strcasecmp(const std::string& s1, const std::string& s2)
27{
28 return !::strcasecmp(s1.c_str(), s2.c_str());
29}
30
31inline void
32to_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
39inline void
40trim(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
52inline void
53tokenize(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
76struct char_delimiter
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
100struct escaped_list_separator
101{
102 using iter = std::string::const_iterator;
103 std::string e, q, s;
104
105 escaped_list_separator(
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
145template <typename TokenizerFunc = char_delimiter>
146class Tokenizer
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
193public:
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
207private:
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 */
228std::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 */
244std::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 */
261std::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 */
277std::string format_string(const char* format, ...) __attribute__((format(printf, 1, 2)));
278
279} // namespace SST
280
281#endif // SST_CORE_STRINGIZE_H
void operator()(iter &first, iter last, std::string &token)
Definition stringize.h:87
void operator()(iter &first, iter last, std::string &token)
Sets pair<iter, iter> = <tok_end, next_tok>.
Definition stringize.h:115