From 5cd5740fd00f5153118d2cd28b2526ac277e434c Mon Sep 17 00:00:00 2001 From: tastytea Date: Sun, 12 May 2019 00:02:31 +0200 Subject: [PATCH] Option parsing is hereby implemented. --- remwharead.1.adoc | 13 ++-- src/main.cpp | 13 +++- src/parse_options.cpp | 143 ++++++++++++++++++++++++++++++++++++++++++ src/parse_options.hpp | 52 +++++++++++++++ 4 files changed, 215 insertions(+), 6 deletions(-) create mode 100644 src/parse_options.cpp create mode 100644 src/parse_options.hpp diff --git a/remwharead.1.adoc b/remwharead.1.adoc index ba7482a..8cf68c5 100644 --- a/remwharead.1.adoc +++ b/remwharead.1.adoc @@ -2,10 +2,9 @@ :doctype: manpage :Author: tastytea :Email: tastytea@tastytea.de -:Date: 2019-05-11 +:Date: 2019-05-12 :Revision: 0.0.0 :man source: remwharead -:man version: {revision} :man manual: General Commands Manual == NAME @@ -16,7 +15,7 @@ remwharead - Remember what you read, and when *remwharead* [*-t* _tags_] _URL_ -*remwhared* *-e* _format_ [*-f* _file_] [*-s* _start_,_end_] +*remwharead* *-e* _format_ [*-f* _file_] [*-s* _start_,_end_] == DESCRIPTION @@ -36,9 +35,13 @@ Save output to _file_. Default is stdout. *-s* _start_,_end_, *--span*=_start_,_end_:: Only export entries between _start_ and _end_. _start_ and _end_ are date and -time representations according to ISO 8601. +time representations according to ISO 8601. Time zones are ignored at the +moment. -*--version*:: +*-h*, *--help*:: +Show help message. + +*-V*, *--version*:: Print version, copyright and license. == EXAMPLES diff --git a/src/main.cpp b/src/main.cpp index 30ecc79..6b5493b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,7 +14,18 @@ * along with this program. If not, see . */ -int main() +#include +#include +#include "parse_options.hpp" + +using std::cout; +using std::cerr; +using std::endl; +using std::string; + +int main(int argc, char *argv[]) { + options opts = parse_options(argc, argv); + return 0; } diff --git a/src/parse_options.cpp b/src/parse_options.cpp new file mode 100644 index 0000000..f189475 --- /dev/null +++ b/src/parse_options.cpp @@ -0,0 +1,143 @@ +/* This file is part of remwharead. + * Copyright © 2019 tastytea + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include "version.hpp" +#include "parse_options.hpp" + +using std::cout; +using std::cerr; +using std::endl; +using std::exit; + +const system_clock::time_point string_to_timepoint(const string &strtime) +{ + std::stringstream sstime(strtime); + struct std::tm tm = {}; + tm.tm_isdst = -1; // Detect daylight saving time. + sstime >> std::get_time(&tm, "%Y-%m-%dT%T"); + std::time_t time = timelocal(&tm); // Assume time is local. + return system_clock::from_time_t(time); +} + +const options parse_options(int argc, char *argv[]) +{ + string tags; + string format; + string file; + string span; + options opts; + + try + { + popl::OptionParser op("Available options"); + op.add> + ("t", "tags", "Add tags to URL, delimited by commas.", "", &tags); + op.add> + ("e", "export", "Export to format.", "", &format); + op.add> + ("f", "file", "Save output to file.", "", &file); + op.add> + ("s", "span", "Only export entries between YYYY-MM-DD,YYYY-MM-DD.", + "", &span); + auto option_help = op.add + ("h", "help", "Show this help message."); + auto option_version = op.add + ("V", "version", "Print version, copyright and license."); + op.parse(argc, argv); + + if (option_help->is_set()) + { + cout << "Usage: " << argv[0] << " [-t tags] URL\n"; + cout << op; + exit(0); + } + + if (option_version->is_set()) + { + cout << "remwharead " << global::version << endl << + "Copyright (C) 2019 tastytea \n" + "License GPLv3: GNU GPL version 3 " + ".\n" + "This program comes with ABSOLUTELY NO WARRANTY. This is free software,\n" + "and you are welcome to redistribute it under certain conditions.\n"; + exit(0); + } + + if (!tags.empty()) + { + size_t pos_end = 0; + size_t pos_start = 0; + while (pos_end != std::string::npos) + { + pos_end = tags.find(',', pos_start); + opts.tags.push_back + (tags.substr(pos_start, pos_end - pos_start)); + pos_start = pos_end + 1; + } + } + + if (!format.empty()) + { + if (format == "csv") + { + opts.format = export_format::csv; + } + else if (format == "asciidoc") + { + opts.format = export_format::asciidoc; + } + else + { + cerr << "Error: Export format must be csv or asciidoc.\n"; + exit(1); + } + } + + opts.file = file; + + if (!span.empty()) + { + size_t pos = span.find(','); + if (pos != std::string::npos) + { + opts.span = + { + string_to_timepoint(span.substr(0, pos)), + string_to_timepoint(span.substr(pos + 1)) + }; + } + else + { + cerr << "Error: Time span must be in format: " + "YYYY-MM-DD,YYYY-MM-DD\n"; + exit(1); + } + } + } + catch (const std::exception &e) + { + cerr << "Error: " << e.what() << endl; + exit(1); + } + + return opts; +} diff --git a/src/parse_options.hpp b/src/parse_options.hpp new file mode 100644 index 0000000..18fd2ca --- /dev/null +++ b/src/parse_options.hpp @@ -0,0 +1,52 @@ +/* This file is part of remwharead. + * Copyright © 2019 tastytea + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef REMWHAREAD_PARSE_OPTIONS_HPP +#define REMWHAREAD_PARSE_OPTIONS_HPP + +#include +#include +#include +#include +#include + +using std::string; +using std::vector; +using std::array; +using std::chrono::system_clock; +using std::uint8_t; + +enum class export_format +{ + csv, + asciidoc +}; + +typedef struct options +{ + vector tags; + export_format format = {}; + string file; + array span; +} options; + +// Convert ISO 8601 time-string to time_point. +const system_clock::time_point string_to_timepoint(const string &strtime); + +// Parse command-line options. +const options parse_options(int argc, char *argv[]); + +#endif // REMWHAREAD_PARSE_OPTIONS_HPP