Logo Search packages:      
Sourcecode: kdeadmin version File versions

String.cc

/* String.cc
**
** Copyright (C) 2000,2001 by Bernhard Rosenkraenzer
**
** Contributions by A. Seigo and W. Bastian.
**
*/

/*
** 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 2 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 in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

/*
** Bug reports and questions can be sent to kde-devel@kde.org
*/
#define _GNU_SOURCE 1
#include <features.h>
#include <string.h>
#include <string>
#include "String.h"
#include <stdio.h>
#include <regex.h>

using namespace std;

void String::sprintf(const char *format, ...)
{
      va_list arg;
      va_start(arg, format);
      char *buf=0;
      int size=vsnprintf(buf, 0, format, arg);
      if(size==-1) { /* ARGH!!! */
            cerr << "WARNING: Your C library (libc) does not conform to the ISO C99 standard!" << endl << "Consider upgrading to glibc 2.1 or higher!" << endl;
            int bufsiz=1024;
            while(size==-1) {
                  buf=(char *) malloc(bufsiz);
                  size=vsnprintf(buf, 0, format, arg);
                  bufsiz+=1024;
                  free(buf);
            }
      }
      buf=(char *) malloc(size+1);
      vsnprintf(buf, size+1, format, arg);
      string str=buf;
      *this=buf;
      va_end(arg);
      free(buf);
      return;
}
bool String::readfile(String filename)
{
      FILE *f=fopen(filename, "r");
      if(!f)
            return false;

      string str="";
      char *buf=(char *) malloc(1024);
      while(!feof(f) && !ferror(f)) {
            if(!fgets(buf, 1024, f))
                  continue;
            str += buf;
      };
      *this=buf;
      free(buf);
      fclose(f);
      return true;
}
char *String::cstr() const
{
      char *a=new char[size()+1];
      a[size()]=0;
      strncpy(a, data(), size());
      return a;
}
bool String::cmp(char const * const s) const
{
      if(size() != strlen(s))
            return false;
      return (strncmp(data(), s, size())==0);
}
bool String::casecmp(char const * const s) const
{
      if(size() != strlen(s))
            return false;
      return (strncasecmp(data(), s, size())==0);
}
bool String::contains(String const &s, bool cs) const
{
      if(cs)
            if(strstr(cstr(), s.cstr()))
                  return true;
            else
                  return false;
      else
            if(strcasestr(cstr(), s.cstr()))
                  return true;
            else
                  return false;
}
int String::locate(String const &s, bool cs, unsigned int startat) const
{
      if(startat>=size())
            return -1;

      char *s0=cstr(), *s1=s.cstr(), *s2;
      int r;
      if(cs)
            s2=strstr(s0+startat, s1);
      else
            s2=strcasestr(s0+startat, s1);
      if(s2==NULL) {
            delete [] s0;
            delete [] s1;
            return -1;
      }
      r=(s2-s0);
      if(startat>0) r++;
      delete [] s0;
      delete [] s1;
      return r;
}
String const String::operator +(char const &s) {
      char a[2];
      a[0]=s;
      a[1]=0;
      String st=cstr();
      st+=a;
      return st;
}
String const String::operator +(char const * const s) {
      String st=cstr();
      st += s;
      return st;
}
bool String::operator ==(char s) {
      if(size()==1 && cstr()[0]==s)
            return true;
      else
            return false;
}
bool String::operator !=(char s) {
      if(size()!=1 || cstr()[0]!=s)
            return true;
      else
            return false;
}
String String::simplifyWhiteSpace() const {
      char *s=cstr();
      for(unsigned int i=0; i<size(); i++)
            if(isspace(s[i]))
                  s[i]=' ';
      while(*s==' ')
            strcpy(s, s+1);
      int l = strlen(s);
      while(l && (s[l-1]==' '))
            s[--l]=0;
            
      while(strstr(s, "  "))
            strcpy(strstr(s, "  "), strstr(s, "  ")+1);
      return s;
}
String String::left(unsigned int num) const
{
      if(num==0) return "";
      char *s=cstr();
      if(size()<=num)
            return s;
      s[num]=0;
      return s;
}
String String::right(unsigned int num) const
{
      if(num==0) return "";
      char *s=cstr();
      if(size()<=num)
            return s;
      strcpy(s, s+strlen(s)-num);
      return s;
}
String String::mid(unsigned int start, unsigned int num) const
{
      if(start>=size())
            return "";
      char *s=cstr();
      start--;
      if(start>0)
            strcpy(s, s+start);
      if(num>0 && num<=strlen(s))
            s[num]=0;
      return s;
}
String &String::regex(String const &expr, bool cs) const
{
      regex_t regexp;
      int err;
      regmatch_t reg[1];
      String *ret=new String("");
      if((err=regcomp(&regexp, expr, cs?REG_EXTENDED:REG_EXTENDED|REG_ICASE))) {
            regfree(&regexp);
            return *ret;
      }
      err=regexec(&regexp, cstr(), 1, reg, 0);
      regfree(&regexp);
      if(err)
            return *ret;
      if(reg[0].rm_so!=-1) {
            char *s=strdup(cstr()+reg[0].rm_so);
            s[reg[0].rm_eo-reg[0].rm_so]=0;
            delete ret;
            ret=new String(s);
            free(s);
      }
      return *ret;
}
String &String::replace(String const &what, String const &with, bool all) const
{
      String *result;
      if(!contains(what)) {
            result=new String(*this);
            return *result;
      }
      result=new String;
      *result=left(locate(what));
      *result+=with;
      if(!all) {
            *result+=right(size()-locate(what)-what.size());
      } else {
            unsigned int start=locate(what)+what.size()+1;
            int loc;
            while((loc=locate(what, true, start+1))!=-1) {
                  *result+=mid(start, loc-start);
                  *result+=with;
                  start=locate(what, true, start)+what.size();
            }
            if(size()>start)
                  *result+=right(size()-start+1);
      }
      return *result;
}
String String::escapeForRegExp(String const &s)
{
      static const char meta[] = "$()*+.?[\\]^{|}";
      String quoted = s;
      int i = 0;

      while ( i < (int) quoted.length() ) {
            if ( strchr(meta, quoted.at(i)) != 0 )
                  quoted.insert( i++, "\\" );
            i++;
      }
      return quoted;
}
StringList::StringList(String const &s)
{
      clear();
      char *st=strdup((char const * const)s);
      char *tok;
      char *line=strtok_r(st, "\n", &tok);
      while(line) {
            if(line[strlen(line)-1]=='\r') // Handle sucking OSes
                  line[strlen(line)-1]=0;
            insert(end(), line);
            line=strtok_r(NULL, "\n", &tok);
      }
      free(st);
}

