summaryrefslogtreecommitdiffstats
path: root/src/orcus_yaml_main.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:48:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:48:59 +0000
commitc484829272cd13a738e35412498e12f2c9a194ac (patch)
treea1f5ec09629ee895bd3963fa8820b45f2f4c574b /src/orcus_yaml_main.cpp
parentInitial commit. (diff)
downloadliborcus-upstream.tar.xz
liborcus-upstream.zip
Adding upstream version 0.19.2.upstream/0.19.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/orcus_yaml_main.cpp')
-rw-r--r--src/orcus_yaml_main.cpp195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/orcus_yaml_main.cpp b/src/orcus_yaml_main.cpp
new file mode 100644
index 0000000..bb1d43c
--- /dev/null
+++ b/src/orcus_yaml_main.cpp
@@ -0,0 +1,195 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "orcus/yaml_document_tree.hpp"
+#include "orcus/yaml_parser_base.hpp"
+#include "orcus/config.hpp"
+#include "orcus/stream.hpp"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#include <boost/program_options.hpp>
+
+#include "filesystem_env.hpp"
+
+using namespace std;
+using namespace orcus;
+
+namespace po = boost::program_options;
+
+const char* help_program = "The FILE must specify a path to an existing file.";
+const char* err_no_input_file = "No input file.";
+const char* help_yaml_output = "Output file path.";
+const char* help_yaml_output_format =
+"Specify the format of output file. Supported format types are:\n"
+" 1) yaml\n"
+" 2) json";
+
+void print_yaml_usage(std::ostream& os, const po::options_description& desc)
+{
+ os << "Usage: orcus-yaml [options] FILE" << endl << endl;
+ os << help_program << endl << endl << desc;
+}
+
+std::unique_ptr<yaml_config> parse_yaml_args(int argc, char** argv)
+{
+ po::options_description desc("Options");
+ desc.add_options()
+ ("help,h", "Print this help.")
+ ("output,o", po::value<string>(), help_yaml_output)
+ ("output-format,f", po::value<string>(), help_yaml_output_format);
+
+ po::options_description hidden("Hidden options");
+ hidden.add_options()
+ ("input", po::value<string>(), "input file");
+
+ po::options_description cmd_opt;
+ cmd_opt.add(desc).add(hidden);
+
+ po::positional_options_description po_desc;
+ po_desc.add("input", -1);
+
+ po::variables_map vm;
+ try
+ {
+ po::store(
+ po::command_line_parser(argc, argv).options(cmd_opt).positional(po_desc).run(), vm);
+ po::notify(vm);
+ }
+ catch (const exception& e)
+ {
+ // Unknown options.
+ cerr << e.what() << endl;
+ print_yaml_usage(cerr, desc);
+ return nullptr;
+ }
+
+ if (vm.count("help"))
+ {
+ print_yaml_usage(cout, desc);
+ return nullptr;
+ }
+
+ std::unique_ptr<yaml_config> config = std::make_unique<yaml_config>();
+
+ if (vm.count("input"))
+ config->input_path = vm["input"].as<string>();
+
+ if (vm.count("output"))
+ config->output_path = vm["output"].as<string>();
+
+ if (vm.count("output-format"))
+ {
+ std::string outformat = vm["output-format"].as<string>();
+ if (outformat == "none")
+ config->output_format = yaml_config::output_format_type::none;
+ else if (outformat == "yaml")
+ config->output_format = yaml_config::output_format_type::yaml;
+ else if (outformat == "json")
+ config->output_format = yaml_config::output_format_type::json;
+ else
+ {
+ cerr << "Unknown output format type '" << outformat << "'." << endl;
+ return nullptr;
+ }
+ }
+ else
+ {
+ cerr << "Output format is not specified." << endl;
+ print_yaml_usage(cerr, desc);
+ return nullptr;
+ }
+
+ if (config->input_path.empty())
+ {
+ cerr << err_no_input_file << endl;
+ print_yaml_usage(cerr, desc);
+ return nullptr;
+ }
+
+ if (!fs::exists(config->input_path))
+ {
+ cerr << "Input file does not exist: " << config->input_path << endl;
+ return nullptr;
+ }
+
+ if (config->output_format != yaml_config::output_format_type::none)
+ {
+ if (config->output_path.empty())
+ {
+ cerr << "Output file not given." << endl;
+ return nullptr;
+ }
+
+ // Check to make sure the output path doesn't point to an existing
+ // directory.
+ if (fs::is_directory(config->output_path))
+ {
+ cerr << "Output file path points to an existing directory. Aborting." << endl;
+ return nullptr;
+ }
+ }
+
+ return config;
+}
+
+std::unique_ptr<yaml::document_tree> load_doc(const char* p, size_t n)
+{
+ std::unique_ptr<yaml::document_tree> doc(std::make_unique<yaml::document_tree>());
+ try
+ {
+ doc->load({p, n});
+ }
+ catch (const parse_error& e)
+ {
+ cerr << create_parse_error_output(std::string_view(p, n), e.offset()) << endl;
+ throw;
+ }
+ return doc;
+}
+
+int main(int argc, char** argv)
+{
+ try
+ {
+ std::unique_ptr<yaml_config> config = parse_yaml_args(argc, argv);
+ if (!config)
+ return EXIT_FAILURE;
+
+ file_content content(config->input_path.data());
+ std::unique_ptr<yaml::document_tree> doc = load_doc(content.data(), content.size());
+
+ switch (config->output_format)
+ {
+ case yaml_config::output_format_type::yaml:
+ {
+ ofstream fs(config->output_path.c_str());
+ fs << doc->dump_yaml();
+ }
+ break;
+ case yaml_config::output_format_type::json:
+ {
+ ofstream fs(config->output_path.c_str());
+ fs << doc->dump_json();
+ }
+ break;
+ default:
+ ;
+ }
+ }
+ catch (const std::exception& e)
+ {
+ cerr << e.what() << endl;
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */