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

thetic / mutiny / 24021211194

06 Apr 2026 06:16AM UTC coverage: 98.912% (-0.06%) from 98.971%
24021211194

Pull #40

github

web-flow
Merge a69e83fde into b70bdccaa
Pull Request #40: WIP: generalize CHECK_EQUAL

21 of 22 new or added lines in 6 files covered. (95.45%)

2 existing lines in 1 file now uncovered.

5544 of 5605 relevant lines covered (98.91%)

3529.8 hits per line

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

97.68
/src/String.cpp
1
#include "mutiny/String.hpp"
2

3
#include "mutiny/math.hpp"
4

5
#if MUTINY_USE_STD_CPP_LIB
6
#include <string>
7
#endif
8

9
#if MUTINY_USE_STD_STRING
10
#include <cctype>
11
#include <cstdlib>
12
#include <cstring>
13
#endif
14

15
#include <inttypes.h>
16
#include <limits.h>
17
#include <stdint.h>
18
#include <stdio.h>
19

20
namespace mu {
21
namespace tiny {
22

23
namespace {
24
#if !MUTINY_USE_STD_STRING
25
char* str_n_cpy(char* s1, const char* s2, size_t n)
135,994✔
26
{
27
  char* result = s1;
135,994✔
28

29
  if ((nullptr == s1) || (0 == n))
135,994✔
30
    return result;
×
31

32
  *s1 = *s2;
135,994✔
33
  while ((--n != 0) && *s1) {
2,529,279✔
34
    *++s1 = *++s2;
2,393,285✔
35
  }
36
  return result;
135,994✔
37
}
38

39
char* copy_to_new_buffer(const char* buffer_to_copy, size_t buffer_size)
94,310✔
40
{
41
  char* new_buffer = new char[buffer_size];
94,310✔
42
  str_n_cpy(new_buffer, buffer_to_copy, buffer_size);
94,310✔
43
  if (buffer_size > 0)
94,310✔
44
    new_buffer[buffer_size - 1] = '\0';
94,310✔
45
  return new_buffer;
94,310✔
46
}
47
#endif
48

49
#if !MUTINY_USE_STD_STRING
50
bool is_digit(char ch)
117✔
51
{
52
  return '0' <= ch && '9' >= ch;
117✔
53
}
54

55
bool is_space(char ch)
39✔
56
{
57
  return (ch == ' ') || (0x08 < ch && 0x0E > ch);
39✔
58
}
59

60
bool is_upper(char ch)
32✔
61
{
62
  return 'A' <= ch && 'Z' >= ch;
32✔
63
}
64
#endif
65
} // namespace
66

67
#if !MUTINY_USE_STD_STRING
68
char* String::get_empty_string() const
13✔
69
{
70
  char* buf = new char[1];
13✔
71
  buf[0] = '\0';
13✔
72
  return buf;
13✔
73
}
74

75
void String::deallocate_internal_buffer()
203,095✔
76
{
77
  if (buffer_) {
203,095✔
78
    delete[] buffer_;
94,543✔
79
    buffer_ = nullptr;
94,543✔
80
    buffer_size_ = 0;
94,543✔
81
    size_ = 0;
94,543✔
82
  }
83
}
203,095✔
84

85
void String::set_internal_buffer_as_empty_string()
13✔
86
{
87
  deallocate_internal_buffer();
13✔
88

89
  buffer_size_ = 1;
13✔
90
  buffer_ = get_empty_string();
13✔
91
}
13✔
92

93
void String::copy_buffer_to_new_internal_buffer(
94,310✔
94
    const char* other_buffer,
95
    size_t buffer_size
96
)
97
{
98
  deallocate_internal_buffer();
94,310✔
99

100
  buffer_size_ = buffer_size;
94,310✔
101
  size_ = buffer_size_ - 1;
94,310✔
102
  buffer_ = copy_to_new_buffer(other_buffer, buffer_size_);
94,310✔
103
}
94,310✔
104

105
void String::reserve(size_t new_capacity)
248✔
106
{
107
  size_t needed = new_capacity + 1;
248✔
108
  if (needed <= buffer_size_)
248✔
109
    return;
1✔
110

111
  char* new_buffer = new char[needed];
247✔
112
  str_n_cpy(new_buffer, buffer_, buffer_size_);
247✔
113
  new_buffer[needed - 1] = '\0';
247✔
114
  delete[] buffer_;
247✔
115
  buffer_ = new_buffer;
247✔
116
  buffer_size_ = needed;
247✔
117
  // size_ is unchanged: the string content was preserved
118
}
119

120
void String::clear()
13✔
121
{
122
  set_internal_buffer_as_empty_string();
13✔
123
}
13✔
124

125
void String::copy_buffer_to_new_internal_buffer(const String& other_buffer)
1,011✔
126
{
127
  copy_buffer_to_new_internal_buffer(
1,011✔
128
      other_buffer.buffer_, other_buffer.size() + 1
1,011✔
129
  );
130
}
1,011✔
131

132
void String::copy_buffer_to_new_internal_buffer(const char* other_buffer)
93,299✔
133
{
134
  copy_buffer_to_new_internal_buffer(other_buffer, strlen(other_buffer) + 1);
93,299✔
135
}
93,299✔
136

137
String::String(const char* other_buffer)
83,943✔
138
  : buffer_(nullptr)
83,943✔
139
  , buffer_size_(0)
83,943✔
140
  , size_(0)
83,943✔
141
{
142
  if (other_buffer == nullptr)
83,943✔
143
    set_internal_buffer_as_empty_string();
×
144
  else
145
    copy_buffer_to_new_internal_buffer(other_buffer);
83,943✔
146
}
83,943✔
147

148
String::String(size_t count, char ch)
232✔
149
  : buffer_(nullptr)
232✔
150
  , buffer_size_(0)
232✔
151
  , size_(0)
232✔
152
{
153
  buffer_size_ = count + 1;
232✔
154
  size_ = count;
232✔
155
  buffer_ = new char[buffer_size_];
232✔
156
  for (size_t i = 0; i < count; i++)
3,531✔
157
    buffer_[i] = ch;
3,299✔
158
  buffer_[count] = '\0';
232✔
159
}
232✔
160

161
String::String(const String& other)
9,356✔
162
  : buffer_(nullptr)
9,356✔
163
  , buffer_size_(0)
9,356✔
164
  , size_(0)
9,356✔
165
{
166
  copy_buffer_to_new_internal_buffer(other.c_str());
9,356✔
167
}
9,356✔
168

169
String::String(String&& other) noexcept
2,795✔
170
  : buffer_(other.buffer_)
2,795✔
171
  , buffer_size_(other.buffer_size_)
2,795✔
172
  , size_(other.size_)
2,795✔
173
{
174
  other.buffer_ = nullptr;
2,795✔
175
  other.buffer_size_ = 0;
2,795✔
176
  other.size_ = 0;
2,795✔
177
}
2,795✔
178

179
String& String::operator=(String&& other) noexcept
12,581✔
180
{
181
  if (this != &other) {
12,581✔
182
    deallocate_internal_buffer();
12,581✔
183
    buffer_ = other.buffer_;
12,581✔
184
    buffer_size_ = other.buffer_size_;
12,581✔
185
    size_ = other.size_;
12,581✔
186
    other.buffer_ = nullptr;
12,581✔
187
    other.buffer_size_ = 0;
12,581✔
188
    other.size_ = 0;
12,581✔
189
  }
190
  return *this;
12,581✔
191
}
192

193
String& String::operator=(const String& other)
1,011✔
194
{
195
  if (this != &other)
1,011✔
196
    copy_buffer_to_new_internal_buffer(other);
1,011✔
197
  return *this;
1,011✔
198
}
199

200
const char* String::c_str() const
128,872✔
201
{
202
  return buffer_;
128,872✔
203
}
204

205
const char* String::data() const
1✔
206
{
207
  return buffer_;
1✔
208
}
209

210
char* String::data()
10,328✔
211
{
212
  return buffer_;
10,328✔
213
}
214

215
size_t String::size() const
5,533✔
216
{
217
  return size_;
5,533✔
218
}
219

220
bool String::empty() const
1,133✔
221
{
222
  return size_ == 0;
1,133✔
223
}
224

225
String::~String()
96,191✔
226
{
227
  deallocate_internal_buffer();
96,191✔
228
}
96,191✔
229

230
bool operator==(const String& left, const String& right)
48,322✔
231
{
232
  return 0 == strcmp(left.c_str(), right.c_str());
48,322✔
233
}
234

235
bool operator!=(const String& left, const String& right)
2,752✔
236
{
237
  return !(left == right);
2,752✔
238
}
239

240
String String::operator+(const String& rhs) const
770✔
241
{
242
  String t(c_str());
770✔
243
  t += rhs.c_str();
770✔
244
  return t;
770✔
245
}
×
246

247
String& String::operator+=(const String& rhs)
4,946✔
248
{
249
  return operator+=(rhs.c_str());
4,946✔
250
}
251

252
String& String::operator+=(const char* rhs)
26,421✔
253
{
254
  size_t rhs_len = strlen(rhs);
26,421✔
255
  size_t new_size = size_ + rhs_len;
26,421✔
256
  size_t needed = new_size + 1;
26,421✔
257
  if (needed <= buffer_size_) {
26,421✔
258
    str_n_cpy(buffer_ + size_, rhs, rhs_len + 1);
11,405✔
259
  } else {
260
    size_t new_cap = buffer_size_ * 2;
15,016✔
261
    if (new_cap < needed)
15,016✔
262
      new_cap = needed;
4,425✔
263
    char* nb = new char[new_cap];
15,016✔
264
    str_n_cpy(nb, buffer_, size_ + 1);
15,016✔
265
    str_n_cpy(nb + size_, rhs, rhs_len + 1);
15,016✔
266
    delete[] buffer_;
15,016✔
267
    buffer_ = nb;
15,016✔
268
    buffer_size_ = new_cap;
15,016✔
269
  }
270
  size_ = new_size;
26,421✔
271
  return *this;
26,421✔
272
}
273

274
String& String::operator+=(char ch)
1,201✔
275
{
276
  size_t needed = size_ + 2;
1,201✔
277
  if (needed <= buffer_size_) {
1,201✔
278
    buffer_[size_] = ch;
1,199✔
279
    buffer_[size_ + 1] = '\0';
1,199✔
280
    size_ += 1;
1,199✔
281
    return *this;
1,199✔
282
  }
283
  char tmp[2] = { ch, '\0' };
2✔
284
  return operator+=(tmp);
2✔
285
}
286

287
void String::resize(size_t new_size)
106✔
288
{
289
  reserve(new_size);
106✔
290
  buffer_[new_size] = '\0';
106✔
291
  size_ = new_size;
106✔
292
}
106✔
293

294
String String::substr(size_t begin_pos, size_t amount) const
1,064✔
295
{
296
  if (begin_pos > size() - 1)
1,064✔
297
    return "";
6✔
298

299
  String new_string = c_str() + begin_pos;
1,058✔
300

301
  if (new_string.size_ > amount) {
1,058✔
302
    new_string.buffer_[amount] = '\0';
944✔
303
    new_string.size_ = amount;
944✔
304
  }
305

306
  return new_string;
1,058✔
307
}
1,058✔
308

309
String String::substr(size_t begin_pos) const
33✔
310
{
311
  return substr(begin_pos, npos);
33✔
312
}
313

314
size_t String::find(char ch, size_t pos) const
18✔
315
{
316
  size_t len = size();
18✔
317
  for (size_t i = pos; i < len; i++)
105✔
318
    if (c_str()[i] == ch)
102✔
319
      return i;
15✔
320
  return npos;
3✔
321
}
322

323
size_t String::find(const char* s, size_t pos) const
495✔
324
{
325
  if (pos > size())
495✔
326
    return npos;
×
327
  const char* found = strstr(c_str() + pos, s);
495✔
328
  if (found == nullptr)
495✔
329
    return npos;
446✔
330
  return static_cast<size_t>(found - c_str());
49✔
331
}
332

333
bool operator<(const String& left, const String& right)
3✔
334
{
335
  return strcmp(left.c_str(), right.c_str()) < 0;
3✔
336
}
337
#endif
338

339
bool string_contains(const String& str, const String& substr)
700✔
340
{
341
  return strstr(str.c_str(), substr.c_str()) != nullptr;
700✔
342
}
343

344
bool string_starts_with(const String& str, const String& prefix)
870✔
345
{
346
  if (prefix.size() == 0)
870✔
347
    return true;
1✔
348
  else if (str.size() == 0)
869✔
349
    return false;
1✔
350
  else
351
    return strstr(str.c_str(), prefix.c_str()) == str.c_str();
868✔
352
}
353

354
bool string_ends_with(const String& str, const String& suffix)
102✔
355
{
356
  size_t len = str.size();
102✔
357
  size_t other_len = suffix.size();
102✔
358

359
  if (other_len == 0)
102✔
360
    return true;
1✔
361
  if (len == 0)
101✔
362
    return false;
1✔
363
  if (len < other_len)
100✔
364
    return false;
1✔
365

366
  return strcmp(str.c_str() + len - other_len, suffix.c_str()) == 0;
99✔
367
}
368

369
void string_replace(String& str, char from, char to)
471✔
370
{
371
  size_t s = str.size();
471✔
372
  for (size_t i = 0; i < s; i++) {
10,401✔
373
    if (str[i] == from)
9,930✔
374
      str[i] = to;
26✔
375
  }
376
}
471✔
377

378
void string_replace(String& str, const char* from, const char* to)
445✔
379
{
380
  size_t fromlen = strlen(from);
445✔
381
  if (fromlen == 0)
445✔
382
    return;
423✔
383

384
  String result;
444✔
385
  size_t pos = 0;
444✔
386
  size_t found = str.find(from, pos);
444✔
387
  while (found != String::npos) {
485✔
388
    result += str.substr(pos, found - pos);
41✔
389
    result += to;
41✔
390
    pos = found + fromlen;
41✔
391
    found = str.find(from, pos);
41✔
392
  }
393
  if (pos == 0)
444✔
394
    return;
422✔
395
  result += str.substr(pos);
22✔
396
  str = result;
22✔
397
}
444✔
398

399
long strtol(const char* str)
12✔
400
{
401
#if MUTINY_USE_STD_STRING
402
  return std::strtol(str, nullptr, 10);
403
#else
404
  while (is_space(*str))
16✔
405
    str++;
4✔
406

407
  char first_char = *str;
12✔
408
  if (first_char == '-' || first_char == '+')
12✔
409
    str++;
3✔
410

411
  long result = 0;
12✔
412
  for (; is_digit(*str); str++) {
55✔
413
    result *= 10;
43✔
414
    result += *str - '0';
43✔
415
  }
416
  return (first_char == '-') ? -result : result;
12✔
417
#endif
418
}
419

420
unsigned long strtoul(const char* str)
18✔
421
{
422
#if MUTINY_USE_STD_STRING
423
  return std::strtoul(str, nullptr, 10);
424
#else
425
  while (is_space(*str))
23✔
426
    str++;
5✔
427

428
  bool negative = (*str == '-');
18✔
429
  if (*str == '-' || *str == '+')
18✔
430
    str++;
3✔
431

432
  unsigned long result = 0;
18✔
433
  for (; is_digit(*str); str++) {
62✔
434
    result *= 10;
44✔
435
    result += static_cast<unsigned long>(*str - '0');
44✔
436
  }
437
  return negative ? -result : result;
18✔
438
#endif
439
}
440

441
int strcmp(const char* s1, const char* s2)
49,439✔
442
{
443
#if MUTINY_USE_STD_STRING
444
  return std::strcmp(s1, s2);
445
#else
446
  while (*s1 && *s1 == *s2) {
147,454✔
447
    ++s1;
98,015✔
448
    ++s2;
98,015✔
449
  }
450
  return *reinterpret_cast<const unsigned char*>(s1) -
49,439✔
451
         *reinterpret_cast<const unsigned char*>(s2);
49,439✔
452
#endif
453
}
454

455
size_t strlen(const char* str)
124,143✔
456
{
457
#if MUTINY_USE_STD_STRING
458
  return std::strlen(str);
459
#else
460
  auto n = static_cast<size_t>(-1);
124,143✔
461
  do
462
    n++;
1,962,145✔
463
  while (*str++);
1,962,145✔
464
  return n;
124,143✔
465
#endif
466
}
467

468
int strncmp(const char* s1, const char* s2, size_t n)
114,858✔
469
{
470
#if MUTINY_USE_STD_STRING
471
  return std::strncmp(s1, s2, n);
472
#else
473
  while (n && *s1 && *s1 == *s2) {
138,315✔
474
    --n;
23,457✔
475
    ++s1;
23,457✔
476
    ++s2;
23,457✔
477
  }
478
  return n ? *reinterpret_cast<const unsigned char*>(s1) -
114,858✔
479
                 *reinterpret_cast<const unsigned char*>(s2)
112,200✔
480
           : 0;
114,858✔
481
#endif
482
}
483

484
const char* strstr(const char* s1, const char* s2)
3,985✔
485
{
486
#if MUTINY_USE_STD_STRING
487
  return std::strstr(s1, s2);
488
#else
489
  if (!*s2)
3,985✔
490
    return s1;
7✔
491
  size_t s2_len = strlen(s2);
3,978✔
492
  for (; *s1; s1++)
116,166✔
493
    if (strncmp(s1, s2, s2_len) == 0)
114,838✔
494
      return s1;
2,650✔
495
  return nullptr;
1,328✔
496
#endif
497
}
498

499
char tolower(char ch)
32✔
500
{
501
#if MUTINY_USE_STD_STRING
502
  return static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
503
#else
504
  return is_upper(ch) ? static_cast<char>(static_cast<int>(ch) + ('a' - 'A'))
32✔
505
                      : ch;
32✔
506
#endif
507
}
508

509
int memcmp(const void* s1, const void* s2, size_t n)
21✔
510
{
511
#if MUTINY_USE_STD_STRING
512
  return std::memcmp(s1, s2, n);
513
#else
514
  auto* p1 = static_cast<const unsigned char*>(s1);
21✔
515
  auto* p2 = static_cast<const unsigned char*>(s2);
21✔
516

517
  while (n--)
74✔
518
    if (*p1 != *p2) {
63✔
519
      return *p1 - *p2;
10✔
520
    } else {
521
      ++p1;
53✔
522
      ++p2;
53✔
523
    }
524
  return 0;
11✔
525
#endif
526
}
527

528
bool iscntrl(char ch)
834✔
529
{
530
#if MUTINY_USE_STD_STRING
531
  return std::iscntrl(static_cast<unsigned char>(ch)) != 0;
532
#else
533
  return ch < ' ' || ch == char(0x7F);
834✔
534
#endif
535
}
536

537
String string_from(bool value)
4✔
538
{
539
  return String(value ? "true" : "false");
4✔
540
}
541

542
String string_from(const char* value)
131✔
543
{
544
  return String(value);
131✔
545
}
546

547
String string_from_or_null(const char* expected)
13✔
548
{
549
  return (expected) ? string_from(expected) : string_from("(null)");
13✔
550
}
551

552
String string_from(int value)
88✔
553
{
554
  return string_from_format("%d", value);
88✔
555
}
556

557
String string_from(long value)
14✔
558
{
559
  return string_from_format("%ld", value);
14✔
560
}
561

562
String string_from(const void* value)
19✔
563
{
564
  return String("0x") + hex_string_from(value);
19✔
565
}
566

567
String string_from(void (*value)())
7✔
568
{
569
  return String("0x") + hex_string_from(value);
7✔
570
}
571

572
String hex_string_from(long value)
8✔
573
{
574
  return hex_string_from(static_cast<unsigned long>(value));
8✔
575
}
576

577
String hex_string_from(int value)
39✔
578
{
579
  return hex_string_from(static_cast<unsigned int>(value));
39✔
580
}
581

582
String hex_string_from(signed char value)
9✔
583
{
584
  String result = string_from_format("%x", value);
9✔
585
  if (value < 0) {
9✔
586
    size_t size = result.size();
6✔
587
    result = result.substr(size - (CHAR_BIT / 4));
6✔
588
  }
589
  return result;
9✔
590
}
×
591

592
String hex_string_from(unsigned long value)
14✔
593
{
594
  return string_from_format("%lx", value);
14✔
595
}
596

597
String hex_string_from(unsigned int value)
51✔
598
{
599
  return string_from_format("%x", value);
51✔
600
}
601

602
String brackets_formatted_hex_string_from(int value)
39✔
603
{
604
  return brackets_formatted_hex_string(hex_string_from(value));
39✔
605
}
606

607
String brackets_formatted_hex_string_from(unsigned int value)
12✔
608
{
609
  return brackets_formatted_hex_string(hex_string_from(value));
12✔
610
}
611

612
String brackets_formatted_hex_string_from(long value)
7✔
613
{
614
  return brackets_formatted_hex_string(hex_string_from(value));
7✔
615
}
616

617
String brackets_formatted_hex_string_from(unsigned long value)
6✔
618
{
619
  return brackets_formatted_hex_string(hex_string_from(value));
6✔
620
}
621

622
String brackets_formatted_hex_string_from(signed char value)
7✔
623
{
624
  return brackets_formatted_hex_string(hex_string_from(value));
7✔
625
}
626

627
String brackets_formatted_hex_string(const String& hex_string)
109✔
628
{
629
  return String("(0x") + hex_string + ")";
218✔
630
}
631

632
#if MUTINY_USE_STD_CPP_LIB
633
String string_from(const std::nullptr_t value)
1✔
634
{
635
  (void)value;
636
  return "(null)";
1✔
637
}
638

639
#if !MUTINY_USE_STD_STRING
640
String string_from(std::string const& str)
1✔
641
{
642
  return String(str.c_str());
1✔
643
}
644
#endif
645
#endif
646

647
String string_from(long long value)
21✔
648
{
649
  return string_from_format("%lld", value);
21✔
650
}
651

652
String string_from(unsigned long long value)
18✔
653
{
654
  return string_from_format("%llu", value);
18✔
655
}
656

657
String hex_string_from(long long value)
22✔
658
{
659
  return hex_string_from(static_cast<unsigned long long>(value));
22✔
660
}
661

662
String hex_string_from(unsigned long long value)
39✔
663
{
664
  return string_from_format("%llx", value);
39✔
665
}
666

667
String hex_string_from(const void* value)
24✔
668
{
669
  return string_from_format("%" PRIxPTR, reinterpret_cast<uintptr_t>(value));
24✔
670
}
671

672
String hex_string_from(void (*value)())
9✔
673
{
674
  return string_from_format("%" PRIxPTR, reinterpret_cast<uintptr_t>(value));
9✔
675
}
676

677
String brackets_formatted_hex_string_from(long long value)
21✔
678
{
679
  return brackets_formatted_hex_string(hex_string_from(value));
21✔
680
}
681

682
String brackets_formatted_hex_string_from(unsigned long long value)
17✔
683
{
684
  return brackets_formatted_hex_string(hex_string_from(value));
17✔
685
}
686

687
String string_from(float value)
2✔
688
{
689
  if (is_nan(value))
2✔
690
    return "Nan - Not a number";
1✔
691
  else if (is_inf(value))
1✔
692
    return "Inf - Infinity";
1✔
693
  else
NEW
694
    return string_from_format("%.7g", value);
×
695
}
696

697
String string_from(double value, int precision)
53✔
698
{
699
  if (is_nan(value))
53✔
700
    return "Nan - Not a number";
4✔
701
  else if (is_inf(value))
49✔
702
    return "Inf - Infinity";
3✔
703
  else
704
    return string_from_format("%.*g", precision, value);
46✔
705
}
706

707
String string_from(char value)
99✔
708
{
709
  return String(1, value);
99✔
710
}
711

712
String string_from(const String& value)
1✔
713
{
714
  return String(value);
1✔
715
}
716

717
String string_from_format(const char* format, ...)
4,834✔
718
{
719
  String result_string;
4,834✔
720
  va_list arguments;
721
  va_start(arguments, format);
4,834✔
722

723
  result_string = v_string_from_format(format, arguments);
4,834✔
724
  va_end(arguments);
4,834✔
725
  return result_string;
9,668✔
726
}
×
727

728
String string_from(unsigned int i)
13✔
729
{
730
  return string_from_format("%u", i);
13✔
731
}
732

733
String string_from(unsigned long i)
2,539✔
734
{
735
  return string_from_format("%lu", i);
2,539✔
736
}
737

738
String v_string_from_format(const char* format, va_list args)
4,834✔
739
{
740
  va_list args_copy;
741
  va_copy(args_copy, args);
4,834✔
742
  constexpr size_t size_ofdefault_buffer = 100;
4,834✔
743
  char default_buffer[size_ofdefault_buffer];
744
  String result_string;
4,834✔
745

746
  auto size = static_cast<size_t>(
747
      vsnprintf(default_buffer, size_ofdefault_buffer, format, args)
4,834✔
748
  );
4,834✔
749
  if (size < size_ofdefault_buffer) {
4,834✔
750
    result_string = String(default_buffer);
4,728✔
751
  } else {
752
#if !MUTINY_USE_STD_STRING
753
    result_string.resize(size);
106✔
754
    vsnprintf(result_string.data(), size + 1, format, args_copy);
106✔
755
#else
756
    size_t new_buffer_size = size + 1;
757
    char* new_buffer = new char[new_buffer_size];
758
    vsnprintf(new_buffer, new_buffer_size, format, args_copy);
759
    result_string = String(new_buffer);
760
    delete[] new_buffer;
761
#endif
762
  }
763
  va_end(args_copy);
4,834✔
764
  return result_string;
9,668✔
765
}
×
766

767
String string_from_binary(const unsigned char* value, size_t size)
44✔
768
{
769
  static const char hex_digits[] = "0123456789ABCDEF";
770
  String result;
44✔
771
  if (size == 0)
44✔
772
    return result;
2✔
773
  result.reserve(size * 3 - 1);
42✔
774
  for (size_t i = 0; i < size; i++) {
318✔
775
    if (i > 0)
276✔
776
      result += ' ';
234✔
777
    result += hex_digits[value[i] >> 4];
276✔
778
    result += hex_digits[value[i] & 0xF];
276✔
779
  }
780
  return result;
42✔
781
}
×
782

783
String string_from_binary_or_null(const unsigned char* value, size_t size)
47✔
784
{
785
  return (value) ? string_from_binary(value, size) : string_from("(null)");
47✔
786
}
787

788
String string_from_binary_with_size(const unsigned char* value, size_t size)
17✔
789
{
790
  String result = string_from_format(
791
      "Size = %u | HexContents = ", static_cast<unsigned>(size)
792
  );
17✔
793
  size_t displayed_size = ((size > 128) ? 128 : size);
17✔
794
  result += string_from_binary_or_null(value, displayed_size);
17✔
795
  if (size > displayed_size) {
17✔
796
    result += " ...";
1✔
797
  }
798
  return result;
17✔
799
}
×
800

801
String string_from_binary_with_size_or_null(
15✔
802
    const unsigned char* value,
803
    size_t size
804
)
805
{
806
  return (value) ? string_from_binary_with_size(value, size)
15✔
807
                 : string_from("(null)");
15✔
808
}
809

810
String string_from_ordinal_number(unsigned int number)
33✔
811
{
812
  const char* suffix = "th";
33✔
813

814
  if ((number < 11) || (number > 13)) {
33✔
815
    unsigned int const ones_digit = number % 10;
27✔
816
    if (3 == ones_digit) {
27✔
817
      suffix = "rd";
6✔
818
    } else if (2 == ones_digit) {
21✔
819
      suffix = "nd";
7✔
820
    } else if (1 == ones_digit) {
14✔
821
      suffix = "st";
3✔
822
    }
823
  }
824

825
  return string_from_format("%u%s", number, suffix);
33✔
826
}
827

828
} // namespace tiny
829
} // namespace mu
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

© 2026 Coveralls, Inc