• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

cpputest / cpputest / 15141709115

20 May 2025 03:31PM CUT coverage: 99.281%. Remained the same
15141709115

push

github

web-flow
Merge pull request #1859 from mtfurlan/ci/run-docker

ci: actually run docker builds

6765 of 6814 relevant lines covered (99.28%)

46692.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.25
/src/CppUTest/SimpleString.cpp
1
/*
2
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *     * Redistributions of source code must retain the above copyright
8
 *       notice, this list of conditions and the following disclaimer.
9
 *     * Redistributions in binary form must reproduce the above copyright
10
 *       notice, this list of conditions and the following disclaimer in the
11
 *       documentation and/or other materials provided with the distribution.
12
 *     * Neither the name of the <organization> nor the
13
 *       names of its contributors may be used to endorse or promote products
14
 *       derived from this software without specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ''AS IS'' AND ANY
17
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
20
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 */
27

28
#include "CppUTest/TestHarness.h"
29
#include "CppUTest/SimpleString.h"
30
#include "CppUTest/PlatformSpecificFunctions.h"
31
#include "CppUTest/TestMemoryAllocator.h"
32

33
GlobalSimpleStringAllocatorStash::GlobalSimpleStringAllocatorStash()
130✔
34
    : originalAllocator_(NULLPTR)
130✔
35
{
36
}
130✔
37

38
void GlobalSimpleStringAllocatorStash::save()
130✔
39
{
40
    originalAllocator_ = SimpleString::getStringAllocator();
130✔
41
}
130✔
42

43
void GlobalSimpleStringAllocatorStash::restore()
130✔
44
{
45
    SimpleString::setStringAllocator(originalAllocator_);
130✔
46
}
130✔
47

48

49
GlobalSimpleStringMemoryAccountant::GlobalSimpleStringMemoryAccountant()
7✔
50
    : allocator_(NULLPTR)
7✔
51
{
52
    accountant_ = new MemoryAccountant();
7✔
53
}
7✔
54

55
GlobalSimpleStringMemoryAccountant::~GlobalSimpleStringMemoryAccountant()
7✔
56
{
57
    restoreAllocator();
7✔
58

59
    delete accountant_;
7✔
60
    delete allocator_;
7✔
61
}
7✔
62

63
void GlobalSimpleStringMemoryAccountant::restoreAllocator()
11✔
64
{
65
    if (allocator_ && (SimpleString::getStringAllocator() == allocator_))
11✔
66
        SimpleString::setStringAllocator(allocator_->originalAllocator());
4✔
67
}
11✔
68

69
void GlobalSimpleStringMemoryAccountant::useCacheSizes(size_t cacheSizes[], size_t length)
1✔
70
{
71
    accountant_->useCacheSizes(cacheSizes, length);
1✔
72
}
1✔
73

74
void GlobalSimpleStringMemoryAccountant::start()
7✔
75
{
76
    if (allocator_ != NULLPTR)
7✔
77
      return;
1✔
78

79
    allocator_ = new AccountingTestMemoryAllocator(*accountant_, SimpleString::getStringAllocator());
6✔
80

81
    SimpleString::setStringAllocator(allocator_);
6✔
82
}
83

84
void GlobalSimpleStringMemoryAccountant::stop()
6✔
85
{
86
    if (allocator_ == NULLPTR)
6✔
87
        FAIL("Global SimpleString allocator stopped without starting");
1✔
88

89
    if (SimpleString::getStringAllocator() != allocator_)
5✔
90
      FAIL("GlobalStrimpleStringMemoryAccountant: allocator has changed between start and stop!");
1✔
91

92
    restoreAllocator();
4✔
93
}
4✔
94

95
SimpleString GlobalSimpleStringMemoryAccountant::report()
2✔
96
{
97
    return accountant_->report();
2✔
98
}
99

100
AccountingTestMemoryAllocator* GlobalSimpleStringMemoryAccountant::getAllocator()
1✔
101
{
102
    return allocator_;
1✔
103
}
104

105
TestMemoryAllocator* SimpleString::stringAllocator_ = NULLPTR;
106

107
TestMemoryAllocator* SimpleString::getStringAllocator()
1,042,466✔
108
{
109
    if (stringAllocator_ == NULLPTR)
1,042,466✔
110
        return defaultNewArrayAllocator();
597✔
111
    return stringAllocator_;
1,041,869✔
112
}
113

114
void SimpleString::setStringAllocator(TestMemoryAllocator* allocator)
431✔
115
{
116
    stringAllocator_ = allocator;
431✔
117
}
431✔
118

119
/* Avoid using the memory leak detector INSIDE SimpleString as its used inside the detector */
120
char* SimpleString::allocStringBuffer(size_t _size, const char* file, size_t line)
521,265✔
121
{
122
    return getStringAllocator()->alloc_memory(_size, file, line);
521,265✔
123
}
124

125
void SimpleString::deallocStringBuffer(char* str, size_t size, const char* file, size_t line)
520,956✔
126
{
127
    getStringAllocator()->free_memory(str, size, file, line);
520,956✔
128
}
520,956✔
129

