--- a/str.cpp Wed May 08 14:57:48 2013 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,503 +0,0 @@ -/* - * LDForge: LDraw parts authoring CAD - * Copyright (C) 2013 Santeri Piippo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <assert.h> -// #include <initializer_list> -#include "str.h" -#include "common.h" -#include "misc.h" - -#define ITERATE_STRING(u) \ - for (unsigned int u = 0; u < strlen (text); u++) - -// ============================================================================ -// vdynformat: Try to write to a formatted string with size bytes first, if -// that fails, double the size and keep recursing until it works. -char* vdynformat (const char* csFormat, va_list vArgs, long lSize) { - char* buffer = new char[lSize]; - int r = vsnprintf (buffer, lSize - 1, csFormat, vArgs); - if (r > (signed)(lSize - 1) || r < 0) { - delete[] buffer; - buffer = vdynformat (csFormat, vArgs, lSize * 2); - } - return buffer; -} - -// ============================================================================ -str::str () { - text = new char[1]; - clear(); - alloclen = strlen (text); -} - -str::str (const char* c) { - text = new char[1]; - text[0] = '\0'; - curs = alloclen = 0; - append (c); -} - -str::str (char c) { - text = new char[1]; - text[0] = '\0'; - curs = alloclen = 0; - append (c); -} - -str::str (QString c) { - text = new char[1]; - text[0] = '\0'; - curs = alloclen = 0; - append (c); -} - -str::~str () { - // delete[] text; -} - -// ============================================================================ -void str::clear () { - delete[] text; - text = new char[1]; - text[0] = '\0'; - curs = 0; - alloclen = 0; -} - -// ============================================================================ -void str::resize (unsigned int len) { - unsigned int oldlen = strlen (text); - char* oldtext = new char[oldlen]; - strncpy (oldtext, text, oldlen); - - delete[] text; - text = new char[len+1]; - for (unsigned int u = 0; u < len+1; u++) - text[u] = 0; - strncpy (text, oldtext, len); - delete[] oldtext; - - alloclen = len; -} - -// ============================================================================ -void str::dump () { - for (unsigned int u = 0; u <= alloclen; u++) - printf ("\t%u. %u (%c)\n", u, text[u], text[u]); -} - -// ============================================================================ -// Adds a new character at the end of the string. -void str::append (const char c) { - // Out of space, thus resize - if (curs == alloclen) - resize (alloclen + 1); - text[curs] = c; - curs++; -} - -void str::append (const char* c) { - resize (alloclen + strlen (c)); - - for (unsigned int u = 0; u < strlen (c); u++) { - if (c[u] != 0) - append (c[u]); - } -} - -void str::append (str c) { - append (c.chars()); -} - -void str::append (QString c) { - append (c.toUtf8 ().constData ()); -} - -// ============================================================================ -void str::appendformat (const char* c, ...) { - va_list v; - - va_start (v, c); - char* buf = vdynformat (c, v, 256); - va_end (v); - - append (buf); - delete[] buf; -} - -void str::format (const char* fmt, ...) { - clear (); - - va_list v; - - va_start (v, fmt); - char* buf = vdynformat (fmt, v, 256); - va_end (v); - - append (buf); - delete[] buf; -} - -// ============================================================================ -char* str::chars () { - return text; -} - -// ============================================================================ -int str::first (const char* c, unsigned int a) { - unsigned int r = 0; - unsigned int index = 0; - for (; a < alloclen; a++) { - if (text[a] == c[r]) { - if (r == 0) - index = a; - - r++; - if (r == strlen (c)) - return index; - } else { - if (r != 0) { - // If the string sequence broke at this point, we need to - // check this character again, for a new sequence just - // might start right here. - a--; - } - - r = 0; - } - } - - return -1; -} - -// ============================================================================ -int str::last (const char* c, int a) { - if (a == -1) - a = len(); - - int max = strlen (c)-1; - - int r = max; - for (; a >= 0; a--) { - if (text[a] == c[r]) { - r--; - if (r == -1) - return a; - } else { - if (r != max) - a++; - - r = max; - } - } - - return -1; -} - -// ============================================================================ -str str::substr (unsigned int a, unsigned int b) { - if (a > len()) a = len(); - if (b > len()) b = len(); - - if (b == a) - return ""; - - if (b < a) { - printf ("str::substring:: indices %u and %u given, should be the other way around, swapping..\n", a, b); - - // Swap the variables - unsigned int c = a; - a = b; - b = c; - } - - char* s = new char[b - a + 1]; - strncpy (s, text + a, b - a); - s[b - a] = '\0'; - - str other = s; - delete[] s; - return other; -} - -// ============================================================================ -void str::remove (unsigned int idx, unsigned int dellen) { - str s1 = substr (0, idx); - str s2 = substr (idx + dellen, -1); - - clear(); - - append (s1); - append (s2); -} - -// ============================================================================ -str str::trim (int dellen) { - if (dellen > 0) - return substr (0, len() - dellen); - return substr (-dellen, len()); -} - -// ============================================================================ -void str::replace (const char* o, const char* n, unsigned int a) { - for (int idx; (idx = first (o, a)) != -1;) { - str s1 = substr (0, idx); - str s2 = substr (idx + strlen (o), len()); - - clear(); - - append (s1); - append (n); - append (s2); - } -} - -// ============================================================================ -str str::strip (char c) { - return strip ({c}); -} - -str str::strip (std::initializer_list<char> unwanted) { - str cache = text; - uint oldlen = len(); - - char* buf = new char[oldlen]; - char* bufptr = buf; - for (uint i = 0; i < oldlen; i++) { - bool valid = true; - for (const char* j = unwanted.begin(); j < unwanted.end() && valid; j++) - if (text[i] == *j) - valid = false; - - if (valid) - *bufptr++ = text[i]; - } - - *bufptr = '\0'; - assert (bufptr <= buf + oldlen); - - str zResult = buf; - delete[] buf; - - return zResult; -} - -void str::insert (char* c, unsigned int pos) { - str s1 = substr (0, pos); - str s2 = substr (pos, len()); - - clear(); - append (s1); - append (c); - append (s2); -} - -str str::reverse () { - char* buf = new char[len() + 1]; - - for (uint i = 0; i < len(); i++) - buf[i] = text[len() - i - 1]; - buf[len()] = '\0'; - - str other = buf; - delete[] buf; - return other; -} - -str str::repeat (int n) { - assert (n >= 0); - - str other; - for (int i = 0; i < n; i++) - other += text; - return other; -} - -// ============================================================================ -bool str::isnumber () { - ITERATE_STRING (u) { - // Minus sign as the first character is allowed for negatives - if (!u && text[u] == '-') - continue; - - if (text[u] < '0' || text[u] > '9') - return false; - } - return true; -} - -// ============================================================================ -bool str::isword () { - ITERATE_STRING (u) { - // lowercase letters - if (text[u] >= 'a' || text[u] <= 'z') - continue; - - // uppercase letters - if (text[u] >= 'A' || text[u] <= 'Z') - continue; - - return false; - } - return true; -} - -int str::instanceof (const char* c, uint n) { - unsigned int r = 0; - unsigned int index = 0; - unsigned int x = 0; - for (uint a = 0; a < alloclen; a++) { - if (text[a] == c[r]) { - if (r == 0) - index = a; - - r++; - if (r == strlen (c)) { - if (x++ == n) - return index; - r = 0; - } - } else { - if (r != 0) - a--; - r = 0; - } - } - - return -1; -} - -// ============================================================================ -int str::compare (const char* c) { - return strcmp (text, c); -} - -int str::compare (str c) { - return compare (c.chars()); -} - -int str::icompare (const char* c) { - return icompare (str ((char*)c)); -} - -int str::icompare (str b) { - return strcmp (tolower().chars(), b.tolower().chars()); -} - -// ============================================================================ -str str::tolower () { - str n = text; - - for (uint u = 0; u < len(); u++) { - if (n[u] >= 'A' && n[u] < 'Z') - n.text[u] += ('a' - 'A'); - } - - return n; -} - -// ============================================================================ -str str::toupper () { - str n = text; - - for (uint u = 0; u < len(); u++) { - if (n[u] >= 'a' && n[u] < 'z') - n.text[u] -= ('a' - 'A'); - } - - return n; -} - -// ============================================================================ -unsigned str::count (char c) { - unsigned n = 0; - ITERATE_STRING (u) - if (text[u] == c) - n++; - return n; -} - -unsigned str::count (char* c) { - unsigned int r = 0; - unsigned int tmp = 0; - ITERATE_STRING (u) { - if (text[u] == c[r]) { - r++; - if (r == strlen (c)) { - r = 0; - tmp++; - } - } else { - if (r != 0) - u--; - r = 0; - } - } - - return tmp; -} - -// ============================================================================ -std::vector<str> str::split (str del, bool bNoBlanks) { - std::vector<str> res; - unsigned int a = 0; - - // Find all separators and store the text left to them. - while (1) { - int b = first (del, a); - - if (b == -1) - break; - - if (!bNoBlanks || (b - a)) - res.push_back (substr (a, b)); - - a = b + strlen (del); - } - - // Add the string at the right of the last separator - if (!bNoBlanks || (len () - a)) - res.push_back (substr (a, len ())); - return res; -} - -std::vector<str> str::operator/ (str splitstring) {return split(splitstring);} -std::vector<str> str::operator/ (char* splitstring) {return split(splitstring);} -std::vector<str> str::operator/ (const char* splitstring) {return split(splitstring);} - -str& str::operator+= (vertex vrt) { - appendformat ("%s", vrt.stringRep (false).chars()); - return *this; -} - -str fmt (const char* fmt, ...) { - va_list va; - char* buf; - - va_start (va, fmt); - buf = vdynformat (fmt, va, 256); - va_end (va); - - str val = buf; - delete[] buf; - return val; -} \ No newline at end of file