|
|
1.1 root 1: #ifndef STRING_DOT_H
2: #define STRING_DOT_H
3:
4: #define _const const
5:
6: #include <sys/types.h>
7: #include <sys/stat.h>
8:
9: #ifdef BSD
10: extern "C" {
11: extern char* bcopy(const char* from, char* to, int); /* vomit */
12: extern int bcmp(const char* from, const char* to, int); /* only for == */
13: }
14: #define memcpy(t,f,n) bcopy(f,t,n)
15: #else
16: extern "C" {
17: extern char* memcpy(char* to, const char* from, int);
18: extern int memcmp(const char* to, const char* from, int);
19: }
20: #endif
21:
22: #include <sysent.h>
23: #include <string.h>
24: #include <stream.h>
25:
26: #ifndef GENERICH
27: #include <generic.h>
28: #endif
29:
30: #ifndef TRUE
31: #define FALSE 0
32: #define TRUE (!FALSE)
33: #endif
34:
35: #ifndef BIT_DEFINED
36: #define BIT_DEFINED
37: typedef int bit;
38: #endif
39:
40: inline int min(int i, int j) { return i<j ? i : j; }
41: inline int min(int i, int j, int k) { return i<j ? min(i,k) : min(j,k); }
42:
43: #define MAXSUBSTRINGLENGTH 0x7FFF
44: const MAXSTRINGLENGTH = 0xFFFF-1;
45:
46: class Rep;
47: class String;
48: class SubString;
49: class Subchar; /* the result of [] */
50: class Regexp;
51:
52: struct Charfield;
53:
54: struct MtRep
55: {
56: MtRep *next;
57: int dummy;
58: };
59:
60: const empty_dummy = ~0 << 16 | 0374;
61:
62: struct Rep
63: {
64: char *start; // the characters (NOT null terminated)
65: unsigned short len;
66: unsigned char refCount;
67: unsigned char flags;
68: bit is_immutable() _const { return (flags & 02) != 0; }
69: void immutable() { flags |= 02; }
70: void mutable() { flags &= ~02; }
71: bit is_constant() _const { return (flags & 01) != 0; }
72: void now_constant() { flags |= 01; }
73: void not_constant() { flags &= ~01; }
74: Rep() {}
75: Rep(const Rep&);
76: Rep(unsigned);
77: Rep(const char *, unsigned);
78: Rep(const char *s) { this = new Rep(s, strlen(s)); }
79: ~Rep();
80: void refDecr() { if (--refCount == 0 && !is_constant())
81: delete this;
82: }
83: void refIncr() { if (++refCount == 0) now_constant(); }
84: unsigned length () _const { return len; }
85: #ifdef BSD
86: int operator==(const Rep& r) _const { return len == r.len ?
87: !bcmp(start, r.start, len) : 0; }
88: int compare(const Rep& r) _const { // bug in case of embedded zero
89: int i = strncmp(start, r.start, min(len, r.len));
90: return i ? i : ((int)len - (int)r.len); }
91: #else
92: int operator==(const Rep& r) _const { return len == r.len ?
93: !memcmp(start, r.start, len) : 0; }
94: int compare(const Rep& r) _const {
95: int i = memcmp(start, r.start, min(len, r.len));
96: return i ? i : ((int)len - (int)r.len); }
97: #endif
98: int compare (const char*) _const;
99: int match(const Rep&) _const; // return first differing position
100: int match(const char*) _const;
101: int hashval () _const; // for use in hash tables, etc.
102: bit extend(int); // TRUE if the Rep is extended
103: bit isMt() _const { return ((MtRep *)this)->dummy == empty_dummy; }
104: Charfield *myField() _const;
105: Rep *canCat(int); // returns a new Rep if this can be catenated
106: Rep *newSub(int offset, int length);
107: /* the following are from String(3) */
108: int strchr(char) _const; // position of first occurrence of char
109: int strrchr(char) _const; // ... last ... (-1 if char not there)
110: int strpbrk(const Rep&) _const;
111: int strspn(const Rep&) _const;
112: int strcspn(const Rep&) _const;
113: };
114:
115: // Strings are at the bottom working up, and Reps are at the top working down
116: struct Charfield
117: {
118: Charfield *next;
119: MtRep *emptyHead; /* of list of free Reps with no space */
120: Rep *lastRep;
121: char *field; /* beginning of characters */
122: char *end; /* ... of data area */
123: char *firstFree;
124: int usedSpace;
125: Charfield();
126: Charfield(unsigned int);
127: int compactify(unsigned int); /* return TRUE if no use */
128: Rep *newRep(unsigned int);
129: char *getSpace(int); /* new String space for old Rep */
130: void putMt(MtRep *);
131: Rep *getMt();
132: };
133:
134: extern Rep *nullRep; /* the null String */
135: extern Rep *oneChar; /* all one-character Strings */
136: extern Charfield *currfield;
137:
138: extern char *Memcpy(char *to, const char *from, int);
139:
140: inline ostream&
141: operator<<(ostream& oo, Rep& r)
142: {
143: oo.write(r.start, r.len); // ark
144: return oo; // ark
145: }
146:
147: class String
148: {
149: static GPT handler;
150: static bit startedUp;
151: void error(int = 0, char * = 0) _const;
152: Rep *d;
153: friend SubString;
154: friend Subchar;
155: public:
156: String();
157: String(char);
158: String(char, char);
159: String(char, char, char);
160: String(char, char, char, char);
161: String(const char *);
162: String(const char *, unsigned);
163: String(const String& s) { d = s.d; d->refIncr(); }
164: String(const SubString&);
165: String(Rep& r) { d = &r; r.refIncr(); }
166: ~String() { d->refDecr(); }
167: friend int stat(const String&, struct stat*);
168: friend int system(const String&);
169: friend int access(const String&, int);
170: friend int acct(const String&);
171: friend int chdir(const String&);
172: friend int chmod(const String&, int);
173: friend int chown(const String&, int, int);
174: friend int creat(const String&, int);
175: friend int link(const String&, const String&);
176: friend int mknod(const String&, int, int);
177: friend int open(const String&, int);
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 () _const { return d->length(); }
195: operator void*() { return length() ? this : 0; }
196: int hashval() _const { return d->hashval(); }
197: int compare(const String& oo) _const { return d == oo.d ? 0 :
198: d->compare(*oo.d); }
199: int compare(const char *p) _const { return d->compare(p); }
200: bit operator==(const String& oo) _const { return d == oo.d ? 1 :
201: (*d == *oo.d); }
202: bit operator>(const String& oo) _const { return compare(oo) > 0; }
203: bit operator>=(const String& oo) _const { return compare(oo) >= 0; }
204: bit operator<=(const String& oo) _const { return compare(oo) <= 0; }
205: bit operator<(const String& oo) _const { return compare(oo) < 0; }
206: bit operator!=(const String& oo) _const { return d == oo.d ? 0 :
207: !(*d == *oo.d); }
208: bit operator==(const char* p) _const { return compare(p) == 0; }
209: bit operator>(const char* p) _const { return compare(p) > 0; }
210: bit operator>=(const char* p) _const { return compare(p) >= 0; }
211: bit operator<=(const char* p) _const { return compare(p) <= 0; }
212: bit operator<(const char* p) _const { return compare(p) < 0; }
213: bit operator!=(const char* p) _const { return compare(p) != 0; }
214: // match returns the first differing position
215: int match(const String& s) _const { return d == s.d ? length() :
216: d->match(*s.d); }
217: int match (const char* p) _const { return d->match(p); }
218: String operator+(const String&) _const; /* catenate */
219: String operator+(const char*) _const; /* catenate */
220: String operator+(const char) _const; /* 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&) _const;
237: bit lastX(char&) _const;
238: SubString& operator() (const unsigned start, const unsigned length);
239: Subchar& operator[] (const unsigned); /* character selection */
240: void dump(char *) _const;
241: GPT sethandler(GPT);
242: /* the following are from String(3) */
243: /* position of first occurrence of char */
244: int strchr(const char c) _const { return d->strchr(c); }
245: /* ... last ... (-1 if char not there) */
246: int strrchr(const char c) _const { return d->strrchr(c); }
247: int strpbrk(const String& oo) _const { return d->strpbrk(*oo.d); }
248: int strspn(const String& oo) _const { return d->strspn(*oo.d); }
249: int strcspn(const String& oo) _const { 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() _const { return ss; }
305: int offset() _const { return oo; }
306: int length() _const { 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.