130
char* SimpleString::getEmptyString() const
68✔
131
{
132
    char* empty = allocStringBuffer(1, __FILE__, __LINE__);
68✔
133
    empty[0] = '\0';
68✔
134
    return empty;
68✔
135
}
136

137
// does not support + or - prefixes
138
unsigned SimpleString::AtoU(const char* str)
19✔
139
{
140
    while (isSpace(*str)) str++;
24✔
141

142
    unsigned result = 0;
19✔
143
    for(; isDigit(*str) && *str >= '0'; str++)
62✔
144
    {
145
        result *= 10;
43✔
146
        result += static_cast<unsigned>(*str - '0');
43✔
147
    }
148
    return result;
19✔
149
}
150

151
int SimpleString::AtoI(const char* str)
12✔
152
{
153
    while (isSpace(*str)) str++;
16✔
154

155
    char first_char = *str;
12✔
156
    if (first_char == '-' || first_char == '+') str++;
12✔
157

158
    int  result = 0;
12✔
159
    for(; isDigit(*str); str++)
55✔
160
    {
161
        result *= 10;
43✔
162
        result += *str - '0';
43✔
163
    }
164
    return (first_char == '-') ? -result : result;
12✔
165
}
166

167
int SimpleString::StrCmp(const char* s1, const char* s2)
315,237✔
168
{
169
   while(*s1 && *s1 == *s2) {
2,723,555✔
170
       ++s1;
2,408,318✔
171
       ++s2;
2,408,318✔
172
   }
173
   return *(const unsigned char *) s1 - *(const unsigned char *) s2;
315,237✔
174
}
175

176
size_t SimpleString::StrLen(const char* str)
698,781✔
177
{
178
    size_t n = (size_t)-1;
698,781✔
179
    do n++; while (*str++);
81,365,816✔
180
    return n;
698,781✔
181
}
182

183
int SimpleString::StrNCmp(const char* s1, const char* s2, size_t n)
135,169✔
184
{
185
    while (n && *s1 && *s1 == *s2) {
170,425✔
186
        --n;
35,256✔
187
        ++s1;
35,256✔
188
        ++s2;
35,256✔
189
    }
190
    return n ? *(const unsigned char *) s1 - *(const unsigned char *) s2 : 0;
135,169✔
191
}
192

193
char* SimpleString::StrNCpy(char* s1, const char* s2, size_t n)
569,001✔
194
{
195
    char* result = s1;
569,001✔
196

197
    if((NULLPTR == s1) || (0 == n)) return result;
569,001✔
198

199
    *s1 = *s2;
568,999✔
200
    while ((--n != 0) && *s1){
78,904,100✔
201
        *++s1 = *++s2;
78,335,101✔
202
    }
203
    return result;
568,999✔
204
}
205

206
const char* SimpleString::StrStr(const char* s1, const char* s2)
4,037✔
207
{
208
    if(!*s2) return s1;
4,037✔
209
    for (; *s1; s1++)
135,938✔
210
        if (StrNCmp(s1, s2, StrLen(s2)) == 0)
134,375✔
211
            return s1;
2,457✔
212
    return NULLPTR;
1,563✔
213
}
214

215
char SimpleString::ToLower(char ch)
6,246✔
216
{
217
    return isUpper(ch) ? (char)((int)ch + ('a' - 'A')) : ch;
6,246✔
218
}
219

220
int SimpleString::MemCmp(const void* s1, const void *s2, size_t n)
21✔
221
{
222
    const unsigned char* p1 = (const unsigned char*) s1;
21✔
223
    const unsigned char* p2 = (const unsigned char*) s2;
21✔
224

225
    while (n--)
78✔
226
        if (*p1 != *p2) {
67✔
227
            return *p1 - *p2;
10✔
228
        } else {
229
            ++p1;
57✔
230
            ++p2;
57✔
231
        }
232
    return 0;
11✔
233
}
234

235
void SimpleString::deallocateInternalBuffer()
976,818✔
236
{
237
    if (buffer_) {
976,818✔
238
        deallocStringBuffer(buffer_, bufferSize_, __FILE__, __LINE__);
520,869✔
239
        buffer_ = NULLPTR;
520,869✔
240
        bufferSize_ = 0;
520,869✔
241
    }
242
}
976,818✔
243

244
void SimpleString::setInternalBufferAsEmptyString()
68✔
245
{
246
    deallocateInternalBuffer();
68✔
247

248
    bufferSize_ = 1;
68✔
249
    buffer_ = getEmptyString();
68✔
250
}
68✔
251

252
void SimpleString::copyBufferToNewInternalBuffer(const char* otherBuffer, size_t bufferSize)
484,521✔
253
{
254
    deallocateInternalBuffer();
484,521✔
255

256
    bufferSize_ = bufferSize;
484,521✔
257
    buffer_ = copyToNewBuffer(otherBuffer, bufferSize_);
484,521✔
258
}
484,521✔
259

