2 /* This file is part of
3 * ======================================================
5 * LyX, The Document Processor
7 * Copyright (C) 1995 1996 Matthias Ettrich
10 *======================================================*/
12 // This one is heavily based on the string class in The C++
13 // Programming Language by Bjarne Stroustrup
22 #include <config.h> // needed at least for compiler that do not
23 // understand 'explicit' (JMarc)
25 // AIX has strange ideas about where definitions like strcasecmp
32 /** A string class for LyX
34 This is a permanent String class. It was supposed to be superseeded
35 with QString when we switch to the Qt library, but now it's so developed
36 that it is as good as theirs (or maybe even better :-)
40 When you declare an LString, it is initially empty. There is no need to
41 do things like #LString a= "";#, especially not in constructors.
43 If you want to use a default empty LString as a parameter, use
45 #void foo(LString par = LString()); // Correct#
49 #void foo(LString par = ""); // WRONG!#
50 #void foo(LString par = 0); // WRONG!#
52 (The last one is only wrong because some compilers can't handle it.)
54 Methods that take an index as parameter all follow this rule: Valid indexes
55 go from 0 to length()-1.
57 Correct: & #foo.substring(0, length()-1);# \\
58 Wrong: & #bar.substring(0, length());#
61 It is important that you declare LStrings as const if possible, because
62 some methods are much more efficient in const versions.
64 If you want to check whether a string is empty, do
66 #if (foo.empty()) something right#
68 rather than something along the lines of
70 #if (!foo) completely wrong#
72 When you use the #.copy()# method, LString calls "#new []#", so you have to
73 release the memory with #delete[]#. Don't preallocate memory.
75 When you want to copy an LString, just do
77 #LString a, b = "String";#
78 #a = b; // That's it!#
82 #LString a, b = "String";#
83 #a = b.copy(); // This leaks.#
85 The class automatically handles deep copying when required.
89 /**@name Constructors and Deconstructors */
93 /// #LString x(LString ...)#
94 LString(LString const &);
95 /// #LString x("abc")#
98 explicit LString(char const);
99 // not all C++ compilers understands explicit as of now
105 /**@name Operators */
108 LString& operator=(LString const &);
110 LString& operator=(char const *);
112 LString& operator=(char);
115 char& operator[](int);
118 char const& operator[](int) const;
121 LString& operator+=(LString const &);
123 LString& operator+=(char const*);
125 LString& operator+=(char);
127 LString& operator+=(int);
129 LString& operator+=(long);
134 /// to comply with the STL strings
137 //bool isEmpty() const;
139 //bool notEmpty() const;
143 // should be renamed to erase() (STL)
144 /** equivalent to *this = empty. But usable outside LString
148 /// This should be renamed to c_str()
149 char const* c_str() const;
151 // we should make the caller supply the storage to copy into. (STL)
152 /** This one returns a verbatim copy. Only temporary.
153 The caller should call delete [] when done with the string
158 bool contains(char const *) const;
160 // Remove and replace (STL)
161 /// Truncate to substring. I.e. #"abcdef".substring(2,4)="cde"#
162 LString& substring(int i1, int i2);
164 /** Splits the string by the first delim.
165 Splits the string by the first appearance of delim.
166 The leading string up to delim is returned in piece (not including
167 delim), while the original string is cut from after the delimiter.
169 #s1=""; s2="a;bc".split(s1, ';') -> s1=="a"; s2 == "bc";#
171 LString& split(LString& piece, char delim);
172 /// Same as split but does not return a piece
173 LString& split(char delim);
174 /// Same as split but uses the last delim.
175 LString& rsplit(LString& piece, char delim);
177 /** Extracts a token from this string at the nth delim.
178 Doesn't modify the original string. Similar to strtok.
180 #"a;bc;d".token(';', 1) == "bc";#
181 #"a;bc;d".token(';', 2) == "d";#
183 LString token(char delim, int n=0) const;
185 /** Search a token in this string using the delim.
186 Doesn't modify the original string. Returns -1 in case of
189 #"a;bc;d".tokenPos(';', "bc") == 1;#
190 #"a;bc;d".token(';', "d") == 2;#
192 int tokenPos(char delim, LString const &tok);
194 /** Strips characters off the end of a string.
195 #"abccc".strip('c') = "ab".#
197 LString& strip(char const c = ' ');
199 /** Strips characters of the beginning of a string.
200 #"cccba".frontstrip('c') = "ba"#. */
201 LString& frontStrip(char const c = ' ');
203 /// Does the string start with this prefix?
204 bool prefixIs(char const *) const;
206 /// Does the string end with this char?
207 bool suffixIs(char) const;
209 /// Does the string end with this suffix?
210 bool suffixIs(char const *) const;
212 /// Substitute all "oldchar"s with "newchar"
213 LString& subst(char oldchar, char newchar);
215 /// Substitutes all instances of oldstr with newstr
216 LString& subst(char const * oldstr, LString const & newstr);
218 /** Compares a string and a (simple) regular expression
219 The only element allowed is "*" for any string of characters
221 bool regexMatch(LString const & pattern) const;
223 /// Lowercases a string
224 LString& lowercase();
226 /// Counts how many of character c there is in string
227 int countChar(const char c) const;
229 /// Position of the character c from the beggining
230 int charPos(const char c) const;
238 friend bool operator==(LString const &x, char const *s)
241 return x.p->s[0] == '\0';
243 return strcmp(x.p->s, s) == 0;
247 friend bool operator==(LString const &x, LString const &y)
249 return strcmp(x.p->s, y.p->s) == 0;
253 friend bool operator!=(LString const &x, char const *s)
256 return x.p->s[0] != '\0';
258 return strcmp(x.p->s, s) != 0;
262 friend bool operator!=(LString const &x, LString const &y)
264 return strcmp(x.p->s, y.p->s) != 0;
270 /// A string representation
274 /// Reference count (number of references - 1)
276 /// Extra space at end of allocated string
278 /// Data. At least 1 char for trailing null.
281 srep() { n = 0; l = 0; e = 0; s[0] = '\0'; }
284 /** The empty srep is a local static in each function that
285 needs one. There is no "global" empty srep but LString
286 doesn't need one (no code actually relies upon a single
288 This overcomes *all* "static initialization" problems,
289 at maximum speed, with a small overhead of 6 local static
292 // This is the only other option (or a variant of this anyway)
293 // I originally offered this style of empty_rep in 9709 but
294 // it was rejected for requiring too many function calls and pointer operations(!)
295 // and because another implementation was to be trialed (which has since
296 // apparently failed for some compilers). ARRae
297 // static srep& empty_rep()
303 /// A string is a pointer to it's representation
310 inline LString::LString(LString const &x)
317 inline void LString::lose()
324 inline LString::~LString()
330 inline int LString::length() const
336 inline bool LString::empty() const
342 inline int LString::countChar(const char c) const
345 for (int i=0; i < length(); i++)
346 if (operator[](i) == c) n++;
351 inline LString operator+(LString const &x, LString const &y)
359 inline LString operator+(LString const &x, char const &y)
367 inline LString operator+(LString const &x, int const &y)
375 inline LString operator+(LString const &x, long const &y)
382 inline char const* LString::c_str() const
384 return (char const*)p->s;
388 inline int LString::charPos(const char c) const
390 for (int i=0; i < length(); i++) {
391 if (operator[](i) == c) return i;