| 5463 | } |
| 5464 | |
| 5465 | String String::sprintf(const Array &values, bool *error) const { |
| 5466 | static const String ZERO("0"); |
| 5467 | static const String SPACE(" "); |
| 5468 | static const String MINUS("-"); |
| 5469 | static const String PLUS("+"); |
| 5470 | |
| 5471 | String formatted; |
| 5472 | char32_t *self = (char32_t *)get_data(); |
| 5473 | bool in_format = false; |
| 5474 | int value_index = 0; |
| 5475 | int min_chars = 0; |
| 5476 | int min_decimals = 0; |
| 5477 | bool in_decimals = false; |
| 5478 | bool pad_with_zeros = false; |
| 5479 | bool left_justified = false; |
| 5480 | bool show_sign = false; |
| 5481 | bool as_unsigned = false; |
| 5482 | |
| 5483 | if (error) { |
| 5484 | *error = true; |
| 5485 | } |
| 5486 | |
| 5487 | for (; *self; self++) { |
| 5488 | const char32_t c = *self; |
| 5489 | |
| 5490 | if (in_format) { // We have % - let's see what else we get. |
| 5491 | switch (c) { |
| 5492 | case '%': { // Replace %% with % |
| 5493 | formatted += c; |
| 5494 | in_format = false; |
| 5495 | break; |
| 5496 | } |
| 5497 | case 'd': // Integer (signed) |
| 5498 | case 'o': // Octal |
| 5499 | case 'x': // Hexadecimal (lowercase) |
| 5500 | case 'X': { // Hexadecimal (uppercase) |
| 5501 | if (value_index >= values.size()) { |
| 5502 | return "not enough arguments for format string"; |
| 5503 | } |
| 5504 | |
| 5505 | if (!values[value_index].is_num()) { |
| 5506 | return "a number is required"; |
| 5507 | } |
| 5508 | |
| 5509 | int64_t value = values[value_index]; |
| 5510 | int base = 16; |
| 5511 | bool capitalize = false; |
| 5512 | switch (c) { |
| 5513 | case 'd': |
| 5514 | base = 10; |
| 5515 | break; |
| 5516 | case 'o': |
| 5517 | base = 8; |
| 5518 | break; |
| 5519 | case 'x': |
| 5520 | break; |
| 5521 | case 'X': |
| 5522 | capitalize = true; |
no test coverage detected