|
|
researchv10 Norman
#ifndef STRING_DOT_H
#define STRING_DOT_H
#define _const const
#include <sys/types.h>
#include <sys/stat.h>
#ifdef BSD
extern "C" {
extern char* bcopy(const char* from, char* to, int); /* vomit */
extern int bcmp(const char* from, const char* to, int); /* only for == */
}
#define memcpy(t,f,n) bcopy(f,t,n)
#else
extern "C" {
extern char* memcpy(char* to, const char* from, int);
extern int memcmp(const char* to, const char* from, int);
}
#endif
#include <sysent.h>
#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
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); }
#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() _const { return (flags & 02) != 0; }
void immutable() { flags |= 02; }
void mutable() { flags &= ~02; }
bit is_constant() _const { 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 (--refCount == 0 && !is_constant())
delete this;
}
void refIncr() { if (++refCount == 0) now_constant(); }
unsigned length () _const { return len; }
#ifdef BSD
int operator==(const Rep& r) _const { return len == r.len ?
!bcmp(start, r.start, len) : 0; }
int compare(const Rep& r) _const { // bug in case of embedded zero
int i = strncmp(start, r.start, min(len, r.len));
return i ? i : ((int)len - (int)r.len); }
#else
int operator==(const Rep& r) _const { return len == r.len ?
!memcmp(start, r.start, len) : 0; }
int compare(const Rep& r) _const {
int i = memcmp(start, r.start, min(len, r.len));
return i ? i : ((int)len - (int)r.len); }
#endif
int compare (const char*) _const;
int match(const Rep&) _const; // return first differing position
int match(const char*) _const;
int hashval () _const; // for use in hash tables, etc.
bit extend(int); // TRUE if the Rep is extended
bit isMt() _const { return ((MtRep *)this)->dummy == empty_dummy; }
Charfield *myField() _const;
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) _const; // position of first occurrence of char
int strrchr(char) _const; // ... last ... (-1 if char not there)
int strpbrk(const Rep&) _const;
int strspn(const Rep&) _const;
int strcspn(const Rep&) _const;
};
// 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);
inline ostream&
operator<<(ostream& oo, Rep& r)
{
oo.write(r.start, r.len); // ark
return oo; // ark
}
class String
{
static GPT handler;
static bit startedUp;
void error(int = 0, char * = 0) _const;
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 *, unsigned);
String(const String& s) { d = s.d; d->refIncr(); }
String(const SubString&);
String(Rep& r) { d = &r; r.refIncr(); }
~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 open(const String&, int);
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 FILE* popen(const String&, const String&);
friend puts(const String&);
friend fputs(const String&, FILE*);
friend inline ostream& operator<<(ostream&, const String&);
friend istream& operator>>(istream&, String&);
friend String operator+(const char, const String&);
friend String operator+(const char*, const String&);
friend Rep;
friend Regexp;
friend void startUp();
unsigned length () _const { return d->length(); }
operator void*() { return length() ? this : 0; }
int hashval() _const { return d->hashval(); }
int compare(const String& oo) _const { return d == oo.d ? 0 :
d->compare(*oo.d); }
int compare(const char *p) _const { return d->compare(p); }
bit operator==(const String& oo) _const { return d == oo.d ? 1 :
(*d == *oo.d); }
bit operator>(const String& oo) _const { return compare(oo) > 0; }
bit operator>=(const String& oo) _const { return compare(oo) >= 0; }
bit operator<=(const String& oo) _const { return compare(oo) <= 0; }
bit operator<(const String& oo) _const { return compare(oo) < 0; }
bit operator!=(const String& oo) _const { return d == oo.d ? 0 :
!(*d == *oo.d); }
bit operator==(const char* p) _const { return compare(p) == 0; }
bit operator>(const char* p) _const { return compare(p) > 0; }
bit operator>=(const char* p) _const { return compare(p) >= 0; }
bit operator<=(const char* p) _const { return compare(p) <= 0; }
bit operator<(const char* p) _const { return compare(p) < 0; }
bit operator!=(const char* p) _const { return compare(p) != 0; }
// match returns the first differing position
int match(const String& s) _const { return d == s.d ? length() :
d->match(*s.d); }
int match (const char* p) _const { return d->match(p); }
String operator+(const String&) _const; /* catenate */
String operator+(const char*) _const; /* catenate */
String operator+(const char) _const; /* catenate */
String& operator=(const char);
String& operator=(const char *);
String& operator=(const String& oo);
String& put(const char); /* append or put */
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); }
String& operator+=(const char *s) { return put(s); }
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&) _const;
bit lastX(char&) _const;
SubString& operator() (const unsigned start, const unsigned length);
Subchar& operator[] (const unsigned); /* character selection */
void dump(char *) _const;
GPT sethandler(GPT);
/* the following are from String(3) */
/* position of first occurrence of char */
int strchr(const char c) _const { return d->strchr(c); }
/* ... last ... (-1 if char not there) */
int strrchr(const char c) _const { return d->strrchr(c); }
int strpbrk(const String& oo) _const { return d->strpbrk(*oo.d); }
int strspn(const String& oo) _const { return d->strspn(*oo.d); }
int strcspn(const String& oo) _const { 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
{
friend String;
static String *ss;
static int oo;
static int ll;
static GPT handler;
void error(int = 0, char * = 0);
SubString(const SubString&);
SubString(String &ii, int off, int len) { this = 0;
ss = ⅈ oo = off; ll = len; }
~SubString() { this = 0; }
public:
void operator=(const String&);
GPT sethandler(GPT);
String *it() _const { return ss; }
int offset() _const { return oo; }
int length() _const { return ll; }
};
class Subchar
{
friend String;
static String *ss;
static int oo; /* position in the String */
static GPT handler;
void error(int = 0, char * = 0);
Subchar(const Subchar&);
Subchar(String &ii, int off) {
this = 0; ss = ⅈ oo = off; }
~Subchar() { this = 0; }
public:
char operator=(const char);
operator char() { return *(ss->d->start + oo); }
GPT sethandler(GPT);
String *it() { return ss; }
int offset() { return oo; }
};
inline int length(const String &s) { return s.length(); }
inline int hashval(const String &s) { return s.hashval(); }
inline int compare(const String &s,const String &t) { return s.compare(t); }
inline int strchr(const String& s, const char c) { return s.strchr(c); }
inline int strrchr(const String& s, const char c) { return s.strrchr(c); }
inline int strpbrk(const String& s, const String& t) { return s.strpbrk(t); }
inline int strspn(const String& s, const String& t) { return s.strspn(t); }
inline int strcspn(const String& s, const String& t) { return s.strcspn(t); }
String sgets(istream&);
int fgets(String&, int, FILE*);
int gets(String&);
#endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.