761 lines · 12.5 KB · Objective-C
RawDownload
 /* * Portable Object Compiler (c) 1997,98,99,2003,2009.  All Rights Reserved. * $Id: ocstring.m,v 1.4 2009/10/23 19:36:44 stes Exp $ */ /* * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library 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 Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h"#include <assert.h>#include <ctype.h>#include <stdlib.h>#include "ocstring.h"#include "outofbnd.h"#include "ascfiler.h" #define DEFAULT_CAPACITY (16)#define SPRINTF_BUFSIZE (2048) typedef struct  {    @defs (String)  }TFString; @implementation String /***************************************************************************** * * Creation * ****************************************************************************/ static int str_len (char *s){  int len = 0;  while (*s++)    len++;  return len;} static void str_ncpy (char *dst, char *src, int n){  int c = 0;  while (n-- && (c = *src++))    {      *dst++ = c;    }  *dst++ = '\0';} static void str_cpy (char *dst, char *src){  int c = 0;  while ((c = *src++))    {      *dst++ = c;    }  *dst++ = '\0';} static void init (objstr_t self, char *s, int n, int c){  assert (0 <= n && n + 1 <= c);   self->count = n;  self->capacity = c;  self->ptr = (char *) OC_MallocAtomic (c);   str_ncpy (self->ptr, s, n);  self->ptr [n] = '\0';} + new{  return [self new:DEFAULT_CAPACITY];} + new:(unsigned)nChars{  id newObj = [super new];  init ([newObj objstrvalue], "", 0, nChars);  return newObj;} static void initstr (objstr_t self, char *s, int n){  init (self, s, n, n + 1);} + str:(STR)aString{  if (aString)    {      id newObj = [super new];      int n = str_len (aString);#if OTBCRT      /* works always, also for -otb */      initstr ([newObj objstrvalue], aString, n);#else      /* faster, but doesn't work for -otb */      initstr (&(((TFString *) newObj)->value), aString, n);#endif      return newObj;    }  else    {      return [self new];    }} + chars:(STR)aString count:(int)n{  if (aString)    {      id newObj = [super new];#if OTBCRT      /* works always, also for -otb */      initstr ([newObj objstrvalue], aString, n);#else      /* faster, but doesn't work for -otb */      initstr (&(((TFString *) newObj)->value), aString, n);#endif      return newObj;    }  else    {      return [self new];    }} + vsprintf:(STR)format:(OC_VA_LIST*)ap{  char aBuffer [SPRINTF_BUFSIZE]; #if OBJCRT_USE_SNPRINTF  if (vsnprintf (aBuffer, SPRINTF_BUFSIZE, format, *ap) >= SPRINTF_BUFSIZE)    {      [OutOfBounds signal];      return nil;    }#else  vsprintf (aBuffer, format, *ap);#endif   return [self str:aBuffer];} + sprintf:(STR)format,...{  id newString;   /* use OC macros for porting to SunOS4 */  OC_VA_LIST ap;  OC_VA_START (ap, format);  newString = [self vsprintf:format:&ap];  OC_VA_END (ap);  return newString;} static void copy (objstr_t dst, objstr_t src){  int n = src->count;   assert (n == str_len (src->ptr) && 0 <= n && n < src->capacity);   dst->count = n;  dst->capacity = n + 1;  dst->ptr = (char *) OC_MallocAtomic (n + 1);  str_cpy (dst->ptr, src->ptr);} - copy{  id aCopy = [super copy];  copy ([aCopy objstrvalue], (&value));  return aCopy;} - deepCopy{  return [self copy];} static void clear (objstr_t self){  OC_Free (self->ptr);  self->ptr = NULL;} - free{  clear ((&value));  return [super free];} - release{#ifdef OBJC_REFCNT  clear ((&value));  return [super release];#else  return [self notImplemented:_cmd];#endif} /***************************************************************************** * * Comparison * ****************************************************************************/ static int str_cmp (char *s1, char *s2){  int r;  int c1, c2;   while (1)    {      c1 = *s1++;      c2 = *s2++;      if (c1 == '\0')	return (c2 == 0) ? 0 : -1;      if (c2 == '\0')	return 1;      if ((r = c1 - c2))	return r;    }   return 0;} static int cmpstr (objstr_t a, char *b){  return str_cmp (a->ptr, b);} - (int) compare:aStr{  return (self == aStr) ? 0 : cmpstr ((&value), [aStr str]);} - (int) compareSTR:(STR)aString{  return cmpstr ((&value), aString);} static unsigned str_hash (char *s){  unsigned hash = 0;   while (1)    {      if (*s == '\0')	break;      else	hash ^= *s++;      if (*s == '\0')	break;      else	hash ^= (*s++ << 8);      if (*s == '\0')	break;      else	hash ^= (*s++ << 16);      if (*s == '\0')	break;      else	hash ^= (*s++ << 24);    }   return hash;} static unsigned hash (objstr_t self){  return str_hash (self->ptr);} - (unsigned) hash{  return hash ((&value));} static int str_dictcmp (char *s1, char *s2){  int r;  int c1, c2;   while (1)    {      while ((c1 = *s1++) && !isalnum (c1))	;      while ((c2 = *s2++) && !isalnum (c2))	;      if (c1 == '\0')	return (c2 == 0) ? 0 : -1;      if (c2 == '\0')	return 1;      if (isupper (c1))	c1 = tolower (c1);      if (isupper (c2))	c2 = tolower (c2);      if ((r = c1 - c2))	return r;    }   return 0;} static int dictcmp (objstr_t a, objstr_t b){  return str_dictcmp (a->ptr, b->ptr);} - (int) dictCompare:aStr{  return dictcmp ((&value), [aStr objstrvalue]);} - (BOOL) isEqual:aStr{  return (self == aStr) ? YES : ([self compare:aStr] == 0);} - (BOOL) isEqualSTR:(STR)aString{  return [self compareSTR:aString] == 0;} /***************************************************************************** * * Interrogation * ****************************************************************************/ - (objstr_t) objstrvalue{  return &value;} - (unsigned) size{  return (&value)->count;} static char charat (objstr_t self, int i){  if (0 <= i && i < self->count)    {      return (self->ptr) [i];    }  else    {      return 0;    }} - (char) charAt:(unsigned)anOffset{  return charat ((&value), anOffset);} static char strputchar (char *self, char c){  char r = *self;  *self = c;  return r;} static char putcharat (objstr_t self, int i, char c){  if (0 <= i && i < self->count)    {      return strputchar (self->ptr + i, c);    }  else    {      return 0;    }} - (char) charAt:(unsigned)anOffset put:(char)aChar{  return putcharat ((&value), anOffset, aChar);} /***************************************************************************** * * Concatenation * ****************************************************************************/ - (STR) strcat:(STR)aBuffer{  str_cpy (aBuffer + str_len (aBuffer), [self str]);  return aBuffer;} static void expand (objstr_t self){  assert (self->count + 1 <= self->capacity);  self->capacity = 1 + self->capacity * 2;  self->ptr = (char *) OC_Realloc (self->ptr, self->capacity);} static void concat (objstr_t self, char *s, int n){  assert (n == str_len (s));  while (self->count + n + 1 > self->capacity)    expand (self);  str_cpy (self->ptr + self->count, s);  self->count += n;} /* patch from finnw, to dereference ptr after expand() */ static void concat_self (objstr_t self){  while (2 * self->count + 1 > self->capacity)    expand (self);  str_ncpy (self->ptr + self->count, self->ptr, self->count);  self->count *= 2;} - concat:aString{  if (aString == self)    {      concat_self (&value);    }  else    {      return [self concatSTR:[aString str]];    }} - concatSTR:(STR)aString{  concat ((&value), aString, str_len (aString));  return self;} - concatenateSTR:(STR)aString{  return [self concatSTR:aString];} static void atinsert (objstr_t self, int i, char *s, int n){  int j;  char *p;   while (self->count + n + 1 > self->capacity)    expand (self);  j = self->count;  p = self->ptr;  while ((--j) >= i)    {      p [j + n] = p [j];    }  for (j = i; j < i + n; j++)    {      p [j] = *s++;    }  self->count += n;

Lines 1–500 of 761.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t