/* * This file is a part of PikoTools * and is distributed under the (new) BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2016-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name Tomasz Sowa nor the names of contributors to this * project may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef headerfile_picotools_mainoptions_mainoptionsparser #define headerfile_picotools_mainoptions_mainoptionsparser #include "space/space.h" #include #include namespace pt { /* * a very little parser for parsing main(int argc, char ** argv) parameters * * */ class MainOptionsParser { public: MainOptionsParser(); ~MainOptionsParser(); /* * status_ok - all argument have been parsed correctly * * status_argument_provided - an argument have been provided but was not requested * this can be in situation when using long form with equal sign, such as: --option=argument * and in 'options' space the option either was not set or have zero requested arguments * * status_argument_not_provided - an argument or arguments are required but were not provided * this can be returned in two situations: * 1. when using long form with equal sign, such as: --option=argument and in 'options' space * you have requested more than one argument * 2. when reading arguments and the input strings ended * */ enum Status { status_ok = 0, status_argument_provided = 1, status_argument_not_provided = 2, }; /* * the name of a field in the output Struct space for non-option arguments (those after two hypens --) * default: L"args" * they will be set as a table of strings/wstrings * */ void set_non_options_arguments_name(const wchar_t * name); void set_non_options_arguments_name(const std::wstring & name); /* * parse parameters * argc argv have the same meaning as in the main(int argc, const char ** argv) method * the first argument from argv is usualy the name of the program and is skip by this parser * * return value: look at the description of the Status enum * */ Status parse(int argc, const char ** argv, Space & out_space); Status parse(int argc, const char ** argv, Space & out_space, const Space & arguments); /* * whether or not options arguments should be converted from utf8 char* strings to wide strings (std::wstring) * default true * * if true all arguments in Space struct will be saved as std::wstring * if false all arguments will be std::string (they are read as they are without checking * whether correct utf8 characters are encountered) * * arguments are always held as std::wstring (in such a case is defined ObjectType in Space struct) * when using use_utf8(false) characters will not be treated as an utf8 string but just all 8bit char bytes * will be copied to std::wstring * */ void use_utf8(bool utf8); /* * return the last option name which was incorrectly parsed * or an empty string if status was equal to status_ok */ std::wstring & get_wrong_option(); private: Space * space; const Space * arguments_required_space; std::wstring non_option_arguments_name; std::wstring options, option, argument; std::vector arguments; bool should_use_utf8; Status last_status; std::wstring last_error_option; void convert_str(const char * src, std::wstring & dst); void convert_str(const char * src, size_t len, std::wstring & dst); void convert_str(const std::wstring & src, Space & space); Status parse(int argc, const char ** argv); void parse(size_t argc, const char ** argv, size_t & argv_index); void parse_short_option(size_t argc, const char ** argv, size_t & argv_index); void parse_long_option(size_t argc, const char ** argv, size_t & argv_index); void parse_arguments(size_t argc, const char ** argv, size_t & argv_index, size_t args_len); void parse_non_option_arguments(size_t argc, const char ** argv, size_t & argv_index); size_t how_many_arguments_required(const std::wstring & arg); void add_option_to_space(const std::wstring & option, const std::vector & arguments); }; } // namespace #endif