]> cygwin.com Git - cygwin-apps/setup.git/blobdiff - String++.cc
Use solver to check for problems and produce a list of package transactions
[cygwin-apps/setup.git] / String++.cc
index 0d188ab529ebe37cd653279fa504ee991a68ad2f..35106e54218b2f194e2a959b7d88c59546097300 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Robert Collins.
+ * Copyright 2005-2006, Various Contributors.
  *
  *     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
  *
  *     A copy of the GNU General Public License can be found at
  *     http://www.gnu.org/
- *
- * Written by Robert Collins.
- *
  */
 
-// A String class to replace all the char * manipulation. 
-
 #include "String++.h"
 #include <string.h>
-#include <ctype.h>
-#include "io_stream.h"
-#include <iostream>
 #include <sstream>
-#include <string>
-
-using namespace std;
-
-// _data
-
-String::_data::_data(_data const &aData) : count (1), theString (new unsigned char[aData.length]), cstr(0), length (aData.length) {
-  memcpy (theString, aData.theString, aData.length);
-}
-
-String::_data::_data(): count (1), theString(new unsigned char[0]), cstr (0), length (0) {}
-String::_data::_data(size_t aLength): count (1), theString(new unsigned char[aLength]), cstr(0), length (aLength) {}
-String::_data::~_data ()
-{
-    if (theString)
-          delete[] theString;
-      if (cstr)
-           delete[] cstr;
-}
-
-//String
-
-String::String (const char *acString) : theData (new _data(acString ? strlen(acString) : 0))
-{
-  memcpy (theData->theString, acString, theData->length);
-}
+#include <algorithm>
 
-String::~String ()
-{
-  if (--theData->count == 0)
-    delete theData;
-}
-
-String::String (int const anInt)
-{
-  ostringstream os;
-  os << anInt;
-  theData = new _data(os.str().size());
-  memcpy (theData->theString, os.str().c_str(), os.str().size());
-}
-
-String::String (string const &aString) : theData (new _data (aString.c_str() ? strlen (aString.c_str()) : 0))
-{
-  memcpy (theData->theString, aString.c_str(), theData->length);
-}
-
-// able to cache the result if needed.
 char *
-String::cstr ()
+new_cstr_char_array (const std::string &s)
 {
-  if (theData->length == 0)
-    return NULL;
-  char * tempcStr =new char[theData->length + 1];
-  // remove when exceptions are done
-  if (!tempcStr)
-        exit (100);
-  tempcStr[theData->length] = '\0';
-  memcpy (tempcStr, theData->theString, theData->length);
-  return tempcStr;
+  size_t len = s.size();
+  char *buf = new char[len + 1];
+  if (len)
+    memcpy(buf, s.c_str(), len);
+  buf[len] = 0;
+  return buf;
 }
 
-char *
-String::cstr () const
+std::string
+format_1000s (int num, char sep)
 {
-  if (theData->length == 0)
-    return NULL;
-  char * tempcStr =new char[theData->length + 1];
-  // remove when exceptions are done
-  if (!tempcStr)
-        exit (100);
-  tempcStr[theData->length] = '\0';
-  memcpy (tempcStr, theData->theString, theData->length);
-  return tempcStr;
-}
-
-// able to cache the result if needed.
-char const *
-String::cstr_oneuse () const
-{
-  if (theData->length == 0)
-    return NULL;
-  if (theData->cstr)
-    delete[] theData->cstr;
-  theData->cstr = new char[theData->length + 1];
-  theData->cstr[theData->length] = '\0';
-  memcpy (theData->cstr, theData->theString, theData->length);
-  return theData->cstr;
-}
-
-// does this character exist in the string?
-// 0 is false, 1 is the first position...
-// XXX FIXME: Introduce npos, and change all
-// if (size) calls to be if (size()==npos)
-size_t
-String::find(char aChar) const
-{
-  for (size_t i=0; i < theData->length; ++i)
-    if (theData->theString[i] == aChar)
-      return i+1;
-  return 0;
+  int mult = 1;
+  while (mult * 1000 < num)
+    mult *= 1000;
+  std::ostringstream os;
+  os << ((num / mult) % 1000);
+  for (mult /= 1000; mult > 0; mult /= 1000)
+    {
+      int triplet = (num / mult) % 1000;
+      os << sep;
+      if (triplet < 100) os << '0';
+      if (triplet < 10) os << '0';
+      os << triplet;
+    }
+  return os.str();
 }
 
