args-4 – это статическая библиотека классов для разбора аргументов командной строки. Так же она может использоваться для разбора простых конфигурационных файлов.
Основа библиотеки args была разработана в 1997-1998 годах в рамках проекта Dss. Впоследствии библиотека подвергалась лишь небольшим косметическим переделкам и добавлением некоторых классов аргументов и потоков ошибок. Весь проектный дизайн практически не изменился с момента первой реализации args.
Предполагается, что аргументы программы задаются в виде имя [значение]. Например:
-c -f some-file.4xx -d DEBUG
|
Здесь -c, -f, -d – это аргументы, some-file.4xx, DEBUG – праметры (значения) аргументов.
Именем аргумента и параметром аргументов являются слова – последовательности непробельных символов. Если в качестве параметра нужно указать последовательность слов, разделенных пробелами (табуляцией, переводом строки), то эту последовательность нужно взять в двойные кавычки – т.е. сформировать строку:
-c -f "some file with spaces.4xx" -d DEBUG
|
Когда параметр-строка указывается в командной строке, то правила представления символов в строке определяет командный процессор конкретной ОС. Если же параметр-строка указыватся в response-файле, то для символов в строке действуют правила языка C и некоторые символы (обратный слеш, двойная кавычка, перевод строки и т.д.) необходимо записывать в виде escape-последовательностей:
-c
-f "c:\\program files\\some file.4xx" -title "Annotation to \"Args-4\"" -http-header "Content-type: text/html\n\n" |
Аналогичные правила действуют и для конфигурационных файлов.
Процесс разбора аргументов состоит в выполнении следующих шагов:
Подробнее см. примеры.
Полный список документированных пространств имен.
Иерархия классов.
Классы с их кратким описанием.
Полный список документированных файлов.
Основное пространство имен проекта args-4.
Args-4
Обнаружен перевод каретки в незакрытой строке.
Комбинация:
"some string starts...
end finished here" |
является недопустимой. Правильный вариант:
"some string starts...\
end finished here" |
Найдена открывающая кавычка в слове.
Комбинация wor"d" является недопустимой. Нужно wor "d".
#include <args.hpp>
Граф наследования:args_4::cmd_on_off_switch_t::
|
Аргумент без параметров - переключатель.
Инициализирующий конструктор.
Возвращает значение m_is_defined.
Переопределяет метод предка args_4::cmd_t.
Возвращается значение m_is_mandatory.
Переопределяет метод предка args_4::cmd_t.
Сразу устанавливает признак того, что аргумент определен.
Повторное извлечение из входного потока уже определенного аргумента воспринимается как ошибка.
Переопределяет метод предка args_4::cmd_t.
true, если аргумент определен.
true, если аргумент обязательный.
Объявления и описания членов классов находятся в файлах:
7.2 Класс args_4::cmd_parser_t
#include <args.hpp>
Разборщик входного потока на аргументы.
Берет на себя функции просмотра входного потока, последовательного извлечения из него слов, поиска по слову соответствующего аргумента, обработки параметров аргумента. После завершения разбора проверяет определенность всех обязательных аргументов.
Инициализирующий конструктор.
Добавить очередные аргументы к списку разбираемых аргументов.
Последний аргумент должен быть нулевым указателем.
Поиск обработчика аргумента по имени.
Осуществить разбор.
Попытка найти и обработать аргумент с указанным именем.
Поток ошибок.
Определен только во время работы метода parse.
Может иметь значение 0.
Объявления и описания членов классов находятся в файлах:
7.3 Класс args_4::cmd_response_file_t
#include <args.hpp>
Граф наследования:args_4::cmd_response_file_t::
|
Аргумент, который является именем (набором имен) response-файлов.
В реализации этого класса использовано предположение, что имена response-файлов задается в виде: <символ><имя-файла>, Например, .txt.
Инициализирующий конструктор.
Переопределяет метод предка args_4::cmd_t.
Заносит имя response-файла (без первого управляющего символа) в вектор значений параметров аргумента.
Для извлечения имени используется тот факт, что если выполнить words.back(), а затем words.next(), то будет возвращено имя аргумента.
Переопределяет метод предка args_4::cmd_strvector_value_t.
Символ, который определяет, что значение является именем response-файла.
Объявления и описания членов классов находятся в файлах:
7.4 Класс args_4::cmd_str_value_t
#include <args.hpp>
Граф наследования:args_4::cmd_str_value_t::
|
Аргумент с единственным обязательным параметром - словом.
Значение параметра сохраняется как C-строка.
Инициализирующий конструктор.
Возвращает значение m_is_defined.
Переопределяет метод предка args_4::cmd_t.
Возвращается значение m_is_mandatory.
Переопределяет метод предка args_4::cmd_t.
Извлечение из входного потока единственного обязательного параметра.
Если параметр успешно извлечен, то аргумент считается успешно определенным.
Повторное извлечение из входного потока уже определенного аргумента воспринимается как ошибка.
Переопределяет метод предка args_4::cmd_t.
Возвращает параметр аргумента.
true, если аргумент определен.
true, если аргумент обязательный.
Значение параметра аргумента.
Объявления и описания членов классов находятся в файлах:
7.5 Класс args_4::cmd_strvector_value_t
#include <args.hpp>
Граф наследования:args_4::cmd_strvector_value_t::
|
Аргумент с одиним обязательным параметром - словом, который может быть указан несколько раз.
Предназначен, например, для случаев: -file p1 -file p2 ... -file p3. Все параметры аргумента объединяеются в один вектор. Для доступа к значениям аргумента предназначены методы query_value_count(), query_value().
Инициализирующий конструктор.
Переопределяет метод предка args_4::cmd_t.
Возвращается значение m_is_mandatory.
Переопределяет метод предка args_4::cmd_t.
Извлечение из входного потока единственного обязательного параметра.
Извлеченный параметр добавляется в конец вектора уже извлеченных значений.
Если параметр успешно извлечен, то аргумент считается успешно определенным.
Переопределяет метод предка args_4::cmd_t.
Переопределяется в args_4::cmd_response_file_t.
Возвращается значение параметра по индексу.
Параметры нумеруются с 0.
true, если аргумент обязательный.
Количество занятых элементов в m_values.
Объявления и описания членов классов находятся в файлах:
#include <args.hpp>
Граф наследования:args_4::cmd_t::
|
Базовый класс, реализующий понятие ’аргумент’.
Каждый аргумент имеет имя и, может различное количество обязательных или необязательных параметров (значений).
Инициализирующий конструктор.
Сравнить указаное имя с именем аргумента.
Используется для определения того, что очередное извлеченное из входного потока имя является именем аргумента.
Эта реализация просто сравнивает m_name и значение name.
Переопределяется в args_4::cmd_response_file_t.
Определен ли аргумент.
Если аргумент был извлечен из входного потока с корректными параметрами, то он должен считаться определенным.
Переопределяется в args_4::cmd_str_value_t, args_4::cmd_uint_value_t, args_4::cmd_on_off_switch_t и args_4::cmd_strvector_value_t.
Обязательный ли аргумент?
Вызывается после окончания разбора входного потока для того, чтобы определить, является ли аргумент обязательным. Если аргумент обязателен, но не определен, то разбор считается не выполненым.
По умолчанию, аргумент не обязательный.
Переопределяется в args_4::cmd_str_value_t, args_4::cmd_uint_value_t, args_4::cmd_on_off_switch_t и args_4::cmd_strvector_value_t.
Извлечения следующего обязательного слова из входного потока.
Предназначен для упрощения извлечения из входного потока обязательных параметров аргумента в методе process_params().
Обработать параметры аргумента.
После того как будет определен объект cmd_t, соответствующий извлеченному из входного потока имени, этому объекту дается возможность извлечь из входного потока все свои параметры. Для этого у объекта cmd_t вызывается данный метод.
Объект cmd_t должен считывать из входного потока свои параметры до тех пор пока:
Может произойти ситуация, когда аргумент извлечет из входного потока все свои обязательные параметры (если таковые имеются), а вместо необязательных параметров обнаруживает неизвестное для себя слово. Это может говорить о том, что необязательные параметры не заданы, а во входном потоке начинается новый аргумент. В этом случае во входной поток необходимо возвратить прочитанное слово и прекратить разбор параметров.
Если же вместо необязательного параметра будет обнаружен конец входного потока, то аргумент должен возвратить c_ok.
Данный метод кроме извлечения параметров должен заниматься из проверкой.
Переопределяется в args_4::cmd_str_value_t, args_4::cmd_uint_value_t, args_4::cmd_on_off_switch_t, args_4::cmd_strvector_value_t и args_4::cmd_response_file_t.
Определить имя аргумента.
Объявления и описания членов классов находятся в файлах:
7.7 Класс args_4::cmd_uint_value_t
#include <args.hpp>
Граф наследования:args_4::cmd_uint_value_t::
|
Аргумент с единственным обязательным параметром - беззнаковым целым числом.
Значение параметра может задаваться в соответствии с C-форматами целого числа (в десятичном, восьмиричном или шестнадцатиричном виде).
Инициализирующий конструктор.
Возвращает значение m_is_defined.
Переопределяет метод предка args_4::cmd_t.
Возвращается значение m_is_mandatory.
Переопределяет метод предка args_4::cmd_t.
Извлечение из входного потока единственного обязательного параметра.
Если параметр успешно извлечен, то аргумент считается успешно определенным.
Повторное извлечение из входного потока уже определенного аргумента воспринимается как ошибка.
Переопределяет метод предка args_4::cmd_t.
Возвращает параметр аргумента.
true, если аргумент определен.
true, если аргумент обязательный.
Значение параметра аргумента.
Объявления и описания членов классов находятся в файлах:
7.8 Класс args_4::error_stream_t
#include <args.hpp>
Граф наследования:args_4::error_stream_t::
|
Базовый класс для потока ошибок.
Библиотека args-4 спроектирована так, чтобы можно было использовать различные потоки вывода ошибок (stdsn, ostream и т.д.). Для того, чтобы можно было заставить средства args-4 отображать ошибки в какой-либо специфический поток (например, в буфер памяти, или в визуальный орган управления типа multiline-edit) все потоки вывода ошибок должны быть производными от класса error_stream_t.
Данный класс может использоваться в качестве null-потока, т.е. потока, который не осуществляет какого-либо вывода.
Осуществить вывод сообщения об ошибке.
В данном классе ничего не делает.
Переопределяется в args_4::iostream_error_stream_t, args_4::iostream_with_file_line_num_t и args_4::stdio_error_stream_t.
Объявления и описания членов классов находятся в файлах:
7.9 Класс args_4::iostream_error_stream_t
#include <args_iostream.hpp>
Граф наследования:args_4::iostream_error_stream_t::
|
Поток вывода ошибок посредством std::ostream.
Инициализирующий конструктор.
Отображает строку в m_stream.
Переопределяет метод предка args_4::error_stream_t.
Переопределяется в args_4::iostream_with_file_line_num_t.
Поток вывода ошибок.
Объявления и описания членов классов находятся в файлах:
7.10 Класс args_4::iostream_with_file_line_num_t
#include <args_iostream.hpp>
Граф наследования:args_4::iostream_with_file_line_num_t::
|
Поток вывода ошибок с именем файла и номером строки, в котором обнаружена ошибка.
Модификация класса iostream_error_stream_t, которая связывается с объектом words_from_file_t, из которого и берется информация об имени файла и номере строки.
Полностью инициализирующий конструктор.
Отображает указанную строку в поток вывода. Если обнаруживается, что строка завершается ’
’, то перед выводом следующей строки в поток вывода будет отображено имя файла и номер строки.
Переопределяет метод предка args_4::iostream_error_stream_t.
Входной поток, ошибки разбора которого, отображаются на поток ошибок.
Признак того, что последнее обращение к out привело к переходу на новую строку.
Объявления и описания членов классов находятся в файлах:
7.11 Класс args_4::stdio_error_stream_t
#include <args_stdio.hpp>
Граф наследования:args_4::stdio_error_stream_t::
|
Поток вывода ошибок в через fprintf.
Инициализирующий конструктор.
Отображает указанную строку в поток m_stream.
Переопределяет метод предка args_4::error_stream_t.
Поток для вывода.
Объявления и описания членов классов находятся в файлах:
7.12 Класс args_4::word_container_t
#include <args.hpp>
Граф наследования:args_4::word_container_t::
|
Базовый класс парсера входного потока.
Средства библиотки args-4 рассматривают входной поток как последовательность слов (последовательности непробельных символов).
В качестве входного потока можно использовать различные средства (stdin, istream, FILE *, pipe, строки, буфера в памяти и т.д.). Для этого необходимо чтобы для каждого типа потока был реализован класс, производный от word_container_t.
В дествительности, класс word_container_t уже содержит всю функциональность по составлению слов из символов и определению ошибок. Производным классам необходимо только преопределить метод word_container_t::getch().
Возвратить последнее извлеченное слово обратно в поток.
Последующий вызов next() возвратит это слово.
Предназначен для реализации т.н. lock-ahead техники разбора.
Если необходимо, расширяет m_word и добавляет ch к m_word.
Извлечь следующий символ.
Если нет больше доступных символов, то должно быть возвращено c_eof.
Переопределяется в args_4::words_from_str_t, args_4::words_from_file_t и args_4::words_from_file_with_simple_comment_t.
Выделить следующие слово из потока.
Переопределяется в args_4::words_from_argv_t.
Текущий поток ошибок.
Определен только в момент работы метода next().
Объявления и описания членов классов находятся в файлах:
7.13 Класс args_4::words_from_argv_t
#include <args.hpp>
Граф наследования:args_4::words_from_argv_t::
|
Разбор значений argv.
Реализация word_container_t для аргументов командной строки, доступных через argc, argv.
Инициализирующий конструктор.
Объявления и описания членов классов находятся в файлах:
7.14 Класс args_4::words_from_file_t
#include <args.hpp>
Граф наследования:args_4::words_from_file_t::
|
Парсер файла.
Реализация word_container_t для случая текстового файла. Работа с файлом осуществляется с использованием средств stdio.
Инициализирующий конструктор.
Осуществляет попытку открытия файла в режиме read-only.
Низкоуровневый метод возвращения последнего прочитанного символа обратно в буфер ввода.
Используется для реализации lock-ahead разбора.
Определить результат последней операции ввода вывода.
Возвращается значение errno. Может использоваться для проверки того, был ли открыт файл в конструкторе.
Буфер с именем файла.
Создается динамически и получает значение параметра file_name из конструкторе.
Объявления и описания членов классов находятся в файлах:
7.15 Класс args_4::words_from_file_with_simple_comment_t
#include <args.hpp>
Граф наследования:args_4::words_from_file_with_simple_comment_t::
|
Класс разбора файла с учетом простых комментариев.
Класс words_from_file_t не предоставляет возможности использования комментариев в разбираемом файле, т.к. предназначен для разбора т.н. response-файлов. Тем не менее, средства args-4 можно использовать для рабора простых конфигурационных файлов. В этом случае желательно предоставить возможность использовать в файлах комментарии.
Реализует эту возможность класс words_from_file_with_simple_comment_t. Разбираемый файл может содержать однострочные комментарии, начинающиеся одним символом, например:
#
# Some server socket config # ip-addr www.some-site.com port 5000 # # Client authentification config # client-auth-method password |
mxx-cmd-line mxxc -f somefile.#not-comment
|
Состояние разбора.
Инициализирующий конструктор.
Осуществляет попытку открытия файла в режиме read-only.
Инициализирующий конструктор.
Осуществляет попытку открытия файла в режиме read-only.
Извлечение очередного символа.
Комментарии изымаются
Переопределяет метод предка args_4::words_from_file_t.
Объявления и описания членов классов находятся в файлах:
7.16 Класс args_4::words_from_str_t
#include <args.hpp>
Граф наследования:args_4::words_from_str_t::
|
Парсер C-строки.
Реализация word_container_t для случая C-строки.
Инициализирующий конструктор.
Если *m_cur != 0, то возвращает *m_cur и передвигает m_cur. В противном случае считается, что входной поток исчерпан.
Переопределяет метод предка args_4::word_container_t.
Объявления и описания членов классов находятся в файлах:
Основные классы проекта args-4.
#include <cstdio>
#include <cstddef>
8.2 Файл args_4/h/args_iostream.hpp
Классы потоков ввода/вывода средствами iostream.
#include <iostream>
#include <args_4/h/args.hpp>
8.3 Файл args_4/h/args_stdio.hpp
Классы потоков ввода/вывода средствами stdio.
#include <args_4/h/args.hpp>
/*
args_4: Command line arguments parsing library Yauheni A. Akhotnikau (C) 2002-2003 eao197@yahoo.com ------------------------------------------------- Permission is granted to anyone to use this software for any purpose on any computer system, and to redistribute it freely, subject to the following restrictions: 1. This software 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. 2. The origin of this software must not be misrepresented, either by explicit claim or by omission. 3. Altered versions must be plainly marked as such, and must not be misrepresented as being the original software. ------------------------------------------------- */ /* Данный пример использования библиотеки args-4 создан из кода реально работающей утилиты, которая выполняет низкоуровневое редактирование информации в файлах на SIM-картах. */ #include <cassert> #include <iostream> #include <fstream> #include <cstdio> #include <cstring> #include <cerrno> #include <args_4/h/args.hpp> #include <args_4/h/args_iostream.hpp> const int c_invalid_argv = 1; const int c_invalid_file_name = 2; const int c_pcsc_error = 3; const int c_invalid_input = 4; // // arg_file_path_t // /* Класс для разбора аргумента командной строки -file-path <file-path> где file-path задан в виде: XXXX[/XXXX[/XXXX[...]] XXXX - шестнадцатиразрядное шестнадцатиричное число. */ class arg_file_path_t : public args_4::cmd_str_value_t { typedef args_4::cmd_str_value_t base_type_t; public : arg_file_path_t( const char * name, bool mandatory ); virtual ~arg_file_path_t(); // Будем выполнять собственную // обработку параметров. virtual int process_params( args_4::word_container_t & words, args_4::error_stream_t * error_stream ); // Получить количество разобранных значений. unsigned int query_value_count() const { return m_value_count; } // Получить вектор значений. const unsigned short * query_values() const { return m_values; } protected : // Вектор полученных значений. unsigned short m_values[ 16 ]; // Количество занятых элементов в m_values. unsigned int m_value_count; int parse_str_value( args_4::error_stream_t * error_stream ); }; // // arg_file_path_t // arg_file_path_t::arg_file_path_t( const char * name, bool mandatory ) : base_type_t( name, mandatory ), m_value_count( 0 ) { } arg_file_path_t::~arg_file_path_t() { } int arg_file_path_t::process_params( args_4::word_container_t & words, args_4::error_stream_t * error_stream ) { // Пусть базовый класс извлечет параметр. int ret_code = base_type_t::process_params( words, error_stream ); if( args_4::c_ok == ret_code ) { // Успешно извлечен параметр аргумента. // Теперь его нужно разобрать ret_code = parse_str_value( error_stream ); } return ret_code; } int arg_file_path_t::parse_str_value( args_4::error_stream_t * error_stream ) { // Максимальная длина имени одного файла. const size_t c_max_str_file_id_len = 4; // Максимальное количество имен файлов в пути. const size_t c_max_path_deep = sizeof( m_values ) / sizeof( m_values[ 0 ] ); const char * str_value = query_value(); char str_file_id[ c_max_str_file_id_len + 1 ]; size_t file_id_len = 0; bool is_invalid_format = false; // Посимвольно просматриваем все строковое значение // и выделяем имена отдельных файлов. while( *str_value && !is_invalid_format ) { if( file_id_len != c_max_str_file_id_len ) { if( isxdigit( *str_value ) ) { str_file_id[ file_id_len++ ] = *str_value; if( file_id_len == c_max_str_file_id_len ) { // Накопили достаточно символов для // преобразования в число unsigned int file_id = 0; str_file_id[ file_id_len ] = 0; sscanf( str_file_id, "%x", &file_id ); if( m_value_count != c_max_path_deep ) m_values[ m_value_count++ ] = file_id; else // Слишком длинный путь к файлу. is_invalid_format = true; } } else is_invalid_format = true; } else { if( ’/’ != *str_value ) is_invalid_format = true; else file_id_len = 0; } ++str_value; } if( is_invalid_format ) { if( error_stream ) { error_stream->out( query_name() ).out( ": " ).out( "invalid file path format\n" ); } return args_4::c_invalid_value; } return args_4::c_ok; } int do_main_work( const char * reader_name, const arg_file_path_t & file_path, const args_4::cmd_str_value_t & arg_chv1, const args_4::cmd_str_value_t & arg_chv2, const args_4::cmd_uint_value_t & arg_offs, bool is_write, bool ascii_dump, const args_4::cmd_str_value_t & arg_dbg_stream ) { // Реальный код изъят. return 0; } // Разбор response-файла. bool parse_resp_file( const char * resp_file_name, // Аргументы, которые могут быть указаны // в response-файле. // Последний элемент должен содержать 0 args_4::cmd_t ** args ) { assert( resp_file_name ); assert( args ); // Создаем и инициализируем парсер, который будет // разбирать входной файл. args_4::cmd_parser_t args_parser; for( ; *args; ++args ) args_parser.add_cmd( *args ); // Входной поток. args_4::words_from_file_t words_container( resp_file_name ); // Поток ошибок. args_4::iostream_error_stream_t args_error_stream; // Выполняем разбор. int error = args_parser.parse( words_container, &args_error_stream ); if( args_4::c_ok == error ) // Разбор завершен успешно. return true; // Определяем причину неудачи. if( args_4::c_io_error == error ) { // Произошла ошибка ввода-вывода std::cerr << resp_file_name << ": " << strerror( words_container.query_last_io_result() ) << std::endl; } else // Произошла какая-то другая ошибка. std::cerr << "error in response file: " << resp_file_name << std::endl; return false; } // Разбор всех аргументов. Начиная с командной строки и // заканчивая response-файлами. bool parse_args( int argc, char ** argv, // Эти три параметра имеют осмысленные названия, // т.к. они могут быть определены только в // определенных сочетаниях. args_4::cmd_t & arg_file, args_4::cmd_t & arg_file_path, args_4::cmd_t & arg_reader, // Реальные имена и типы остальных параметров для // разбора не имеют значения. args_4::cmd_t & arg4, args_4::cmd_t & arg5, args_4::cmd_t & arg6, args_4::cmd_t & arg7, args_4::cmd_t & arg8, args_4::cmd_t & arg9 ) { // Аргумент response-файл скрывается от прикладной // программы, т.к. ей об этом знать не обязательно. args_4::cmd_response_file_t arg_resp_file; // Создаем и инициализируем парсер. args_4::cmd_parser_t parser; parser.add_cmds( &arg_file, &arg_file_path, &arg_reader, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, &arg_resp_file, 0 ); // Входной поток. args_4::words_from_argv_t words( argc, argv ); // Поток ошибок. args_4::iostream_error_stream_t error_stream; bool is_success = true; // Выполняем разбор. int error_code = parser.parse( words, &error_stream ); if( args_4::c_ok == error_code ) { // Разбор прошел успешно. Проводим дальнейший анализ. // Если есть response-файлы, то они должны быть // обработаны. if( arg_resp_file.is_defined() ) { // Нужно обрабатывать response-файлы args_4::cmd_t * args[] = { &arg_file, &arg_file_path, &arg_reader, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, 0 }; for( size_t i = 0, i_max = arg_resp_file.query_value_count(); i != i_max; ++i ) if( !parse_resp_file( arg_resp_file.query_value( i ), args ) ) is_success = false; } // Анализ допустимости сочетаний некоторых // аргументов. if( !arg_reader.is_defined() ) { std::cerr << "reader name must be specified" << std::endl; is_success = false; } if( arg_file.is_defined() == arg_file_path.is_defined() ) { std::cerr << "either ’-file’ or ’-file-path’" " must be specified" << std::endl; is_success = false; } } else is_success = false; return is_success; } // Разбор аргументов и выполнение основной работы. int do_work( int argc, char ** argv ) { /* Аргумент ’-reader’ является обязательным. Но объект arg_reader специально объявляется необязательным аргументом. Сделано это из-за того, что при наличии response-файлов разбором аргументов будут заниматься несколько объектов-парсеров. Если бы arg_reader был обязательным аргументом, то часть объектов-парсеров выдавало бы ошибку о том, что обязательный аргумент ’-reader’ не определен. Хотя, на самом деле, этот аргумент определен в другом входном потоке, обрабатываемом другим парсером. */ args_4::cmd_str_value_t arg_reader( "-reader", false ); args_4::cmd_str_value_t arg_chv1( "-chv1", false ); args_4::cmd_str_value_t arg_chv2( "-chv2", false ); args_4::cmd_str_value_t arg_file( "-file", false ); arg_file_path_t arg_file_path( "-file-path", false ); args_4::cmd_on_off_switch_t arg_write( "-w", false ); args_4::cmd_on_off_switch_t arg_ascii( "-ascii", false ); args_4::cmd_uint_value_t arg_offset( "-offset", false ); args_4::cmd_str_value_t arg_dbg_stream( "-dbg-stream", false ); // Производим разбор аргументов. if( parse_args( argc, argv, arg_file, arg_file_path, arg_reader, arg_chv1, arg_chv2, arg_write, arg_ascii, arg_offset, arg_dbg_stream ) ) { //Часть кода про проверке допустимости значений некоторых //аргументов изъята. return do_main_work( arg_reader.query_value(), arg_file_path, arg_chv1, arg_chv2, arg_offset, arg_write.is_defined(), arg_ascii.is_defined(), arg_dbg_stream ); } return c_invalid_argv; } int show_usage_and_exit() { std::cout << "SmartCard file viewer and editor (in hex format)\n" "sc_hed <args>*\n" "where args are:\n" "\t-reader <reader name> (mandatory)\n" "\t-chv1 <CHV1 value>\n" "\t-chv2 <CHV2 value>\n" "\t-file <GSM file name>\n" "\t-file-path <XXXX[/XXXX[/XXXX[...]]]>\n" "\t-w\n" "\t-offset <offset | record num>\n" "\t-ascii\n" "\t-dbg-stream <file name>\n" "\t@<file name>\n" "Either ’-file’ or ’-file-path’ must be specified.\n" "Data will be read from standard input" << std::endl; return 0; } int main( int argc, char ** argv ) { // Если не задано аргументов, то печатаем справку и // завершаемся. Если аргументы заданы, то пытаемся // их разобрать и выполнить работу. return ( 1 == argc ? show_usage_and_exit() : do_work( argc, argv ) ); } |