& Quot; Условный & Quot; парсинг аргументов командной строки

Допустим, у меня есть исполняемый файл (работает на Mac, Win и Linux)

 a.out [-a] [-b] [-r -i <file> -o <file> -t <double> -n <int> ]

где аргумент в [ ] означает, что это необязательно. Однако, если последний аргумент -r устанавливается -i,-o,-t, а также -n должны быть поставлены тоже.

Существует множество хороших библиотек C ++ для анализа аргументов командной строки, например, gflags (http://code.google.com/p/gflags/), тклап (http://tclap.sourceforge.net/), simpleopt (http://code.jellycan.com/simpleopt/), boost.program_options (http://www.boost.org/doc/libs/1_52_0/doc/html/program_options.html) и т. д. Но мне было интересно, есть ли такой, который позволяет мне кодировать эти условные отношения между аргументами напрямую, без ручного кодирования обработки ошибок

if ( argR.isSet() && ( ! argI.isSet() || ! argO.isSet() || ... ) ) ...

и вручную настроить --help,

Библиотека tclap позволяет XOR аргументы, например или -a или же -b разрешено, но не оба. Таким образом, в этой терминологии И для аргументов было бы неплохо.

Кто-нибудь знает универсальную, легкую и кроссплатформенную библиотеку, которая может это сделать?

9

Решение

Вы могли бы два прохода по аргументам; Если -r в опциях вы сбрасываете парсер и начинаете заново с добавлением новых обязательных опций.


Вы также можете посмотреть, как TCLAP XorHandler работает и создай свой AndHandler,

2

Другие решения

Вы можете изменить синтаксис аргумента так, чтобы -r принимала четыре значения подряд.

0

У меня есть часть TCLAP фрагмент кода, лежащий вокруг, который, кажется, соответствует части обработки ошибок, которую вы ищете, однако он не совсем соответствует тому, что вы ищете:

# include "tclap/CmdLine.h"
namespace TCLAP {

class RequiredDependentArgException : public ArgException {
public:
/**
* Constructor.
* \param text - The text of the exception.
* \param parentArg - The text identifying the parent argument source
* \param dependentArg - The text identifying the required dependent argument
* of the exception.
*/
RequiredDependentArgException(
const TCLAP::Arg& parentArg,
const TCLAP::Arg& requiredArg)
: ArgException(
std::string( "Required argument ") +
requiredArg.toString() +
std::string(" missing when the ") +
parentArg.toString() +
std::string(" flag is specified."),
requiredArg.toString())
{ }
};

} // namespace TCLAP

А затем использовать новое исключение после TCLAP::CmdLine::parse был назван:

if (someArg.isSet() && !conditionallyRequiredArg.isSet()) {
throw(TCLAP::RequiredDependentArgException(someArg, conditionallyRequiredArg));
}

Я помню, как смотрел на расширение и добавление дополнительного класса, который обрабатывал бы эту логику, но потом я понял, что единственное, что я на самом деле искал, это хороший отчет об ошибках, потому что логика была не совсем простой и не может быть легко сжатой (в по крайней мере, не таким образом, который был бы полезен для следующего бедняка, который пришел). Придуманный сценарий отговорил меня от дальнейшей работы, что-то вроде «если A истинно, B должно быть установлено, но C не может быть установлено, если D имеет значение N.» Выражение таких вещей в нативном C ++ — путь, особенно когда приходит время делать очень строгие проверки аргументов во время синтаксического анализа CLI.

Для действительно патологических случаев и требований создайте конечный автомат, используя что-то вроде Увеличение.MSM (Multi-State Machine). НТН.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector