Skip to content

Commit

Permalink
Fix crash when saving output to file
Browse files Browse the repository at this point in the history
  • Loading branch information
hjaremko committed Aug 28, 2020
1 parent ca336f5 commit 3593703
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 37 deletions.
23 changes: 21 additions & 2 deletions include/parsing/cli_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@

#include "interpreter.hpp"
#include "machine.hpp"
#include "printing/printer_interface.hpp"
#include "printing/file_printer.hpp"

#include <cxxopts.hpp>
#include <filesystem>
#include <fstream>

namespace vnm
{
Expand All @@ -24,7 +25,25 @@ class cli_parser
private:
auto get_input_filename() const -> std::filesystem::path;
auto get_starting_pc() const -> vnm::word;
auto get_output_stream( std::fstream& out_file ) const -> std::ostream*;

template <class Policy>
auto make_base_printer( const vnm::machine& m ) const
-> std::unique_ptr<printer_interface>
{
const auto make_output_filename = []( const auto& input_filename ) {
auto ss { std::stringstream {} };
ss << "output-" << input_filename.stem().string() << ".txt";
return ss.str();
};

if ( parse_result.count( "save" ) )
{
return std::make_unique<file_printer<Policy>>(
make_output_filename( get_input_filename() ), m );
}

return std::make_unique<printer<Policy>>( std::cout, m );
}

cxxopts::ParseResult parse_result;
};
Expand Down
44 changes: 44 additions & 0 deletions include/printing/file_printer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#ifndef VON_NEUMANN_FILE_PRINTER_HPP
#define VON_NEUMANN_FILE_PRINTER_HPP

#include "printer.hpp"

#include <filesystem>
#include <fstream>

namespace vnm
{

template <class T>
class file_printer : public printer_interface
{
public:
file_printer( const std::filesystem::path& f, const vnm::machine& m )
: f_( f, std::ios::out | std::ios::trunc ),
p_( std::make_unique<printer<T>>( f_, m ) )
{
}

void print_registers_table() const override
{
p_->print_registers_table();
}

void print_registers() const override
{
p_->print_registers();
}

void print_memory() const override
{
p_->print_memory();
}

private:
std::fstream f_;
std::unique_ptr<printer_interface> p_;
};

} // namespace vnm

#endif // VON_NEUMANN_FILE_PRINTER_HPP
2 changes: 2 additions & 0 deletions include/printing/printer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "with_sign.hpp"
#include "word.hpp"

#include <iomanip>

namespace vnm
{

Expand Down
41 changes: 6 additions & 35 deletions src/parsing/cli_parser.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
#include "parsing/cli_parser.hpp"

#include "printing/printer.hpp"

#include <fstream>

namespace
{

auto parse_command_line( int argc, char** argv ) -> cxxopts::ParseResult
{
static auto options { cxxopts::Options { *argv,
"Von Neumann Machine emulator" } };
static auto options { cxxopts::Options {
*argv, "Von Neumann Machine emulator v0.2.0" } };
options.positional_help( "[optional args]" ).show_positional_help();

options.add_options()( "h,help",
Expand All @@ -36,22 +34,6 @@ auto parse_command_line( int argc, char** argv ) -> cxxopts::ParseResult
return result;
}

auto make_output_filename( const std::filesystem::path& input_filename )
-> std::string
{
auto ss { std::stringstream {} };
ss << "output-" << input_filename.stem().string() << ".txt";
return ss.str();
}

auto open_output_file( std::fstream& out_file,
const std::filesystem::path& filename ) -> std::ostream*
{
out_file.open( make_output_filename( filename ),
std::ios::out | std::ios::trunc );
return &out_file;
}

} // namespace

vnm::cli_parser::cli_parser( int argc, char** argv )
Expand All @@ -61,8 +43,7 @@ vnm::cli_parser::cli_parser( int argc, char** argv )

auto vnm::cli_parser::make_machine() const -> vnm::machine
{
auto input_path { get_input_filename() };
auto input_file { std::fstream { input_path } };
auto input_file { std::fstream { get_input_filename() } };
auto pmc { vnm::machine {} };

pmc.ram = vnm::interpreter { input_file }.interpret();
Expand Down Expand Up @@ -92,28 +73,18 @@ auto vnm::cli_parser::make_printer( const vnm::machine& m ) const
-> std::unique_ptr<printer_interface>
{
using namespace print_policy;
auto out_file { std::fstream {} }; // TODO: check if this crashes
auto* output_stream { get_output_stream( out_file ) };

if ( parse_result.count( "binary" ) )
{
return std::make_unique<printer<binary>>( *output_stream, m );
return make_base_printer<binary>( m );
}

if ( parse_result.count( "signed" ) )
{
return std::make_unique<printer<with_sign>>( *output_stream, m );
return make_base_printer<with_sign>( m );
}

return std::make_unique<printer<normal>>( *output_stream, m );
}

auto vnm::cli_parser::get_output_stream( std::fstream& out_file ) const
-> std::ostream*
{
return parse_result.count( "save" )
? open_output_file( out_file, get_input_filename() )
: &std::cout;
return make_base_printer<normal>( m );
}

auto vnm::cli_parser::get_parse_result() const -> cxxopts::ParseResult
Expand Down

0 comments on commit 3593703

Please sign in to comment.