260
void SimpleString::setInternalBufferToNewBuffer(size_t bufferSize)
273✔
261
{
262
    deallocateInternalBuffer();
273✔
263

264
    bufferSize_ = bufferSize;
273✔
265
    buffer_ = allocStringBuffer(bufferSize_, __FILE__, __LINE__);
273✔
266
    buffer_[0] = '\0';
273✔
267
}
273✔
268

269
void SimpleString::setInternalBufferTo(char* buffer, size_t bufferSize)
36,316✔
270
{
271
    deallocateInternalBuffer();
36,316✔
272

273
    bufferSize_ = bufferSize;
36,316✔
274
    buffer_ = buffer;
36,316✔
275
}
36,316✔
276

277
void SimpleString::copyBufferToNewInternalBuffer(const SimpleString& otherBuffer)
28,801✔
278
{
279
    copyBufferToNewInternalBuffer(otherBuffer.buffer_, otherBuffer.size() + 1);
28,801✔
280
}
28,801✔
281

282
void SimpleString::copyBufferToNewInternalBuffer(const char* otherBuffer)
455,720✔
283
{
284
    copyBufferToNewInternalBuffer(otherBuffer, StrLen(otherBuffer) + 1);
455,720✔
285
}
455,720✔
286

287
const char* SimpleString::getBuffer() const
803,734✔
288
{
289
    return buffer_;
803,734✔
290
}
291

292
SimpleString::SimpleString(const char *otherBuffer)
442,074✔
293
    : buffer_(NULLPTR), bufferSize_(0)
442,074✔
294
{
295
    if (otherBuffer == NULLPTR)
442,074✔
296
        setInternalBufferAsEmptyString();
67✔
297
    else
298
        copyBufferToNewInternalBuffer(otherBuffer);
442,007✔
299
}
442,074✔
300

301
SimpleString::SimpleString(const char *other, size_t repeatCount)
162✔
302
    : buffer_(NULLPTR), bufferSize_(0)
162✔
303
{
304
    size_t otherStringLength = StrLen(other);
162✔
305
    setInternalBufferToNewBuffer(otherStringLength * repeatCount + 1);
162✔
306

307
    char* next = buffer_;
162✔
308
    for (size_t i = 0; i < repeatCount; i++) {
11,887✔
309
        StrNCpy(next, other, otherStringLength + 1);
11,725✔
310
        next += otherStringLength;
11,725✔
311
    }
312
    *next = 0;
162✔
313
}
162✔
314

315
SimpleString::SimpleString(const SimpleString& other)
13,713✔
316
    : buffer_(NULLPTR), bufferSize_(0)
13,713✔
317
{
318
    copyBufferToNewInternalBuffer(other.getBuffer());
13,713✔
319
}
13,713✔
320

321
SimpleString& SimpleString::operator=(const SimpleString& other)
28,801✔
322
{
323
    if (this != &other)
28,801✔
324
        copyBufferToNewInternalBuffer(other);
28,801✔
325
    return *this;
28,801✔
326
}
327

328
bool SimpleString::contains(const SimpleString& other) const
960✔
329
{
330
    return StrStr(getBuffer(), other.getBuffer()) != NULLPTR;
960✔
331
}
332

333
bool SimpleString::containsNoCase(const SimpleString& other) const
13✔
334
{
335
    return lowerCase().contains(other.lowerCase());
13✔
336
}
337

338
bool SimpleString::startsWith(const SimpleString& other) const
1,379✔
339
{
340
    if (other.size() == 0) return true;
1,379✔
341
    else if (size() == 0) return false;
1,379✔
342
    else return StrStr(getBuffer(), other.getBuffer()) == getBuffer();
1,379✔
343
}
344

345
bool SimpleString::endsWith(const SimpleString& other) const
81✔
346
{
347
    size_t length = size();
81✔
348
    size_t other_length = other.size();
81✔
349

350
    if (other_length == 0) return true;
81✔
351
    if (length == 0) return false;
81✔
352
    if (length < other_length) return false;
80✔
353

354
    return StrCmp(getBuffer() + length - other_length, other.getBuffer()) == 0;
79✔
355
}
356

357
size_t SimpleString::count(const SimpleString& substr) const
502✔
358
{
359
    size_t num = 0;
502✔
360
    const char* str = getBuffer();
502✔
361
    const char* strpart = NULLPTR;
502✔
362
    if (*str){
502✔
363
        strpart = StrStr(str, substr.getBuffer());
302✔
364
    }
365
    while (*str && strpart) {
1,241✔
366
        str = strpart;
739✔
367
        str++;
739✔
368
        num++;
739✔
369
        strpart = StrStr(str, substr.getBuffer());
739✔
370
    }
371
    return num;
502✔
372
}
373

