Skip to content

Commit 6aa1e3c

Browse files
committed
Improvements to format.cpp.
- `format` now checks for invalid values of index. - Added tests for `format`.
1 parent 19db61e commit 6aa1e3c

File tree

4 files changed

+70
-6
lines changed

4 files changed

+70
-6
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ SET(COMPONENTS
105105
# NEW_COMPONENT: PATCH Do NOT remove the previous comment.
106106

107107
SET(TARGETS ${COMPONENTS} util)
108-
SET(TEST_TARGETS_TEMP util fraction number factors ${COMPONENTS})
108+
SET(TEST_TARGETS_TEMP util fraction number factors format ${COMPONENTS})
109109

110110
FOREACH(TEST_TARGET IN LISTS TEST_TARGETS_TEMP)
111111
SET(TARGET_NAME "test")

include/output.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ namespace steppable::output
130130
const std::basic_string<T>& msg,
131131
const std::vector<std::string>& args = {})
132132
{
133-
std::cout << colors::brightGreen << formats::bold << LARGE_DOT << name << " INFO: " << reset
133+
std::cout << colors::brightGreen << formats::bold << LARGE_DOT << name << " - INFO: " << reset
134134
<< colors::brightGreen;
135135
std::cout << format::format(msg, args) << reset << '\n';
136136
}

src/format.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include "format.hpp"
2424

25+
#include <algorithm>
2526
#include <stdexcept>
2627
#include <string>
2728
#include <vector>
@@ -41,28 +42,36 @@ namespace steppable::__internals::format
4142
std::string result = format;
4243
std::string index;
4344
bool inBrackets = false;
44-
for (char i : format)
45+
for (size_t idx = 0; idx < format.size(); idx++)
4546
{
47+
char i = format.at(idx);
4648
switch (i)
4749
{
4850
// Start replacing!
4951
case '{':
5052
{
5153
inBrackets = true;
52-
index = i;
54+
index.erase(index.begin(), index.end());
5355
break;
5456
}
5557

5658
// End replacing
5759
case '}':
5860
{
5961
inBrackets = false;
60-
size_t argIndex = std::stoull(index.substr(1));
62+
// SIZE_MAX is 20 digits long, so we can safely assume that the index must not be longer than 20
63+
// characters.
64+
if (index.length() > 20 or index.length() < 1)
65+
throw std::length_error("Argument index too long or too short.");
66+
if (not std::ranges::all_of(index, [](const char& c) { return std::isdigit(c); }))
67+
throw std::invalid_argument("Argument index must be a number.");
68+
69+
size_t argIndex = std::stoull(index);
6170
if (argIndex >= args.size())
6271
throw std::out_of_range("Argument index out of range.");
6372

6473
// +1 for the closing bracket
65-
result.replace(result.find(index), index.size() + 1, args.at(argIndex));
74+
result.replace(result.find("{" + index), index.size() + 2, args.at(argIndex));
6675
break;
6776
}
6877

tests/testFormat.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**************************************************************************************************
2+
* Copyright (c) 2023-2024 NWSOFT *
3+
* *
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy *
5+
* of this software and associated documentation files (the "Software"), to deal *
6+
* in the Software without restriction, including without limitation the rights *
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
8+
* copies of the Software, and to permit persons to whom the Software is *
9+
* furnished to do so, subject to the following conditions: *
10+
* *
11+
* The above copyright notice and this permission notice shall be included in all *
12+
* copies or substantial portions of the Software. *
13+
* *
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
20+
* SOFTWARE. *
21+
**************************************************************************************************/
22+
23+
#include "colors.hpp"
24+
#include "factors.hpp"
25+
#include "output.hpp"
26+
#include "testing.hpp"
27+
#include "util.hpp"
28+
29+
#include <iomanip>
30+
#include <iostream>
31+
#include <string>
32+
33+
using namespace steppable::__internals;
34+
35+
TEST_START()
36+
SECTION(Test format)
37+
const std::string& formatOrig = "Hello, {0}!";
38+
const std::string& arg = "world";
39+
const std::string& expected = "Hello, world!";
40+
41+
const std::string& result = format::format(formatOrig, { arg });
42+
_.assertIsEqual(result, expected);
43+
SECTION_END()
44+
45+
SECTION(Test format with multiple values)
46+
const std::string& formatOrig = "{0}, {1}!";
47+
const std::string& arg1 = "Hello";
48+
const std::string& arg2 = "world";
49+
const std::string& expected = "Hello, world!";
50+
51+
const std::string& result = format::format(formatOrig, { arg1, arg2 });
52+
_.assertIsEqual(result, expected);
53+
SECTION_END()
54+
55+
TEST_END()

0 commit comments

Comments
 (0)