1 /**
2 * @file string_manip.cpp
3 * std::string helpers
4 *
5 * @remark Copyright 2002 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author Philippe Elie
9 * @author John Levon
10 */
11
12 #include <sstream>
13 #include <iomanip>
14
15 #include <cstdlib>
16 #include <cmath>
17
18 #include "string_manip.h"
19
20 using namespace std;
21
22
erase_to_last_of(string const & str,char ch)23 string erase_to_last_of(string const & str, char ch)
24 {
25 string result = str;
26 string::size_type pos = result.find_last_of(ch);
27 if (pos != string::npos)
28 result.erase(0, pos + 1);
29
30 return result;
31 }
32
33
split(string & s,char c)34 string split(string & s, char c)
35 {
36 string::size_type i = s.find_first_of(c);
37 if (i == string::npos)
38 return string();
39
40 string const tail = s.substr(i + 1);
41 s = s.substr(0, i);
42 return tail;
43 }
44
45
is_prefix(string const & s,string const & prefix)46 bool is_prefix(string const & s, string const & prefix)
47 {
48 // gcc 2.95 and below don't have this
49 // return s.compare(0, prefix.length(), prefix) == 0;
50 return s.find(prefix) == 0;
51 }
52
53
separate_token(string const & str,char sep)54 vector<string> separate_token(string const & str, char sep)
55 {
56 vector<string> result;
57 string next;
58
59 for (size_t pos = 0 ; pos != str.length() ; ++pos) {
60 char ch = str[pos];
61 if (ch == '\\') {
62 if (pos < str.length() - 1 && str[pos + 1] == sep) {
63 ++pos;
64 next += sep;
65 } else {
66 next += '\\';
67 }
68 } else if (ch == sep) {
69 result.push_back(next);
70 // some stl lacks string::clear()
71 next.erase(next.begin(), next.end());
72 } else {
73 next += ch;
74 }
75 }
76
77 if (!next.empty())
78 result.push_back(next);
79
80 return result;
81 }
82
83
ltrim(string const & str,string const & totrim)84 string ltrim(string const & str, string const & totrim)
85 {
86 string result(str);
87
88 return result.erase(0, result.find_first_not_of(totrim));
89 }
90
91
rtrim(string const & str,string const & totrim)92 string rtrim(string const & str, string const & totrim)
93 {
94 string result(str);
95
96 return result.erase(result.find_last_not_of(totrim) + 1);
97 }
98
99
trim(string const & str,string const & totrim)100 string trim(string const & str, string const & totrim)
101 {
102 return rtrim(ltrim(str, totrim), totrim);
103 }
104
105
106 string const
format_percent(double value,size_t int_width,size_t fract_width,bool showpos)107 format_percent(double value, size_t int_width, size_t fract_width, bool showpos)
108 {
109 ostringstream os;
110
111 if (value == 0.0)
112 return string(int_width + fract_width, ' ') + "0";
113
114 if (showpos)
115 os.setf(ios::showpos);
116
117 if (fabs(value) > .001) {
118 // os << fixed << value unsupported by gcc 2.95
119 os.setf(ios::fixed, ios::floatfield);
120 os << setw(int_width + fract_width + 1)
121 << setprecision(fract_width) << value;
122 } else {
123 // os << scientific << value unsupported by gcc 2.95
124 os.setf(ios::scientific, ios::floatfield);
125 os << setw(int_width + fract_width + 1)
126 // - 3 to count exponent part
127 << setprecision(fract_width - 3) << value;
128 }
129
130 string formatted = os.str();
131 if (is_prefix(formatted, "100."))
132 formatted.erase(formatted.size() - 1);
133 return formatted;
134 }
135
136
137 template <>
op_lexical_cast(string const & str)138 unsigned int op_lexical_cast<unsigned int, string>(string const & str)
139 {
140 char* endptr;
141
142 // 2.91.66 fix
143 unsigned long ret = 0;
144 ret = strtoul(str.c_str(), &endptr, 0);
145 if (*endptr)
146 throw invalid_argument("op_lexical_cast(\""+ str +"\")");
147 return ret;
148 }
149