• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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