string_manip.cpp revision 8cfa702f803c5ef6a2b062a489a1b2cf66b45b5e
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
20using namespace std;
21
22
23string 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
34string 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
46bool 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
54vector<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
84string 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
92string 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
100string trim(string const & str, string const & totrim)
101{
102	return rtrim(ltrim(str, totrim), totrim);
103}
104
105
106string const
107format_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
137template <>
138unsigned 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