|
Sierra Toolkit
Version of the Day
|
00001 00010 #include <iostream> 00011 #include <iomanip> 00012 #include <sstream> 00013 #include <stdexcept> 00014 #include <string> 00015 #include <cstring> 00016 #include <vector> 00017 #include <typeinfo> 00018 00019 #include <float.h> 00020 #include <time.h> 00021 00022 #include <stk_util/diag/StringUtil.hpp> 00023 00024 // Set for unit testing 00025 00026 #define SIERRA_STRING_UNIT_TEST 0 00027 00028 //---------------------------------------------------------------------- 00029 00030 namespace sierra { 00031 00032 std::istream & 00033 getline( 00034 std::istream & is, 00035 sierra::String & s, 00036 char eol) 00037 { 00038 std::string std_string; 00039 00040 getline(is, std_string, eol); 00041 s = std_string.c_str(); 00042 return is; 00043 } 00044 00045 00046 int 00047 case_strcmp( 00048 const char * c1, 00049 const char * c2) 00050 { 00051 for ( ; ; c1++, c2++) { 00052 if ( std::tolower(*c1) != std::tolower(*c2) ) 00053 return ( std::tolower(*c1) - std::tolower(*c2) ) ; 00054 if (*c1 == '\0') 00055 return 0 ; 00056 } 00057 } 00058 00059 00060 int 00061 case_strncmp( 00062 const char * c1, 00063 const char * c2, 00064 size_t n) 00065 { 00066 00067 if (n == 0) 00068 return 0; 00069 00070 do { 00071 if (*c1 != *c2++) 00072 return std::tolower(*c1) - std::tolower(*(c2 - 1)); 00073 if (*c1++ == 0) 00074 break; 00075 } while (--n != 0); 00076 return 0; 00077 } 00078 00079 00080 const char * 00081 case_strstr( 00082 const char * s, 00083 const char * find) 00084 { 00085 if (!*find) 00086 return s; 00087 00088 const char *cp = s; 00089 while (*cp) { 00090 const char *t1 = cp; 00091 const char *t2 = find; 00092 00093 for ( ; std::tolower(*t1) && std::tolower(*t2) && !(std::tolower(*t1) - std::tolower(*t2)); ++t1, ++t2) 00094 ; 00095 00096 if (!*t2) 00097 return cp; 00098 00099 cp++; 00100 } 00101 00102 return NULL; 00103 } 00104 00105 00106 std::string 00107 title( 00108 const std::string & s) 00109 { 00110 std::string t(s); 00111 00112 bool all_upper = true; 00113 bool all_lower = true; 00114 00115 bool next_upper = true; 00116 for (std::string::iterator c = t.begin(); c != t.end(); ++c) { 00117 all_upper &= (*c == std::toupper(*c)); 00118 all_lower &= (*c == std::tolower(*c)); 00119 if (next_upper) 00120 *c = std::toupper(*c); 00121 else 00122 *c = std::tolower(*c); 00123 next_upper = !isalpha(*c); 00124 } 00125 00126 if (all_upper || all_lower) 00127 return t; 00128 else 00129 return s; 00130 } 00131 00132 00133 template <typename T> 00134 std::string 00135 to_string( 00136 const T & t) 00137 { 00138 std::ostringstream os; 00139 os << t; 00140 return os.str(); 00141 } 00142 00143 template std::string to_string<double>(const double &); 00144 template std::string to_string<float>(const float &); 00145 template std::string to_string<int>(const int &); 00146 template std::string to_string<unsigned>(const unsigned &); 00147 template std::string to_string<long>(const long &); 00148 template std::string to_string<unsigned long>(const unsigned long &); 00149 00150 std::string 00151 to_string( 00152 const double & r, 00153 int precision) 00154 { 00155 std::ostringstream os; 00156 os << std::setprecision(precision) << r; 00157 return std::string(os.str()); 00158 } 00159 00160 00161 std::string 00162 to_string( 00163 const float & r, 00164 int precision) 00165 { 00166 std::ostringstream os; 00167 os << std::setprecision(precision) << r; 00168 return std::string(os.str()); 00169 } 00170 00171 00172 std::string 00173 format_time( 00174 double t, 00175 const char * format) 00176 { 00177 time_t time = (time_t) t; 00178 char s[128]; 00179 00180 ::strftime(s, sizeof(s), format, ::localtime(&time)); 00181 00182 return std::string(s); 00183 } 00184 00185 00186 std::ostream & 00187 object_phrase::print( 00188 std::ostream & os) const 00189 { 00190 if (m_n == 0) 00191 os << m_plural << " no " << m_noun << "s"; 00192 else if (m_n == 1) 00193 os << m_singular << " 1 " << m_noun; 00194 else 00195 os << m_plural << " " << m_n << " " << m_noun << "s"; 00196 00197 return os; 00198 } 00199 00200 00201 object_phrase::operator std::string() const 00202 { 00203 std::ostringstream strout; 00204 strout << *this; 00205 00206 return strout.str(); 00207 } 00208 00209 00210 namespace { 00211 00212 std::string::const_iterator 00213 find_next_char( 00214 std::string::const_iterator p, 00215 std::string::const_iterator end, 00216 char c) 00217 { 00218 while (p != end && *p != c) 00219 p++; 00220 return p; 00221 } 00222 00223 std::string::const_iterator 00224 find_next_not_char( 00225 std::string::const_iterator p, 00226 std::string::const_iterator end, 00227 char c) 00228 { 00229 while (p != end && *p == c) 00230 p++; 00231 return p; 00232 } 00233 00234 inline std::string::const_iterator find_next_space(std::string::const_iterator p, std::string::const_iterator end) { 00235 return find_next_char(p, end, ' '); 00236 } 00237 00238 inline std::string::const_iterator find_next_endl(std::string::const_iterator p, std::string::const_iterator end) { 00239 return find_next_char(p, end, '\n'); 00240 } 00241 00242 inline std::string::const_iterator find_next_nonspace(std::string::const_iterator p, std::string::const_iterator end) { 00243 return find_next_not_char(p, end, ' '); 00244 } 00245 00246 } // namespace <null> 00247 00248 std::string 00249 word_wrap( 00250 const std::string & s, 00251 unsigned int line_length, 00252 const std::string & prefix, 00253 const std::string & prefix_first_line) 00254 { 00255 std::string t; 00256 const std::string *u = &prefix_first_line; 00257 00258 std::string::const_iterator p0, p1, p2, p3; 00259 p0 = p1 = p2 = s.begin(); 00260 00261 while (p2 != s.end() ) { 00262 00263 // skip preceeding whitespace 00264 p1 = find_next_nonspace(p0, s.end()); 00265 p3 = find_next_endl(p0, s.end()); 00266 p2 = p1 = find_next_space(p1, s.end()); 00267 do { 00268 p1 = find_next_nonspace(p1, s.end()); 00269 p1 = find_next_space(p1, s.end()); 00270 if (p3 < p1) { 00271 p2 = p3; 00272 break; 00273 } 00274 if ((unsigned int) (p1 - p0) > (line_length - u->size())) 00275 break; 00276 p2 = p1; 00277 } while (p2 != s.end()); 00278 00279 t.append(*u).append(p0, p2).append("\n"); 00280 00281 if (p2 == p3) 00282 u = &prefix_first_line; 00283 else 00284 u = &prefix; 00285 00286 p0 = p2 + 1; 00287 } 00288 00289 return t; 00290 } 00291 00292 00293 template <class T> 00294 T convert_cast(const String &s) 00295 { 00296 /* %TRACE% */ /* %TRACE% */ 00297 std::istringstream is(s.c_str()); 00298 T t = 0; 00299 00300 is >> t; 00301 00302 if (!is) { 00303 std::ostringstream msg; 00304 msg << "Unable to convert \"" << s << "\" to type " << typeid(T).name(); 00305 throw std::runtime_error(msg.str().c_str()); 00306 } 00307 00308 00309 return t; 00310 } 00311 00312 template double convert_cast<double>(const String &); 00313 template float convert_cast<float>(const String &); 00314 template int convert_cast<int>(const String &); 00315 template unsigned convert_cast<unsigned>(const String &); 00316 template long convert_cast<long>(const String &); 00317 template unsigned long convert_cast<unsigned long>(const String &); 00318 00319 00320 // void 00321 // get_function_spec_parts( 00322 // const std::string & spec, 00323 // std::string & namespace_name, 00324 // std::string & class_name, 00325 // std::string & function_name, 00326 // std::vector<std::string> & arglist) 00327 // { 00328 // namespace_name.erase(namespace_name.begin(), namespace_name.end()); 00329 // class_name.erase(class_name.begin(), class_name.end()); 00330 // function_name.erase(function_name.begin(), function_name.end()); 00331 // arglist.erase(arglist.begin(), arglist.end()); 00332 00333 // std::string::const_iterator it_paren = find_next_open_paren(spec.begin(), spec.end()); 00334 // std::string::const_iterator it_func_name = find_prev_double_colon(spec.begin(), it_paren); 00335 // function_name = std::string(it_func_name, it_paren); 00336 // if (it_func_name != spec.begin()) { 00337 // it_func_name -= 2; 00338 // std::string::const_iterator it_class_name = find_prev_double_colon(spec.begin(), it_func_name); 00339 // class_name = std::string(it_class_name, it_func_name); 00340 // if (it_class_name != spec.begin()) { 00341 // it_class_name -= 2; 00342 // namespace_name = std::string(spec.begin(), it_class_name); 00343 // } 00344 // } 00345 // } 00346 00347 } // namespace sierra