374
void SimpleString::split(const SimpleString& delimiter, SimpleStringCollection& col) const
70✔
375
{
376
    size_t num = count(delimiter);
70✔
377
    size_t extraEndToken = (endsWith(delimiter)) ? 0 : 1U;
70✔
378
    col.allocate(num + extraEndToken);
70✔
379

380
    const char* str = getBuffer();
70✔
381
    const char* prev;
382
    for (size_t i = 0; i < num; ++i) {
722✔
383
        prev = str;
652✔
384
        str = StrStr(str, delimiter.getBuffer()) + 1;
652✔
385
        col[i] = SimpleString(prev).subString(0, size_t (str - prev));
652✔
386
    }
387
    if (extraEndToken) {
70✔
388
        col[num] = str;
9✔
389
    }
390
}
70✔
391

392
void SimpleString::replace(char to, char with)
361✔
393
{
394
    size_t s = size();
361✔
395
    for (size_t i = 0; i < s; i++) {
9,301✔
396
        if (getBuffer()[i] == to) buffer_[i] = with;
8,940✔
397
    }
398
}
361✔
399

400
void SimpleString::replace(const char* to, const char* with)
425✔
401
{
402
    size_t c = count(to);
425✔
403
    if (c == 0) {
425✔
404
        return;
385✔
405
    }
406
    size_t len = size();
40✔
407
    size_t tolen = StrLen(to);
40✔
408
    size_t withlen = StrLen(with);
40✔
409

410
    size_t newsize = len + (withlen * c) - (tolen * c) + 1;
40✔
411

412
    if (newsize > 1) {
40✔
413
        char* newbuf = allocStringBuffer(newsize, __FILE__, __LINE__);
39✔
414
        for (size_t i = 0, j = 0; i < len;) {
812✔
415
            if (StrNCmp(&getBuffer()[i], to, tolen) == 0) {
773✔
416
                StrNCpy(&newbuf[j], with, withlen + 1);
58✔
417
                j += withlen;
58✔
418
                i += tolen;
58✔
419
            }
420
            else {
421
                newbuf[j] = getBuffer()[i];
715✔
422
                j++;
715✔
423
                i++;
715✔
424
            }
425
        }
426
        newbuf[newsize - 1] = '\0';
39✔
427
        setInternalBufferTo(newbuf, newsize);
39✔
428
    }
429
    else
430
        setInternalBufferAsEmptyString();
1✔
431
}
432

433
SimpleString SimpleString::printable() const
111✔
434
{
435
    static const char* shortEscapeCodes[] =
436
    {
437
        "\\a",
438
        "\\b",
439
        "\\t",
440
        "\\n",
441
        "\\v",
442
        "\\f",
443
        "\\r"
444
    };
445

446
    SimpleString result;
111✔
447
    result.setInternalBufferToNewBuffer(getPrintableSize() + 1);
111✔
448

449
    size_t str_size = size();
111✔
450
    size_t j = 0;
111✔
451
    for (size_t i = 0; i < str_size; i++)
616✔
452
    {
453
        char c = buffer_[i];
505✔
454
        if (isControlWithShortEscapeSequence(c))
505✔
455
        {
456
            StrNCpy(&result.buffer_[j], shortEscapeCodes[(unsigned char)(c - '\a')], 2);
11✔
457
            j += 2;
11✔
458
        }
459
        else if (isControl(c))
494✔
460
        {
461
            SimpleString hexEscapeCode = StringFromFormat("\\x%02X ", c);
5✔
462
            StrNCpy(&result.buffer_[j], hexEscapeCode.asCharString(), 4);
5✔
463
            j += 4;
5✔
464
        }
5✔
465
        else
466
        {
467
            result.buffer_[j] = c;
489✔
468
            j++;
489✔
469
        }
470
    }
471
    result.buffer_[j] = 0;
111✔
472

473
    return result;
111✔
474
}
×
475

476
size_t SimpleString::getPrintableSize() const
111✔
477
{
478
    size_t str_size = size();
111✔
479
    size_t printable_str_size = str_size;
111✔
480

481
    for (size_t i = 0; i < str_size; i++)
616✔
482
    {
483
        char c = buffer_[i];
505✔
484
        if (isControlWithShortEscapeSequence(c))
505✔
485
        {
486
            printable_str_size += 1;
11✔
487
        }
488
        else if (isControl(c))
494✔
489
        {
490
            printable_str_size += 3;
5✔
491
        }
492
    }
493

494
    return printable_str_size;
111✔
495
}
496

497
SimpleString SimpleString::lowerCase() const
43✔
498
{
499
    SimpleString str(*this);
43✔
500

501
    size_t str_size = str.size();
43✔
502
    for (size_t i = 0; i < str_size; i++)
6,213✔
503
        str.buffer_[i] = ToLower(str.getBuffer()[i]);
6,170✔
504

505
    return str;
43✔
506
}
×
507

508
const char *SimpleString::asCharString() const
642,367✔
509
{
510
    return getBuffer();
642,367✔
511
}
512

513
size_t SimpleString::size() const
72,051✔
514
{
515
    return StrLen(getBuffer());
72,051✔
516
}
517

518
bool SimpleString::isEmpty() const
1,230✔
519
{
520
    return size() == 0;
1,230✔
521
}
522

523
SimpleString::~SimpleString()
455,640✔
524
{
525
    deallocateInternalBuffer();
455,640✔
526
}
455,640✔
527

