NEURON
string.cpp
Go to the documentation of this file.
1 #ifdef HAVE_CONFIG_H
2 #include <../../nrnconf.h>
3 #endif
4 /*
5  * Copyright (c) 1987, 1988, 1989, 1990, 1991 Stanford University
6  * Copyright (c) 1991 Silicon Graphics, Inc.
7  *
8  * Permission to use, copy, modify, distribute, and sell this software and
9  * its documentation for any purpose is hereby granted without fee, provided
10  * that (i) the above copyright notices and this permission notice appear in
11  * all copies of the software and related documentation, and (ii) the names of
12  * Stanford and Silicon Graphics may not be used in any advertising or
13  * publicity relating to the software without the specific, prior written
14  * permission of Stanford and Silicon Graphics.
15  *
16  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * IN NO EVENT SHALL STANFORD OR SILICON GRAPHICS BE LIABLE FOR
21  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
22  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
23  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
24  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
25  * OF THIS SOFTWARE.
26  */
27 
28 #include <OS/string.h>
29 #include <ctype.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 /*
34  * Just to be sure ...
35  */
36 
37 /* fails on mac osx
38 extern "C" {
39 #if !MAC
40 #ifndef tolower
41  extern int tolower(int);
42 #endif
43 #ifndef toupper
44  extern int toupper(int);
45 #endif
46 #endif
47  extern long int strtol(const char*, char**, int);
48  extern double strtod(const char*, char**);
49 }
50 */
51 
53  data_ = nil;
54  length_ = 0;
55 }
56 
57 String::String(const char* s) {
58  data_ = s;
59  length_ = strlen(s);
60 }
61 
62 String::String(const char* s, int n) {
63  data_ = s;
64  length_ = n;
65 }
66 
68  data_ = s.data_;
69  length_ = s.length_;
70 }
71 
73 
74 unsigned long String::hash() const {
75  const char* p;
76  unsigned long v = 0;
77  if (length_ == -1) {
78  for (p = data_; *p != '\0'; p++) {
79  v = (v << 1) ^ (*p);
80  }
81  String* s = (String*)this;
82  s->length_ = p - data_;
83  } else {
84  const char* q = &data_[length_];
85  for (p = data_; p < q; p++) {
86  v = (v << 1) ^ (*p);
87  }
88  }
89  unsigned long t = v >> 10;
90  t ^= (t >> 10);
91  return v ^ t;
92 }
93 
95  data_ = s.data_;
96  length_ = s.length_;
97  return *this;
98 }
99 
100 String& String::operator =(const char* s) {
101  data_ = s;
102  length_ = strlen(s);
103  return *this;
104 }
105 
106 bool String::operator ==(const String& s) const {
107  return (length_ == s.length_) && (strncmp(data_, s.data_, length_) == 0);
108 }
109 
110 bool String::operator ==(const char* s) const {
111  return (strncmp(data_, s, length_) == 0) && (s[length_] == '\0');
112 }
113 
114 bool String::operator !=(const String& s) const {
115  return (length_ != s.length_) || (strncmp(data_, s.data_, length_) != 0);
116 }
117 
118 bool String::operator !=(const char* s) const {
119  return (strncmp(data_, s, length_) != 0) || (s[length_] != '\0');
120 }
121 
122 bool String::operator >(const String& s) const {
123  return strncmp(data_, s.data_, length_) > 0;
124 }
125 
126 bool String::operator >(const char* s) const {
127  return strncmp(data_, s, length_) > 0;
128 }
129 
130 bool String::operator >=(const String& s) const {
131  return strncmp(data_, s.data_, length_) >= 0;
132 }
133 
134 bool String::operator >=(const char* s) const {
135  return strncmp(data_, s, length_) >= 0;
136 }
137 
138 bool String::operator <(const String& s) const {
139  return strncmp(data_, s.data_, length_) < 0;
140 }
141 
142 bool String::operator <(const char* s) const {
143  return strncmp(data_, s, length_) < 0;
144 }
145 
146 bool String::operator <=(const String& s) const {
147  return strncmp(data_, s.data_, length_) <= 0;
148 }
149 
150 bool String::operator <=(const char* s) const {
151  return strncmp(data_, s, length_) <= 0;
152 }
153 
155  if (length() != s.length()) {
156  return false;
157  }
158  const char* p = string();
159  const char* p2 = s.string();
160  const char* q = p + length();
161  for (; p < q; p++, p2++) {
162  int c1 = *p;
163  int c2 = *p2;
164  if (c1 != c2 && tolower(c1) != tolower(c2)) {
165  return false;
166  }
167  }
168  return true;
169 }
170 
171 bool String::case_insensitive_equal(const char* s) const {
172  return case_insensitive_equal(String(s));
173 }
174 
175 /*
176  * A negative value for start initializes the position at the end
177  * of the string before indexing. Any negative length makes
178  * the substring extend to the end of the string.
179  */
180 
181 String String::substr(int start, int length) const {
182  if (start >= length_ || start < -length_) {
183  /* should raise exception */
184  return String("");
185  }
186  int pos = (start >= 0) ? start : (length_ + start);
187  if (pos + length > length_) {
188  /* should raise exception */
189  return String("");
190  }
191  int len = (length >= 0) ? length : (length_ - pos);
192  return String(data_ + pos, len);
193 }
194 
195 void String::set_to_substr(int start, int length) {
196  if (start > length_ || start < -length_) {
197  /* should raise exception */
198  return;
199  }
200  int pos = (start >= 0) ? start : (length_ + start);
201  if (pos + length > length_) {
202  /* should raise exception */
203  return;
204  }
205  int len = (length >= 0) ? length : (length_ - pos);
206  data_ += pos;
207  length_ = len;
208 }
209 
210 bool String::null_terminated() const { return false; }
211 
212 void String::set_value(const char* s) {
213  data_ = s;
214  length_ = strlen(s);
215 }
216 
217 void String::set_value(const char* s, int len) {
218  data_ = s;
219  length_ = len;
220 }
221 
222 /*
223  * A negative value for start initializes the position to the end
224  * of the string before indexing and searches right-to-left.
225  */
226 
227 int String::search(int start, u_char c) const {
228  if (start >= length_ || start < -length_) {
229  /* should raise exception */
230  return -1;
231  }
232  if (start >= 0) {
233  const char* end = data_ + length_;
234  for (const char* p = data_ + start; p < end; p++) {
235  if (*p == c) {
236  return p - data_;
237  }
238  }
239  } else {
240  for (const char* p = data_ + length_ + start; p >= data_; p--) {
241  if (*p == c) {
242  return p - data_;
243  }
244  }
245  }
246  return -1;
247 }
248 
249 /*
250  * Convert a string to binary value.
251  */
252 
253 bool String::convert(int& value) const {
254  NullTerminatedString s(*this);
255  const char* str = s.string();
256  char* ptr;
257  value = (int)strtol(str, &ptr, 0);
258  return ptr != str;
259 }
260 
261 bool String::convert(long& value) const {
262  NullTerminatedString s(*this);
263  const char* str = s.string();
264  char* ptr;
265  value = strtol(str, &ptr, 0);
266  return ptr != str;
267 }
268 
269 bool String::convert(float& value) const {
270  NullTerminatedString s(*this);
271  const char* str = s.string();
272  char* ptr;
273  value = (float)strtod(str, &ptr);
274  return ptr != str;
275 }
276 
277 bool String::convert(double& value) const {
278  NullTerminatedString s(*this);
279  const char* str = s.string();
280  char* ptr;
281  value = strtod(str, &ptr);
282  return ptr != str;
283 }
284 
285 /* class CopyString */
286 
288 
289 CopyString::CopyString(const char* s) : String() {
290  set_value(s);
291 }
292 
293 CopyString::CopyString(const char* s, int length) : String() {
294  set_value(s, length);
295 }
296 
298  set_value(s.string(), s.length());
299 }
300 
302  set_value(s.string(), s.length());
303 }
304 
306  strfree();
307 }
308 
310  strfree();
311  set_value(s.string(), s.length());
312  return *this;
313 }
314 
316  strfree();
317  set_value(s.string(), s.length());
318  return *this;
319 }
320 
322  strfree();
323  set_value(s);
324  return *this;
325 }
326 
327 bool CopyString::null_terminated() const { return true; }
328 
329 void CopyString::set_value(const char* s) {
330  set_value(s, strlen(s));
331 }
332 
333 /*
334  * Guarantee null-terminated string for compatibility with printf et al.
335  */
336 
337 void CopyString::set_value(const char* s, int len) {
338  char* ns = new char[len + 1];
339  ns[len] = '\0';
340  String::set_value(strncpy(ns, s, len), len);
341 }
342 
344  char* s = (char*)(string());
345  delete [] s;
346 }
347 
348 /*
349  * class NullTerminatedString
350  */
351 
353  allocated_ = false;
354 }
355 
357  assign(s);
358 }
359 
361  const NullTerminatedString& s
362 ) : String() {
363  allocated_ = false;
364  String::set_value(s.string(), s.length());
365 }
366 
368  strfree();
369 }
370 
372  strfree();
373  assign(s);
374  return *this;
375 }
376 
378  strfree();
379  allocated_ = false;
380  String::set_value(s, strlen(s));
381  return *this;
382 }
383 
384 bool NullTerminatedString::null_terminated() const { return true; }
385 
387  if (s.null_terminated()) {
388  allocated_ = false;
389  String::set_value(s.string(), s.length());
390  } else {
391  allocated_ = true;
392  int len = s.length();
393  char* ns = new char[len + 1];
394  ns[len] = '\0';
395  String::set_value(strncpy(ns, s.string(), len), len);
396  }
397 }
398 
400  if (allocated_) {
401  char* s = (char*)(string());
402  delete [] s;
403  allocated_ = false;
404  }
405 }
#define nil
Definition: enter-scope.h:36
unsigned char u_char
Definition: enter-scope.h:42
virtual String & operator=(const CopyString &)
Definition: string.cpp:309
virtual ~CopyString()
Definition: string.cpp:305
CopyString()
Definition: string.cpp:287
virtual bool null_terminated() const
Definition: string.cpp:327
virtual void set_value(const char *)
Definition: string.cpp:329
void strfree()
Definition: string.cpp:343
virtual String & operator=(const String &)
Definition: string.cpp:371
virtual ~NullTerminatedString()
Definition: string.cpp:367
void assign(const String &)
Definition: string.cpp:386
virtual bool null_terminated() const
Definition: string.cpp:384
Definition: string.h:34
virtual unsigned long hash() const
Definition: string.cpp:74
virtual int search(int start, u_char) const
Definition: string.cpp:227
const char * string() const
Definition: string.h:139
virtual bool null_terminated() const
Definition: string.cpp:210
virtual String substr(int start, int length) const
Definition: string.cpp:181
virtual bool operator==(const String &) const
Definition: string.cpp:106
virtual bool operator>=(const String &) const
Definition: string.cpp:130
virtual bool convert(int &) const
Definition: string.cpp:253
virtual bool operator>(const String &) const
Definition: string.cpp:122
int length() const
Definition: string.h:140
const char * data_
Definition: string.h:90
String()
Definition: string.cpp:52
virtual bool operator!=(const String &) const
Definition: string.cpp:114
virtual String & operator=(const String &)
Definition: string.cpp:94
virtual bool operator<(const String &) const
Definition: string.cpp:138
virtual void set_value(const char *)
Definition: string.cpp:212
int length_
Definition: string.h:91
virtual bool operator<=(const String &) const
Definition: string.cpp:146
virtual ~String()
Definition: string.cpp:72
virtual void set_to_substr(int start, int length)
Definition: string.cpp:195
virtual bool case_insensitive_equal(const String &) const
Definition: string.cpp:154
double t
Definition: cvodeobj.cpp:59
#define c
void start()
Definition: hel2mos.cpp:204
#define v
Definition: md1redef.h:4
int const size_t const size_t n
Definition: nrngsl.h:11
size_t q
size_t p
static uint32_t value
Definition: scoprand.cpp:25