00001 #include "string_util.h"
00002 #include <cctype>
00003 #include <locale>
00004 #include <pwd.h>
00005 #include <stdlib.h>
00006 #include <regex.h>
00007
00008 using namespace std;
00009
00010 namespace string_util {
00011
00012
00013 static const std::locale& curLocale=std::locale::classic();
00014
00015 char localeToUpper(char c) {
00016 return std::toupper(c,curLocale);
00017 }
00018
00019 char localeToLower(char c) {
00020 return std::tolower(c,curLocale);
00021 }
00022
00023 string makeUpper(const string& s) {
00024 string ans(s);
00025 std::transform(ans.begin(), ans.end(), ans.begin(), (int(*)(int)) std::toupper);
00026 return ans;
00027 }
00028
00029 string makeLower(const string& s) {
00030 string ans(s);
00031 std::transform(ans.begin(), ans.end(), ans.begin(), (int(*)(int)) std::tolower);
00032 return ans;
00033 }
00034
00035 string removePrefix(const string& str, const string& pre) {
00036 if(str.compare(0,pre.size(),pre)==0)
00037 return str.substr(pre.size());
00038 return string();
00039 }
00040
00041 string tildeExpansion(const string& str) {
00042 string ans;
00043 if(str[0]!='~') {
00044 return str;
00045 }
00046 #ifndef PLATFORM_APERIOS
00047 else if(str=="~" || str[1]=='/') {
00048 char* home=getenv("HOME");
00049 if(home==NULL)
00050 return str;
00051 if(str=="~")
00052 return home;
00053 return home+str.substr(1);
00054 } else {
00055 string::size_type p=str.find('/');
00056 struct passwd * pw;
00057 pw=getpwnam(str.substr(1,p-1).c_str());
00058 if(pw==NULL)
00059 return str;
00060 return pw->pw_dir+str.substr(p);
00061 }
00062 #else
00063 return str.substr(1);
00064 #endif
00065 }
00066
00067 string trim(const string& str) {
00068 if(str.size()==0)
00069 return str;
00070 unsigned int b=0;
00071 unsigned int e=str.size()-1;
00072 while(b<str.size() && isspace(str[b]))
00073 b++;
00074 while(b<e && isspace(str[e]))
00075 e--;
00076 return str.substr(b,e-b+1);
00077 }
00078
00079 bool parseArgs(const string& input, vector<string>& args, vector<unsigned int>& offsets) {
00080 string cur;
00081 bool isDoubleQuote=false;
00082 bool isSingleQuote=false;
00083 args.clear();
00084 offsets.clear();
00085 unsigned int begin=-1U;
00086 for(unsigned int i=0; i<input.size(); i++) {
00087 char c=input[i];
00088 if(begin==-1U && !isspace(c))
00089 begin=i;
00090 switch(c) {
00091 case ' ':
00092 case '\n':
00093 case '\r':
00094 case '\t':
00095 case '\v':
00096 case '\f':
00097 if(isSingleQuote || isDoubleQuote)
00098 cur+=c;
00099 else if(cur.size()!=0) {
00100 args.push_back(cur);
00101 offsets.push_back(begin);
00102 cur.clear();
00103 begin=-1U;
00104 }
00105 break;
00106 case '\\':
00107 if(i==input.size()-1) {
00108 return false;
00109 } else
00110 cur.push_back(input[++i]);
00111 break;
00112 case '"':
00113 if(isSingleQuote)
00114 cur.push_back(c);
00115 else
00116 isDoubleQuote=!isDoubleQuote;
00117 break;
00118 case '\'':
00119 if(isDoubleQuote)
00120 cur+=c;
00121 else
00122 isSingleQuote=!isSingleQuote;
00123 break;
00124 default:
00125 cur+=c;
00126 break;
00127 }
00128 }
00129 if(cur.size()>0) {
00130 args.push_back(cur);
00131 offsets.push_back(begin);
00132 }
00133 return !isDoubleQuote && !isSingleQuote;
00134 }
00135
00136 bool reMatch(const std::string& str, const std::string& regex) {
00137 return reMatch(str,regex,REG_EXTENDED);
00138 }
00139
00140 bool reMatch(const std::string& str, const std::string& regex, int flags) {
00141 regex_t re;
00142 if(int err=regcomp(&re,regex.c_str(),flags | REG_NOSUB)) {
00143 char msg[128];
00144 regerror(err,&re,msg,128);
00145 string errmsg;
00146 errmsg.append("Bad filter '").append(regex).append("': ").append(msg);
00147 regfree(&re);
00148 throw errmsg;
00149 }
00150 int match=regexec(&re,str.c_str(),0,NULL,0);
00151 regfree(&re);
00152 if(match==0) {
00153 return true;
00154 } else if(match==REG_NOMATCH) {
00155 return false;
00156 } else {
00157 char msg[128];
00158 regerror(match,&re,msg,128);
00159 string errmsg;
00160 errmsg.append("Regex error on reMatch('").append(str).append("', '").append(regex).append("'): ").append(msg);
00161 throw errmsg;
00162 }
00163 }
00164
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176