aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt5
-rw-r--r--justify.cc85
-rw-r--r--src/line_accumulator.cc10
-rw-r--r--src/line_accumulator.h3
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
diff --git a/justify.cc b/justify.cc
index b20496c..8120ded 100644
--- a/justify.cc
+++ b/justify.cc
@@ -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_;