-String
-String::substr(size_t start, int len) const
+std::string
+stringify (int num)
 {
-  // Adapt the C++ string class
-  return string(cstr_oneuse()).substr(start, len);
+  std::ostringstream os;
+  os << num;
+  return os.str();
 }
 
 int
-String::compare (String const &aString, size_t const count) const
+casecompare (const std::string& a, const std::string& b, size_t limit)
 {
-  // trivial cases:
-  if (theData == aString.theData)
-    return 0;
-  size_t length = count ? count : theData->length;
-  if (length > theData->length)
-    length = theData->length;
-  if (length > aString.theData->length)
-    length = aString.theData->length;
-  size_t i;
-  for (i=0; i < length ; ++i)
-    if (theData->theString[i] < aString.theData->theString[i])
-      return -1;
-    else if (theData->theString[i] > aString.theData->theString[i])
-      return 1;
-  // equal for length
-  if (i == count && count != 0)
-    return 0;
-  if (theData->length < aString.theData->length)
-    return -1;
-  else if (theData->length > aString.theData->length)
-    return 1;
-  return 0;
-}
+  size_t length_to_check = std::min(a.length(), b.length());
+  if (limit && length_to_check > limit)
+    length_to_check = limit;
 
-int
-String::casecompare (String const &aString, size_t const count) const
-{
-  // trivial cases:
-  if (theData == aString.theData)
-    return 0;
-  size_t length = count ? count : theData->length;
-  if (length > theData->length)
-    length = theData->length;
-  if (length > aString.theData->length)
-    length = aString.theData->length;
   size_t i;
-  for (i=0; i < length; ++i)
-    if (toupper(theData->theString[i]) < toupper(aString.theData->theString[i]))
+  for (i = 0; i < length_to_check; ++i)
+    if (toupper(a[i]) < toupper(b[i]))
       return -1;
-    else if (toupper(theData->theString[i]) > toupper(aString.theData->theString[i]))
+    else if (toupper(a[i]) > toupper(b[i]))
       return 1;
-  // equal for length
-  if (i == count && count != 0)
+
+  // Hit the comparison limit without finding a difference
+  if (limit && i == limit) 
     return 0;
-  if (theData->length < aString.theData->length)
+
+  if (a.length() < b.length())
     return -1;
-  else if (theData->length > aString.theData->length)
+  else if (a.length() > b.length())
     return 1;
+
   return 0;
 }
 
