00001 #include "string_util.h"
00002 #include <cctype>
00003 #include <locale>
00004 #include <pwd.h>
00005 #include <stdlib.h>
00006 #include <regex.h>
00007 #include <sstream>
00008 #include <algorithm>
00009 #include <memory>
00010 #ifdef __GNUC__
00011 # include <cxxabi.h>
00012 #endif
00013
00014 using namespace std;
00015
00016 namespace string_util {
00017
00018
00019 static const std::locale& curLocale=std::locale::classic();
00020
00021 char localeToUpper(char c) {
00022 return std::toupper(c,curLocale);
00023 }
00024
00025 char localeToLower(char c) {
00026 return std::tolower(c,curLocale);
00027 }
00028
00029 string makeUpper(const string& s) {
00030 string ans(s);
00031 std::transform(ans.begin(), ans.end(), ans.begin(), (int(*)(int)) std::toupper);
00032 return ans;
00033 }
00034
00035 string makeLower(const string& s) {
00036 string ans(s);
00037 std::transform(ans.begin(), ans.end(), ans.begin(), (int(*)(int)) std::tolower);
00038 return ans;
00039 }
00040
00041 string removePrefix(const string& str, const string& pre) {
00042 if(str.compare(0,pre.size(),pre)==0)
00043 return str.substr(pre.size());
00044 return string();
00045 }
00046
00047 string tildeExpansion(const string& str) {
00048 string ans;
00049 if(str[0]!='~') {
00050 return str;
00051 }
00052 #ifndef PLATFORM_APERIOS
00053 else if(str=="~" || str[1]=='/') {
00054 char* home=getenv("HOME");
00055 if(home==NULL)
00056 return str;
00057 if(str=="~")
00058 return home;
00059 return home+str.substr(1);
00060 } else {
00061 string::size_type p=str.find('/');
00062 struct passwd * pw;
00063 pw=getpwnam(str.substr(1,p-1).c_str());
00064 if(pw==NULL)
00065 return str;
00066 return pw->pw_dir+str.substr(p);
00067 }
00068 #else
00069 return str.substr(1);
00070 #endif
00071 }
00072
00073 string trim(const string& str) {
00074 if(str.size()==0)
00075 return str;
00076 unsigned int b=0;
00077 unsigned int e=str.size()-1;
00078 while(b<str.size() && isspace(str[b]))
00079 b++;
00080 while(b<e && isspace(str[e]))
00081 e--;
00082 return str.substr(b,e-b+1);
00083 }
00084
00085 bool beginsWith(const std::string& str, const std::string& prefix) {
00086 if(str.size()<prefix.size())
00087 return false;
00088 if(prefix.size()==0)
00089 return true;
00090 return str.compare(0,prefix.size(),prefix)==0;
00091 }
00092
00093 bool endsWith(const std::string& str, const std::string& suffix) {
00094 if(str.size()<suffix.size())
00095 return false;
00096 if(suffix.size()==0)
00097 return true;
00098 return str.compare(str.size()-suffix.size(),suffix.size(),suffix)==0;
00099 }
00100
00101 std::string makePath(const std::string& rel, const std::string& path) {
00102 if(path[0]=='/') {
00103 return path;
00104 } else {
00105 std::string::size_type d = rel.rfind('/');
00106 if(d==std::string::npos) {
00107 return path;
00108 } else {
00109 return rel.substr(0,d+1)+path;
00110 }
00111 }
00112 }
00113
00114 std::vector<std::string> tokenize(const std::string & str, const std::string & delims ) {
00115
00116 string::size_type lastPos = str.find_first_not_of(delims, 0);
00117
00118 string::size_type pos = str.find_first_of(delims, lastPos);
00119
00120 vector<string> tokens;
00121 while (string::npos != pos || string::npos != lastPos) {
00122
00123 tokens.push_back(str.substr(lastPos, pos - lastPos));
00124
00125 lastPos = str.find_first_not_of(delims, pos);
00126
00127 pos = str.find_first_of(delims, lastPos);
00128 }
00129 return tokens;
00130 }
00131
00132 bool parseArgs(const string& input, vector<string>& args, vector<unsigned int>& offsets) {
00133 string cur;
00134 bool isDoubleQuote=false;
00135 bool isSingleQuote=false;
00136 args.clear();
00137 offsets.clear();
00138 unsigned int begin=-1U;
00139 for(unsigned int i=0; i<input.size(); i++) {
00140 char c=input[i];
00141 if(begin==-1U && !isspace(c))
00142 begin=i;
00143 switch(c) {
00144 case ' ':
00145 case '\n':
00146 case '\r':
00147 case '\t':
00148 case '\v':
00149 case '\f':
00150 if(isSingleQuote || isDoubleQuote)
00151 cur+=c;
00152 else if(cur.size()!=0) {
00153 args.push_back(cur);
00154 offsets.push_back(begin);
00155 cur.clear();
00156 begin=-1U;
00157 }
00158 break;
00159 case '\\':
00160 if(i==input.size()-1) {
00161 return false;
00162 } else
00163 cur.push_back(input[++i]);
00164 break;
00165 case '"':
00166 if(isSingleQuote)
00167 cur.push_back(c);
00168 else
00169 isDoubleQuote=!isDoubleQuote;
00170 break;
00171 case '\'':
00172 if(isDoubleQuote)
00173 cur+=c;
00174 else
00175 isSingleQuote=!isSingleQuote;
00176 break;
00177 default:
00178 cur+=c;
00179 break;
00180 }
00181 }
00182 if(cur.size()>0) {
00183 args.push_back(cur);
00184 offsets.push_back(begin);
00185 }
00186 return !isDoubleQuote && !isSingleQuote;
00187 }
00188
00189 bool reMatch(const std::string& str, const std::string& regex) {
00190 return reMatch(str,regex,REG_EXTENDED);
00191 }
00192
00193 bool reMatch(const std::string& str, const std::string& regex, int flags) {
00194 regex_t re;
00195 if(int err=regcomp(&re,regex.c_str(),flags | REG_NOSUB)) {
00196 char msg[128];
00197 regerror(err,&re,msg,128);
00198 string errmsg;
00199 errmsg.append("Bad filter '").append(regex).append("': ").append(msg);
00200 regfree(&re);
00201 throw errmsg;
00202 }
00203 int match=regexec(&re,str.c_str(),0,NULL,0);
00204 regfree(&re);
00205 if(match==0) {
00206 return true;
00207 } else if(match==REG_NOMATCH) {
00208 return false;
00209 } else {
00210 char msg[128];
00211 regerror(match,&re,msg,128);
00212 string errmsg;
00213 errmsg.append("Regex error on reMatch('").append(str).append("', '").append(regex).append("'): ").append(msg);
00214 throw errmsg;
00215 }
00216 }
00217
00218 std::string intToStringIP(int ip) {
00219 std::stringstream ret;
00220 ret << (ip >> 24 & 0xff) << '.' << (ip >> 16 & 0xff) << '.'
00221 << (ip >> 8 & 0xff) << '.' << (ip >> 0 & 0xff);
00222 return ret.str();
00223 }
00224
00225 int stringToIntIP(std::string ip_str) {
00226 std::istringstream sstr;
00227 sstr.str(ip_str);
00228 int ip = 0, b;
00229 char c;
00230
00231 sstr >> b >> c;
00232 ip |= b << 24;
00233
00234 sstr >> b >> c;
00235 ip |= b << 16;
00236
00237 sstr >> b >> c;
00238 ip |= b << 8;
00239
00240 sstr >> b;
00241 ip |= b << 0;
00242
00243 return ip;
00244 }
00245
00246 size_t utf8len(const std::string& str) {
00247 size_t len=0, i=0;
00248 while(i<str.size()) {
00249 unsigned char c = str[i];
00250 if(c < 0x80)
00251 ++i;
00252 else if((c >> 5) == 0x6)
00253 i+=2;
00254 else if((c >> 4) == 0xe)
00255 i+=3;
00256 else if((c >> 3) == 0x1e)
00257 i+=4;
00258 else
00259 ++i;
00260 ++len;
00261 }
00262 return len;
00263 }
00264
00265 #ifndef __GNUC__
00266 std::string demangle(const std::string& symbol) { return symbol; }
00267 #else
00268 std::string demangle(const std::string& symbol) {
00269 std::string ret = symbol;
00270 try {
00271 int status = 0;
00272 std::auto_ptr<const char> d(abi::__cxa_demangle(symbol.c_str(), 0, 0, &status));
00273 if(d.get()!=NULL)
00274 ret = d.get();
00275 } catch(...) { }
00276 return ret;
00277 }
00278 #endif
00279
00280 std::string int2str(int const n) {
00281 ostringstream os;
00282 os << n;
00283 return os.str();
00284 }
00285
00286 }
00287
00288
00289
00290
00291