00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020
00021 #include "util.h"
00022
00023 namespace Pentagram {
00024
00025 template<class T> T to_uppercase(const T s)
00026 {
00027 T str = s;
00028 typename T::iterator X;
00029 for(X = str.begin(); X != str.end(); ++X) {
00030 #if (defined(BEOS) || defined(OPENBSD) || defined(CYGWIN) || defined(__MORPHOS__))
00031 if ((*X >= 'a') && (*X <= 'z')) *X -= 32;
00032 #else
00033 *X = static_cast<char>(std::toupper(*X));
00034 #endif
00035 }
00036 return str;
00037 }
00038
00039 template std::string to_uppercase<std::string>(const std::string s);
00040 template Pentagram::istring to_uppercase<Pentagram::istring>(const Pentagram::istring s);
00041
00042 template<class T> void StringToArgv(const T &args, std::vector<T> &argv)
00043 {
00044
00045 argv.clear();
00046
00047 bool quoted = false;
00048 typename T::const_iterator it;
00049 int ch;
00050 T arg;
00051
00052 for(it = args.begin(); it != args.end(); ++it)
00053 {
00054 ch = *it;
00055
00056
00057 if (ch == '\"')
00058 {
00059 quoted = !quoted;
00060 continue;
00061 }
00062
00063
00064 if (ch == '\\')
00065 {
00066 typename T::const_iterator next = it+1;
00067 if (next != args.end())
00068 {
00069 if (*next == '\\' || *next == '\"' || *next == '\'')
00070 {
00071 ch = *next;
00072 ++it;
00073 }
00074 else if (*next == 'n')
00075 {
00076 ch = '\n';
00077 ++it;
00078 }
00079 else if (*next == 'r')
00080 {
00081 ch = '\r';
00082 ++it;
00083 }
00084 else if (*next == 't')
00085 {
00086 ch = '\t';
00087 ++it;
00088 }
00089 else if (*next == ' ')
00090 {
00091 ch = ' ';
00092 ++it;
00093 }
00094 }
00095 }
00096
00097
00098 if (!quoted && (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'))
00099 {
00100
00101
00102 if (!arg.empty())
00103 {
00104 argv.push_back(arg);
00105 arg.clear();
00106 }
00107
00108 continue;
00109 }
00110
00111
00112 arg += ch;
00113 }
00114
00115
00116 if (!arg.empty()) argv.push_back(arg);
00117 }
00118
00119 template void StringToArgv<std::string>(const std::string &args, std::vector<std::string> &argv);
00120 template void StringToArgv<Pentagram::istring>(const Pentagram::istring &args, std::vector<Pentagram::istring> &argv);
00121
00122 template<class T> void ArgvToString(const std::vector<T> &argv, T &args)
00123 {
00124
00125 args.clear();
00126
00127 typename std::vector<T>::const_iterator i;
00128 typename T::const_iterator j;
00129 int ch;
00130
00131 for(i = argv.begin(); i != argv.end(); ++i)
00132 {
00133 for(j = i->begin(); j != i->end(); ++j)
00134 {
00135 ch = *j;
00136
00137
00138
00139
00140 if (ch == '\\' || ch == '\"' || ch == '\'' || ch == ' ')
00141 {
00142 args += '\\';
00143 }
00144 else if (ch == '\n')
00145 {
00146 args += '\\';
00147 ch = 'n';
00148 }
00149 else if (ch == '\r')
00150 {
00151 args += '\\';
00152 ch = 'r';
00153 }
00154 else if (ch == '\t')
00155 {
00156 args += '\\';
00157 ch = 't';
00158 }
00159
00160 args += ch;
00161 }
00162 args += ' ';
00163 }
00164 }
00165
00166 template void ArgvToString<std::string>(const std::vector<std::string> &argv, std::string &args);
00167 template void ArgvToString<Pentagram::istring>(const std::vector<Pentagram::istring> &argv, Pentagram::istring &args);
00168
00169 template<class T> void TrimSpaces(T& str)
00170 {
00171 if (str.empty()) return;
00172
00173 typename T::size_type pos1 = str.find_first_not_of(' ');
00174 if (pos1 == T::npos) {
00175 str = "";
00176 return;
00177 }
00178
00179 typename T::size_type pos2 = str.find_last_not_of(' ');
00180 str = str.substr(pos1, pos2-pos1+1);
00181 }
00182
00183 template void TrimSpaces<std::string>(std::string& str);
00184 template void TrimSpaces<Pentagram::istring>(Pentagram::istring& str);
00185
00186
00187 template<class T> void TabsToSpaces(T& str, unsigned int n)
00188 {
00189 T repl(n, ' ');
00190 typename T::size_type p;
00191 while ((p = str.find('\t')) != T::npos)
00192 str.replace(p, 1, repl);
00193 }
00194
00195 template void TabsToSpaces<std::string>(std::string& str, unsigned int n);
00196 template void TabsToSpaces<Pentagram::istring>(Pentagram::istring& str,
00197 unsigned int n);
00198
00199
00200 template<class T> void SplitString(const T &args, char sep,
00201 std::vector<T> &argv)
00202 {
00203
00204 argv.clear();
00205
00206 if (args.empty()) return;
00207
00208 typename T::size_type pos, start;
00209 start = 0;
00210 while (start != T::npos) {
00211 pos = args.find(sep, start);
00212 if (pos == T::npos) {
00213 argv.push_back(args.substr(start));
00214 start = pos;
00215 } else {
00216 argv.push_back(args.substr(start, pos-start));
00217 start = pos+1;
00218 }
00219 }
00220 }
00221
00222
00223 template void SplitString<std::string>(const std::string& args, char sep, std::vector<std::string> &argv);
00224 template void SplitString<Pentagram::istring>(const Pentagram::istring& args, char sep, std::vector<Pentagram::istring> &argv);
00225
00226
00227
00228
00229 template<class T> void SplitStringKV(const T &args, char sep,
00230 std::vector<std::pair<T,T> > &argv)
00231 {
00232
00233 argv.clear();
00234
00235 if (args.empty()) return;
00236
00237 std::vector<T> keyvals;
00238 SplitString(args, sep, keyvals);
00239
00240 for (unsigned int i = 0; i < keyvals.size(); ++i)
00241 {
00242 std::pair<T,T> keyval;
00243 typename T::size_type pos;
00244 pos = keyvals[i].find('=');
00245 keyval.first = keyvals[i].substr(0, pos);
00246 TrimSpaces(keyval.first);
00247 if (pos == T::npos) {
00248 keyval.second = "";
00249 } else {
00250 keyval.second = keyvals[i].substr(pos+1);
00251 TrimSpaces(keyval.second);
00252 }
00253 if (!(keyval.first.empty() && keyval.second.empty()))
00254 argv.push_back(keyval);
00255 }
00256 }
00257
00258 template void SplitStringKV<std::string>(const std::string& args, char sep, std::vector<std::pair<std::string, std::string> > &argv);
00259 template void SplitStringKV<Pentagram::istring>(const Pentagram::istring& args, char sep, std::vector<std::pair<Pentagram::istring,Pentagram::istring> > &argv);
00260
00261
00262
00263 }