-String &
-String::operator+= (String const &aString)
+std::string
+replace(const std::string& haystack, const std::string& needle,
+        const std::string& replacement)
 {
-  if (theData->count > 1) 
+  std::string rv(haystack);
+  size_t n_len = needle.length(), r_len = replacement.length(),
+         search_start = 0;
+  
+  while (true)
   {
-    _data * someData = new _data(*theData);
-    --theData->count;
-    theData = someData;
+    size_t pos = rv.find(needle, search_start);
+    if (pos == std::string::npos)
+      return rv;
+    rv.replace(pos, n_len, replacement);
+    search_start = pos + r_len;
   }
-
-  unsigned char *tempString = theData->theString;
-  theData->theString = new unsigned char [theData->length + aString.theData->length];
-  // remove when exceptions are done
-  if (!theData->theString)
-    exit (100);
-  memcpy (theData->theString, tempString, theData->length);
-  delete[] tempString;
-  memcpy (&theData->theString[theData->length], aString.theData->theString, aString.theData->length);
-  theData->length += aString.theData->length;
-  return *this;
-}
-
-String
-String::operator + (String const &aString) const
-{
-  unsigned char *tempcString = new unsigned char [theData->length + aString.theData->length];
-  // remove when exceptions are done
-  if (!tempcString)
-      exit (100);
-  memcpy (tempcString, theData->theString, theData->length);
-  memcpy (&tempcString[theData->length], aString.theData->theString, aString.theData->length);
-  return absorb (tempcString, theData->length + aString.theData->length);
-}
-
-String
-String::operator + (char const *aString) const
-{
-  // expensive, but quick to code.
-  return *this + String (aString);
-}
-
-bool
-String::operator == (String const &rhs) const
-{
-  return compare (rhs) ? false : true;
-}
-
-bool
-String::operator == (char const *rhs) const
-{
-    return compare (rhs) ? false : true;
-}
-
-bool
-String::operator != (String const &rhs) const
-{
-  return !(*this == rhs);
-}
-
-bool
-String::operator != (char const *rhs) const
-{
-  return !(*this == rhs);
-}
-
-String
-String::absorb (unsigned char *aString, size_t aLength)
-{
-  String theString;
-  theString.theData->theString = aString;
-  theString.theData->length = aLength;
-  return theString;
-}
-
-int
-String::casecompare (String const lhs, String const rhs)
-{
-  return lhs.casecompare (rhs);
-}
-
-/*
- * This supports two wildcard characters, '*' and '?', as well as the
- * '[]'-style character sets ('^' to invert).
- * Use '\' to escape special characters.
- * Shamelessly stolen from fileutils-4.1 (adapted for <buf,len> strings).
- */
-static bool
-strmatch (const unsigned char *pattern, size_t plen,
-         const unsigned char *name, size_t nlen)
-{
-  register const unsigned char *pend = pattern + plen, *nend = name + nlen;
-  register const unsigned char *p = pattern, *n = name;
-  register unsigned char c;
-
-  while (p < pend)
-    {
-      c = *p++;
-      switch (c)
-       {
-       case '?':  /* A '?' matches exactly one character */
-         if (n == nend)
-           return false;
-         break;
-
-       case '\\':  /* Escape next character */
-         if (p == pend)
-           return false;
-         c = *p++;
-         if (n == nend || *n != c)
-           return false;
-         break;
-
-       case '*':  /* A '*' matches any number of characters */
-         while (p < pend && (c == '?' || c == '*'))
-           {
-             c = *p++;
-             if (c == '?')
-               {
-                 /* A '?' needs to match one character.  */
-                 if (n == nend)
-                   /* There isn't another character; no match.  */
-                   return false;
-                 else
-                   /* One character of the name is consumed in matching
-                      this ? wildcard, so *??? won't match if there are
-                      less than three characters.  */
-                   ++n;
-               }
-           }
-
-         if (p == pend)
-           return true;
-
-         {
-           unsigned char c1 = (c == '\\') ? *p : c;
-           for (--p; n != nend; ++n)  /* Eat up all chars */
-             if ((c == '[' || *n == c1) && strmatch (p, pend-p, n, nend-n))
-               return true;
-           return false;
-         }
-
-       case '[':  /* A '[A-Z]' matches any char between 'A' and 'Z' */
-         {
-           /* Nonzero if the sense of the character class is inverted.  */
-           register bool invert;
-
-           if (n == nend)
-             return false;
-
-           invert = (*p == '^');
-           if (invert)
-             ++p;
-
-           if (p == pend)
-             /* [ (unterminated) loses.  */
-             return false;
-
-           c = *p++;
-           for (;;)
-             {
-               register unsigned char cstart = c, cend = c;
-
-               if (p == pend)
-                 /* [ (unterminated) loses.  */
-                 return false;
-
-               c = *p++;
-
-               if (c == '-' && *p != ']')
-                 {
-                   if (p == pend)
-                     return false;
-                   cend = *p++;
-
-                   c = *p++;
-                 }
-
-               if (*n >= cstart && *n <= cend)
-                 goto matched;
-
-               if (c == ']')
-                 break;
-             }
-           if (!invert)
-             return false;
-           break;
-
-         matched:;
-           /* Skip the rest of the [...] that already matched.  */
-           while (c != ']')
-             {
-               if (p == pend)
-                 /* [... (unterminated) loses.  */
-                 return false;
-
-               c = *p++;
-             }
-           if (invert)
-             return false;
-         }
-         break;
-
-       default:
-         if (n == nend || c != *n)
-           return false;
-       }
-
-      ++n;
-    }
-
-  if (n == nend)
-    return true;
-
-  return false;
-}
-
-bool
-String::matches (String const &pattern) const
-{
-  return strmatch (pattern.theData->theString, pattern.theData->length,
-                  theData->theString, theData->length);
-}
-
-/* TODO: research how wide char and unicode interoperate with
- * C++ streams
- */
-ostream &
-operator << (ostream &os, String const &theString)
-{
-  os << theString.cstr_oneuse();
-  return os;
 }
This page took 0.028908 seconds and 5 git commands to generate.