diff options
-rw-r--r-- | CMakeLists.txt | 5 | ||||
-rw-r--r-- | justify.cc | 85 | ||||
-rw-r--r-- | src/line_accumulator.cc | 10 | ||||
-rw-r--r-- | src/line_accumulator.h | 3 |
4 files changed, 93 insertions, 10 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index ce0a332..656fe91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,11 @@ add_executable( src/line_accumulator.cc ) +target_link_libraries( + justify + boost_program_options +) + install( TARGETS justify @@ -1,32 +1,101 @@ #include <string> #include <iostream> +#include <boost/optional.hpp> +#include <boost/program_options.hpp> + #include "line_accumulator.h" -int main(int argc, char* argv[]) { +boost::optional<boost::program_options::variables_map> input( + int argc, char* argv[]) { + boost::program_options::options_description optionDescription( + "Supported options" + ); + + optionDescription.add_options() + ( + "length", + boost::program_options::value<int>(), + "Output line length" + ) + ( + "offset", + boost::program_options::value<int>(), + "Number of spaces to be prepended on each line" + ) + ; + + boost::program_options::variables_map variables; + + try { + boost::program_options::store( + boost::program_options::parse_command_line( + argc, argv, optionDescription + ), + variables + ); + + boost::program_options::notify(variables); + } + catch ( const std::exception& exception ) { + std::cerr << exception.what() << std::endl; + std::cout << optionDescription << std::endl; + + return boost::optional<boost::program_options::variables_map>(); + } + + return boost::make_optional(variables); +} + +bool process(const boost::program_options::variables_map& variables) { std::cout.sync_with_stdio(false); std::cin.sync_with_stdio(false); - std::uint8_t max_line_length = 60; + std::uint8_t line_length = 60; + std::uint8_t line_offset = 0; - if ( argc == 2 ) { - const int user_length = std::stoi(argv[1]); + if ( variables.count("length") ) { + const int user_length = variables["length"].as<int>(); if ( user_length > 1 && user_length < 256 ) { - max_line_length = user_length; + line_length = user_length; } else { std::cerr << "Invalid line length.\n"; - return -1; + return false; } } - justify::LineAccumulator acc{max_line_length}; + if ( variables.count("offset") ) { + const int user_offset = variables["offset"].as<int>(); + + if ( user_offset >= 0 && user_offset < 256 ) { + line_offset = user_offset; + } else { + std::cerr << "Invalid line offset.\n"; + + return false; + } + } + + justify::LineAccumulator acc{line_length, line_offset}; std::string token; while ( std::cin >> token ) { acc(token); } - return 0; + return true; +} + +int main(int argc, char* argv[]) { + if ( auto variables = input(argc, argv) ) { + if ( process(*variables) ) { + return 0; + } else { + return 1; + } + } else { + return 1; + } } diff --git a/src/line_accumulator.cc b/src/line_accumulator.cc index d12ef54..31b8ddc 100644 --- a/src/line_accumulator.cc +++ b/src/line_accumulator.cc @@ -54,8 +54,12 @@ std::size_t getCharacterLength(const std::string& token) { namespace justify { -LineAccumulator::LineAccumulator(const std::uint8_t max_length): +LineAccumulator::LineAccumulator( + const std::uint8_t max_length, + const std::uint8_t offset +): max_length_{max_length}, + offset_{offset}, length_{0}, tokens_{} { } @@ -160,6 +164,10 @@ void LineAccumulator::discharge(const bool full) { this->justify(); } + if ( this->offset_ > 0 ) { + std::cout << std::string(this->offset_, ' '); + } + for ( const auto& token : this->tokens_ ) { std::cout << token.first << std::string(token.second, ' '); diff --git a/src/line_accumulator.h b/src/line_accumulator.h index 2ca271c..69b4c74 100644 --- a/src/line_accumulator.h +++ b/src/line_accumulator.h @@ -9,7 +9,7 @@ namespace justify { class LineAccumulator { public: - LineAccumulator(const std::uint8_t max_length); + LineAccumulator(const std::uint8_t max_length, const std::uint8_t offset); ~LineAccumulator(); std::uint8_t getMissing() const; @@ -18,6 +18,7 @@ class LineAccumulator { private: const std::uint8_t max_length_; + const std::uint8_t offset_; std::uint8_t length_; |