Skip to content

Commit

Permalink
Fix #78 with new c'tor for read_input.
Browse files Browse the repository at this point in the history
  • Loading branch information
ColinH committed Dec 10, 2017
1 parent 78eb286 commit 60b6987
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 17 deletions.
7 changes: 6 additions & 1 deletion doc/Inputs-and-Parsing.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,20 @@ The classes `file_input<>`, `read_input<>` and, on supported platforms, `mmap_in
* `mmap_input<>` uses `mmap(2)` and is available on POSIX compliant systems.
* `file_input<>` is a type alias for `mmap_input<>` when available, and `read_input<>` otherwise.

All file input classes take a single argument, the filename, which can be supplied as `std::string` or `const char*`.
Most file input classes take a single argument, the filename, which can be supplied as `std::string` or `const char*`.
They immediately make available the complete contents of the file; `read_input<>` reads the entire file upon construction.

The constructors that take a `FILE*` argument take ownership of the file pointer, i.e. they `fclose()` it in the destructor.

```c++
template< tracking_mode P = tracking_mode::IMMEDIATE, typename Eol = eol::lf_crlf >
struct read_input
{
explicit read_input( const char* filename );
explicit read_input( const std::string& filename );

read_input( FILE* file, const char* filename );
read_input( FILE* file, const std::string& filename );
};

template< tracking_mode P = tracking_mode::IMMEDIATE, typename Eol = eol::lf_crlf >
Expand Down
38 changes: 22 additions & 16 deletions include/tao/pegtl/internal/file_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ namespace tao
{
namespace internal
{
std::FILE* file_open( const char* source )
{
errno = 0;
#if defined( _MSC_VER )
std::FILE* file;
if(::fopen_s( &file, source, "rb" ) == 0 )
#else
if( auto* file = std::fopen( source, "rb" ) )
#endif
{
return file;
}
TAOCPP_PEGTL_THROW_INPUT_ERROR( "unable to fopen() file " << source << " for reading" );
}

struct file_close
{
void operator()( FILE* f ) const
Expand All @@ -31,7 +46,13 @@ namespace tao
public:
explicit file_reader( const char* filename )
: m_source( filename ),
m_file( open() )
m_file( file_open( m_source ) )
{
}

file_reader( FILE* file, const char* filename )
: m_source( filename ),
m_file( file )
{
}

Expand Down Expand Up @@ -70,21 +91,6 @@ namespace tao
private:
const char* const m_source;
const std::unique_ptr< std::FILE, file_close > m_file;

std::FILE* open() const
{
errno = 0;
#if defined( _MSC_VER )
std::FILE* file;
if(::fopen_s( &file, m_source, "rb" ) == 0 )
#else
if( auto* file = std::fopen( m_source, "rb" ) )
#endif
{
return file;
}
TAOCPP_PEGTL_THROW_INPUT_ERROR( "unable to fopen() file " << m_source << " for reading" );
}
};

} // namespace internal
Expand Down
7 changes: 7 additions & 0 deletions include/tao/pegtl/read_input.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ namespace tao
string_input< P, Eol, const char* >( internal::file_reader( filename.c_str() ).read(), filename.c_str() )
{
}

template< typename T >
read_input( FILE* in_file, T&& in_filename )
: internal::filename_holder( std::forward< T >( in_filename ) ),
string_input< P, Eol, const char* >( internal::file_reader( in_file, filename.c_str() ).read(), filename.c_str() )
{
}
};

} // namespace TAOCPP_PEGTL_NAMESPACE
Expand Down
18 changes: 18 additions & 0 deletions src/test/pegtl/file_read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,27 @@ namespace tao
{
namespace TAOCPP_PEGTL_NAMESPACE
{
template< tracking_mode P = tracking_mode::IMMEDIATE, typename Eol = eol::lf_crlf >
struct open_input
: public read_input< P, Eol >
{
explicit
open_input( const char* filename )
: read_input< P, Eol >( internal::file_open( filename ), filename )
{
}

explicit
open_input( const std::string& filename )
: open_input( filename.c_str() )
{
}
};

void unit_test()
{
verify_file< read_input<> >();
verify_file< open_input<> >();
}

} // namespace TAOCPP_PEGTL_NAMESPACE
Expand Down

0 comments on commit 60b6987

Please sign in to comment.