[med-svn] [Git][med-team/graphmap2][master] Add argparser for simplicity reasons
Andreas Tille
gitlab at salsa.debian.org
Thu Jun 4 20:42:09 BST 2020
Andreas Tille pushed to branch master at Debian Med / graphmap2
Commits:
76d7960f by Andreas Tille at 2020-06-04T21:41:46+02:00
Add argparser for simplicity reasons
- - - - -
5 changed files:
- debian/changelog
- + debian/missing-sources/argparser/LICENSE
- + debian/missing-sources/argparser/argparser.cc
- + debian/missing-sources/argparser/argparser.h
- + debian/missing-sources/argparser/get-argparser
Changes:
=====================================
debian/changelog
=====================================
@@ -4,8 +4,7 @@ graphmap2 (0.6.4-1) UNRELEASED; urgency=medium
TODO:
* https://github.com/isovic/seqlib/
Despite the same name it is not the code packaged in libseqlib!
- * https://github.com/isovic/argparser
- Upstream seems to be afraid of getopt :-(
+ * argparser is in debian/missing-sources
* https://github.com/isovic/gindex
(also uses seqlib)
=====================================
debian/missing-sources/argparser/LICENSE
=====================================
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Ivan Sovic
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
=====================================
debian/missing-sources/argparser/argparser.cc
=====================================
@@ -0,0 +1,576 @@
+//============================================================================
+// Name : argparser.cc
+// Author : Ivan Sovic
+// Version : 1.0
+// Created on : Sep 21, 2014
+// Copyright : License: MIT
+// Description : Library for parsing command line parameters.
+//============================================================================
+
+#include "argparser.h"
+#include <algorithm>
+#include <wordexp.h>
+
+ArgumentParser::ArgumentParser() {
+// AddArgument(NULL, VALUE_TYPE_NONE, "h", "help", "", "Displays this list of commands.", 0, "Help");
+}
+
+ArgumentParser::~ArgumentParser() {
+ valid_args_all_.clear();
+ valid_args_short_.clear();
+ valid_args_long_.clear();
+ valid_args_group_.clear();
+ valid_args_positional_.clear();
+ arguments_.clear();
+ program_name_.clear();
+ composite_args_.clear();
+}
+
+void ArgumentParser::AddArgument(void *target,
+ ValueType value_type,
+ std::string arg_short, std::string arg_long,
+ std::string default_value,
+ std::string description,
+ int32_t positional,
+ std::string argument_group) {
+
+ if (arg_short == "" && arg_long == "") {
+ fprintf(stderr, "Warning: Argument initialization. Neither a short nor a long name of argument specified. Omitting.\n\n");
+ fflush(stderr);
+ return;
+ }
+
+ /// Check if argument already exists in any of the lists.
+ if ((arg_short != "" && valid_args_short_.find(arg_short) != valid_args_short_.end()) ||
+ (arg_long != "" && valid_args_long_.find(arg_long) != valid_args_long_.end())) {
+ fprintf(stderr, "Warning: Argument '-%s' / '--%s' already defined. Omitting.\n\n", arg_short.c_str(), arg_long.c_str());
+ fflush(stderr);
+ return;
+ }
+
+ Argument arg;
+ arg.target = target;
+ arg.arg_short = arg_short;
+ arg.arg_long = arg_long;
+ arg.value = default_value;
+ arg.value_type = value_type;
+ arg.default_value = default_value;
+ arg.description = description;
+ arg.positional = positional;
+ arg.arg_group = argument_group;
+ arg.is_set = false;
+
+ /// In case the argument doesn't require a parameter (but is a switch instead), and the given value is not 0 or 1, set the default value to 0 (False).
+ if (arg.value_type == VALUE_TYPE_NONE || arg.value_type == VALUE_TYPE_BOOL) {
+ if (arg.default_value != "0" && arg.default_value != "1") {
+ arg.value = "0";
+ arg.default_value = "0";
+ }
+ }
+
+ if (value_type != VALUE_TYPE_STRING_LIST) {
+ SetArgumentTarget_(target, value_type, default_value);
+ }
+
+ arguments_.push_back(arg);
+ valid_args_short_[arg.arg_short] = (arguments_.size() - 1);
+ valid_args_long_[arg.arg_long] = (arguments_.size() - 1);
+ valid_args_all_[arg.arg_short] = (arguments_.size() - 1);
+ valid_args_all_[arg.arg_long] = (arguments_.size() - 1);
+ if (arg.positional != 0)
+ valid_args_positional_[arg.positional] = (arguments_.size() - 1);
+
+ if (valid_args_group_.find(arg.arg_group) == valid_args_group_.end()) {
+ std::vector<int32_t> indices;
+ indices.push_back((arguments_.size() - 1));
+ valid_args_group_[arg.arg_group] = indices;
+ arg_groups_in_order_of_appearance_.push_back(arg.arg_group);
+ } else {
+ valid_args_group_[arg.arg_group].push_back((arguments_.size() - 1));
+ }
+}
+
+/// Defines composite parameters. A composite parameter can change more than one
+/// parameter through a symbolic name. The argument name is literally expanded with the given
+/// arg_expansion string containing other valid command line parameters.
+void ArgumentParser::AddCompositeArgument(std::string arg_name, std::string arg_expansion) {
+ composite_args_[arg_name] = arg_expansion;
+}
+
+/// Checks if a given arg_name is in specified arguments.
+/// Returns: 0 if it's not specified, 1 if it's a short argument and 2 if it's a long argument.
+Argument* ArgumentParser::CheckArguments_(std::string arg_name) {
+ if (arg_name.size() < 2) return NULL;
+ if (arg_name[0] != '-') return NULL;
+
+ /// The argument has only '-' specified, which means it should be of short type.
+ if (arg_name[1] != '-') {
+ auto it = valid_args_short_.find(arg_name.substr(1));
+ if (it != valid_args_short_.end())
+ return &(arguments_[it->second]);
+ return NULL;
+
+ } else {
+ /// If there is nothing specified after the "--", then something is wrong.
+ if (arg_name.size() == 2) return NULL;
+ auto it = valid_args_long_.find(arg_name.substr(2));
+ if (it != valid_args_long_.end())
+ return &(arguments_[it->second]);
+ return NULL;
+ }
+
+ return NULL;
+}
+
+void ArgumentParser::ProcessArguments(int argc, char* argv[], int offset) {
+ program_name_ = std::string(argv[0]);
+
+ if ((argc - offset) == 0 && valid_args_positional_.size() > 0) {
+ fprintf (stderr, "ERROR: Not all required arguments specified. Exiting.\n\n");
+ exit(1);
+ }
+
+ for (int32_t i=offset; i<argc; i++) {
+ std::string arg = argv[i];
+ std::string arg_next = "";
+
+ // Check if for some reason the string is empty.
+ if (arg.size() == 0)
+ continue;
+
+ // The argument should start with a dash. Otherwise, it can only be positional, or an error.
+ if (arg[0] == '-' && arg.size() > 1) {
+ // If only a dash is given, then something is wrong (or perhaps that was the intention,
+ // for instance, to enable pipe processing).
+ if (arg.size() == 1) {
+ fprintf (stderr, "ERROR: Unspecified parameter '%s'.\n", arg.c_str());
+ exit(1);
+
+ } else {
+ ///////////////////////////////////////////////////////////////
+ /// Find the argument by either the short or the long name.
+ //////////////////////////////////////////////////////////////
+ int32_t argument_index = -1;
+ // If the second character is not '-' then the argument is specified by its short name.
+ if (arg[1] != '-') { // Handle the short argument assignment.
+ std::string arg_name = arg.substr(1);
+
+ // If the argument cannot be found, report it.
+ if (valid_args_short_.find(arg_name) == valid_args_short_.end()) {
+ fprintf (stderr, "ERROR: Unknown parameter '%s'.\n", arg.c_str());
+ exit(1);
+ } else {
+ argument_index = valid_args_short_[arg_name];
+ }
+
+ } else if (arg[1] == '-') { // Handle the long argument assignment.
+ /// Check if there is nothing after '--' in the given argument name.
+ if (arg.size() == 2) {
+ fprintf (stderr, "ERROR: Unspecified parameter '%s'. Exiting.\n\n", arg.c_str());
+ exit(1);
+ } else {
+ std::string arg_name = arg.substr(2);
+ // If the argument cannot be found, report it.
+ if (valid_args_long_.find(arg_name) == valid_args_long_.end()) {
+ fprintf (stderr, "ERROR: Unknown argument '%s'. Exiting.\n\n", arg.c_str());
+ exit(1);
+ } else {
+ argument_index = valid_args_long_[arg_name];
+ }
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////
+ /// Process the argument.
+ //////////////////////////////////////////////////////////////
+ if (argument_index >= 0) {
+ arguments_[argument_index].count += 1;
+ arguments_[argument_index].is_set = true;
+
+ if (arguments_[argument_index].value_type != VALUE_TYPE_NONE && arguments_[argument_index].value_type != VALUE_TYPE_BOOL) { // This argument expects a value.
+ if ((i + 1) < argc) {
+ arguments_[argument_index].value = argv[i + 1];
+ SetArgumentTarget_(arguments_[argument_index].target, arguments_[argument_index].value_type, arguments_[argument_index].value);
+ i += 1;
+ } else {
+ fprintf (stderr, "ERROR: Argument '%s' expects a value. Exiting.\n", arg.c_str());
+ exit(1);
+ }
+
+ /// Handle the special case when the argument is a composite one. Need to find the composite definition and expand it (recursively).
+ if (arguments_[argument_index].value_type == VALUE_TYPE_COMPOSITE) {
+ auto it_arg = composite_args_.find(arguments_[argument_index].value);
+ if (it_arg == composite_args_.end()) {
+ fprintf (stderr, "ERROR: Composite parameter '%s' not defined. Exiting.\n", arguments_[argument_index].value.c_str());
+ exit(1);
+ }
+ wordexp_t p;
+ wordexp(it_arg->second.c_str(), &p, 0);
+ ProcessArguments((int32_t) p.we_wordc, (char **) p.we_wordv, 0);
+ wordfree(&p);
+ }
+
+ } else if (arguments_[argument_index].value_type == VALUE_TYPE_BOOL) {
+ // Switch the value of the boolean variable.
+ if (arguments_[argument_index].value == "0" || arguments_[argument_index].value == "false") {
+ arguments_[argument_index].value = "1";
+ } else {
+ arguments_[argument_index].value = "0";
+ }
+ SetArgumentTarget_(arguments_[argument_index].target, arguments_[argument_index].value_type, arguments_[argument_index].value);
+
+ } else {
+ arguments_[argument_index].value = "1";
+ }
+ }
+ /////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////
+ }
+ } else { // In this case, the argument can either be positional, or misspelled.
+ int32_t position_back = i - argc;
+ int32_t position_front = i;
+
+ if (valid_args_positional_.find(position_back) != valid_args_positional_.end()) {
+ arguments_[valid_args_positional_[position_back]].value = arg;
+ arguments_[valid_args_positional_[position_back]].is_set = true;
+ SetArgumentTarget_(arguments_[valid_args_positional_[position_back]].target, arguments_[valid_args_positional_[position_back]].value_type, arguments_[valid_args_positional_[position_back]].value);
+
+ } else if (valid_args_positional_.find(position_front) != valid_args_positional_.end()) {
+ arguments_[valid_args_positional_[position_front]].value = arg;
+ arguments_[valid_args_positional_[position_front]].is_set = true;
+ SetArgumentTarget_(arguments_[valid_args_positional_[position_front]].target, arguments_[valid_args_positional_[position_front]].value_type, arguments_[valid_args_positional_[position_front]].value);
+
+ } else {
+ fprintf (stderr, "ERROR: Unknown parameter value: '%s'. Exiting.\n\n", arg.c_str());
+ exit(1);
+ }
+ }
+ }
+
+ /// Check if there are any positional arguments that were not loaded. These are necessary arguments.
+ for (uint32_t i = 0; i < arguments_.size(); i++) {
+ if (arguments_[i].positional != 0 && arguments_[i].is_set == false) {
+ std::string argument_name = (arguments_[i].arg_long != "") ? arguments_[i].arg_long : arguments_[i].arg_short;
+ fprintf (stderr, "ERROR: Not all required arguments specified. Parameter '%s' missing a value. Exiting.\n", argument_name.c_str());
+ exit(1);
+ }
+ }
+}
+
+std::string ArgumentParser::VerboseUsage() {
+ int32_t max_arg_len = 0;
+ for (int32_t i=0; i<arguments_.size(); i++) {
+ max_arg_len = std::max(max_arg_len, (int32_t) arguments_[i].arg_long.length());
+ }
+
+ std::map<std::string, std::vector<int32_t>>::iterator it;
+ const int32_t short_name_starting_char = 4;
+ const int32_t value_type_starting_char = short_name_starting_char + 6 + max_arg_len + 1;
+ const int32_t description_starting_char = value_type_starting_char + 3 + 3; /// 3 is the length of the type name, and 3 is the spacing between the type name and the description.
+ const int32_t wrap_width = MAX_LINE_LENGTH - description_starting_char;
+
+ std::stringstream ret_ss;
+
+ // Printout the usage of the program, if program arguments have actually been processed already.
+ // If they haven't been, then program_name is empty (program_name == argv[0]).
+ if (program_name_.size() > 0) {
+ int32_t num_non_positional_args = 0;
+ for (int32_t i=0; i<arguments_.size(); i++) { if (arguments_[i].positional == 0) num_non_positional_args += 1; }
+
+ ret_ss << "Usage:\n";
+ ret_ss << " " << program_name_.c_str();
+
+ // Positional arguments need to be sorted in the ascending order of their position.
+ std::vector<Argument> positional_arguments_back;
+ std::vector<Argument> positional_arguments_front;
+ for (uint32_t i=0; i<arguments_.size(); i++) {
+ if (arguments_.at(i).positional < 0) {
+ positional_arguments_back.push_back(arguments_.at(i));
+ } else if (arguments_.at(i).positional > 0) {
+ positional_arguments_front.push_back(arguments_.at(i));
+ }
+ }
+ std::sort(positional_arguments_back.begin(), positional_arguments_back.end(), positional_less_than_key());
+ std::sort(positional_arguments_front.begin(), positional_arguments_front.end(), positional_less_than_key());
+
+ for (uint32_t i=0; i<positional_arguments_front.size(); i++) {
+ std::string arg_name = positional_arguments_front[i].arg_long;
+ if (arg_name == "")
+ arg_name = positional_arguments_front[i].arg_short;
+ ret_ss << " " << arg_name.c_str();
+ }
+
+ if (num_non_positional_args > 0) {
+ ret_ss << " [options]";
+ }
+
+ for (uint32_t i=0; i<positional_arguments_back.size(); i++) {
+ std::string arg_name = positional_arguments_back[i].arg_long;
+ if (arg_name == "")
+ arg_name = positional_arguments_back[i].arg_short;
+ ret_ss << " " << arg_name.c_str();
+ }
+ ret_ss << "\n\n";
+ }
+
+ ret_ss << "Options\n";
+
+// for (it = valid_args_group_.begin(); it != valid_args_group_.end(); it++) {
+ for (uint32_t group_id = 0; group_id < arg_groups_in_order_of_appearance_.size(); group_id++) {
+ it = valid_args_group_.find(arg_groups_in_order_of_appearance_[group_id]);
+ if (it == valid_args_group_.end()) { continue; }
+
+ if (it->first.size() > 0) {
+ // In case a group is nameless, the ':' should be omitted.
+ ret_ss << " " << it->first.c_str() << ":\n";
+ }
+
+ for (uint32_t i = 0; i < it->second.size(); i++) {
+ std::stringstream ss;
+ int32_t num_chars = 0;
+
+// ss << " ";
+ ss << std::string(short_name_starting_char, ' ');
+ num_chars += short_name_starting_char;
+
+ if (arguments_[it->second.at(i)].positional == 0) {
+ if (arguments_[it->second.at(i)].arg_short != "") {
+ ss << "-" << arguments_[it->second.at(i)].arg_short;
+ num_chars += 2;
+ } else {
+ ss << " ";
+ num_chars += 2;
+ }
+
+ if (arguments_[it->second.at(i)].arg_short != "" && arguments_[it->second.at(i)].arg_long != "") {
+ ss << ", ";
+ num_chars += 2;
+ } else {
+ ss << " ";
+ num_chars += 2;
+ }
+
+ if (arguments_[it->second.at(i)].arg_long != "") {
+ ss << "--" << arguments_[it->second.at(i)].arg_long;
+ num_chars += 2 + arguments_[it->second.at(i)].arg_long.size();
+ }
+
+ } else {
+ std::string arg_name = arguments_[it->second.at(i)].arg_long;
+ if (arg_name == "")
+ arg_name = arguments_[it->second.at(i)].arg_short;
+
+ ss << arg_name;
+ num_chars += arg_name.size();
+ }
+
+// if (arguments_[it->second.at(i)].value_type != "") {
+ int32_t num_empty_chars = (((value_type_starting_char - num_chars) > 0)?(value_type_starting_char - num_chars):1);
+ std::string empty_chars(num_empty_chars, ' ');
+ ss << empty_chars;
+
+ ss << ValueTypeToStr(arguments_[it->second.at(i)].value_type);
+// if (arguments_[it->second.at(i)].value_type.size() >= 3)
+// ss << arguments_[it->second.at(i)].value_type.substr(0, 3);
+// else {
+// ss << arguments_[it->second.at(i)].value_type << std::string((3 - arguments_[it->second.at(i)].value_type.size()), ' ');
+// }
+
+ num_chars += num_empty_chars + 3;
+// }
+
+ if (arguments_[it->second.at(i)].description != "") {
+ int32_t num_empty_chars = (((description_starting_char - num_chars) > 0)?(description_starting_char - num_chars):1);
+ std::string empty_chars(num_empty_chars, ' ');
+ ss << empty_chars;
+// printf ("description_starting_char = %d\n", description_starting_char);
+// printf ("wrap_width = %d\n", wrap_width);
+// printf ("description =\n%s\n", arguments_[it->second.at(i)].description.c_str());
+
+ ss << WrapString_(description_starting_char, wrap_width, arguments_[it->second.at(i)].description);
+ num_chars += num_empty_chars + arguments_[it->second.at(i)].description.size();
+ }
+ if (arguments_[it->second.at(i)].value_type != VALUE_TYPE_NONE && arguments_[it->second.at(i)].default_value != "") {
+ if (arguments_[it->second.at(i)].value_type != VALUE_TYPE_BOOL) {
+ ss << " [" << arguments_[it->second.at(i)].default_value << "]";
+ } else {
+ ss << " [" << ((arguments_[it->second.at(i)].default_value == "0" || arguments_[it->second.at(i)].default_value == "false") ? "false" : "true") << "]";
+ }
+ }
+
+ if (arguments_[it->second.at(i)].arg_short != "" || arguments_[it->second.at(i)].arg_long != "") {
+ ret_ss << ss.str() << "\n";
+ }
+ }
+
+ ret_ss << "\n";
+ }
+
+ return ret_ss.str();
+}
+
+std::string ArgumentParser::VerboseArguments() {
+ std::stringstream ss;
+
+ int32_t max_arg_len = 0;
+ for (int32_t i=0; i<arguments_.size(); i++) {
+ max_arg_len = std::max(max_arg_len, (int32_t) arguments_[i].arg_long.length());
+ }
+
+ std::string padding_string(3, ' ');
+
+ for (uint32_t i=0; i<arguments_.size(); i++) {
+ ss << "'-" << arguments_[i].arg_short << "'" << std::string(1 + padding_string.size() - arguments_[i].arg_short.size(), ' ');
+ ss << "'--" << arguments_[i].arg_long << "'" << std::string(max_arg_len + padding_string.size() - arguments_[i].arg_long.size(), ' ');
+ ss << "'" << ValueTypeToStr(arguments_[i].value_type) << "'" << padding_string;
+ ss << "value = '" << arguments_[i].value << "'" << padding_string;
+ ss << "default = '" << arguments_[i].default_value << "'" << padding_string;
+ ss << "count = " << arguments_[i].count << padding_string;
+ ss << "positional = " << arguments_[i].positional << "\n";
+ }
+ return ss.str();
+}
+
+Argument* ArgumentParser::GetArgument(std::string arg_name) {
+ std::map<std::string, int32_t>::iterator it = valid_args_all_.find(arg_name);
+ if (it == valid_args_all_.end())
+ return NULL;
+ return (&(arguments_.at(it->second)));
+}
+
+Argument* ArgumentParser::GetArgumentByShortName(std::string arg_name) {
+ std::map<std::string, int32_t>::iterator it = valid_args_short_.find(arg_name);
+ if (it == valid_args_short_.end())
+ return NULL;
+ return (&(arguments_.at(it->second)));
+}
+
+Argument* ArgumentParser::GetArgumentByLongName(std::string arg_name) {
+ std::map<std::string, int32_t>::iterator it = valid_args_long_.find(arg_name);
+ if (it == valid_args_long_.end())
+ return NULL;
+ return (&(arguments_.at(it->second)));
+}
+
+std::string ArgumentParser::WrapString_(int32_t leading_tab, int32_t wrap_width, std::string text) {
+ if (text.size() == 0)
+ return text;
+
+ std::stringstream ss;
+ std::vector<int32_t> spaces;
+ std::string prefix(leading_tab, ' ');
+
+ /// Enumerate all whitespaces in the text. This is used to split on word delineations.
+ spaces.push_back(-1);
+ for (uint32_t i=0; i<text.size(); i++) {
+ if (text[i] == ' ' || text[i] == '\t' || text[i] == '\n') {
+ spaces.push_back(i);
+ }
+ }
+ spaces.push_back(text.size());
+
+ /// Check for each word whether it contributes with enough characters to exceed the wrap_width.
+ int32_t line_length = 0;
+ for (uint32_t i=1; i<spaces.size(); i++) {
+ int32_t word_length = spaces[i] - (spaces[i - 1] + 1);
+
+ if ((i + 1) == spaces.size() || ((i + 1) < spaces.size() && text[spaces[i-1]] != '\n' && (line_length + word_length) < wrap_width)) {
+ if (i > 1) { ss << text[spaces[i-1]]; }
+ ss << text.substr((spaces[i - 1] + 1), word_length);
+ line_length += word_length + 1;
+ } else {
+ ss << "\n" << prefix;
+ ss << text.substr((spaces[i - 1] + 1), word_length);
+ line_length = word_length;
+ }
+ }
+
+ return ss.str();
+}
+
+int ArgumentParser::GetValue(std::string arg_name, int64_t* value) {
+ std::map<std::string, int32_t>::iterator it = valid_args_all_.find(arg_name);
+ if (it == valid_args_all_.end())
+ return 1;
+ ValueType value_type = arguments_.at(it->second).value_type;
+// if (value_type != VALUE_TYPE_INT32 || value_type != VALUE_TYPE_INT64 || value_type != VALUE_TYPE_UINT32 || value_type != VALUE_TYPE_UINT64)
+ if (value_type != VALUE_TYPE_INT64)
+ return 1;
+ sscanf(arguments_.at(it->second).value.c_str(), "%lld", value);
+ return 0;
+}
+
+int ArgumentParser::GetValue(std::string arg_name, float* value) {
+ std::map<std::string, int32_t>::iterator it = valid_args_all_.find(arg_name);
+ if (it == valid_args_all_.end())
+ return 1;
+ if (arguments_.at(it->second).value_type != VALUE_TYPE_FLOAT)
+ return 1;
+ sscanf(arguments_.at(it->second).value.c_str(), "%f", value);
+ return 0;
+}
+
+int ArgumentParser::GetValue(std::string arg_name, std::string* value) {
+ std::map<std::string, int32_t>::iterator it = valid_args_all_.find(arg_name);
+ if (it == valid_args_all_.end())
+ return 1;
+ if (arguments_.at(it->second).value_type != VALUE_TYPE_STRING)
+ return 1;
+ *value = arguments_.at(it->second).value;
+ return 0;
+}
+
+void ArgumentParser::SetArgumentTarget_(void *target, ValueType value_type, std::string &argument_value) {
+ if (value_type == VALUE_TYPE_NONE)
+ return;
+
+ std::stringstream ss(argument_value);
+ if (value_type == VALUE_TYPE_BOOL) {
+ std::string ss_str = ss.str();
+ if (ss_str == "0" || ss_str == "false") {
+ *((bool *) target) = false;
+ } else {
+ *((bool *) target) = true;
+ }
+ } else if (value_type == VALUE_TYPE_INT32) {
+ int32_t value = 0;
+ ss >> value;
+ *((int32_t *) target) = value;
+ } else if (value_type == VALUE_TYPE_UINT32) {
+ uint32_t value = 0;
+ ss >> value;
+ *((uint32_t *) target) = value;
+ } else if (value_type == VALUE_TYPE_INT64) {
+ int64_t value = 0;
+ ss >> value;
+ *((int64_t *) target) = value;
+ } else if (value_type == VALUE_TYPE_UINT64) {
+ uint64_t value = 0;
+ ss >> value;
+ *((uint64_t *) target) = value;
+ } else if (value_type == VALUE_TYPE_FLOAT) {
+ float value = 0.0f;
+ ss >> value;
+ *((float *) target) = value;
+ } else if (value_type == VALUE_TYPE_DOUBLE) {
+ double value = 0.0f;
+ ss >> value;
+ *((double *) target) = value;
+ } else if (value_type == VALUE_TYPE_STRING) {
+ *((std::string *) target) = argument_value;
+
+ } else if (value_type == VALUE_TYPE_STRING_LIST) {
+ ((std::vector<std::string> *) target)->emplace_back(argument_value);
+
+ } else if (value_type == VALUE_TYPE_COMPOSITE) {
+ *((std::string *) target) = argument_value;
+ }
+}
+
+const std::string& ArgumentParser::get_program_name() const {
+ return program_name_;
+}
+
+void ArgumentParser::set_program_name(const std::string& programName) {
+ program_name_ = programName;
+}
=====================================
debian/missing-sources/argparser/argparser.h
=====================================
@@ -0,0 +1,151 @@
+//============================================================================
+// Name : argparser.h
+// Author : Ivan Sovic
+// Version : 1.0
+// Created on : Sep 21, 2014
+// Copyright : License: MIT
+// Description : Library for parsing command line parameters.
+//============================================================================
+
+#ifndef ARGPARSER_H_
+#define ARGPARSER_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <map>
+
+#define MAX_LINE_LENGTH 120
+
+typedef enum {
+ VALUE_TYPE_NONE = 0,
+ VALUE_TYPE_BOOL = 1,
+ VALUE_TYPE_INT32 = 2,
+ VALUE_TYPE_UINT32 = 3,
+ VALUE_TYPE_INT64 = 4,
+ VALUE_TYPE_UINT64 = 5,
+ VALUE_TYPE_FLOAT = 6,
+ VALUE_TYPE_DOUBLE = 7,
+ VALUE_TYPE_STRING = 8,
+ VALUE_TYPE_COMPOSITE = 9,
+ VALUE_TYPE_STRING_LIST = 10
+} ValueType;
+
+inline std::string ValueTypeToStr(ValueType value_type) {
+ if (value_type == VALUE_TYPE_NONE)
+ return std::string(" - ");
+ else if (value_type == VALUE_TYPE_BOOL)
+ return std::string(" - ");
+ else if (value_type == VALUE_TYPE_INT32 || value_type == VALUE_TYPE_UINT32 || value_type == VALUE_TYPE_INT64 || value_type == VALUE_TYPE_UINT64)
+ return std::string("INT");
+ else if (value_type == VALUE_TYPE_FLOAT || value_type == VALUE_TYPE_DOUBLE)
+ return std::string("FLT");
+ else if (value_type == VALUE_TYPE_STRING || value_type == VALUE_TYPE_STRING_LIST || value_type == VALUE_TYPE_COMPOSITE)
+ return std::string("STR");
+ return std::string(" - ");
+}
+
+struct Argument {
+ void *target = NULL; /// Pointer to the variable to where the parsed value will be stored.
+ std::string arg_short = ""; /// The short name of the argument.
+ std::string arg_long = ""; /// The long name of the argument.
+ std::string value = ""; /// The value parsed from the command line.
+ std::string default_value = ""; /// Fallback value in case the argument was not specified.
+ ValueType value_type = VALUE_TYPE_NONE; /// The type of the argument (integer, float, string).
+ std::string description = ""; /// Description of the argument.
+ std::string arg_group = ""; /// The group of the argument.
+ int32_t positional = 0; /// If 0, the parameter can be placed in an optional position. If > 0 parameter must be located at the front of the command line. If < 0, the parameter must be located at the end of command line.
+ int32_t count = 0; /// Counts the number of occurances of the arguments.
+ bool is_set = false; /// If the argument is found, is_set == true.
+};
+
+struct positional_less_than_key {
+ inline bool operator() (const Argument& op1, const Argument& op2) {
+ return (op1.positional < op2.positional);
+ }
+};
+
+class ArgumentParser {
+ public:
+ ArgumentParser();
+ ~ArgumentParser();
+
+ /// Specify an argument to parse for.
+ /// Parameters:
+ /// @target Pointer to a variable where the value will be parsed to.
+ /// @value_type Specifies the variable type which is expected.
+ /// @arg_short Short argument name, single letter. Can be omitted, but either a short or long name needs to be specified.
+ /// @arg_long Long argument name, e.g. a word. Can be omitted, but either a short or long name needs to be specified.
+ /// @default value The default value of the parameter in case it was never used on the command line.
+ /// @description The description that will be used to generate program usage.
+ /// @positional If 0, the argument is optional and can be placed anywhere in between required arguments. If > 0 specifies a required argument at this position from the program name. If < 0, the argument is required at the end of the command line.
+ /// @argument group Specifies the group of an argument. Used to group arguments when printing usage.
+ void AddArgument(void *target,
+ ValueType value_type,
+ std::string arg_short, std::string arg_long,
+ std::string default_value,
+ std::string description, int32_t positional=0,
+ std::string argument_group="unknown");
+
+ /// Defines composite parameters. A composite parameter can change more than one
+ /// parameter through a symbolic name. The argument name is literally expanded with the given
+ /// arg_expansion string containing other valid command line parameters.
+ void AddCompositeArgument(std::string arg_name, std::string arg_expansion);
+
+ /// Processes the command line and parses arguments. Prints usage if argument parameter is invalid.
+ /// If offset > 0, then the given number of arguments from the beginning will be skipped (i.e. program name).
+ void ProcessArguments(int argc, char* argv[], int offset=1);
+
+ /// Formats and returns the usage of the program according to the specified arguments.
+ std::string VerboseUsage();
+
+ /// Formats and returns the values and specifications of all arguments.
+ std::string VerboseArguments();
+
+ /// Finds and returns a pointer to the argument by its name. The name can be either a short or a long name.
+ Argument* GetArgument(std::string arg_name);
+
+ /// Finds and returns a pointer to the argument by its short name.
+ Argument* GetArgumentByShortName(std::string arg_name);
+
+ /// Finds and returns a pointer to the argument by its long name.
+ Argument* GetArgumentByLongName(std::string arg_name);
+
+ /// Finds an argument given its name, and parses the integer value.
+ int GetValue(std::string arg_name, int64_t *value);
+
+ /// Finds an argument given its name, and parses the float value.
+ int GetValue(std::string arg_name, float *value);
+
+ /// Finds an argument given its name, and parses the string value.
+ int GetValue(std::string arg_name, std::string *value);
+
+ const std::string& get_program_name() const;
+ void set_program_name(const std::string& programName);
+
+ private:
+ /// Wraps a string to a given number of characters in width. Also, assigns a number of tabs at the beginning of each line.
+ std::string WrapString_(int32_t leading_tab, int32_t wrap_width, std::string text);
+
+ /// For a given argument value, parses it's value according to the argument_value parameter and stores it into the target variable.
+ void SetArgumentTarget_(void *target, ValueType value_type, std::string &argument_value);
+ /// Checks if a given arg_name can be found in specified arguments, either long or short ones.
+ /// Returns: 0 if it's not specified, 1 if it's a short argument and 2 if it's a long argument.
+ /// The value of arg_name must start with a '-', e.g. "-t" or "--threads".
+ Argument* CheckArguments_(std::string arg_name);
+
+ std::map<std::string, int32_t> valid_args_all_;
+ std::map<std::string, int32_t> valid_args_short_;
+ std::map<std::string, int32_t> valid_args_long_;
+ std::map<std::string, std::vector<int32_t>> valid_args_group_;
+ std::map<int32_t, int32_t> valid_args_positional_;
+ std::vector<std::string> arg_groups_in_order_of_appearance_;
+ std::vector<Argument> arguments_;
+ std::string program_name_;
+ std::map<std::string, std::string> composite_args_;
+};
+
+#endif /* CMDPARSER_H_ */
=====================================
debian/missing-sources/argparser/get-argparser
=====================================
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+wget -N -q https://github.com/isovic/argparser/raw/master/src/argparser.cc
+wget -N -q https://github.com/isovic/argparser/raw/master/src/argparser.h
+wget -N -q https://github.com/isovic/argparser/raw/master/LICENSE
View it on GitLab: https://salsa.debian.org/med-team/graphmap2/-/commit/76d7960f2bd844091a3f287c86523ff9dd7834cd
--
View it on GitLab: https://salsa.debian.org/med-team/graphmap2/-/commit/76d7960f2bd844091a3f287c86523ff9dd7834cd
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20200604/726be980/attachment-0001.html>
More information about the debian-med-commit
mailing list