Added regex essignment operator
[AXE.git] / src / String.h
1 /**************************************************************************
2 **  (c) Copyright 1997, Andromeda Technology & Automation
3 ***************************************************************************
4 ** MODULE INFORMATION *
5 ***********************
6 **      FILE NAME      : String.h
7 **      SYSTEM NAME    : Andromeda X-Windows Encapsulation
8 **      VERSION NUMBER : $Revision: 1.6 $
9 **
10 **  DESCRIPTION      :  Character String class definition
11 **
12 **  EXPORTED OBJECTS : class String
13 **  LOCAL    OBJECTS : class substring
14 **  MODULES  USED    :
15 ***************************************************************************
16 **  ADMINISTRATIVE INFORMATION *
17 ********************************
18 **      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
19 **      CREATION DATE   : Nov 17, 1995
20 **      LAST UPDATE     : Nov 02, 2002
21 **      MODIFICATIONS   : 
22 **************************************************************************/
23
24 /*****************************
25    $Log: String.h,v $
26    Revision 1.6  2010-12-30 12:04:02  arjen
27    Added regex assignment operator
28
29    Revision 1.4  2007-05-04 13:56:05  arjen
30    Added a copy contructor to the regex class. This prevents multiple frees in the destructor.
31
32    Revision 1.3  2002/11/03 13:18:57  arjen
33    New functions - String::escape() and String::unescape()
34
35    Revision 1.2  2002/09/28 06:45:51  arjen
36    New feature: subtring selection by regular expression.
37    Bugfix: use the std: namespace for STL classes istream and ostream
38
39    Revision 1.1  2002/07/25 08:01:26  arjen
40    First checkin, AXE release 0.2
41
42 *****************************/
43
44 // static const char RCSID[] = "$Id: String.h,v 1.6 2010-12-30 12:04:02 arjen Exp $";
45
46 #ifndef STRING_H
47 #define STRING_H
48
49 #include <stdlib.h>
50 #include <iostream>
51 #include <string.h>
52
53 #include <regex.h>
54
55 //  Forward declarations.
56 class substring;
57 class regex;
58
59 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
60 **  NAME           : String - Character String class.
61 **  MEMBERS        : p -> s : Pointer to the actual String data.
62 **                   p -> n : Number of references to this String.
63 **  OPERATORS      : =      : Assign a String, char *, char to a String.
64 **                   +, +=  : concatenate Strings
65 **                   ~      : Length of a String
66 **                   []     : Individual character access.
67 **                   !      : Empty String test.
68 **                   ()     : Substring selection.
69 **                   ostream << : String to output stream.
70 **                   istream << : String from input stream.
71 **                   ==, !=, <,
72 **                   >, <=, >= : String comparison.
73 **  METHODS        :
74 **
75 **  DESCRIPTION    : The String class counts the references to a String to
76 **                   minimize copying and uses standard C++ character strings
77 **                   as constants.
78 **
79 **  RELATIONS      : substring
80 **  SEE ALSO       :
81 **  LAST MODIFIED  : Aug 27, 1999
82 **+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
83 */
84
85 class String
86 {
87    friend class substring;
88    friend class regex;
89
90    struct srep
91    {
92       char  *s;    // pointer to data;
93       int    n;    // reference count
94    } *p;
95
96 public:
97
98    String(const char *);      // String x = "abc"
99    String(char);              // String x = 'a'
100    String();                  // String x;
101    String(const String &);    // String x = String ...
102    String(const substring &); // String x = String(s, l)
103
104    String& operator=(const char);
105    String& operator=(const char *);
106    String& operator=(const String &);
107    ~String();
108
109    /*  Numerical conversion */
110
111    String(long);             //  String x(12);  x = "12"
112    String(unsigned long);    //  String x(12);  x = "12"
113    String(int);              //  String x(12);  x = "12"
114    operator long()
115    {
116       return strtol(p->s, 0, 0);
117    }
118
119    operator unsigned long()
120    {
121       return strtoul(p->s, 0, 0);
122    }
123
124    long dec(void)
125    {
126       return strtol(p->s, 0, 10);
127    }
128
129    long oct(void)
130    {
131       return strtol(p->s, 0, 8);
132    }
133
134    long hex(void) 
135    {
136       return strtol(p->s, 0, 16);
137    }
138
139    String(double);
140    operator double()
141    {
142       return strtod(p->s, 0);
143    }
144
145    /*     */
146
147    char& operator[](int i);    //  Individual character access
148
149    int operator~() const      //  Length of the String
150    {
151       return strlen(p->s);
152    }
153
154    operator char*()
155    {
156       if (p->s && p->s[0])
157          return p->s;
158       else
159          return 0;
160    }
161    operator const char*() const
162    {
163       if (p->s && p->s[0])
164          return p->s;
165       else
166          return 0;
167    }
168
169    operator bool()   //  Test for empty String
170    {
171       return p->s != 0 && p->s[0] != '\0';
172    }
173
174    /*
175     *   String concatenation.
176     *   char and char* are handled by constructors.
177     */
178
179    String& operator+=(const String&);
180    String& operator+=(const char *);
181    friend String operator+(const String&, const String&);
182    friend String operator+(const String&, const char *);
183    friend String operator+(const char *,  const String&);
184
185    /*
186     *  Shifting characters out
187     *            "abcdefgh" <<= 3  = "defgh"
188     *            "abcdefgh" >>= 3  = "abcde"
189     */
190
191    friend String operator<<(const String &x, int n);
192    String & operator<<=(int n);
193
194    friend String operator>>(const String &x, int n);
195    String & operator>>=(int n);
196
197    /*
198     *   Substring selection
199     *
200     *   A substring can be selected by a start index and a length or
201     *   by matching a regular expression.
202     *
203     *   Selecting a substring by regular expression, combined with
204     *   the lvalue semantics of the substring class is a particularly
205     *   powerful concept. Possible uses are for example:
206     *
207     *   (assuming String S, M; regex R;)
208     *   M = S(R);             ->  Returns matching part of S into M.
209     *   S(R) = "replacement"; -> replace matching part of S.
210     *   S(R) = "";            -> Removes matching part from S.
211     *   S(R) == S;            -> true if and only if all of S matches R exactly.
212     */
213
214    substring operator()(int start, int len);
215    substring operator()(const regex &r);
216
217    /*
218     *   Input and output
219     */
220
221    friend std::ostream& operator<<(std::ostream &, const String &);
222    friend std::istream& operator>>(std::istream &, String &);
223
224    /*
225     *   String comparison tests
226     */
227
228    friend int operator==(const String& x, const String& y)
229    {
230       return strcmp(x.p->s, y.p->s) == 0;
231    }
232
233    friend int operator!=(const String& x, const String& y)
234    {
235       return strcmp(x.p->s, y.p->s) != 0;
236    }
237
238    friend int operator<=(const String& x, const String& y)
239    {
240       return strcmp(x.p->s, y.p->s) <= 0;
241    }
242
243    friend int operator>=(const String& x, const String& y)
244    {
245       return strcmp(x.p->s, y.p->s) >= 0;
246    }
247
248    friend int operator<(const String& x, const String& y)
249    {
250       return strcmp(x.p->s, y.p->s) < 0;
251    }
252
253    friend int operator>(const String& x, const String& y)
254    {
255       return strcmp(x.p->s, y.p->s) > 0;
256    }
257
258    friend int operator==(const String& x, const char * y)
259    {
260       return strcmp(x.p->s, y) == 0;
261    }
262
263    friend int operator!=(const String& x, const char * y)
264    {
265       return strcmp(x.p->s, y) != 0;
266    }
267
268    friend int operator<=(const String& x, const char * y)
269    {
270       return strcmp(x.p->s, y) <= 0;
271    }
272
273    friend int operator>=(const String& x, const char * y)
274    {
275       return strcmp(x.p->s, y) >= 0;
276    }
277
278    friend int operator<(const String& x, const char * y)
279    {
280       return strcmp(x.p->s, y) < 0;
281    }
282
283    friend int operator>(const String& x, const char * y)
284    {
285       return strcmp(x.p->s, y) > 0;
286    }
287
288    /*
289     *  Modifiers
290     */
291
292    String upper();   //  Convert to upper case (ASCII)
293    String lower();   //  Convert to lower case (ASCII)
294    String escape();   //  Insert backslashes to escape special characters
295    String unescape(); //  Remove backslashes from escape codes.
296
297    /*
298     *  Character searching and Pattern matching
299     */
300
301    int index(char c);
302    int rindex(char c);
303
304    int in(String & x);
305
306    //  Regular expression pattern matching
307  
308    friend bool operator == (const String &s, const regex &r);
309    friend bool operator == (const regex &r, const String &s);
310 };
311    /*
312     *   Other operators to think about...
313     *
314     *
315     *   Numeric conversion with strtod and strtol and vice-versa,
316     *   so we can do:
317     *                 String nr = 123  //  nr = "123"
318     *                 float x = 2.32; String f = x;  // f = "2.32"
319     *                             f = "3.145";
320     *                         int i = f;           // i = 3
321     *
322     *   String matching:
323     *       int index(String&, start=0)  // Find position of substring
324     *
325     *
326     *  Literature:  Bjarne Stroustrup, Section 6.9
327     *               DDJ October 1991, pg 24
328     */
329
330
331 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
332 **  NAME           : substring - Determine part of a String object.
333 **  MEMBERS        : str   : The String object of which this is a substring
334 **                   start : index of the first substring character.
335 **                   len   : Number of characters in the substring
336 **  OPERATORS      : =     : Assignment of a String or char *
337 **  METHODS        :
338 **
339 **  DESCRIPTION    : This implements substring selection from a String object
340 **                   with l-value semantics.
341 **
342 **  RELATIONS      : String
343 **  SEE ALSO       :
344 **  LAST MODIFIED  :
345 **+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
346 */
347
348 class substring
349 {
350    friend class String;
351
352    String     *str;   //  Where I am a substring of.
353    int  start, len;
354
355 public:
356    String& operator=(const String &); 
357    String& operator=(char *s)
358    {
359       *this = String(s);
360       return *str;
361    }
362 };
363
364 /*  Regular expression matching */
365
366 class regex
367 {
368    friend class String;
369
370    regex_t    expression;
371    String     original;
372
373 public:
374
375    regex(const String & reg);
376    regex(const char * reg);
377    regex(const regex & reg);
378    ~regex();
379
380    friend bool operator == (const String &s, const regex &r);
381    friend bool operator == (const regex &r, const String &s);
382 };
383
384 #endif  /* STRING_H */