Skip to content

Commit

Permalink
Fix single header csv.hpp (#53)
Browse files Browse the repository at this point in the history
* Added compile test for #including single header csv.hpp in multiple .cpp files

* Update csv_utility.cpp

* Updated single header csv.hpp

* Code cleanup
  • Loading branch information
vincentlaucsb authored Sep 7, 2019
1 parent 6eb439f commit e4a899d
Show file tree
Hide file tree
Showing 28 changed files with 6,410 additions and 400 deletions.
10 changes: 9 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ endif(CSV_CXX_STANDARD)
message("Building CSV library using C++${CMAKE_CXX_STANDARD}")

# Defines CSV_HAS_CXX17 in compatibility.hpp
add_compile_definitions(CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD})
if (CMAKE_VERSION VERSION_LESS "3.12.0")
add_definitions(-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD})
else()
add_compile_definitions(CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD})
endif()

set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads QUIET REQUIRED)
Expand Down Expand Up @@ -60,12 +64,16 @@ if (CSV_DEVELOPER)
if(Python3_Interpreter_FOUND)
add_custom_target(generate_single_header
COMMAND ${Python3_EXECUTABLE} single_header.py > single_include/csv.hpp
COMMAND ${Python3_EXECUTABLE} single_header.py > single_include_test/csv.hpp
WORKING_DIRECTORY ${CSV_ROOT_DIR}
)
else()
message(WARNING "Python3 not found, skipping target 'generate_single_header'.")
endif()

# Single header compilation test
add_subdirectory(single_include_test)

# Documentation
find_package(Doxygen QUIET)
if(DOXYGEN_FOUND)
Expand Down
6 changes: 3 additions & 3 deletions Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -1997,15 +1997,15 @@ ENABLE_PREPROCESSING = YES
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.

MACRO_EXPANSION = NO
MACRO_EXPANSION = YES

# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
# the macro expansion is limited to the macros specified with the PREDEFINED and
# EXPAND_AS_DEFINED tags.
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.

EXPAND_ONLY_PREDEF = NO
EXPAND_ONLY_PREDEF = YES

# If the SEARCH_INCLUDES tag is set to YES, the include files in the
# INCLUDE_PATH will be searched if a #include is found.
Expand Down Expand Up @@ -2046,7 +2046,7 @@ PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS
# definition found in the source code.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.

EXPAND_AS_DEFINED =
EXPAND_AS_DEFINED = CSV_INLINE

# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have
Expand Down
5 changes: 5 additions & 0 deletions include/internal/compatibility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
* Defines various compatibility macros
*/

/** Helper macro which should be #defined as "inline"
* in the single header version
*/
#define CSV_INLINE

#pragma once
#include "../external/string_view.hpp"

Expand Down
48 changes: 7 additions & 41 deletions include/internal/csv_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,77 +8,43 @@
#include "csv_format.hpp"

namespace csv {
CSVFormat create_default_csv_strict() {
CSVFormat format;
format.delimiter(',')
.quote('"')
.header_row(0)
.detect_bom(true)
.strict_parsing(true);

return format;
}

CSVFormat create_guess_csv() {
CSVFormat format;
format.delimiter({ ',', '|', '\t', ';', '^' })
.quote('"')
.header_row(0)
.detect_bom(true);

return format;
}

const CSVFormat CSVFormat::RFC4180_STRICT = create_default_csv_strict();
const CSVFormat CSVFormat::GUESS_CSV = create_guess_csv();

CSVFormat& CSVFormat::delimiter(char delim) {
CSV_INLINE CSVFormat& CSVFormat::delimiter(char delim) {
this->possible_delimiters = { delim };
this->assert_no_char_overlap();
return *this;
}

CSVFormat& CSVFormat::delimiter(const std::vector<char> & delim) {
CSV_INLINE CSVFormat& CSVFormat::delimiter(const std::vector<char> & delim) {
this->possible_delimiters = delim;
this->assert_no_char_overlap();
return *this;
}

CSVFormat& CSVFormat::quote(char quote) {
CSV_INLINE CSVFormat& CSVFormat::quote(char quote) {
this->quote_char = quote;
this->assert_no_char_overlap();
return *this;
}

CSVFormat& CSVFormat::trim(const std::vector<char> & chars) {
CSV_INLINE CSVFormat& CSVFormat::trim(const std::vector<char> & chars) {
this->trim_chars = chars;
this->assert_no_char_overlap();
return *this;
}

CSVFormat& CSVFormat::column_names(const std::vector<std::string>& names) {
CSV_INLINE CSVFormat& CSVFormat::column_names(const std::vector<std::string>& names) {
this->col_names = names;
this->header = -1;
return *this;
}

CSVFormat& CSVFormat::header_row(int row) {
CSV_INLINE CSVFormat& CSVFormat::header_row(int row) {
this->header = row;
this->col_names = {};
return *this;
}

CSVFormat& CSVFormat::strict_parsing(bool throw_error) {
this->strict = throw_error;
return *this;
}

CSVFormat& CSVFormat::detect_bom(bool detect) {
this->unicode_detect = detect;
return *this;
}

void CSVFormat::assert_no_char_overlap()
CSV_INLINE void CSVFormat::assert_no_char_overlap()
{
auto delims = std::set<char>(
this->possible_delimiters.begin(), this->possible_delimiters.end()),
Expand Down
35 changes: 30 additions & 5 deletions include/internal/csv_format.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <string>
#include <vector>

#include "compatibility.hpp"

namespace csv {
class CSVReader;

Expand Down Expand Up @@ -65,10 +67,16 @@ namespace csv {
/** Tells the parser to throw an std::runtime_error if an
* invalid CSV sequence is found
*/
CSVFormat& strict_parsing(bool strict = true);
CONSTEXPR CSVFormat& strict_parsing(bool strict = true) {
this->strict = strict;
return *this;
}

/** Tells the parser to detect and remove UTF-8 byte order marks */
CSVFormat& detect_bom(bool detect = true);
CONSTEXPR CSVFormat& detect_bom(bool detect = true) {
this->unicode_detect = detect;
return *this;
}

#ifndef DOXYGEN_SHOULD_SKIP_THIS
char get_delim() {
Expand All @@ -80,16 +88,33 @@ namespace csv {
return this->possible_delimiters.at(0);
}

int get_header() {
CONSTEXPR int get_header() {
return this->header;
}
#endif

/** CSVFormat for guessing the delimiter */
static const CSVFormat GUESS_CSV;
CSV_INLINE static CSVFormat guess_csv() {
CSVFormat format;
format.delimiter({ ',', '|', '\t', ';', '^' })
.quote('"')
.header_row(0)
.detect_bom(true);

return format;
}

/** CSVFormat for strict RFC 4180 parsing */
static const CSVFormat RFC4180_STRICT;
CSV_INLINE static CSVFormat rfc4180_strict() {
CSVFormat format;
format.delimiter(',')
.quote('"')
.header_row(0)
.detect_bom(true)
.strict_parsing(true);

return format;
}

friend CSVReader;
private:
Expand Down
Loading

0 comments on commit e4a899d

Please sign in to comment.