528
bool operator==(const SimpleString& left, const SimpleString& right)
313,598✔
529
{
530
    return 0 == SimpleString::StrCmp(left.asCharString(), right.asCharString());
313,598✔
531
}
532

533
bool SimpleString::equalsNoCase(const SimpleString& str) const
8✔
534
{
535
    return lowerCase() == str.lowerCase();
8✔
536
}
537

538

539
bool operator!=(const SimpleString& left, const SimpleString& right)
65,672✔
540
{
541
    return !(left == right);
65,672✔
542
}
543

544
SimpleString SimpleString::operator+(const SimpleString& rhs) const
1,204✔
545
{
546
    SimpleString t(getBuffer());
1,204✔
547
    t += rhs.getBuffer();
1,204✔
548
    return t;
1,204✔
549
}
×
550

551
SimpleString& SimpleString::operator+=(const SimpleString& rhs)
10,545✔
552
{
553
    return operator+=(rhs.getBuffer());
10,545✔
554
}
555

556
SimpleString& SimpleString::operator+=(const char* rhs)
36,277✔
557
{
558
    size_t originalSize = this->size();
36,277✔
559
    size_t additionalStringSize = StrLen(rhs) + 1;
36,277✔
560
    size_t sizeOfNewString = originalSize + additionalStringSize;
36,277✔
561
    char* tbuffer = copyToNewBuffer(this->getBuffer(), sizeOfNewString);
36,277✔
562
    StrNCpy(tbuffer + originalSize, rhs, additionalStringSize);
36,277✔
563

564
    setInternalBufferTo(tbuffer, sizeOfNewString);
36,277✔
565
    return *this;
36,277✔
566
}
567

568
void SimpleString::padStringsToSameLength(SimpleString& str1, SimpleString& str2, char padCharacter)
36✔
569
{
570
    if (str1.size() > str2.size()) {
36✔
571
        padStringsToSameLength(str2, str1, padCharacter);
3✔
572
        return;
3✔
573
    }
574

575
    char pad[2];
576
    pad[0] = padCharacter;
33✔
577
    pad[1] = 0;
33✔
578
    str1 = SimpleString(pad, str2.size() - str1.size()) + str1;
33✔
579
}
580

581
SimpleString SimpleString::subString(size_t beginPos, size_t amount) const
790✔
582
{
583
    if (beginPos > size()-1) return "";
790✔
584

585
    SimpleString newString = getBuffer() + beginPos;
789✔
586

587
    if (newString.size() > amount)
789✔
588
        newString.buffer_[amount] = '\0';
707✔
589

590
    return newString;
789✔
591
}
789✔
592

593
SimpleString SimpleString::subString(size_t beginPos) const
11✔
594
{
595
    return subString(beginPos, npos);
11✔
596
}
597

598
char SimpleString::at(size_t pos) const
503✔
599
{
600
    return getBuffer()[pos];
503✔
601
}
602

603
size_t SimpleString::find(char ch) const
11✔
604
{
605
    return findFrom(0, ch);
11✔
606
}
607

608
size_t SimpleString::findFrom(size_t starting_position, char ch) const
18✔
609
{
610
    size_t length = size();
18✔
611
    for (size_t i = starting_position; i < length; i++)
124✔
612
        if (at(i) == ch) return i;
120✔
613
    return npos;
4✔
614
}
615

616
SimpleString SimpleString::subStringFromTill(char startChar, char lastExcludedChar) const
8✔
617
{
618
    size_t beginPos = find(startChar);
8✔
619
    if (beginPos == npos) return "";
8✔
620

621
    size_t endPos = findFrom(beginPos, lastExcludedChar);
7✔
622
    if (endPos == npos) return subString(beginPos);
7✔
623

624
    return subString(beginPos, endPos - beginPos);
5✔
625
}
626

627
char* SimpleString::copyToNewBuffer(const char* bufferToCopy, size_t bufferSize)
520,798✔
628
{
629
    char* newBuffer = allocStringBuffer(bufferSize, __FILE__, __LINE__);
520,798✔
630
    StrNCpy(newBuffer, bufferToCopy, bufferSize);
520,798✔
631
    newBuffer[bufferSize-1] = '\0';
520,798✔
632
    return newBuffer;
520,798✔
633
}
634

635

636
void SimpleString::copyToBuffer(char* bufferToCopy, size_t bufferSize) const
4✔
637
{
638
    if (bufferToCopy == NULLPTR || bufferSize == 0) return;
4✔
639

640
    size_t sizeToCopy = (bufferSize-1 < size()) ? (bufferSize-1) : size();
3✔
641

642
    StrNCpy(bufferToCopy, getBuffer(), sizeToCopy);
3✔
643
    bufferToCopy[sizeToCopy] = '\0';
3✔
644
}
645

646
bool SimpleString::isDigit(char ch)
117✔
647
{
648
    return '0' <= ch && '9' >= ch;
117✔
649
}
650