StringList::StringList(char **strs, int num)
{
      clear();
      if(num>=0) {
            for(int i=0; i<num; i++)
                  insert(end(), strs[i]);
      } else {
            for(int i=0; strs[i]!=NULL; i++)
                  insert(end(), strs[i]);
      }
}

bool StringList::readfile(String const &filename)
{
      clear();
      FILE *f=fopen(filename, "r");
      if(!f)
            return false;
      char *buf=(char *) malloc(1024);
      while(!feof(f) && !ferror(f)) {
            if(!fgets(buf, 1024, f))
                  continue;
            while(strlen(buf) && (buf[strlen(buf)-1]=='\n' || buf[strlen(buf)-1]=='\r'))
                  buf[strlen(buf)-1]=0;
            insert(end(), buf);
      };
      free(buf);
      fclose(f);
      return true;
}
bool StringList::writefile(String const &filename) const
{
      FILE *f=fopen(filename, "w");
      if(!f)
            return false;
      for(const_iterator it=begin(); it!=end(); it++) {
            fputs(*it, f);
            fputs("\n", f);
      }
      fclose(f);
      return true;
}
void StringList::operator +=(StringList const &s)
{
      for(const_iterator it=s.begin(); it!=s.end(); it++)
            insert(end(), *it);
}
void StringList::operator +=(StringList const * const s)
{
      for(const_iterator it=s->begin(); it!=s->end(); it++)
            insert(end(), *it);
}
bool StringList::contains(String const &s) const
{
      for(const_iterator it=begin(); it!=end(); it++)
            if(*it == s)
                  return true;
      return false;
}
void StringList::remove(String const &s)
{
      bool done=false;
      for(iterator it=begin(); !done && it!=end(); it++)
            if(*it==s) {
                  erase(it);
                  done=true;
            }
}
String const &StringList::grep(String const &s) const
{
      for(const_iterator it=begin(); it!=end(); it++)
            if(!(*it).regex(s).empty())
                  return *it;
      String *r=new String;
      return *r;
}
int __stringlist_compare(const void *a, const void *b)
{
      if(a==0 && b==0)
            return 0;
      else if(a==0)
            return 1;
      else if(b==0)
            return -1;
      else
            return strcmp((const char *)a,(const char *)b);
}
int __stringlist_compare_noncs(const void *a, const void *b)
{
      if(a==0 && b==0)
            return 0;
      else if(a==0)
            return 1;
      else if(b==0)
            return -1;
      else
            return strcasecmp((const char *)a,(const char *)b);
}
void StringList::sort(bool cs)
{
      unsigned int i=0, s=size();
      char **strings=new char*[s];
      for(const_iterator it=begin(); it!=end(); it++)
            strings[i++]=(*it).cstr();
      if(cs)
            qsort(strings, s, sizeof(char*),  __stringlist_compare);
      else
            qsort(strings, s, sizeof(char*), __stringlist_compare_noncs);
      clear();
      for(i=0; i<s; i++) {
            insert(end(), strings[i]);
            delete [] strings[i];
      }
      delete [] strings;
}
StringList::operator String() const
{
      String s="";
      for(const_iterator it=begin(); it!=end(); it++) {
            s+=(*it);
            if(s.right()!=String("\n") && s.right()!=String("\r"))
                  s+="\n";
      }
      return s;
}

ostream &operator <<(ostream &os, String const &s)
{
      if(!s.empty())
            os << (char const * const) s;
      return os;
}
ostream &operator <<(ostream &os, String const *s)
{
      if(!s->empty())
            os << (char const * const) *s;
      return os;
}
ostream &operator <<(ostream &os, StringList const &s)
{
      for(StringList::const_iterator it=s.begin(); it!=s.end(); it++) {
            os << *it;
            if((*it).right()!=String("\n") && (*it).right()!=String("\r"))
                  os << endl;
      }
      return os;
}
ostream &operator <<(ostream &os, StringList const *s)
{
      for(StringList::const_iterator it=s->begin(); it!=s->end(); it++) {
            os << *it;
            if((*it).right()!=String("\n") && (*it).right()!=String("\r"))
                  os << endl;
      }
      return os;
}

Generated by  Doxygen 1.6.0   Back to index