Skip to content

Commit 6630020

Browse files
committed
Merge branch 'header-parsing'
2 parents bef3103 + 2c9912e commit 6630020

File tree

6 files changed

+161
-16
lines changed

6 files changed

+161
-16
lines changed

CMakeLists.txt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,23 @@ cmake_minimum_required(VERSION 3.10)
22

33
project(dbc)
44

5+
option(DEBUG "use debug flag" NO)
6+
57
# specify the C++ standard
68
set(CMAKE_CXX_STANDARD 11)
79
set(CMAKE_CXX_STANDARD_REQUIRED True)
810

9-
# Add in the debug flag0.
10-
set(GCC_COVERAGE_COMPILE_FLAGS "-g")
11+
set(GCC_COMPILE_FLAGS "-Wextra -Wall -Wfloat-equal -Wundef -Wshadow \
12+
-Wpointer-arith -Wcast-align -Wstrict-prototypes -Wwrite-strings \
13+
-Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wconversion \
14+
-Wunreachable-code -Wformat=2 -Werror -Wuninitialized -Winit-self")
15+
16+
if(DEBUG)
17+
set(GCC_COMPILE_FLAGS ${GCC_COMPILE_FLAGS}" -g")
18+
else()
19+
set(GCC_COMPILE_FLAGS ${GCC_COMPILE_FLAGS}" -O2")
20+
endif()
21+
1122
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
1223

1324
# add where to find the source files

src/dbc.hpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ namespace libdbc {
1818

1919
class DbcParser : public Parser {
2020
public:
21-
DbcParser() : version(""), version_re("(VERSION)\\s\"(.*)\"") {}
21+
DbcParser() : version(""), version_re("^(VERSION)\\s\"(.*)\""),
22+
bit_timing_re("^(BS_:)"), name_space_re("^(NS_)\\s\\:") {
23+
24+
}
2225

2326
virtual ~DbcParser() = default;
2427

@@ -29,7 +32,7 @@ namespace libdbc {
2932
parse_dbc_header(s);
3033

3134
while(!s.eof()) {
32-
utils::SafeString::get_line(s, line);
35+
utils::StreamHandler::get_line(s, line);
3336

3437
}
3538

@@ -43,23 +46,44 @@ namespace libdbc {
4346
std::string version;
4447

4548
const std::regex version_re;
49+
const std::regex bit_timing_re;
50+
const std::regex name_space_re;
4651

4752
void parse_dbc_header(std::istream& file_stream) {
4853
std::string line;
4954
std::smatch match;
55+
bool is_blank = true;
56+
bool not_blank = true;
5057

51-
utils::SafeString::get_line(file_stream, line);
58+
utils::StreamHandler::get_line(file_stream, line);
5259

5360
if(!std::regex_search(line, match, version_re)) {
5461
throw validity_error();
5562
}
5663

5764
version = match.str(2);
5865

66+
utils::StreamHandler::get_next_non_blank_line( file_stream, line );
67+
68+
utils::StreamHandler::skip_to_next_blank_line( file_stream, line );
69+
70+
utils::StreamHandler::get_next_non_blank_line( file_stream, line );
71+
72+
if(!std::regex_search(line, match, bit_timing_re))
73+
throw validity_error();
74+
75+
}
76+
std::string trim(const std::string& line)
77+
{
78+
const char* WhiteSpace = " \t\v\r\n";
79+
std::size_t start = line.find_first_not_of(WhiteSpace);
80+
std::size_t end = line.find_last_not_of(WhiteSpace);
81+
return start == end ? std::string() : line.substr(start, end - start + 1);
5982
}
6083

6184
};
6285

86+
6387
struct Message {
6488

6589
};

src/util/utils.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#include "util/utils.hpp"
22

3+
#include <regex>
4+
35
namespace utils {
46

5-
std::istream & SafeString::get_line( std::istream & stream, std::string & line ) {
7+
std::istream & StreamHandler::get_line( std::istream & stream, std::string & line ) {
68
std::string newline;
79

810
std::getline( stream, newline );
@@ -20,4 +22,46 @@ namespace utils {
2022
return stream;
2123
}
2224

25+
26+
std::istream & StreamHandler::get_next_non_blank_line( std::istream & stream, std::string & line ) {
27+
bool is_blank = true;
28+
29+
const std::regex whitespace_re("\\s*(.*)");
30+
std::smatch match;
31+
32+
while(is_blank) {
33+
utils::StreamHandler::get_line(stream, line);
34+
35+
std::regex_search(line, match, whitespace_re);
36+
37+
if((!line.empty() && !match.empty()) || (stream.eof())){
38+
if((match.length(1) > 0) || (stream.eof())){
39+
is_blank = false;
40+
}
41+
}
42+
}
43+
44+
return stream;
45+
}
46+
47+
std::istream & StreamHandler::skip_to_next_blank_line( std::istream & stream, std::string & line ) {
48+
bool line_is_empty = false;
49+
50+
const std::regex whitespace_re("\\s*(.*)");
51+
std::smatch match;
52+
53+
while(!line_is_empty) {
54+
utils::StreamHandler::get_line(stream, line);
55+
56+
std::regex_search(line, match, whitespace_re);
57+
58+
if((match.length(1) == 0) || (stream.eof())){
59+
line_is_empty = true;
60+
}
61+
}
62+
63+
return stream;
64+
}
65+
66+
2367
} // Namespace Utils

src/util/utils.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace utils {
66

7-
class SafeString {
7+
class StreamHandler {
88
public:
99
/**
1010
* This is a safe non line ending specific get_ine function. This is to help with files
@@ -17,6 +17,11 @@ namespace utils {
1717
*/
1818
static std::istream & get_line( std::istream & stream, std::string & line );
1919

20+
21+
static std::istream & get_next_non_blank_line( std::istream & stream, std::string & line );
22+
23+
static std::istream & skip_to_next_blank_line( std::istream & stream, std::string & line );
24+
2025
};
2126

2227
}

test/test_dbc.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,30 @@
22
#include "defines.hpp"
33
#include "dbc.hpp"
44

5-
TEST_CASE("Testing dbc file loading", "[fileio]") {
5+
TEST_CASE("Testing dbc file loading error issues", "[fileio][error]") {
66
auto parser = std::unique_ptr<libdbc::DbcParser>(new libdbc::DbcParser());
77

88
SECTION("Loading a non dbc file should throw an error", "[error]") {
99
REQUIRE_THROWS_AS(parser->parse_file(TEXT_FILE), libdbc::validity_error);
1010
}
1111

12-
// Undecided on the type of error yet. Need to think about this.
13-
// SECTION("Loading a dbc with bad headers throws an error", "[error]") {
14-
// REQUIRE_THROWS_AS(parser->parse_file(MISSING_VERSION_DBC_FILE), libdbc::header_error);
15-
// }
12+
SECTION("Loading a dbc with bad headers throws an error", "[error]") {
13+
REQUIRE_THROWS_AS(parser->parse_file(MISSING_VERSION_DBC_FILE), libdbc::validity_error);
14+
}
15+
16+
SECTION("Loading a dbc without the required bit timing section (BS_:)", "[error]") {
17+
REQUIRE_THROWS_AS(parser->parse_file(MISSING_BIT_TIMING_DBC_FILE), libdbc::validity_error);
18+
}
19+
20+
SECTION("Loading a dbc with some missing namespace section tags (_NS :)", "[error]") {
21+
// Confusion about this type of error. it appears that the header isn't
22+
// very well standardized for now we ignore this type of error.
23+
CHECK_NOTHROW(parser->parse_file(MISSING_NEW_SYMBOLS_DBC_FILE));
24+
}
25+
}
26+
27+
TEST_CASE("Testing dbc file loading", "[fileio]") {
28+
auto parser = std::unique_ptr<libdbc::DbcParser>(new libdbc::DbcParser());
1629

1730
SECTION("Loading a single simple dbc file", "[dbc]") {
1831
std::vector<libdbc::Message> messages;

test/test_utils.cpp

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#include "defines.hpp"
33
#include "util/utils.hpp"
44

5+
#include <sstream>
6+
57
using namespace utils;
68

79
TEST_CASE("Basic file input with safe get_line that is non line ending specific", "") {
@@ -13,16 +15,62 @@ TEST_CASE("Basic file input with safe get_line that is non line ending specific"
1315
CHECK(TextFile.is_open());
1416

1517
if(TextFile.is_open()) {
16-
SafeString::get_line(TextFile, test);
18+
StreamHandler::get_line(TextFile, test);
1719
REQUIRE(test == "This is a non dbc formatted file.");
18-
SafeString::get_line(TextFile, test);
20+
StreamHandler::get_line(TextFile, test);
1921
REQUIRE(test == "");
20-
SafeString::get_line(TextFile, test);
22+
StreamHandler::get_line(TextFile, test);
2123
REQUIRE(test == "Make sure things pass with this");
22-
SafeString::get_line(TextFile, test);
24+
StreamHandler::get_line(TextFile, test);
2325
REQUIRE(test == "Who knows what might happen.");
2426

2527
TextFile.close();
2628
}
2729
}
2830
}
31+
32+
TEST_CASE("Test line finding utility functions", "") {
33+
std::string line;
34+
std::string test_string = \
35+
"hello\n\
36+
\n\
37+
\n\
38+
\n\
39+
this is not blank\n\
40+
maybe not this one either\n\
41+
\n\
42+
Someone wrote something....\n\
43+
b\n\
44+
end";
45+
46+
std::istringstream stream(test_string);
47+
48+
SECTION("Test skipping empty lines") {
49+
StreamHandler::get_line(stream, line);
50+
51+
CHECK(line == "hello");
52+
53+
StreamHandler::get_next_non_blank_line(stream, line);
54+
REQUIRE(line == "this is not blank");
55+
56+
StreamHandler::skip_to_next_blank_line(stream, line);
57+
REQUIRE(line == "");
58+
59+
StreamHandler::get_next_non_blank_line(stream, line);
60+
REQUIRE(line == "Someone wrote something....");
61+
62+
StreamHandler::get_next_non_blank_line(stream, line);
63+
REQUIRE(line == " b");
64+
65+
StreamHandler::get_next_non_blank_line(stream, line);
66+
REQUIRE(line == "end");
67+
68+
SECTION("Test end of the files", "[edge case]") {
69+
StreamHandler::get_next_non_blank_line(stream, line);
70+
REQUIRE(line == "");
71+
72+
StreamHandler::skip_to_next_blank_line(stream, line);
73+
REQUIRE(line == "");
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)