651
bool SimpleString::isSpace(char ch)
40✔
652
{
653
    return (ch == ' ') || (0x08 < ch && 0x0E > ch);
40✔
654
}
655

656
bool SimpleString::isUpper(char ch)
6,246✔
657
{
658
    return 'A' <= ch && 'Z' >= ch;
6,246✔
659
}
660

661
bool SimpleString::isControl(char ch)
988✔
662
{
663
    return ch < ' ' || ch == char(0x7F);
988✔
664
}
665

666
bool SimpleString::isControlWithShortEscapeSequence(char ch)
1,010✔
667
{
668
    return '\a' <= ch && '\r' >= ch;
1,010✔
669
}
670

671
SimpleString StringFrom(bool value)
4✔
672
{
673
    return SimpleString(StringFromFormat("%s", value ? "true" : "false"));
4✔
674
}
675

676
SimpleString StringFrom(const char *value)
147✔
677
{
678
    return SimpleString(value);
147✔
679
}
680

681
SimpleString StringFromOrNull(const char * expected)
9✔
682
{
683
    return (expected) ? StringFrom(expected) : StringFrom("(null)");
9✔
684
}
685

686
SimpleString PrintableStringFromOrNull(const char * expected)
121✔
687
{
688
    return (expected) ? StringFrom(expected).printable() : StringFrom("(null)");
242✔
689
}
690

691
SimpleString StringFrom(int value)
106✔
692
{
693
    return StringFromFormat("%d", value);
106✔
694
}
695

696
SimpleString StringFrom(long value)
39✔
697
{
698
    return StringFromFormat("%ld", value);
39✔
699
}
700

701
SimpleString StringFrom(const void* value)
20✔
702
{
703
    return SimpleString("0x") + HexStringFrom(value);
20✔
704
}
705

706
SimpleString StringFrom(void (*value)())
7✔
707
{
708
    return SimpleString("0x") + HexStringFrom(value);
7✔
709
}
710

711
SimpleString HexStringFrom(long value)
33✔
712
{
713
    return HexStringFrom((unsigned long)value);
33✔
714
}
715

716
SimpleString HexStringFrom(int value)
53✔
717
{
718
    return HexStringFrom((unsigned int)value);
53✔
719
}
720

721
SimpleString HexStringFrom(signed char value)
8✔
722
{
723
    SimpleString result = StringFromFormat("%x", value);
8✔
724
    if(value < 0) {
8✔
725
        size_t size = result.size();
6✔
726
        result = result.subString(size-(CPPUTEST_CHAR_BIT/4));
6✔
727
    }
728
    return result;
8✔
729
}
×
730

731
SimpleString HexStringFrom(unsigned long value)
54✔
732
{
733
    return StringFromFormat("%lx", value);
54✔
734
}
735

736
SimpleString HexStringFrom(unsigned int value)
70✔
737
{
738
    return StringFromFormat("%x", value);
70✔
739
}
740

741
SimpleString BracketsFormattedHexStringFrom(int value)
53✔
742
{
743
    return BracketsFormattedHexString(HexStringFrom(value));
53✔
744
}
745

746
SimpleString BracketsFormattedHexStringFrom(unsigned int value)
17✔
747
{
748
    return BracketsFormattedHexString(HexStringFrom(value));
17✔
749
}
750

751
SimpleString BracketsFormattedHexStringFrom(long value)
32✔
752
{
753
    return BracketsFormattedHexString(HexStringFrom(value));
32✔
754
}
755

756

757
SimpleString BracketsFormattedHexStringFrom(unsigned long value)
21✔
758
{
759
    return BracketsFormattedHexString(HexStringFrom(value));
21✔
760
}
761

762
SimpleString BracketsFormattedHexStringFrom(signed char value)
7✔
763
{
764
    return BracketsFormattedHexString(HexStringFrom(value));
7✔
765
}
766

767
SimpleString BracketsFormattedHexString(SimpleString hexString)
156✔
768
{
769
    return SimpleString("(0x") + hexString + ")" ;
312✔
770
}
771

772
/*
773
 * ARM compiler has only partial support for C++11.
774
 * Specifically nullptr_t is not officially supported
775
 */
776
#if __cplusplus > 199711L && !defined __arm__ && CPPUTEST_USE_STD_CPP_LIB
777
SimpleString StringFrom(const std::nullptr_t value)
1✔
778
{
779
    (void) value;
780
    return "(null)";
1✔
781
}
782
#endif
783

784
#if CPPUTEST_USE_LONG_LONG
785

786
SimpleString StringFrom(cpputest_longlong value)
13✔
787
{
788
    return StringFromFormat("%lld", value);
13✔
789
}
790

791
SimpleString StringFrom(cpputest_ulonglong value)
14✔
792
{
793
    return StringFromFormat("%llu", value);
14✔
794
}
795

796
SimpleString HexStringFrom(cpputest_longlong value)
14✔
797
{
798
    return HexStringFrom((cpputest_ulonglong)value);
14✔
799
}
800

