Fri, 10 Jan 2014 21:58:42 +0200
- major refactoring begins
#include <cstring> #include "main.h" #include "str.h" // ============================================================================= // int string::compare (const string& other) const { return m_string.compare (other.std_string()); } // ============================================================================= // void string::trim (string::length_type n) { if (n > 0) m_string = substring (0, length() - n).std_string(); else m_string = substring (n, -1).std_string(); } // ============================================================================= // string string::strip (list<char> unwanted) { string copy (m_string); for (char c : unwanted) for (int i = 0; i < copy.length(); ++i) if (copy[i] == c) copy.erase (i); /* while(( pos = copy.first( c )) != -1 ) copy.erase( pos ); */ return copy; } // ============================================================================= // string string::to_uppercase() const { string newstr = m_string; for (char& c : newstr) if (c >= 'a' && c <= 'z') c -= 'a' - 'A'; return newstr; } // ============================================================================= // string string::to_lowercase() const { string newstr = m_string; for (char & c : newstr) if (c >= 'A' && c <= 'Z') c += 'a' - 'A'; return newstr; } // ============================================================================= // string_list string::split (char del) const { string delimstr; delimstr += del; return split (delimstr); } // ============================================================================= // string_list string::split (string del) const { string_list res; long a = 0; // Find all separators and store the text left to them. for (;;) { long b = first (del, a); if (b == -1) break; string sub = substring (a, b); if (sub.length() > 0) res.push_back (substring (a, b)); a = b + strlen (del); } // Add the string at the right of the last separator if (a < (int) length()) res.push_back (substring (a, length())); return res; } // ============================================================================= // void string::replace (const char* a, const char* b) { long pos; while ( (pos = first (a)) != -1) m_string = m_string.replace (pos, strlen (a), b); } // ============================================================================= // int string::count (const char needle) const { int numNeedles = 0; for (const char & c : m_string) if (c == needle) numNeedles++; return numNeedles; } // ============================================================================= // string string::substring (long a, long b) const { if (b == -1) b = length(); if (b == a) return ""; if (b < a) { // Swap the variables int c = a; a = b; b = c; } char* newString = new char[b - a + 1]; strncpy (newString, m_string.c_str() + a, b - a); newString[b - a] = '\0'; string other (newString); delete[] newString; return other; } // ============================================================================= // string::length_type string::posof (int n) const { int count = 0; for (int i = 0; i < length(); ++i) { if (m_string[i] != ' ') continue; if (++count < n) continue; return i; } return -1; } // ============================================================================= // int string::first (const char* c, string::length_type a) const { for (; a < length(); a++) if (m_string[a] == c[0] && strncmp (m_string.c_str() + a, c, strlen (c)) == 0) return a; return -1; } // ============================================================================= // int string::last (const char* c, string::length_type a) const { if (a == -1 || a >= length()) a = length() - 1; for (; a > 0; a--) if (m_string[a] == c[0] && strncmp (m_string.c_str() + a, c, strlen (c)) == 0) return a; return -1; } // ============================================================================= // void string::dump() const { print ("`%1`:\n", chars()); int i = 0; for (char u : m_string) print ("\t%1. [%d2] `%3`\n", i++, u, string (u)); } // ============================================================================= // long string::to_long (bool* ok, int base) const { errno = 0; char* endptr; long i = strtol (m_string.c_str(), &endptr, base); *ok = (errno == 0 && *endptr == '\0'); return i; } // ============================================================================= // float string::to_float (bool* ok) const { errno = 0; char* endptr; float i = strtof (m_string.c_str(), &endptr); *ok = (errno == 0 && *endptr == '\0'); return i; } // ============================================================================= // double string::to_double (bool* ok) const { errno = 0; char* endptr; double i = strtod (m_string.c_str(), &endptr); *ok = (errno == 0 && *endptr == '\0'); return i; } // ============================================================================= // bool operator== (const char* a, const string& b) { return b == a; } // ============================================================================= // string operator+ (const char* a, const string& b) { return string (a) + b; } // ============================================================================= // string string::operator+ (const string data) const { string newString = *this; newString += data; return newString; } // ============================================================================= // string string::operator+ (const char* data) const { string newString = *this; newString += data; return newString; } // ============================================================================= // string& string::operator+= (const string data) { append (data); return *this; } // ============================================================================= // string& string::operator+= (const char* data) { append (data); return *this; } // ============================================================================= // bool string::is_numeric() const { bool gotDot = false; for (const char & c : m_string) { // Allow leading hyphen for negatives if (&c == &m_string[0] && c == '-') continue; // Check for decimal point if (!gotDot && c == '.') { gotDot = true; continue; } if (c >= '0' && c <= '9') continue; // Digit // If the above cases didn't catch this character, it was // illegal and this is therefore not a number. return false; } return true; } // ============================================================================= // bool string::ends_with (const string& other) { if (length() < other.length()) return false; const int ofs = length() - other.length(); return strncmp (chars() + ofs, other.chars(), other.length()) == 0; } // ============================================================================= // bool string::starts_with (const string& other) { if (length() < other.length()) return false; return strncmp (chars(), other.chars(), other.length()) == 0; } // ============================================================================= // void string::sprintf (const char* fmtstr, ...) { char* buf; int bufsize = 256; va_list va; va_start (va, fmtstr); do buf = new char[bufsize]; while (vsnprintf (buf, bufsize, fmtstr, va) >= bufsize); va_end (va); m_string = buf; delete[] buf; } // ============================================================================= // void string::prepend (string a) { m_string = (a + m_string).std_string(); } // ============================================================================= // string string_list::join (const string& delim) { string result; for (const string & it : std_deque()) { if (!result.is_empty()) result += delim; result += it; } return result; } // ============================================================================= // bool string::mask (const string& pattern) const { // Elevate to uppercase for case-insensitive matching string pattern_upper = pattern.to_uppercase(); string this_upper = to_uppercase(); const char* maskstring = pattern_upper.chars(); const char* mptr = &maskstring[0]; for (const char* sptr = this_upper.chars(); *sptr != '\0'; sptr++) { if (*mptr == '?') { if (* (sptr + 1) == '\0') { // ? demands that there's a character here and there wasn't. // Therefore, mask matching fails return false; } } elif (*mptr == '*') { char end = * (++mptr); // If '*' is the final character of the message, all of the remaining // string matches against the '*'. We don't need to bother checking // the string any further. if (end == '\0') return true; // Skip to the end character while (*sptr != end && *sptr != '\0') sptr++; // String ended while the mask still had stuff if (*sptr == '\0') return false; } elif (*sptr != *mptr) return false; mptr++; } return true; }