cprover
string_utils.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Poetzl
6 
7 \*******************************************************************/
8 
9 #include "string_utils.h"
10 #include "exception_utils.h"
11 #include "invariant.h"
12 
13 #include <algorithm>
14 #include <cassert>
15 #include <cctype>
16 #include <iomanip>
17 
22 std::string strip_string(const std::string &s)
23 {
24  auto pred=[](char c){ return std::isspace(c); };
25 
26  std::string::const_iterator left
27  =std::find_if_not(s.begin(), s.end(), pred);
28  if(left==s.end())
29  return "";
30 
31  std::string::size_type i=std::distance(s.begin(), left);
32 
33  std::string::const_reverse_iterator right
34  =std::find_if_not(s.rbegin(), s.rend(), pred);
35  std::string::size_type j=std::distance(right, s.rend())-1;
36 
37  return s.substr(i, (j-i+1));
38 }
39 
41  const std::string &s,
42  char delim,
43  std::vector<std::string> &result,
44  bool strip,
45  bool remove_empty)
46 {
47  PRECONDITION(result.empty());
48  // delim can't be a space character if using strip
49  PRECONDITION(!std::isspace(delim) || !strip);
50 
51  if(s.empty())
52  {
53  if(!remove_empty)
54  result.push_back("");
55  return;
56  }
57 
58  std::string::size_type n=s.length();
59  INVARIANT(n > 0, "Empty string case should already be handled");
60 
61  std::string::size_type start=0;
63 
64  for(i=0; i<n; i++)
65  {
66  if(s[i]==delim)
67  {
68  std::string new_s=s.substr(start, i-start);
69 
70  if(strip)
71  new_s=strip_string(new_s);
72 
73  if(!remove_empty || !new_s.empty())
74  result.push_back(new_s);
75 
76  start=i+1;
77  }
78  }
79 
80  std::string new_s=s.substr(start, n-start);
81 
82  if(strip)
83  new_s=strip_string(new_s);
84 
85  if(!remove_empty || !new_s.empty())
86  result.push_back(new_s);
87 
88  if(!remove_empty && result.empty())
89  result.push_back("");
90 }
91 
93  const std::string &s,
94  char delim,
95  std::string &left,
96  std::string &right,
97  bool strip)
98 {
99  // delim can't be a space character if using strip
100  PRECONDITION(!std::isspace(delim) || !strip);
101 
102  std::vector<std::string> result;
103 
104  split_string(s, delim, result, strip);
105  if(result.size() != 2)
106  {
107  throw deserialization_exceptiont{"expected string '" + s +
108  "' to contain two substrings "
109  "delimited by " +
110  delim + " but has " +
111  std::to_string(result.size())};
112  }
113 
114  left=result[0];
115  right=result[1];
116 }
117 
118 std::vector<std::string> split_string(
119  const std::string &s,
120  char delim,
121  bool strip,
122  bool remove_empty)
123 {
124  std::vector<std::string> result;
125  split_string(s, delim, result, strip, remove_empty);
126  return result;
127 }
128 
130  const std::string &s,
131  const char delim)
132 {
133  std::string result;
134  const size_t index=s.find_last_of(delim);
135  if(index!=std::string::npos)
136  result=s.substr(0, index);
137  return result;
138 }
139 
140 std::string escape(const std::string &s)
141 {
142  std::string result;
143 
144  for(std::size_t i=0; i<s.size(); i++)
145  {
146  if(s[i]=='\\' || s[i]=='"')
147  result+='\\';
148 
149  result+=s[i];
150  }
151 
152  return result;
153 }
154 
155 std::string escape_non_alnum(const std::string &to_escape)
156 {
157  std::ostringstream escaped;
158  for(auto &ch : to_escape)
159  {
160  if(ch == '_')
161  escaped << "__";
162  else if(isalnum(ch))
163  escaped << ch;
164  else
165  escaped << '_' << std::hex << std::setfill('0') << std::setw(2)
166  << (unsigned int)ch;
167  }
168  return escaped.str();
169 }
exception_utils.h
escape_non_alnum
std::string escape_non_alnum(const std::string &to_escape)
Replace non-alphanumeric characters with _xx escapes, where xx are hex digits.
Definition: string_utils.cpp:155
string_utils.h
deserialization_exceptiont
Thrown when failing to deserialize a value from some low level format, like JSON or raw bytes.
Definition: exception_utils.h:73
to_string
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Definition: string_constraint.cpp:55
trim_from_last_delimiter
std::string trim_from_last_delimiter(const std::string &s, const char delim)
Definition: string_utils.cpp:129
split_string
void split_string(const std::string &s, char delim, std::vector< std::string > &result, bool strip, bool remove_empty)
Given a string s, split into a sequence of substrings when separated by specified delimiter.
Definition: string_utils.cpp:40
strip_string
std::string strip_string(const std::string &s)
Remove all whitespace characters from either end of a string.
Definition: string_utils.cpp:22
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:464
invariant.h
INVARIANT
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition: invariant.h:424
size_type
unsignedbv_typet size_type()
Definition: c_types.cpp:58
escape
std::string escape(const std::string &s)
Generic escaping of strings; this is not meant to be a particular programming language.
Definition: string_utils.cpp:140