801
SimpleString HexStringFrom(cpputest_ulonglong value)
61✔
802
{
803
    return StringFromFormat("%llx", value);
61✔
804
}
805

806
SimpleString HexStringFrom(const void* value)
25✔
807
{
808
    return HexStringFrom((cpputest_ulonglong) value);
25✔
809
}
810

811
SimpleString HexStringFrom(void (*value)())
9✔
812
{
813
    return HexStringFrom((cpputest_ulonglong) value);
9✔
814
}
815

816
SimpleString BracketsFormattedHexStringFrom(cpputest_longlong value)
13✔
817
{
818
    return BracketsFormattedHexString(HexStringFrom(value));
13✔
819
}
820

821

822
SimpleString BracketsFormattedHexStringFrom(cpputest_ulonglong value)
13✔
823
{
824
    return BracketsFormattedHexString(HexStringFrom(value));
13✔
825
}
826

827
#else   /* CPPUTEST_USE_LONG_LONG */
828

829
static long convertPointerToLongValue(const void* value)
830
{
831
    /*
832
     * This way of converting also can convert a 64bit pointer in a 32bit integer by truncating.
833
     * This isn't the right way to convert pointers values and need to change by implementing a
834
     * proper portable way to convert pointers to strings.
835
     */
836
    long* long_value = (long*) &value;
837
    return *long_value;
838
}
839

840
static long convertFunctionPointerToLongValue(void (*value)())
841
{
842
    /*
843
     * This way of converting also can convert a 64bit pointer in a 32bit integer by truncating.
844
     * This isn't the right way to convert pointers values and need to change by implementing a
845
     * proper portable way to convert pointers to strings.
846
     */
847
    long* long_value = (long*) &value;
848
    return *long_value;
849
}
850

851
SimpleString StringFrom(cpputest_longlong)
852
{
853
    return "<longlong_unsupported>";
854
}
855

856
SimpleString StringFrom(cpputest_ulonglong)
857
{
858
    return "<ulonglong_unsupported>";
859
}
860

861
SimpleString HexStringFrom(cpputest_longlong)
862
{
863
    return "<longlong_unsupported>";
864
}
865

866
SimpleString HexStringFrom(cpputest_ulonglong)
867
{
868
    return "<ulonglong_unsupported>";
869
}
870

871
SimpleString HexStringFrom(const void* value)
872
{
873
    return StringFromFormat("%lx", convertPointerToLongValue(value));
874
}
875

876
SimpleString HexStringFrom(void (*value)())
877
{
878
    return StringFromFormat("%lx", convertFunctionPointerToLongValue(value));
879
}
880

881
SimpleString BracketsFormattedHexStringFrom(cpputest_longlong)
882
{
883
    return "";
884
}
885

886

887
SimpleString BracketsFormattedHexStringFrom(cpputest_ulonglong)
888
{
889
    return "";
890
}
891

892
#endif  /* CPPUTEST_USE_LONG_LONG */
893

894
SimpleString StringFrom(double value, int precision)
58✔
895
{
896
    if (PlatformSpecificIsNan(value))
58✔
897
        return "Nan - Not a number";
5✔
898
    else if (PlatformSpecificIsInf(value))
53✔
899
        return "Inf - Infinity";
4✔
900
    else
901
        return StringFromFormat("%.*g", precision, value);
49✔
902
}
903

904
SimpleString StringFrom(char value)
9✔
905
{
906
    return StringFromFormat("%c", value);
9✔
907
}
908

909
SimpleString StringFrom(const SimpleString& value)
1✔
910
{
911
    return SimpleString(value);
1✔
912
}
913

914
SimpleString StringFromFormat(const char* format, ...)
12,306✔
915
{
916
    SimpleString resultString;
12,306✔
917
    va_list arguments;
918
    va_start(arguments, format);
12,306✔
919

920
    resultString = VStringFromFormat(format, arguments);
12,306✔
921
    va_end(arguments);
12,306✔
922
    return resultString;
24,612✔
923
}
×
924

925
SimpleString StringFrom(unsigned int i)
18✔
926
{
927
    return StringFromFormat("%u", i);
18✔
928
}
929

930
#if CPPUTEST_USE_STD_CPP_LIB
931

932
#include <string>
933

934
SimpleString StringFrom(const std::string& value)
1✔
935
{
936
    return SimpleString(value.c_str());
1✔
937
}
938

939
#endif
940

941
SimpleString StringFrom(unsigned long i)
3,862✔
942
{
943
    return StringFromFormat("%lu", i);
3,862✔
944
}
945

