V9/include/CC/String.h
#ifndef STRING_DOT_H
#define STRING_DOT_H
#define _OVERLOAD_STAT sleaze
#include <sys/types.h>
#include <sys/stat.h>
#undef _OVERLOAD_STAT
overload system, access, acct, chdir, chmod, chown, creat, link, mknod, mount,
open, umount, unlink, read, write;
#include <sysent.h>
overload fopen, fdopen, freopen, gets, fgets, puts, fputs;
#include <string.h>
#include <stream.h>
#ifndef GENERICH
#include <generic.h>
#endif
#ifndef TRUE
#define FALSE 0
#define TRUE (!FALSE)
#endif
#ifndef BIT_DEFINED
#define BIT_DEFINED
typedef int bit;
#endif
#define MAXSUBSTRINGLENGTH 0x7FFF
const MAXSTRINGLENGTH = 0xFFFF-1;
class Rep;
class String;
class SubString;
class Subchar; /* the result of [] */
class Regexp;
struct Charfield;
struct MtRep
{
MtRep *next;
int dummy;
};
const empty_dummy = ~0 << 16 | 0374;
struct Rep
{
char *start; // the characters (NOT null terminated)
unsigned short len;
unsigned char refCount;
unsigned char flags;
bit is_immutable() { return (flags & 02) != 0; }
void immutable() { flags |= 02; }
void mutable() { flags &= ~02; }
bit is_constant() { return (flags & 01) != 0; }
void now_constant() { flags |= 01; }
void not_constant() { flags &= ~01; }
Rep() {}
Rep(const Rep&);
Rep(unsigned);
Rep(const char *, unsigned);
Rep(const char *s) { this = new Rep(s, strlen(s)); }
~Rep();
void refDecr() { if (!is_constant() && --refCount == 0 )
delete this;
}
void refIncr() { if (!is_constant()) ++refCount; }
unsigned length () { return len; }
int compare (const Rep&); /* like strcmp(3C) */
int compare (const char*);
int match(const Rep&); // return first differing position
int match(const char*);
int hashval (); // for use in hash tables, etc.
bit extend(int); // TRUE if the Rep is extended
bit isMt() { return ((MtRep *)this)->dummy == empty_dummy; }
Charfield *myField();
Rep *canCat(int); // returns a new Rep if this can be catenated
Rep *newSub(int offset, int length);
/* the following are from String(3) */
int strchr(char); // position of first occurrence of char
int strrchr(char); // ... last ... (-1 if char not there)
int strpbrk(const Rep&);
int strspn(const Rep&);
int strcspn(const Rep&);
};
// Strings are at the bottom working up, and Reps are at the top working down
struct Charfield
{
Charfield *next;
MtRep *emptyHead; /* of list of free Reps with no space */
Rep *lastRep;
char *field; /* beginning of characters */
char *end; /* ... of data area */
char *firstFree;
int usedSpace;
Charfield();
Charfield(unsigned int);
int compactify(unsigned int); /* return TRUE if no use */
Rep *newRep(unsigned int);
char *getSpace(int); /* new String space for old Rep */
void putMt(MtRep *);
Rep *getMt();
};
extern Rep *nullRep; /* the null String */
extern Rep *oneChar; /* all one-character Strings */
extern Charfield *currfield;
extern char *Memcpy(char *to, const char *from, int);
extern ostream& operator<<(ostream&, Rep&);
class String
{
static GPT handler;
static bit startedUp;
void error(int = 0, char * = 0);
Rep *d;
friend SubString;
friend Subchar;
public:
String();
String(char);
String(char, char);
String(char, char, char);
String(char, char, char, char);
String(const char *);
String(const char *, int);
String(const String& s) { d = s.d; d->refIncr(); }
String(const SubString&);
String(Rep& r) { d = &r; r.refCount++; }
~String() { d->refDecr(); }
friend int stat(const String&, struct stat*);
friend int system(const String&);
friend int access(const String&, int);
friend int acct(const String&);
friend int chdir(const String&);
friend int chmod(const String&, int);
friend int chown(const String&, int, int);
friend int creat(const String&, int);
friend int link(const String&, const String&);
friend int mknod(const String&, int, int);
friend int mount(const String&, const String&, int);
friend int open(const String&, int);
friend int umount(const String&);
friend int unlink(const String&);
friend int read(int, String&, int);
friend int write(int, const String&);
friend FILE* fopen(const String&, const String&);
friend FILE* fdopen(int, const String&);
friend FILE* freopen(const String&, const String&, FILE*);
friend puts(const String&);
friend fputs(const String&, FILE*);
friend inline ostream& operator<<(ostream&, const String&);
friend istream& operator>>(istream&, String&);
friend String sgets(istream&);
friend String operator+(const char, const String&);
friend String operator+(const char*, const String&);
friend Rep;
friend Regexp;
friend void startUp();
unsigned length (){ return d->length(); }
operator void*() { return length() ? this : 0; }
int hashval() { return d->hashval(); }
int compare(const String&); /* like strcmp(3C) */
int compare(const char *p) { return d->compare(p); }
bit operator==(const String& oo) { return compare(oo) == 0; }
bit operator>(const String& oo) { return compare(oo) > 0; }
bit operator>=(const String& oo) { return compare(oo) >= 0; }
bit operator<=(const String& oo) { return compare(oo) <= 0; }
bit operator<(const String& oo) { return compare(oo) < 0; }
bit operator!=(const String& oo) { return compare(oo) != 0; }
bit operator==(const char* p) { return compare(p) == 0; }
bit operator>(const char* p) { return compare(p) > 0; }
bit operator>=(const char* p) { return compare(p) >= 0; }
bit operator<=(const char* p) { return compare(p) <= 0; }
bit operator<(const char* p) { return compare(p) < 0; }
bit operator!=(const char* p) { return compare(p) != 0; }
// match returns the first differing position
int match(const String&);
int match (const char* p) { return d->match(p); }
String operator+(const String&); /* catenate */
String operator+(const char*); /* catenate */
String operator+(const char); /* catenate */
String& operator=(const char);
String& operator=(const char *);
String& operator=(const String& oo);
String& put(const char); /* append or put */
String& put(const String&); /* append or put */
String& operator+=(const char c) { return put(c); }
String& operator+=(const String& oo) { return put(oo); }
bit getX(char&); /* get or lop */
bit get() { char c; return getX(c); }
String& unget(const char); /* prepend */
String& unget(const String&); /* prepend */
bit unputX(char&); /* remove from back */
bit unput() { char c; return unputX(c); }
bit firstX(char&);
bit lastX(char&);
SubString& operator() (const unsigned start, const unsigned length);
Subchar& operator[] (const unsigned); /* character selection */
void dump(char *);
GPT sethandler(GPT);
/* the following are from String(3) */
/* position of first occurrence of char */
int strchr(const char c) { return d->strchr(c); }
/* ... last ... (-1 if char not there) */
int strrchr(const char c) { return d->strrchr(c); }
int strpbrk(const String& oo) { return d->strpbrk(*oo.d); }
int strspn(const String& oo) { return d->strspn(*oo.d); }
int strcspn(const String& oo) { return d->strcspn(*oo.d); }
};
inline bit
operator==(const char* p, const String s)
{
return s.compare(p) == 0;
}
inline bit
operator>(const char* p, const String s)
{
return s < p;
}
inline bit
operator>=(const char* p, const String s)
{
return s >= p;
}
inline bit
operator<=(const char* p, const String s)
{
return s >= p;
}
inline bit
operator<(const char* p, const String s)
{
return s > p;
}
inline bit
operator!=(const char* p, const String s)
{
return s != p;
}
inline ostream&
operator<<(ostream& oo, const String& ss)
{
return oo << *ss.d;
}
class SubString
{
static String *ss;
static int oo;
static int ll;
static GPT handler;
void error(int = 0, char * = 0);
SubString(const SubString&);
SubString(const String &ii, int off, int len) { this = 0;
ss = ⅈ oo = off; ll = len; }
~SubString() { this = 0; }
void operator=(const String&);
public:
GPT sethandler(GPT);
String *it() { return ss; }
int offset() { return oo; }
int length() { return ll; }
};
class Subchar
{
static String *ss;
static int oo; /* position in the String */
static GPT handler;
void error(int = 0, char * = 0);
Subchar(const Subchar&);
Subchar(const String &ii, int off) {
this = 0; ss = ⅈ oo = off; }
~Subchar() { this = 0; }
char operator=(const char);
operator char() { return *(ss->d->start + oo); }
public:
GPT sethandler(GPT);
String *it() { return ss; }
int offset() { return oo; }
};
overload length;
int length(const String&);
inline int length(const String &s) { return s.length(); }
overload hashval;
int hashval(const String&);
inline int hashval(const String &s) { return s.hashval(); }
overload compare;
int compare(const String&,const String&);
inline int compare(const String &s,const String &t) { return s.compare(t); }
overload strchr;
int strchr(const String&, const char);
inline int strchr(const String& s, const char c) { return s.strchr(c); }
overload strrchr;
int strrchr(const String&, const char);
inline int strrchr(const String& s, const char c) { return s.strrchr(c); }
overload strpbrk;
int strpbrk(const String&, const String&);
inline int strpbrk(const String& s, const String& t) { return s.strpbrk(t); }
overload strspn;
int strspn(const String&, const String&);
inline int strspn(const String& s, const String& t) { return s.strspn(t); }
overload strcspn;
int strcspn(const String&, const String&);
inline int strcspn(const String& s, const String& t) { return s.strcspn(t); }
overload min;
int min(int, int);
int min(int, int, int);
inline int min(int i, int j) { return i<j ? i : j; }
inline int min(int i, int j, int k) { return i<j ? min(i,k) : min(j,k); }
#endif