|
|
1.1 root 1: #ifndef STRING_DOT_H
2: #define STRING_DOT_H
3:
4: #include <sys/types.h>
5: #include <sys/stat.h>
6:
7: #ifdef BSD
8: extern "C" {
9: extern char* bcopy(const char* from, char* to, int); /* vomit */
10: extern int bcmp(const char* from, const char* to, int); /* only for == */
11: }
12: #define memcpy(t,f,n) bcopy(f,t,n)
13: #else
14: extern "C" {
15: extern char* memcpy(char* to, const char* from, int);
16: extern int memcmp(const char* to, const char* from, int);
17: }
18: #endif
19:
20: #include <sysent.h>
21: #include <string.h>
22: #include <stream.h>
23:
24: #ifndef GENERICH
25: #include <generic.h>
26: #endif
27:
28: #ifndef TRUE
29: #define FALSE 0
30: #define TRUE (!FALSE)
31: #endif
32:
33: #ifndef BIT_DEFINED
34: #define BIT_DEFINED
35: typedef int bit;
36: #endif
37:
38: inline int min(int i, int j) { return i<j ? i : j; }
39: inline int min(int i, int j, int k) { return i<j ? min(i,k) : min(j,k); }
40:
41: #define MAXSUBSTRINGLENGTH 0x7FFF
42: const MAXSTRINGLENGTH = 0xFFFF-1;
43:
44: class Rep;
45: class String;
46: class SubString;
47: class Subchar; /* the result of [] */
48: class Regexp;
49:
50: struct Charfield;
51:
52: struct MtRep
53: {
54: MtRep *next;
55: int dummy;
56: };
57:
58: const empty_dummy = ~0 << 16 | 0374;
59:
60: struct Rep
61: {
62: char *start; // the characters (NOT null terminated)
63: unsigned short len;
64: unsigned char refCount;
65: unsigned char flags;
66: bit is_immutable() { return (flags & 02) != 0; }
67: void immutable() { flags |= 02; }
68: void mutable() { flags &= ~02; }
69: bit is_constant() { return (flags & 01) != 0; }
70: void now_constant() { flags |= 01; }
71: void not_constant() { flags &= ~01; }
72: Rep() {}
73: Rep(const Rep&);
74: Rep(unsigned);
75: Rep(const char *, unsigned);
76: Rep(const char *s) { this = new Rep(s, strlen(s)); }
77: ~Rep();
78: void refDecr() { if (--refCount == 0 && !is_constant())
79: delete this;
80: }
81: void refIncr() { if (++refCount == 0) now_constant(); }
82: unsigned length () { return len; }
83: #ifdef BSD
84: int operator==(const Rep& r) { return len == r.len ?
85: !bcmp(start, r.start, len) : 0; }
86: int compare(const Rep& r) { // bug in case of embedded zero
87: int i = strncmp(start, r.start, min(len, r.len));
88: return i ? i : ((int)len - (int)r.len); }
89: #else
90: int operator==(const Rep& r) { return len == r.len ?
91: !memcmp(start, r.start, len) : 0; }
92: int compare(const Rep& r) {
93: int i = memcmp(start, r.start, min(len, r.len));
94: return i ? i : ((int)len - (int)r.len); }
95: #endif
96: int compare (const char*);
97: int match(const Rep&); // return first differing position
98: int match(const char*);
99: int hashval (); // for use in hash tables, etc.
100: bit extend(int); // TRUE if the Rep is extended
101: bit isMt() { return ((MtRep *)this)->dummy == empty_dummy; }
102: Charfield *myField();
103: Rep *canCat(int); // returns a new Rep if this can be catenated
104: Rep *newSub(int offset, int length);
105: /* the following are from String(3) */
106: int strchr(char); // position of first occurrence of char
107: int strrchr(char); // ... last ... (-1 if char not there)
108: int strpbrk(const Rep&);
109: int strspn(const Rep&);
110: int strcspn(const Rep&);
111: };
112:
113: // Strings are at the bottom working up, and Reps are at the top working down
114: struct Charfield
115: {
116: Charfield *next;
117: MtRep *emptyHead; /* of list of free Reps with no space */
118: Rep *lastRep;
119: char *field; /* beginning of characters */
120: char *end; /* ... of data area */
121: char *firstFree;
122: int usedSpace;
123: Charfield();
124: Charfield(unsigned int);
125: int compactify(unsigned int); /* return TRUE if no use */
126: Rep *newRep(unsigned int);
127: char *getSpace(int); /* new String space for old Rep */
128: void putMt(MtRep *);
129: Rep *getMt();
130: };
131:
132: extern Rep *nullRep; /* the null String */
133: extern Rep *oneChar; /* all one-character Strings */
134: extern Charfield *currfield;
135:
136: extern char *Memcpy(char *to, const char *from, int);
137:
138: inline ostream&
139: operator<<(ostream& oo, Rep& r)
140: {
141: oo.write(r.start, r.len); // ark
142: return oo; // ark
143: }
144:
145: class String
146: {
147: static GPT handler;
148: static bit startedUp;
149: void error(int = 0, char * = 0);
150: Rep *d;
151: friend SubString;
152: friend Subchar;
153: public:
154: String();
155: String(char);
156: String(char, char);
157: String(char, char, char);
158: String(char, char, char, char);
159: String(const char *);
160: String(const char *, unsigned);
161: String(const String& s) { d = s.d; d->refIncr(); }
162: String(const SubString&);
163: String(Rep& r) { d = &r; r.refIncr(); }
164: ~String() { d->refDecr(); }
165: friend int fstat(const String&, stat*);
166: friend int system(const String&);
167: friend int access(const String&, int);
168: friend int acct(const String&);
169: friend int chdir(const String&);
170: friend int chmod(const String&, int);
171: friend int chown(const String&, int, int);
172: friend int creat(const String&, int);
173: friend int link(const String&, const String&);
174: friend int mknod(const String&, int, int);
175: friend int mount(const String&, const String&, int);
176: friend int open(const String&, int);
177: friend int umount(const String&);
178: friend int unlink(const String&);
179: friend int read(int, String&, int);
180: friend int write(int, const String&);
181: friend FILE* fopen(const String&, const String&);
182: friend FILE* fdopen(int, const String&);
183: friend FILE* freopen(const String&, const String&, FILE*);
184: friend FILE* popen(const String&, const String&);
185: friend puts(const String&);
186: friend fputs(const String&, FILE*);
187: friend inline ostream& operator<<(ostream&, const String&);
188: friend istream& operator>>(istream&, String&);
189: friend String operator+(const char, const String&);
190: friend String operator+(const char*, const String&);
191: friend Rep;
192: friend Regexp;
193: friend void startUp();
194: unsigned length (){ return d->length(); }
195: operator void*() { return length() ? this : 0; }
196: int hashval() { return d->hashval(); }
197: int compare(const String& oo) { return d == oo.d ? 0 :
198: d->compare(*oo.d); }
199: int compare(const char *p) { return d->compare(p); }
200: bit operator==(const String& oo) { return d == oo.d ? 1 :
201: (*d == *oo.d); }
202: bit operator>(const String& oo) { return compare(oo) > 0; }
203: bit operator>=(const String& oo) { return compare(oo) >= 0; }
204: bit operator<=(const String& oo) { return compare(oo) <= 0; }
205: bit operator<(const String& oo) { return compare(oo) < 0; }
206: bit operator!=(const String& oo) { return d == oo.d ? 0 :
207: !(*d == *oo.d); }
208: bit operator==(const char* p) { return compare(p) == 0; }
209: bit operator>(const char* p) { return compare(p) > 0; }
210: bit operator>=(const char* p) { return compare(p) >= 0; }
211: bit operator<=(const char* p) { return compare(p) <= 0; }
212: bit operator<(const char* p) { return compare(p) < 0; }
213: bit operator!=(const char* p) { return compare(p) != 0; }
214: // match returns the first differing position
215: int match(const String& s) { return d == s.d ? length() :
216: d->match(*s.d); }
217: int match (const char* p) { return d->match(p); }
218: String operator+(const String&); /* catenate */
219: String operator+(const char*); /* catenate */
220: String operator+(const char); /* catenate */
221: String& operator=(const char);
222: String& operator=(const char *);
223: String& operator=(const String& oo);
224: String& put(const char); /* append or put */
225: String& put(const char*); /* append or put */
226: String& put(const String&); /* append or put */
227: String& operator+=(const char c) { return put(c); }
228: String& operator+=(const String& oo) { return put(oo); }
229: String& operator+=(const char *s) { return put(s); }
230: bit getX(char&); /* get or lop */
231: bit get() { char c; return getX(c); }
232: String& unget(const char); /* prepend */
233: String& unget(const String&); /* prepend */
234: bit unputX(char&); /* remove from back */
235: bit unput() { char c; return unputX(c); }
236: bit firstX(char&);
237: bit lastX(char&);
238: SubString& operator() (const unsigned start, const unsigned length);
239: Subchar& operator[] (const unsigned); /* character selection */
240: void dump(char *);
241: GPT sethandler(GPT);
242: /* the following are from String(3) */
243: /* position of first occurrence of char */
244: int strchr(const char c) { return d->strchr(c); }
245: /* ... last ... (-1 if char not there) */
246: int strrchr(const char c) { return d->strrchr(c); }
247: int strpbrk(const String& oo) { return d->strpbrk(*oo.d); }
248: int strspn(const String& oo) { return d->strspn(*oo.d); }
249: int strcspn(const String& oo) { return d->strcspn(*oo.d); }
250: };
251:
252: inline bit
253: operator==(const char* p, const String& s)
254: {
255: return s.compare(p) == 0;
256: }
257: inline bit
258: operator>(const char* p, const String& s)
259: {
260: return s < p;
261: }
262: inline bit
263: operator>=(const char* p, const String& s)
264: {
265: return s >= p;
266: }
267: inline bit
268: operator<=(const char* p, const String& s)
269: {
270: return s >= p;
271: }
272: inline bit
273: operator<(const char* p, const String& s)
274: {
275: return s > p;
276: }
277: inline bit
278: operator!=(const char* p, const String& s)
279: {
280: return s != p;
281: }
282:
283: inline ostream&
284: operator<<(ostream& oo, const String& ss)
285: {
286: return oo << *ss.d;
287: }
288:
289: class SubString
290: {
291: friend String;
292: static String *ss;
293: static int oo;
294: static int ll;
295: static GPT handler;
296: void error(int = 0, char * = 0);
297: SubString(const SubString&);
298: SubString(String &ii, int off, int len) { this = 0;
299: ss = ⅈ oo = off; ll = len; }
300: ~SubString() { this = 0; }
301: public:
302: void operator=(const String&);
303: GPT sethandler(GPT);
304: String *it() { return ss; }
305: int offset() { return oo; }
306: int length() { return ll; }
307: };
308:
309: class Subchar
310: {
311: friend String;
312: static String *ss;
313: static int oo; /* position in the String */
314: static GPT handler;
315: void error(int = 0, char * = 0);
316: Subchar(const Subchar&);
317: Subchar(String &ii, int off) {
318: this = 0; ss = ⅈ oo = off; }
319: ~Subchar() { this = 0; }
320: public:
321: char operator=(const char);
322: operator char() { return *(ss->d->start + oo); }
323: GPT sethandler(GPT);
324: String *it() { return ss; }
325: int offset() { return oo; }
326: };
327:
328: inline int length(const String &s) { return s.length(); }
329: inline int hashval(const String &s) { return s.hashval(); }
330: inline int compare(const String &s,const String &t) { return s.compare(t); }
331: inline int strchr(const String& s, const char c) { return s.strchr(c); }
332: inline int strrchr(const String& s, const char c) { return s.strrchr(c); }
333: inline int strpbrk(const String& s, const String& t) { return s.strpbrk(t); }
334: inline int strspn(const String& s, const String& t) { return s.strspn(t); }
335: inline int strcspn(const String& s, const String& t) { return s.strcspn(t); }
336:
337: String sgets(istream&);
338: int fgets(String&, int, FILE*);
339: int gets(String&);
340: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.