946
SimpleString VStringFromFormat(const char* format, va_list args)
12,306✔
947
{
948
    va_list argsCopy;
949
    va_copy(argsCopy, args);
12,306✔
950
    enum
951
    {
952
        sizeOfdefaultBuffer = 100
953
    };
954
    char defaultBuffer[sizeOfdefaultBuffer];
955
    SimpleString resultString;
12,306✔
956

957
    size_t size = (size_t)PlatformSpecificVSNprintf(defaultBuffer, sizeOfdefaultBuffer, format, args);
12,306✔
958
    if (size < sizeOfdefaultBuffer) {
12,306✔
959
        resultString = SimpleString(defaultBuffer);
12,219✔
960
    }
961
    else {
962
        size_t newBufferSize = size + 1;
87✔
963
        char* newBuffer = SimpleString::allocStringBuffer(newBufferSize, __FILE__, __LINE__);
87✔
964
        PlatformSpecificVSNprintf(newBuffer, newBufferSize, format, argsCopy);
87✔
965
        resultString = SimpleString(newBuffer);
87✔
966

967
        SimpleString::deallocStringBuffer(newBuffer, newBufferSize, __FILE__, __LINE__);
87✔
968
    }
969
    va_end(argsCopy);
12,306✔
970
    return resultString;
24,612✔
971
}
×
972

973
SimpleString StringFromBinary(const unsigned char* value, size_t size)
48✔
974
{
975
    SimpleString result;
48✔
976

977
    for (size_t i = 0; i < size; i++) {
340✔
978
        result += StringFromFormat("%02X ", value[i]);
292✔
979
    }
980
    result = result.subString(0, result.size() - 1);
48✔
981

982
    return result;
48✔
983
}
×
984

985
SimpleString StringFromBinaryOrNull(const unsigned char* value, size_t size)
51✔
986
{
987
    return (value) ? StringFromBinary(value, size) : StringFrom("(null)");
51✔
988
}
989

990
SimpleString StringFromBinaryWithSize(const unsigned char* value, size_t size)
21✔
991
{
992
    SimpleString result = StringFromFormat("Size = %u | HexContents = ", (unsigned) size);
21✔
993
    size_t displayedSize = ((size > 128) ? 128 : size);
21✔
994
    result += StringFromBinaryOrNull(value, displayedSize);
21✔
995
    if (size > displayedSize)
21✔
996
    {
997
        result += " ...";
1✔
998
    }
999
    return result;
21✔
1000
}
×
1001

1002
SimpleString StringFromBinaryWithSizeOrNull(const unsigned char* value, size_t size)
19✔
1003
{
1004
    return (value) ? StringFromBinaryWithSize(value, size) : StringFrom("(null)");
19✔
1005
}
1006

1007
SimpleString StringFromMaskedBits(unsigned long value, unsigned long mask, size_t byteCount)
34✔
1008
{
1009
    SimpleString result;
34✔
1010
    size_t bitCount = (byteCount > sizeof(unsigned long)) ? (sizeof(unsigned long) * CPPUTEST_CHAR_BIT) : (byteCount * CPPUTEST_CHAR_BIT);
34✔
1011
    const unsigned long msbMask = (((unsigned long) 1) << (bitCount - 1));
34✔
1012

1013
    for (size_t i = 0; i < bitCount; i++) {
706✔
1014
        if (mask & msbMask) {
672✔
1015
            result += (value & msbMask) ? "1" : "0";
370✔
1016
        }
1017
        else {
1018
            result += "x";
302✔
1019
        }
1020

1021
        if (((i % 8) == 7) && (i != (bitCount - 1))) {
672✔
1022
            result += " ";
50✔
1023
        }
1024

1025
        value <<= 1;
672✔
1026
        mask <<= 1;
672✔
1027
    }
1028

1029
    return result;
34✔
1030
}
×
1031

1032
SimpleString StringFromOrdinalNumber(unsigned int number)
33✔
1033
{
1034
    const char* suffix = "th";
33✔
1035

1036
    if ((number < 11) || (number > 13)) {
33✔
1037
        unsigned int const onesDigit = number % 10;
27✔
1038
        if (3 == onesDigit) {
27✔
1039
            suffix = "rd";
6✔
1040
        } else if (2 == onesDigit) {
21✔
1041
            suffix = "nd";
7✔
1042
        } else if (1 == onesDigit) {
14✔
1043
            suffix = "st";
3✔
1044
        }
1045
    }
1046

1047
    return StringFromFormat("%u%s", number, suffix);
33✔
1048
}
1049

1050
SimpleStringCollection::SimpleStringCollection()
49✔
1051
{
1052
    collection_ = NULLPTR;
49✔
1053
    size_ = 0;
49✔
1054
}
49✔
1055

1056
void SimpleStringCollection::allocate(size_t _size)
74✔
1057
{
1058
    delete[] collection_;
385✔
1059

1060
    size_ = _size;
74✔
1061
    collection_ = new SimpleString[size_];
751✔
1062
}
74✔
1063

1064
SimpleStringCollection::~SimpleStringCollection()
49✔
1065
{
1066
    delete[] (collection_);
415✔
1067
}
49✔
1068

1069
size_t SimpleStringCollection::size() const
15✔
1070
{
1071
    return size_;
15✔
1072
}
1073

1074
SimpleString& SimpleStringCollection::operator[](size_t index)
743✔
1075
{
1076
    if (index >= size_) {
743✔
1077
        empty_ = "";
3✔
1078
        return empty_;
3✔
1079
    }
1080

1081
    return collection_[index];
740✔
1082
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc