11// This file is part of SmallBASIC
22//
3- // Copyright(C) 2001-2014 Chris Warren-Smith.
3+ // Copyright(C) 2001-2019 Chris Warren-Smith.
44//
55// This program is distributed under the terms of the GPL v2.0 or later
66// Download the GNU Public License (GPL) from www.gnu.org
@@ -15,29 +15,29 @@ using namespace strlib;
1515
1616// --String----------------------------------------------------------------------
1717
18- String::String () : _buffer(NULL ) {
18+ String::String () : _buffer(nullptr ) {
1919}
2020
2121String::String (const char *s) {
22- _buffer = (s == NULL ? NULL : strdup (s));
22+ _buffer = (s == nullptr ? nullptr : strdup (s));
2323}
2424
2525String::String (const String &s) {
26- _buffer = s._buffer == NULL ? NULL : strdup (s._buffer );
26+ _buffer = s._buffer == nullptr ? nullptr : strdup (s._buffer );
2727}
2828
29- String::String (const char *s, int len) : _buffer(NULL ) {
29+ String::String (const char *s, int len) : _buffer(nullptr ) {
3030 append (s, len);
3131}
3232
3333String::~String () {
3434 free (_buffer);
35- _buffer = NULL ;
35+ _buffer = nullptr ;
3636}
3737
3838const String &String::operator =(const String &s) {
3939 clear ();
40- if (_buffer != s._buffer && s._buffer != NULL ) {
40+ if (_buffer != s._buffer && s._buffer != nullptr ) {
4141 _buffer = strdup (s._buffer );
4242 }
4343 return *this ;
@@ -85,7 +85,7 @@ String &String::append(char c) {
8585}
8686
8787String &String::append (const char *s) {
88- if (s != NULL && s[0 ]) {
88+ if (s != nullptr && s[0 ]) {
8989 int len = length ();
9090 _buffer = (char *)realloc (_buffer, len + strlen (s) + 1 );
9191 strcpy (_buffer + len, s);
@@ -94,7 +94,7 @@ String &String::append(const char *s) {
9494}
9595
9696String &String::append (const char *s, int numCopy) {
97- if (s != NULL && numCopy) {
97+ if (s != nullptr && numCopy) {
9898 int len = strlen (s);
9999 if (numCopy > len) {
100100 numCopy = len;
@@ -117,14 +117,14 @@ String &String::append(FILE *fp, long filelen) {
117117
118118void String::clear () {
119119 free (_buffer);
120- _buffer = NULL ;
120+ _buffer = nullptr ;
121121}
122122
123123bool String::equals (const String &s, bool ignoreCase) const {
124124 bool result;
125125 if (_buffer == s._buffer ) {
126126 result = true ;
127- } else if (_buffer == NULL || s._buffer == NULL ) {
127+ } else if (_buffer == nullptr || s._buffer == nullptr ) {
128128 result = _buffer == s._buffer ;
129129 } else if (ignoreCase) {
130130 result = strcasecmp (_buffer, s._buffer ) == 0 ;
@@ -135,22 +135,24 @@ bool String::equals(const String &s, bool ignoreCase) const {
135135}
136136
137137bool String::equals (const char *s, bool ignoreCase) const {
138- return (_buffer == 0 ? s == 0 : ignoreCase ?
138+ return (_buffer == nullptr ? s == nullptr :
139+ s == nullptr ? _buffer == nullptr : ignoreCase ?
139140 strcasecmp (_buffer, s) == 0 : strcmp (_buffer, s) == 0 );
140141}
141142
142143int String::indexOf (const char *s, int fromIndex) const {
144+ int result;
143145 int len = length ();
144- if (fromIndex >= len) {
145- return -1 ;
146- }
147- if (strlen (s) == 1 ) {
146+ if (fromIndex >= len || _buffer == nullptr ) {
147+ result = -1 ;
148+ } else if (strlen (s) == 1 ) {
148149 char *c = strchr (_buffer + fromIndex, s[0 ]);
149- return (c == NULL ? -1 : (c - _buffer));
150+ result = (c == nullptr ? -1 : (c - _buffer));
150151 } else {
151152 char *c = strstr (_buffer + fromIndex, s);
152- return (c == NULL ? -1 : (c - _buffer));
153+ result = (c == nullptr ? -1 : (c - _buffer));
153154 }
155+ return result;
154156}
155157
156158int String::indexOf (char chr, int fromIndex) const {
@@ -159,7 +161,7 @@ int String::indexOf(char chr, int fromIndex) const {
159161 return -1 ;
160162 }
161163 char *c = strchr (_buffer + fromIndex, chr);
162- return (c == NULL ? -1 : (c - _buffer));
164+ return (c == nullptr ? -1 : (c - _buffer));
163165}
164166
165167int String::lastIndexOf (char chr, int untilIndex) const {
@@ -168,7 +170,7 @@ int String::lastIndexOf(char chr, int untilIndex) const {
168170 return -1 ;
169171 }
170172 char *c = strrchr (_buffer + untilIndex, chr);
171- return (c == NULL ? -1 : (c - _buffer));
173+ return (c == nullptr ? -1 : (c - _buffer));
172174}
173175
174176String String::leftOf (char ch) const {
@@ -350,15 +352,40 @@ template<> void Properties<String *>::put(const char *key, const char *value) {
350352template <> void Properties<String *>::get(const char *key, List<String *> *arrayValues) {
351353 for (int i = 0 ; i < _count; i++) {
352354 String *nextKey = (String *)_head[i++];
353- if (nextKey == NULL || i == _count) {
355+ if (nextKey == nullptr || i == _count) {
354356 break ;
355357 }
356358 String *nextValue = (String *)_head[i];
357- if (nextValue == NULL ) {
359+ if (nextValue == nullptr ) {
358360 break ;
359361 }
360362 if (nextKey->equals (key)) {
361363 arrayValues->add (new String (*nextValue));
362364 }
363365 }
364366}
367+
368+ // g++ -DUNIT_TESTS=1 -I. ui/strlib.cpp && ./a.out
369+ #if defined(UNIT_TESTS)
370+ #include < stdio.h>
371+ void assertEq (int a, int b) {
372+ if (a != b) {
373+ fprintf (stderr, " FAIL: %d != %d\n " , a, b);
374+ }
375+ }
376+ int main () {
377+ String s1 = " test string is here x" ;
378+ String s2;
379+ String s3 = " cats" ;
380+ assertEq (0 , s1.indexOf (" t" , 0 ));
381+ assertEq (20 , s1.indexOf (" x" , 20 ));
382+ assertEq (5 , s1.indexOf (" string" , 4 ));
383+ assertEq (-1 , s1.indexOf (" not" , 10 ));
384+ assertEq (-1 , s2.indexOf (" not" , 10 ));
385+ assertEq (0 , s3.equals (nullptr , true ));
386+ assertEq (1 , s3.equals (" CATS" , true ));
387+ assertEq (0 , s3.equals (" CATS" , false ));
388+ assertEq (1 , s3.equals (" cats" , false ));
389+ return 0 ;
390+ }
391+ #endif
0 commit comments