# HG changeset patch # User John Schneiderman # Date 1402751857 0 # Node ID 04ad7227e290a4f83aeaddb6263abd43f04f60b4 Rebuilding structure for development. diff -r 000000000000 -r 04ad7227e290 INSTALL --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/INSTALL Sat Jun 14 13:17:37 2014 +0000 @@ -0,0 +1,39 @@ +******************************************************************************** +*** This file is part of QtArgs. *** +*** *** +*** Copyright (C) 2011, 2012, 2014 *** +*** CodeGNU Solutions *** +*** *** +*** This program is free software: you can redistribute it and/or modify *** +*** it under the terms of the GNU Lesser General Public License as *** +*** published by the Free Software Foundation, either version 3 of the *** +*** License, or (at your option) any later version. *** +*** *** +*** This program 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. *** +*** See the GNU Lesser General Public License for more details. *** +*** *** +*** You should have received a copy of the GNU Lesser General Public *** +*** License along with this program. If not, see *** +*** . *** +******************************************************************************** + +Needed for compiling +==================== +1) QT 5.0 or later + +How To compile the programme +============================ +2) Compile the programme from a build directory or using Qt Creator + 2a) qmake + For Debug: qmake CONFIG+=debug + For Path, default /usr: qmake PREFIX=installPrefix + 2b) make + 2c) make install + +Known Issues +============ +1) The library build in Windows contains the version in the name. +2) Compiling the library in Windows using the MinGW compiler will not generate + a PDB file. So, an error when installing is expected. diff -r 000000000000 -r 04ad7227e290 LICENSE --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LICENSE Sat Jun 14 13:17:37 2014 +0000 @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff -r 000000000000 -r 04ad7227e290 README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Sat Jun 14 13:17:37 2014 +0000 @@ -0,0 +1,45 @@ +******************************************************************************** +*** This file is part of QtArgs. *** +*** *** +*** Copyright (C) 2011, 2012, 2014 *** +*** CodeGNU Solutions *** +*** *** +*** This program is free software: you can redistribute it and/or modify *** +*** it under the terms of the GNU Lesser General Public License as *** +*** published by the Free Software Foundation, either version 3 of the *** +*** License, or (at your option) any later version. *** +*** *** +*** This program 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. *** +*** See the GNU Lesser General Public License for more details. *** +*** *** +*** You should have received a copy of the GNU Lesser General Public *** +*** License along with this program. If not, see *** +*** . *** +******************************************************************************** + DESCRIPTION +QtArgs is a library to ease the handeling of command line options in Qt +applications. After parsing an argument, the value is guaranteed to be the +correct type ready for assignment and use in an application. + +Main website: http://www.codegnu.com/pages/qtargs.html +Development website: http://www.codegnu.org + + BUILD ENVIRONMENT +QtArgs is mainly developed on Mageia 4 using the standard development libraries, +and QT 5. It has not been tested on Debian Stable. + + DIRECTORY MAP +All the source code is listed in the src directory. The UNIT_TEST directory +contains code to perform unit tests for the library API to guarantee future +changes do not break existing code. The build instructions are explained in the +INSTALL file. For a listing of all the contributors to QtArgs you can find that +information in the CREDITS file. All the current news can be be found on the +development website. + + INSTRUCTIONS +Once compiled and installed the library is installed in the lib directory and +the include headers in the includes directory. Documentation files are installed +in the doc directory. From that point forward any application can link to the +library by pointing to the lib and include directories. diff -r 000000000000 -r 04ad7227e290 doc/CREDITS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/CREDITS Sat Jun 14 13:17:37 2014 +0000 @@ -0,0 +1,40 @@ +******************************************************************************** +*** This file is part of QtArgs. *** +*** *** +*** Copyright (C) 2011, 2012, 2014 *** +*** CodeGNU Solutions *** +*** *** +*** This program is free software: you can redistribute it and/or modify *** +*** it under the terms of the GNU Lesser General Public License as *** +*** published by the Free Software Foundation, either version 3 of the *** +*** License, or (at your option) any later version. *** +*** *** +*** This program 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. *** +*** See the GNU Lesser General Public License for more details. *** +*** *** +*** You should have received a copy of the GNU Lesser General Public *** +*** License along with this program. If not, see *** +*** . *** +******************************************************************************** + +This is a listing of the people that have contributed to the project. It is +sorted by name, and formatted in a way that allows for easy grepping and +beautification by scripts. The fields are: + - name (N) + - email (E) + - web-address (W) + - PGP key ID (K) + - PGP key fingerprint (F) + - description (D). +This was modified from: http://www.kernel.org/pub/linux/kernel/CREDITS +If one of the contributors did not wish to make a field public the text +"NOT_MADE_PUBLIC" is used instead. +--------------------------------------------------------------------- +N: John Schneiderman +E: JohnMS AT CodeGNU DOT com +W: http://www.codegnu.com +K: D060DD6F +F: 7BCAF9D478C242A4399B517A590BE289D060DD6F +D: Lead developer diff -r 000000000000 -r 04ad7227e290 doc/ChangeLog --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/ChangeLog Sat Jun 14 13:17:37 2014 +0000 @@ -0,0 +1,50 @@ +******************************************************************************** +*** This file is part of QtArgs. *** +*** *** +*** Copyright (C) 2011, 2012, 2014 *** +*** CodeGNU Solutions *** +*** *** +*** This program is free software: you can redistribute it and/or modify *** +*** it under the terms of the GNU Lesser General Public License as *** +*** published by the Free Software Foundation, either version 3 of the *** +*** License, or (at your option) any later version. *** +*** *** +*** This program 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. *** +*** See the GNU Lesser General Public License for more details. *** +*** *** +*** You should have received a copy of the GNU Lesser General Public *** +*** License along with this program. If not, see *** +*** . *** +******************************************************************************** +2014-05-20 John Schneiderman 1.3.0b0 + - Upgraded to build using Qt 5. +2011-05-27 John Schneiderman 1.2.1 + - Fixed issue with unit test failing because tabs were converted to spaces. + - Fixed warnings when using QCoreApplication prior to creation. + - Fixed exception when accessing a short option missing its value. + - Fixed problem compiling both 32-bit and 64-bit due to path. +2011-05-16 John Schneiderman 1.2.0 + - Support for arguments needing a single character. + - Requesting value of an argument fires the co-responding signal. + - Complete unit test for the API now that it is finalised and frozen. + - Ensured all documentation files are installed. + - Automatically verify all arguments passed in are supported by an application. + - API support for accessing arguments passed in. + - Automatically generate help summary both standard out and in signal. + - Support to require an argument is passed into an application. + - Simplified API (Breaks prior library) + - Customised install paths. + - Specific options for compiler. + - Argument counts supplied by the user. +2011-03-19 John Schneiderman 1.1.0 + - Default arguments cannot work with library structure. + - Windows GUI applications to swallowed all arguments. + - Debug trace statements. + - License information slot. +2011-01-30 John Schneiderman 1.0.0 + - First release with strong type support + - Unix and Windows command line markers supported + - Short and Long option names supported + - Simple argument initialisation. diff -r 000000000000 -r 04ad7227e290 doc/Doxyfile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/Doxyfile Sat Jun 14 13:17:37 2014 +0000 @@ -0,0 +1,1749 @@ +# Doxyfile 1.7.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = QtArgs + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.3 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Qt Argument Processor" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = /home/codegnu/Projects/QtArgs + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = YES + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = YES + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = YES + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = YES + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = NO + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = /home/codegnu/Projects/QtArgs/errors.log + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = /home/codegnu/Projects/QtArgs/TRUNK/src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = *.svn + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = NO + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is adviced to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = YES + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = YES + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = com.CodeGNU.QtArgs + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = /usr/lib/qt4/bin/qhelpgenerator + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = YES + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 4 + +# By default doxygen will write a font called Helvetica to the output +# directory and reference it in all dot files that doxygen generates. +# When you want a differently looking font you can specify the font name +# using DOT_FONTNAME. You need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = YES + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff -r 000000000000 -r 04ad7227e290 doc/TODO --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/TODO Sat Jun 14 13:17:37 2014 +0000 @@ -0,0 +1,31 @@ +******************************************************************************** +*** This file is part of QtArgs. *** +*** *** +*** Copyright (C) 2011, 2012, 2014 *** +*** CodeGNU Solutions *** +*** *** +*** This program is free software: you can redistribute it and/or modify *** +*** it under the terms of the GNU Lesser General Public License as *** +*** published by the Free Software Foundation, either version 3 of the *** +*** License, or (at your option) any later version. *** +*** *** +*** This program 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. *** +*** See the GNU Lesser General Public License for more details. *** +*** *** +*** You should have received a copy of the GNU Lesser General Public *** +*** License along with this program. If not, see *** +*** . *** +******************************************************************************** + + Outlined below are potential features which are thought to be needed. Their +development is subject to the time of the developers and the demand made by the +users. If you see a feature you would like and can contribute check the mailing +list or IRC channel to join! If you see a hash-mark, then it has an issue number +in the tracking system too. + +*** *** +*** Feature Goals *** +*** *** +- Looking for suggestions ... diff -r 000000000000 -r 04ad7227e290 qtargs.pro --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qtargs.pro Sat Jun 14 13:17:37 2014 +0000 @@ -0,0 +1,48 @@ +#******************************************************************************* +#** This file is part of QtArgs. *** +#** *** +#** Copyright (C) 2011, 2012, 2014 *** +#** CodeGNU Solutions *** +#** *** +#** This program is free software: you can redistribute it and/or modify *** +#** it under the terms of the GNU Lesser General Public License as *** +#** published by the Free Software Foundation, either version 3 of the *** +#** License, or (at your option) any later version. *** +#** *** +#** This program 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. *** +#** See the GNU Lesser General Public License for more details. *** +#** *** +#** You should have received a copy of the GNU Lesser General Public *** +#** License along with this program. If not, see *** +#** . *** +#******************************************************************************* +TEMPLATE = subdirs +SUBDIRS = src/qargs.pro \ + src/UNIT_TESTS/qargsut.pro + +isEmpty(PREFIX) { + win32 { + PREFIX = $$quote(C:\\QtSDK\\QtArgs\\) + } else { + PREFIX = /usr + } +} +isEmpty(DOC_PATH) { + win32 { + DOC_PATH = $${PREFIX}/doc + } else { + DOC_PATH = $${PREFIX}/share/doc/QtArgs + } +} +docs.files += \ + INSTALL \ + README \ + COPYING \ + doc/ChangeLog \ + doc/CREDITS \ + doc/TODO +docs.path = $${DOC_PATH} +INSTALLS += docs +DISTFILES += docs diff -r 000000000000 -r 04ad7227e290 src/UNIT_TESTS/qargsut.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/UNIT_TESTS/qargsut.hpp Sat Jun 14 13:17:37 2014 +0000 @@ -0,0 +1,1966 @@ +/******************************************************************************* +*** This file is part of QtArgs. *** +*** *** +*** Copyright (C) 2011, 2012, 2014 *** +*** CodeGNU Solutions *** +*** *** +*** This program is free software: you can redistribute it and/or modify *** +*** it under the terms of the GNU Lesser General Public License as *** +*** published by the Free Software Foundation, either version 3 of the *** +*** License, or (at your option) any later version. *** +*** *** +*** This program 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. *** +*** See the GNU Lesser General Public License for more details. *** +*** *** +*** You should have received a copy of the GNU Lesser General Public *** +*** License along with this program. If not, see *** +*** . *** +*******************************************************************************/ +#ifndef QARGSUT_HPP_ +#define QARGSUT_HPP_ + +#include "qargs.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +using std::domain_error; +using std::runtime_error; +using std::logic_error; + + +/** + * QArgs Unit Test + * + * Full unit test for all the components of QArgs. Each member function is + * tested for handling both valid and invalid data. Those member functions + * that fire signals are verified as well. Any exceptions thrown by a member + * function is verified for both throwing and not throwing the specified + * exception. + */ +class QArgsUT: public QObject +{ + Q_OBJECT + /// Assumed operating system marker, '?' in Windows and 'h' in Unix. + const QChar MARKER; + /// Argument value used for testing short name options. + const char* const shortValueTest; + /// Number of arguments tested + static const int ARGC = 8; + /// Container to represent the arguments from an user. + const char* argv[ARGC]; + /// First argument as the application running. + const char* const arg0; + /// Short-name argument test option. + const char* const arg1; + /// Value for the short-named argument. + const char* const arg2; + /// Long-name argument test option and the value in Unix. + const char* const arg3; + /// Long-name argument value in Windows. + const char* const arg4; + /// Short-name help option test + const char* const arg5; + /// Long-name help option test + const char* const arg6; + /// Flag option test + const char* const arg7; + +public: + /// Default construct for testing + QArgsUT(): + QObject(NULL), +#ifdef Q_OS_WIN32 + MARKER('/'), + shortValueTest("/v"), + arg0("C:\\QtMGW\\QtArgs\\qargsut.exe"), // Not a valid argument + arg1("/i"), // First half of a short named argument + arg2("5"), // value for the short named argument + arg3("/double"), // Whole argument + arg4("25.25"), // Whole argument value + arg5("/?"), // short help + arg6("/help"), // long help + arg7("/f") // Flag argument +#else + MARKER('-'), + shortValueTest("-v"), + arg0("/usr/bin/qargsut"), // Not a valid argument + arg1("-i"), // First half of a short named argument + arg2("5"), // value for the short named argument + arg3("--double=25.25"), // Whole argument + arg4(""), // Unix whole values are together + arg5("-h"), // short help + arg6("--help"), // long help + arg7("-f") // Flag argument +#endif + { + qDebug() << "Detected OS marker:" << MARKER; + + argv[0] = arg0; + argv[1] = arg1; + argv[2] = arg2; + argv[3] = arg3; + argv[4] = arg4; + argv[5] = arg5; + argv[6] = arg6; + argv[7] = arg7; + } + +private slots: +#ifndef QT_NO_DEBUG_OUTPUT + /// Test argument constructor + void constructor() + { + QArgs args(ARGC, argv); + + QVERIFY(args.mArguments.count() == ARGC); + QVERIFY(args.mArguments[0] == arg0); + QVERIFY(args.mArguments[1] == arg1); + QVERIFY(args.mArguments[2] == arg2); + QVERIFY(args.mArguments[3] == arg3); + QVERIFY(args.mArguments[4] == arg4); + QVERIFY(args.mArguments[5] == arg5); + QVERIFY(args.mArguments[6] == arg6); + QVERIFY(args.mArguments[7] == arg7); + + // Verify help is established + QVERIFY(args.mSupported.value(QArgs::SHORT_HELP).shortName == + QArgs::SHORT_HELP); + QVERIFY(args.mSupported.value(QArgs::SHORT_HELP).longName == "help"); + QVERIFY(args.mSupported.value( + QArgs::SHORT_HELP).description.isEmpty()); + QVERIFY(args.mSupported.value(QArgs::SHORT_HELP).needsValue == false); + QVERIFY(args.mSupported.value(QArgs::SHORT_HELP).required == false); + QVERIFY(args.mIsCaseSensative == true); + QVERIFY(args.mIsLocked == false); + } + + /// Test adding argument support + void addSupported() + { + QArgs args(ARGC, argv); + + // Test normal support usage + args.addSupported('i', "integer", "Whole number test", true, true); + args.addSupported('d', "double", "Real number test", true); + args.addSupported('f', "flag", "Flag test"); + + QVERIFY(args.mSupported.value('i').shortName == 'i'); + QVERIFY(args.mSupported.value('i').longName == "integer"); + QVERIFY(args.mSupported.value('i').description == + "Whole number test"); + QVERIFY(args.mSupported.value('i').needsValue == true); + QVERIFY(args.mSupported.value('i').required == true); + QVERIFY(args.mSupported.value('d').shortName == 'd'); + QVERIFY(args.mSupported.value('d').longName == "double"); + QVERIFY(args.mSupported.value('d').description == + "Real number test"); + QVERIFY(args.mSupported.value('d').needsValue == true); + QVERIFY(args.mSupported.value('d').required == false); + QVERIFY(args.mSupported.value('f').shortName == 'f'); + QVERIFY(args.mSupported.value('f').longName == "flag"); + QVERIFY(args.mSupported.value('f').description == + "Flag test"); + QVERIFY(args.mSupported.value('f').needsValue == false); + QVERIFY(args.mSupported.value('f').required == false); + + // Test exception cases + try + { + args.addSupported('h', "question", "Short help test"); + QVERIFY2(false, "Short help argument not caught"); + } + catch (domain_error& error) + { + qDebug() << error.what(); + } + try + { + args.addSupported('?', "win-question", + "Short help for Windows test"); + QVERIFY2(false, "Short help argument for Windows not caught"); + } + catch (domain_error& error) + { + qDebug() << error.what(); + } + try + { + args.addSupported('p', "help", "Long help test"); + QVERIFY2(false, "Long help argument not caught"); + } + catch (domain_error& error) + { + qDebug() << error.what(); + } + try + { + args.addSupported(' ', "aaaa", "Empty argument short test"); + QVERIFY2(false, "Empty short argument not caught"); + } + catch (logic_error& error) + { + qDebug() << error.what(); + } + try + { + args.addSupported('e', " ", "Empty argument long test"); + QVERIFY2(false, "Empty long argument not caught"); + } + catch (logic_error& error) + { + qDebug() << error.what(); + } + try + { + args.addSupported('r', "required", "Required test", false, true); + QVERIFY2(false, "Required not caught"); + } + catch (runtime_error& error) + { + qDebug() << error.what(); + } + try + { + args.addSupported('a', "longA1", "First in repeated short option " + "name test"); + args.addSupported('a', "longA2", "The repeated short option " + "name test"); + QVERIFY2(false, "Repeated short option name not caught"); + } + catch (logic_error& error) + { + qDebug() << error.what(); + } + try + { + args.addSupported('b', "longB", "First in repeated long option " + "name test"); + args.addSupported('c', "longB", "The repeated long option " + "name test"); + QVERIFY2(false, "Repeated long option name not caught"); + } + catch (logic_error& error) + { + qDebug() << error.what(); + } + } + + /// Test verification of supported arguments + void verifySupport() + { + try + { + QArgs args(ARGC, argv); + args.addSupported('i', "integer", "Whole number test", true, true); + args.addSupported('d', "double", "Real number test", true); + args.addSupported('f', "flag", "Flag test"); + + args.verifySupport(); + QVERIFY(true); + } + catch(runtime_error& error) + { + qDebug() << error.what(); + QVERIFY2(false, "Short & long arguments provided, and are " + "listed as supported"); + } + try + { + QArgs args(ARGC, argv); + + args.verifySupport(); + QVERIFY2(false, "Short & long arguments not provided, but none " + "listed as supported"); + } + catch(logic_error& error) + { + qDebug() << error.what(); + } + try + { + QArgs args(ARGC, argv); + args.addSupported('i', "integer", "Whole number test", true, true); + args.addSupported('d', "double", "Real number test", true); + + args.verifySupport(); + QVERIFY2(false, "Short & long arguments provided, but some are " + "not listed as supported"); + } + catch(runtime_error& error) + { + qDebug() << error.what(); + } + } + + // Test argument list lock + void argumentListLock() + { + try + { + QArgs args(ARGC, argv); + + QVERIFY2(false == args.mIsLocked, "Arguments list not " + "locked test."); + args.lock(); + QVERIFY2(true == args.mIsLocked, "Arguments list locked test."); + args.addSupported('a', "longA", "Test argument adding after lock."); + QVERIFY2(false, "Test argument adding after lock failed."); + } + catch(logic_error& error) + { + qDebug() << error.what(); + } + + } + + /// Test index of a short name argument + void shortNameIndex() + { + QArgs args(ARGC, argv); + args.addSupported('i', "integer", "Whole number test", true, true); + args.addSupported('d', "double", "Real number test", true); + args.addSupported('f', "flag", "Flag test"); + + QVERIFY(args.shortNameIndex('i') == 1); + QVERIFY(args.shortNameIndex('d') == -1); + #ifdef Q_OS_WIN32 + QVERIFY(args.shortNameIndex('?') == 5); + QVERIFY(args.shortNameIndex('h') == -1); + #else + QVERIFY(args.shortNameIndex('h') == 5); + QVERIFY(args.shortNameIndex('?') == -1); + #endif + QVERIFY(args.shortNameIndex('f') == 7); + QVERIFY(args.shortNameIndex('a') == -1); + } + + /// Test index of a long name argument + void longNameIndex() + { + { + QArgs args(ARGC, argv); + args.addSupported('i', "integer", "Whole number test", + true, true); + args.addSupported('d', "double", "Real number test", true); + args.addSupported('f', "flag", "Flag test"); + + QVERIFY(args.longNameIndex('i') == -1); + QVERIFY(args.longNameIndex('d') == 3); + #ifdef Q_OS_WIN32 + QVERIFY(args.longNameIndex('?') == 6); + QVERIFY(args.longNameIndex('h') == -1); + #else + QVERIFY(args.longNameIndex('h') == 6); + QVERIFY(args.longNameIndex('?') == -1); + #endif + QVERIFY(args.longNameIndex('f') == -1); + QVERIFY(args.longNameIndex('a') == -1); + } + { + QArgs args(ARGC, argv); // Arguments not listed + + QVERIFY(args.longNameIndex('i') == -1); + QVERIFY(args.longNameIndex('d') == -1); + #ifdef Q_OS_WIN32 + QVERIFY(args.longNameIndex('?') == 6); + #else + QVERIFY(args.longNameIndex('h') == 6); + #endif + QVERIFY(args.longNameIndex('f') == -1); + } + } +#endif + + /// Test arguments accessor + void arguments() + { + QArgs args(ARGC, argv); + QStringList argsTest(args.arguments()); + + QVERIFY(argsTest.count() == ARGC); + QVERIFY(argsTest[0] == arg0); + QVERIFY(argsTest[1] == arg1); + QVERIFY(argsTest[2] == arg2); + QVERIFY(argsTest[3] == arg3); + QVERIFY(argsTest[4] == arg4); + QVERIFY(argsTest[5] == arg5); + QVERIFY(argsTest[6] == arg6); + QVERIFY(argsTest[7] == arg7); + } + + /// Test marker accessor + void marker() + { + QArgs args(ARGC, argv); + + QVERIFY(args.marker() == MARKER); + } + + /// Test count + void count() + { + { + // Only application name test + #ifdef Q_OS_WIN32 + const char* argvValue[1] = { "C:\bin\bash" }; + #else + const char* argvValue[1] = { "/bin/sh" }; + #endif + QArgs args(1, argvValue); + + QVERIFY(args.count() == 0); + } + { + // No Argument test + #ifdef Q_OS_WIN32 + const char* argvValue[3] = { "C:\bin\bash", "v", "dfd" }; + #else + const char* argvValue[3] = { "/bin/sh", "v", "dfd" }; + #endif + QArgs args(3, argvValue); + + QVERIFY(args.count() == 0); + } + { + QArgs args(ARGC, argv); + + // Valid arguments that are counted: -i, --double, -h, --help, -f + QVERIFY(args.count() == 5); + } + } + + /// Test automated help test support + void hasHelp() + { + { + const char* help[1] = { arg5 }; + QArgs args(1, help); + QVERIFY(args.hasHelp() == true); + } + { + const char* help[1] = { arg6 }; + QArgs args(1, help); + QVERIFY(args.hasHelp() == true); + } + { + const char* help[1] = { arg1 }; // no help + QArgs args(1, help); + QVERIFY(args.hasHelp() == false); + } + } + + /// Test automated display help + /// @todo verify the standard output buffer contains the same text as + /// the signal fired. + void showHelp() + { + QArgs args(ARGC, argv); + QSignalSpy help(&args, SIGNAL(help(const QString&))); + + args.addSupported('i', "integer", "Whole number test", true, true); + args.addSupported('d', "double", "Real number test", true); + args.addSupported('f', "flag", "Flag test"); + + QVERIFY(help.isValid()); + args.showHelp(); + QVERIFY(help.count() == 1); + QList< QVariant > arguments(help.takeAt(0)); + QString text(arguments.at(0).toString()); + #ifdef Q_OS_WIN32 + # ifdef QT_NO_DEBUG_OUTPUT + QVERIFY(text.startsWith("usage: qtargsut.exe [options]")); + # else + QVERIFY(text.startsWith("usage: qtargsutd.exe [options]")); + # endif + QVERIFY(text.contains("Options:")); + QVERIFY(text.contains(" /d ")); + QVERIFY(text.contains("Real number test")); + QVERIFY(text.contains(" /f")); + QVERIFY(text.contains("Flag test")); + QVERIFY(text.contains(" /i ")); + QVERIFY(text.contains("Whole number test")); + #else + # ifdef QT_NO_DEBUG_OUTPUT + QVERIFY(text.startsWith("usage: qtargsut [options]")); + # else + QVERIFY(text.startsWith("usage: qtargsutd [options]")); + # endif + QVERIFY(text.contains("Options:")); + QVERIFY(text.contains(" -d ")); + QVERIFY(text.contains("Real number test")); + QVERIFY(text.contains(" -f")); + QVERIFY(text.contains("Flag test")); + QVERIFY(text.contains(" -i ")); + QVERIFY(text.contains("Whole number test")); + #endif + } + + /// Test display about + /// @todo verify the standard output buffer contains the same text as + /// the signal fired. + void showAbout() + { + QArgs args(ARGC, argv); + QSignalSpy about(&args, SIGNAL(about(const QString&))); + + QVERIFY(about.isValid()); + args.about(); + QVERIFY(about.count() == 1); + QList< QVariant > arguments(about.takeAt(0)); + QVERIFY(arguments.at(0).toString() == QString( + "QtArgs version 1.3.0\n" + "Copyright (C) 2011 - 2014 John Schneiderman\n" + "QtArgs comes with ABSOLUTELY NO WARRANTY.\nThis is " + "free software, and you are welcome to redistribute it\n" + "under certain conditions; see the LICENSE file for details,\n" + "or the Free Software Foundation's LGPL.\n")); + } + + /// Test has argument + void hasArgument() + { + { + QArgs args(ARGC, argv); + + QVERIFY(args.hasArgument('f') == true); + } + { + QArgs args(ARGC, argv); + + QVERIFY(args.hasArgument('p') == false); + } + } + + // Test multiple values + void values() + { + { + const char* argvValue[5] = { shortValueTest, "1", "2", "3", "4" }; + QArgs args(5, argvValue); + args.addSupported('v', "values", "Multiple values short test.", + true); + try + { + QList< qint32 > values(args.values('v', 15)); + QVERIFY(4 == values.size()); + QVERIFY(1 == values.at(0)); + QVERIFY(2 == values.at(1)); + QVERIFY(3 == values.at(2)); + QVERIFY(4 == values.at(3)); + } + catch (runtime_error& error) + { + QVERIFY2(false, error.what()); + } + } + { + const char* argvValue[5] = { shortValueTest, "1", "2", "a", "4" }; + QArgs args(5, argvValue); + args.addSupported('v', "values", "Multiple values short test, " + "with a bad value.", true); + try + { + QList< qint32 > values(args.values('v', 15)); + QVERIFY(3 == values.size()); + QVERIFY(1 == values.at(0)); + QVERIFY(2 == values.at(1)); + QVERIFY(4 == values.at(2)); + } + catch (runtime_error& error) + { + QVERIFY2(false, error.what()); + } + } + { + const char* argvValue[9] = + { + #ifdef Q_OS_WIN32 + "/a", + #else + "-a", + #endif + "p", + shortValueTest, + "1", + "2", + "3", + "4", + #ifdef Q_OS_WIN32 + "/b", + #else + "-b", + #endif + "5", + }; + QArgs args(9, argvValue); + args.addSupported('v', "values", "Multiple values short test " + "with extra options.", true); + args.addSupported('a', "aValue", "Leader value", true); + args.addSupported('b', "bValue", "Follower value", true); + try + { + QList< qint32 > values(args.values('v', 15)); + QVERIFY(4 == values.size()); + QVERIFY(1 == values.at(0)); + QVERIFY(2 == values.at(1)); + QVERIFY(3 == values.at(2)); + QVERIFY(4 == values.at(3)); + } + catch (runtime_error& error) + { + QVERIFY2(false, error.what()); + } + } + { + const char* argvValue[5] = + { + #ifdef Q_OS_WIN32 + "/values", + #else + "--values", + #endif + "4", + "3", + "2", + "1" + }; + QArgs args(5, argvValue); + args.addSupported('v', "values", "Multiple values long test ", + true); + try + { + QList< qint32 > values(args.values('v', 15)); + QVERIFY(4 == values.size()); + QVERIFY(4 == values.at(0)); + QVERIFY(3 == values.at(1)); + QVERIFY(2 == values.at(2)); + QVERIFY(1 == values.at(3)); + } + catch (runtime_error& error) + { + QVERIFY2(false, error.what()); + } + } + } + + /// Test value boolean + void valueBoolean() + { + bool value = false; + // Short name tests + { + const char* argvValue[2] = { shortValueTest, "TrUe"}; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean true/false value " + "sensative short test", true); + QVERIFY(args.value('v', value) == true); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == true); + } + { + const char* argvValue[2] = { shortValueTest, "TrUe"}; + QArgs args(2, argvValue, QArgs::CASE_INSENSATIVE); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('V', "value", "Boolean true/false value " + "insensative short test", true); + QVERIFY(args.value('V', value) == true); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'V'); + QVERIFY(arguments.at(1).toBool() == true); + } + { + const char* argvValue[2] = { shortValueTest, "T"}; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean t/f value short test", + true); + QVERIFY(args.value('v', value, QArgs::T_OR_F) == true); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == true); + } + { + const char* argvValue[2] = { shortValueTest, "1"}; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean 1/0 value short test", + true); + QVERIFY(args.value('v', value, QArgs::ONE_OR_ZERO) == true); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == true); + } + { + const char* argvValue[2] = { shortValueTest, "YeS"}; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean yes/no value short test", + true); + QVERIFY(args.value('v', value, QArgs::YES_OR_NO) == true); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == true); + } + { + const char* argvValue[2] = { shortValueTest, "Y"}; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean y/n value short test", + true); + QVERIFY(args.value('v', value, QArgs::Y_OR_N) == true); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == true); + } + { + const char* argvValue[2] = { shortValueTest, "On" }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean on/off value short test", + true); + QVERIFY(args.value('v', value, QArgs::ON_OR_OFF) == true); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == true); + } + + // Long name tests + { + const char* argvValue[2] = + { + #ifdef Q_OS_WIN32 + "/value", + "TrUe" + #else + "--value=TrUe", + "" + #endif + }; // Test case + // insensitivity + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean true/false value " + "long test", true); + QVERIFY(args.value('v', value) == true); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == true); + } + { + const char* argvValue[2] = + { + #ifdef Q_OS_WIN32 + "/value", + "T" + #else + "--value=T", + "" + #endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean t/f value long test", + true); + QVERIFY(args.value('v', value, QArgs::T_OR_F) == true); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == true); + } + { + const char* argvValue[2] = + { + #ifdef Q_OS_WIN32 + "/value", + "1" + #else + "--value=1", + "" + #endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean 1/0 value long test", + true); + QVERIFY(args.value('v', value, QArgs::ONE_OR_ZERO) == true); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == true); + } + { + const char* argvValue[2] = + { + #ifdef Q_OS_WIN32 + "/value", + "yes" + #else + "--value=yes", + "" + #endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean yes/no value long test", + true); + QVERIFY(args.value('v', value, QArgs::YES_OR_NO) == true); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == true); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "Y" +#else + "--value=Y", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean y/n value long test", + true); + QVERIFY(args.value('v', value, QArgs::Y_OR_N) == true); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == true); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "ON" +#else + "--value=On", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean on/off value long test", + true); + QVERIFY(args.value('v', value, QArgs::ON_OR_OFF) == true); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == true); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "ON" +#else + "--value=On", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean on/off and 1/0 value " + "combined test", true); + QVERIFY(args.value('v', value, static_cast( + QArgs::ON_OR_OFF | QArgs::ONE_OR_ZERO)) == true); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == true); + } + { + const char* argvValue[1] = { shortValueTest }; + QArgs args(1, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean value short test fail", + true); + QVERIFY(args.value('v', value) == false); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == false); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "1.0" +#else + "--value=1.0", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean value long test " + "fail invalid argument", true); + QVERIFY(args.value('v', value, QArgs::ONE_OR_ZERO) == false); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == false); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "dog" +#else + "--value=DOG", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,bool))); + + args.addSupported('v', "value", "Boolean value long test " + "fail invalid word", true); + QVERIFY(args.value('v', value) == false); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toBool() == false); + } + } + + /// Test value real numbers + void valueReal() + { + qreal value = 9.630; + { + const char* argvValue[2] = { shortValueTest, "1.234" }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qreal))); + + args.addSupported('v', "value", "Real value short test", true); + QVERIFY(qFuzzyCompare(1.0 + args.value('v', value), 1.0 + 1.234)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(qFuzzyCompare(1.0 + arguments.at(1).toDouble(), + 1.0 + 1.234)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4.321" +#else + "--value=4.321", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qreal))); + + args.addSupported('v', "value", "Real value long test", true); + QVERIFY(qFuzzyCompare(1.0 + args.value('v', value), 1.0 + 4.321)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(qFuzzyCompare(1.0 + arguments.at(1).toDouble(), + 1.0 + 4.321)); + } + { + const char* argvValue[1] = { shortValueTest }; + QArgs args(1, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qreal))); + + args.addSupported('v', "value", "Real value short test fail", + true); + QVERIFY(qFuzzyCompare(1.0 + args.value('v', value), 1.0 + 9.630)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(qFuzzyCompare(1.0 + arguments.at(1).toDouble(), + 1.0 + 9.630)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "Jack" +#else + "--value=Jack", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qreal))); + + args.addSupported('v', "value", "Real value long test fail", true); + QVERIFY(qFuzzyCompare(1.0 + args.value('v', value), 1.0 + 9.630)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(qFuzzyCompare(1.0 + arguments.at(1).toDouble(), + 1.0 + 9.630)); + } + } + + /// Test value 8-bit integer numbers + void value8BitIntenger() + { + qint8 value = -9; + { + const char* argvValue[2] = { shortValueTest, "-2" }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint8))); + + args.addSupported('v', "value", "8-bit value short test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-2)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-2)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "-4" +#else + "--value=-4", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint8))); + + args.addSupported('v', "value", "8-bit value long test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-4)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-4)); + } + { + const char* argvValue[1] = { shortValueTest }; + QArgs args(1, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint8))); + + args.addSupported('v', "value", "8-bit value short test fail", + true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-9)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4.45" +#else + "--value=4.45", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint8))); + + args.addSupported('v', "value", "8-bit value long " + "long test fail", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-9)); + } + } + + /// Test value 16-bit integer numbers + void value16BitIntenger() + { + qint16 value = -9; + { + const char* argvValue[2] = { shortValueTest, "-2" }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint16))); + + args.addSupported('v', "value", "16-bit value short test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-2)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-2)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "-4" +#else + "--value=-4", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint16))); + + args.addSupported('v', "value", "16-bit value long test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-4)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-4)); + } + { + const char* argvValue[1] = { shortValueTest }; + QArgs args(1, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint16))); + + args.addSupported('v', "value", "16-bit value short test fail", + true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-9)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4.45" +#else + "--value=4.45", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint16))); + + args.addSupported('v', "value", "16-bit value long " + "long test fail", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-9)); + } + } + + /// Test value 32-bit integer numbers + void value32BitIntenger() + { + qint32 value = -9; + { + const char* argvValue[2] = { shortValueTest, "-2" }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint32))); + + args.addSupported('v', "value", "32-bit value short test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-2)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-2)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "-4" +#else + "--value=-4", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint32))); + + args.addSupported('v', "value", "32-bit value long test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-4)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-4)); + } + { + const char* argvValue[1] = { shortValueTest }; + QArgs args(1, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint32))); + + args.addSupported('v', "value", "32-bit value short test fail", + true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-9)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4.45" +#else + "--value=4.45", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint32))); + + args.addSupported('v', "value", "32-bit value long " + "long test fail", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-9)); + } + } + + /// Test value 64-bit integer numbers + void value64BitIntenger() + { + qint64 value = -9; + { + const char* argvValue[2] = { shortValueTest, "-2" }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint64))); + + args.addSupported('v', "value", "64-bit value short test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-2)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-2)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "-4" +#else + "--value=-4", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint64))); + + args.addSupported('v', "value", "64-bit value long test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-4)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-4)); + } + { + const char* argvValue[1] = { shortValueTest }; + QArgs args(1, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint64))); + + args.addSupported('v', "value", "64-bit value short test fail", + true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-9)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4.45" +#else + "--value=4.45", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,qint64))); + + args.addSupported('v', "value", "64-bit value long " + "long test fail", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(-9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toLongLong()) == + static_cast(-9)); + } + } + + /// Test value 8-bit unsigned integer numbers + void value8BitUnsignedIntenger() + { + quint8 value = 9; + { + const char* argvValue[2] = { shortValueTest, "2" }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,quint8))); + + args.addSupported('v', "value", "8-bit unsigned value " + "short test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(2)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(2)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4" +#else + "--value=4", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,quint8))); + + args.addSupported('v', "value", "8-bit unsigned value " + "long test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(4)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(4)); + } + { + const char* argvValue[1] = { shortValueTest }; + QArgs args(1, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,quint8))); + + args.addSupported('v', "value", "8-bit unsigned value " + "short test fail", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(9)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4.45" +#else + "--value=4.45", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, SIGNAL(argumentValue(QChar,quint8))); + + args.addSupported('v', "value", "8-bit unsigned value " + "long test fail", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(9)); + } + } + + /// Test value 16-bit unsigned integer numbers + void value16BitUnsignedIntenger() + { + quint16 value = 9; + { + const char* argvValue[2] = { shortValueTest, "2" }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,quint16))); + + args.addSupported('v', "value", "16-bit unsigned value " + "short test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(2)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(2)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4" +#else + "--value=4", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,quint16))); + + args.addSupported('v', "value", "16-bit unsigned value " + "long test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(4)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(4)); + } + { + const char* argvValue[1] = { shortValueTest }; + QArgs args(1, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,quint16))); + + args.addSupported('v', "value", "16-bit unsigned value " + "short test fail", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(9)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4.45" +#else + "--value=4.45", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,quint16))); + + args.addSupported('v', "value", "16-bit unsigned value " + "long test fail", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(9)); + } + } + + /// Test value 32-bit unsigned integer numbers + void value32BitUnsignedIntenger() + { + quint32 value = 9; + { + const char* argvValue[2] = { shortValueTest, "2" }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,quint32))); + + args.addSupported('v', "value", "32-bit unsigned value " + "short test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(2)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(2)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4" +#else + "--value=4", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,quint32))); + + args.addSupported('v', "value", "32-bit unsigned value " + "long test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(4)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(4)); + } + { + const char* argvValue[1] = { shortValueTest }; + QArgs args(1, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,quint32))); + + args.addSupported('v', "value", "32-bit unsigned value " + "short test fail", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(9)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4.45" +#else + "--value=4.45", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,quint32))); + + args.addSupported('v', "value", "32-bit unsigned value " + "long test fail", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(9)); + } + } + + /// Test value 64-bit unsigned integer numbers + void value64BitUnsignedIntenger() + { + quint64 value = 9; + { + const char* argvValue[2] = { shortValueTest, "2" }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,quint64))); + + args.addSupported('v', "value", "64-bit unsigned value " + "short test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(2)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(2)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4" +#else + "--value=4", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,quint64))); + + args.addSupported('v', "value", "64-bit unsigned value " + "long test", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(4)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(4)); + } + { + const char* argvValue[1] = { shortValueTest }; + QArgs args(1, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,quint64))); + + args.addSupported('v', "value", "64-bit unsigned value " + "short test fail", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(9)); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4.45" +#else + "--value=4.45", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,quint64))); + + args.addSupported('v', "value", "64-bit unsigned value " + "long test fail", true); + QVERIFY(static_cast(args.value('v', value)) == + static_cast(9)); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(static_cast(arguments.at(1).toULongLong()) == + static_cast(9)); + } + } + + /// Test value QChar + void valueQChar() + { + QChar value('9'); + { + const char* argvValue[2] = { shortValueTest, "2"}; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,QChar))); + + args.addSupported('v', "value", "QChar value short test", true); + QVERIFY(args.value('v', value) == '2'); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toChar() == '2'); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4" +#else + "--value=4", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,QChar))); + + args.addSupported('v', "value", "QChar value shot test", true); + QVERIFY(args.value('v', value) == '4'); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toChar() == '4'); + } + { + const char* argvValue[1] = { shortValueTest }; + QArgs args(1, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,QChar))); + + args.addSupported('v', "value", "QChar value short test fail", + true); + QVERIFY(args.value('v', value) == '9'); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toChar() == '9'); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "\0" +#else + "--value=\0", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,QChar))); + + args.addSupported('v', "value", "QChar empty value " + "long test fail", true); + QVERIFY(args.value('v', value) == '9'); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toChar() == '9'); + } + } + + /// Test value QString + void valueQString() + { + QString value("9"); + { + const char* argvValue[2] = { shortValueTest, "2" }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,QString))); + + args.addSupported('v', "value", "QString value short test", true); + QVERIFY(args.value('v', value) == "2"); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toString() == "2"); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "4" +#else + "--value=4", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,QString))); + + args.addSupported('v', "value", "QString value long test", true); + QVERIFY(args.value('v', value) == "4"); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toString() == "4"); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "a " +#else + "--value=a ", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,QString))); + + args.addSupported('v', "value", "QString emtpy spaced value " + "long test", true); + QVERIFY(args.value('v', value) == "a"); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toString() == "a"); + } + { + const char* argvValue[1] = { shortValueTest }; + QArgs args(1, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,QString))); + + args.addSupported('v', "value", "QString value short test fail", + true); + QVERIFY(args.value('v', value) == "9"); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toString() == "9"); + } + { + const char* argvValue[2] = + { +#ifdef Q_OS_WIN32 + "/value", + "\0\0\0" +#else + "--value=\0\0\0", + "" +#endif + }; + QArgs args(2, argvValue); + QSignalSpy valueSignal(&args, + SIGNAL(argumentValue(QChar,QString))); + + args.addSupported('v', "value", "QString null value " + "long test fail", true); + QVERIFY(args.value('v', value) == "9"); + QVERIFY(valueSignal.isValid()); + QVERIFY(valueSignal.count() == 1); + QList< QVariant > arguments(valueSignal.takeAt(0)); + QVERIFY(arguments.at(0).toChar() == 'v'); + QVERIFY(arguments.at(1).toString() == "9"); + } + } +}; +#endif +QTEST_MAIN(QArgsUT) diff -r 000000000000 -r 04ad7227e290 src/UNIT_TESTS/qargsut.pro --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/UNIT_TESTS/qargsut.pro Sat Jun 14 13:17:37 2014 +0000 @@ -0,0 +1,113 @@ +#******************************************************************************* +#** This file is part of QtArgs. *** +#** *** +#** Copyright (C) 2011, 2012, 2014 *** +#** CodeGNU Solutions *** +#** *** +#** This program is free software: you can redistribute it and/or modify *** +#** it under the terms of the GNU Lesser General Public License as *** +#** published by the Free Software Foundation, either version 3 of the *** +#** License, or (at your option) any later version. *** +#** *** +#** This program 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. *** +#** See the GNU Lesser General Public License for more details. *** +#** *** +#** You should have received a copy of the GNU Lesser General Public *** +#** License along with this program. If not, see *** +#** . *** +#******************************************************************************* +TEMPLATE = app +QT += testlib +QT -= gui +DEPENDPATH += .. +INCLUDEPATH += .. + +CONFIG += \ + qt \ + dynamic \ + exceptions \ + stl +CONFIG (debug, debug|release) { + !buildpass:message(Compiling QtArgs unit test debug build.) + TARGET = qtargsutd +win32 { + LIBS += -lqtargsd1 +} else { + LIBS += -lqtargsd +} + LIBS += -L../../debug + DESTDIR = ../../debug + OBJECTS_DIR = debug + CONFIG -= release + CONFIG += \ + warn_on \ + debug + linux-g++ { + !buildpass:message(Setting GCC debug flags.) + QMAKE_CXXFLAGS_DEBUG += \ + -std=c++98 \ # Conform to ISO standard + -pg \ # Enable code profiling + -fstack-protector-all \ # Check for buffer overflows + -Wall \ # Enable all normal code execution warnings + -Wextra \ # Enable extra warnings not enabled by Wall +# @bug Currently the build breaks due to QMapNode. +# -Wctor-dtor-privacy \ # Warn if a class seems unusable due to ctor + -Wold-style-cast \ # Warn C-style cast is used within a program. + -Woverloaded-virtual \ # Warn when a function declaration hides + # virtual functions from a base class + -Wswitch-enum \ # Warn whenever a switch statement has an index of + # enumerated type and lacks a case for one or more + # of the named codes of that enumeration. + -Wformat-security \ # Warn about uses of format functions + # that represent possible security problems. + -Wlogical-op \ # Warn about suspicious uses of + # logical operators in expressions. + -Wstack-protector \ # Warns about functions that will not + # be protected against stack smashing. + -g3 # Produce debugging information in the OS's native format + } + win32-g++ { + !buildpass:message(Setting MinGW debug flags.) + QMAKE_CXXFLAGS_DEBUG += \ + -Wall \ # Enable all normal code execution warnings + -Wextra \ # Enable extra warnings not enabled by Wall +# @bug Currently the build breaks due to QMapNode. +# -Wctor-dtor-privacy \ # Warn if a class seems unusable due to ctor + -Wold-style-cast \ # Warn C-style cast is used within a program. + -Woverloaded-virtual \ # Warn when a function declaration hides + # virtual functions from a base class + -Wswitch-enum \ # Warn whenever a switch statement has an index of + # enumerated type and lacks a case for one or more + # of the named codes of that enumeration. + -Wformat-security \ # Warn about uses of format functions + # that represent possible security problems. + -Wlogical-op \ # Warn about suspicious uses of + # logical operators in expressions. + -Wstack-protector # Warns about functions that will not + # be protected against stack smashing. + } + } else { + !buildpass:message(Compiling QtArgs unit test release build.) + TARGET = qtargsut +win32 { + LIBS += -lqtargs1 +} else { + LIBS += -lqtargs +} + LIBS += -L../../release + DESTDIR = ../../release + OBJECTS_DIR = release + CONFIG -= debug + CONFIG += release + DEFINES += QT_NO_DEBUG_OUTPUT + linux-g++ { + !buildpass:message(Setting GCC release flags.) + QMAKE_CXXFLAGS_RELEASE += -O3 # Use all optimizations from O2 and more. + } +} +MOC_DIR = $$OBJECTS_DIR +UI_DIR = $$OBJECTS_DIR + +HEADERS = qargsut.hpp diff -r 000000000000 -r 04ad7227e290 src/qargs.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/qargs.cpp Sat Jun 14 13:17:37 2014 +0000 @@ -0,0 +1,810 @@ +/******************************************************************************* +*** This file is part of QtArgs. *** +*** *** +*** Copyright (C) 2011, 2012, 2014 *** +*** CodeGNU Solutions *** +*** *** +*** This program is free software: you can redistribute it and/or modify *** +*** it under the terms of the GNU Lesser General Public License as *** +*** published by the Free Software Foundation, either version 3 of the *** +*** License, or (at your option) any later version. *** +*** *** +*** This program 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. *** +*** See the GNU Lesser General Public License for more details. *** +*** *** +*** You should have received a copy of the GNU Lesser General Public *** +*** License along with this program. If not, see *** +*** . *** +*******************************************************************************/ +#include "qargs.h" + +#include +#include +#include +#include +#include +#include + +#include +using std::cout; +using std::endl; +#include +using std::domain_error; +using std::runtime_error; +using std::logic_error; + + +#ifdef Q_OS_WIN32 + const QChar& QArgs::ARGUMENT_MARKER('/'); + const QChar& QArgs::SHORT_HELP('?'); + const QChar& QArgs::OTHER_OS_SHORT_HELP('h'); +#else + const QChar& QArgs::ARGUMENT_MARKER('-'); + const QChar& QArgs::SHORT_HELP('h'); + const QChar& QArgs::OTHER_OS_SHORT_HELP('?'); +#endif +const QChar& QArgs::ARGUMENT_LONG_ASSIGNMENT('='); +const QString& QArgs::LONG_HELP("help"); +const qint8 QArgs::MINIMUM_LONG_OPTION(2); + +//{ Type Conversions for multiple values +template<> +bool convertToValueType(const QString& value, qreal& converted) +{ + qDebug() << "convertToValueType(const QString&, qreal&)" << value + << converted; + bool conversionState; + converted = value.toDouble(&conversionState); + return conversionState; +} + +template<> +bool convertToValueType(const QString& value, qint8& converted) +{ + qDebug() << "convertToValueType(const QString&, qint8&)" << value + << converted; + bool conversionState; + converted = static_cast(value.toShort(&conversionState)); + return conversionState; +} + +template<> +bool convertToValueType(const QString& value, qint16& converted) +{ + qDebug() << "convertToValueType(const QString&, qint16&)" << value + << converted; + bool conversionState; + converted = value.toShort(&conversionState); + return conversionState; +} + +template<> +bool convertToValueType(const QString& value, qint32& converted) +{ + qDebug() << "convertToValueType(const QString&, qint32&)" << value + << converted; + bool conversionState; + converted = value.toLong(&conversionState); + return conversionState; +} + +template<> +bool convertToValueType(const QString& value, qint64& converted) +{ + qDebug() << "convertToValueType(const QString&, qint64&)" << value + << converted; + bool conversionState; + converted = value.toLongLong(&conversionState); + return conversionState; +} + +template<> +bool convertToValueType(const QString& value, quint8& converted) +{ + qDebug() << "convertToValueType(const QString&, quint8&)" << value + << converted; + bool conversionState; + converted = static_cast(value.toShort(&conversionState)); + return conversionState; +} + +template<> +bool convertToValueType(const QString& value, quint16& converted) +{ + qDebug() << "convertToValueType(const QString&, quint16&)" << value + << converted; + bool conversionState; + converted = value.toUShort(&conversionState); + return conversionState; +} + +template<> +bool convertToValueType(const QString& value, quint32& converted) +{ + qDebug() << "convertToValueType(const QString&, quint32&)" << value + << converted; + bool conversionState; + converted = value.toULong(&conversionState); + return conversionState; +} + +template<> +bool convertToValueType(const QString& value, quint64& converted) +{ + qDebug() << "convertToValueType(const QString&, quint64&)" << value + << converted; + bool conversionState; + converted = value.toULongLong(&conversionState); + return conversionState; +} + +template<> +bool convertToValueType(const QString& value, QChar& converted) +{ + qDebug() << "convertToValueType(const QString&, QChar&)" << value + << converted; + bool valid; + if (value.isEmpty()) + valid = false; + else + { + converted = value.at(0); + valid = true; + } + return valid; +} + +template<> +bool convertToValueType(const QString& value, QString& converted) +{ + qDebug() << "convertToValueType(const QString&, QString&)" << value + << converted; + converted = value; + return true; +} +//} + +QArgs::QArgs(int argc, const char* argv[], Sensitivity caseing): + QObject(NULL), + mArguments(), + mSupported(), + mIsCaseSensative(CASE_SENSATIVE == caseing), + mIsLocked(false), + mAreArgumentsVerified(false) +{ + qDebug() << "QArgs::QArgs(argc, const char*[])" << argc << *argv; + + for (int index(0); index < argc; ++index) + this->mArguments.append(QString(argv[index]).trimmed()); + + Properties help; + help.shortName = SHORT_HELP; + help.longName = LONG_HELP; + help.description = QString(); + help.needsValue = false; + help.required = false; + this->mSupported.insert(help.shortName, help); +} + +QArgs::QArgs(int argc, char* argv[], Sensitivity caseing): + QObject(NULL), + mArguments(), + mSupported(), + mIsCaseSensative(CASE_SENSATIVE == caseing), + mIsLocked(false), + mAreArgumentsVerified(false) +{ + qDebug() << "QArgs::QArgs(argc, char*[])" << argc << *argv; + + for (int index(0); index < argc; ++index) + this->mArguments.append(QString(argv[index]).trimmed()); + + Properties help; + help.shortName = SHORT_HELP; + help.longName = LONG_HELP; + help.description = QString(); + help.needsValue = false; + help.required = false; + this->mSupported.insert(help.shortName, help); +} + +const QStringList& QArgs::arguments() const +{ + qDebug() << "QArgs::arguments()"; + return this->mArguments; +} + +const QChar& QArgs::marker() const +{ + qDebug() << "QArgs::marker()"; + return ARGUMENT_MARKER; +} + +qint32 QArgs::count() const +{ + qDebug() << "QArgs::count()"; + const QString LONG_MARKER(QString("%1%2").arg(ARGUMENT_MARKER).arg( + ARGUMENT_MARKER)); + qint32 count(0); + + foreach (QString argument, this->mArguments) + if (argument.startsWith(ARGUMENT_MARKER) + || argument.startsWith(LONG_MARKER)) + ++count; + return count; +} + +void QArgs::addSupported(const QChar& shortName, const QString& longName, + const QString& description, bool takesValue, bool required) +{ + qDebug() << "QArgs::addSupported(QChar, QString, QString, bool, bool)" << + shortName << longName << description << + (takesValue ? "TakesValue" : "DoesNotTakeValue") << + (required ? "Required" : "NotRequired"); + + // Verify short name is valid. + if ((SHORT_HELP == shortName) || (OTHER_OS_SHORT_HELP == shortName)) + throw domain_error(tr("Cannot override short " + "help argument name, %1.").arg(shortName).toStdString()); + else if (shortName.isNull() || shortName.isSpace()) + throw logic_error(tr("Option for the short name cannot be " + "null or empty.").toStdString()); + else if (this->mSupported.contains(shortName)) + throw logic_error(tr("The short name '%1' was already in the " + "supported options list.").arg(shortName).toStdString()); + + // Verify long name is valid. + if (LONG_HELP == longName.trimmed()) + throw domain_error(tr("Cannot override long " + "help argument name, %1.").arg(LONG_HELP).toStdString()); + else if (longName.trimmed().isNull() || ( + longName.trimmed().count() < MINIMUM_LONG_OPTION)) + throw logic_error(tr("Option for the long name cannot be " + "null, a single character, or empty.").toStdString()); + foreach (Properties supported, this->mSupported) + if (supported.longName == longName.trimmed()) + throw logic_error(tr("The long name '%1' was already in the " + "supported options list under the '%2' " + "short name and cannot be listed under '%3' " + "for the short name as well." + ).arg(longName.trimmed() + ).arg(supported.shortName + ).arg(shortName).toStdString()); + + // Check to see if futher options are allowed. + if (this->mIsLocked) + throw logic_error(tr("Cannot add futher arguments as the supported " + "option list is locked.").toStdString()); + + // Add the valid option. + Properties support; + support.shortName = shortName; + support.longName = longName.trimmed(); + support.description = description.trimmed(); + support.needsValue = takesValue; + support.required = required; + this->mSupported.insert(shortName, support); + + // Guarantee Required Arguments + if (required && (! hasArgument(shortName))) + throw runtime_error(tr("Missing Required Argument: %1(%2) -- %3").arg( + shortName).arg(longName.trimmed()).arg( + description).toStdString()); +} + +bool QArgs::hasArgument(const QChar& shortName) const +{ + qDebug() << "QArgs::hasArgument(QChar)" << shortName; + + if ((-1 != shortNameIndex(shortName)) || (-1 != longNameIndex(shortName))) + return true; + else + return false; +} + +void QArgs::lock() +{ + qDebug() << "QArgs::lock()"; + this->mIsLocked = true; +} + +bool QArgs::hasHelp() const +{ + qDebug() << "QArgs::hasHelp()"; + + if ((-1 != shortNameIndex(SHORT_HELP)) || + (-1 != longNameIndex(SHORT_HELP))) + return true; + else + return false; +} + +void QArgs::showHelp() const +{ + QString helpMessage; + QString fileName((NULL == QCoreApplication::instance()) ? + "application" : QCoreApplication::applicationFilePath()); + + helpMessage = "usage: " % QFileInfo(fileName).fileName() % + " [options]\nOptions:\n"; + foreach (Properties property, this->mSupported) + if (property.description.isNull()) + continue; + else + helpMessage = helpMessage % " " % ARGUMENT_MARKER % + property.shortName % + (property.needsValue ? " \t" : "\t\t" ) % + "\t" % property.description % "\n"; + cout << helpMessage.toStdString() << endl; + if (NULL != QCoreApplication::instance()) + emit help(helpMessage); +} + +void QArgs::about() const +{ + QString legalText("QtArgs version "); + + legalText = legalText % LIBRARY_VERSION % "\nCopyright (C) " % + COPYRIGHT_YEARS % " John Schneiderman\nQtArgs comes with " + "ABSOLUTELY NO WARRANTY.\nThis is free software, and you are " % + "welcome to redistribute it\nunder certain conditions; see the " + "LICENSE file for details,\nor the Free Software " + "Foundation's LGPL.\n"; + + cout << legalText.toStdString() << endl; + if (NULL != QCoreApplication::instance()) + emit about(legalText); +} + +bool QArgs::value(const QChar& shortName, bool defaultValue, + BooleanSupport types) const +{ + qDebug() << "QArgs::value(QChar, bool)" << shortName + << (defaultValue ? "True" : "False"); + bool value(defaultValue); + int shortIndex(shortNameIndex(shortName)); + int longIndex(longNameIndex(shortName)); + bool converted(false); + QString valueTest; + + verifySupport(); + if ((-1 != shortIndex) && ((shortIndex + 1) < this->mArguments.size())) + valueTest = this->mArguments.at(shortIndex + 1).toLower(); + else if (-1 != longIndex) +#ifdef Q_OS_WIN32 + valueTest = this->mArguments.at(longIndex + 1).toLower(); +#else + valueTest = this->mArguments.at(longIndex).split( + ARGUMENT_LONG_ASSIGNMENT)[1].toLower(); +#endif + + // Generate the boolean value from the supplied option. + if (((types & QArgs::ONE_OR_ZERO) == QArgs::ONE_OR_ZERO) + && (("1" == valueTest) || ("0" == valueTest))) + value = (1 == valueTest.toUInt(&converted)); + else if (((types & QArgs::T_OR_F) == QArgs::T_OR_F) + && (("t" == valueTest) || ("f" == valueTest))) + value = ("t" == valueTest); + else if (((types & QArgs::TRUE_OR_FALSE) == QArgs::TRUE_OR_FALSE) + && (("true" == valueTest) || ("false" == valueTest))) + value = ("true" == valueTest); + else if (((types & QArgs::ON_OR_OFF) == QArgs::ON_OR_OFF) + && (("on" == valueTest) || ("off" == valueTest))) + value = ("on" == valueTest); + else if (((types & QArgs::YES_OR_NO) == QArgs::YES_OR_NO) + && (("yes" == valueTest) || ("no" == valueTest))) + value = ("yes" == valueTest); + else if (((types & QArgs::Y_OR_N) == QArgs::Y_OR_N) + && (("y" == valueTest) || ("n" == valueTest))) + value = ("y" == valueTest); + else + value = defaultValue; + + if (NULL != QCoreApplication::instance()) + emit argumentValue(shortName, value); + return value; +} + +qreal QArgs::value(const QChar& shortName, qreal defaultValue) const +{ + qDebug() << "QArgs::value(QChar, qreal)" << shortName << defaultValue; + qreal value(defaultValue); + int shortIndex(shortNameIndex(shortName)); + int longIndex(longNameIndex(shortName)); + bool converted(false); + + verifySupport(); + if ((-1 != shortIndex) && ((shortIndex + 1) < this->mArguments.size())) + value = this->mArguments.at(shortIndex + 1).toDouble(&converted); + else if (-1 != longIndex) +#ifdef Q_OS_WIN32 + value = this->mArguments.at(longIndex + 1).toDouble(&converted); +#else + value = this->mArguments.at(longIndex).split( + ARGUMENT_LONG_ASSIGNMENT)[1].toDouble(&converted); +#endif + + if (! converted) + value = defaultValue; + + if (NULL != QCoreApplication::instance()) + emit argumentValue(shortName, value); + return value; +} + +qint8 QArgs::value(const QChar& shortName, qint8 defaultValue) const +{ + qDebug() << "QArgs::value(QChar, qint8)" << shortName << defaultValue; + qint8 value(defaultValue); + int shortIndex(shortNameIndex(shortName)); + int longIndex(longNameIndex(shortName)); + bool converted(false); + + verifySupport(); + if ((-1 != shortIndex) && ((shortIndex + 1) < this->mArguments.size())) + value = this->mArguments.at(shortIndex + 1).toShort(&converted); + else if (-1 != longIndex) +#ifdef Q_OS_WIN32 + value = this->mArguments.at(longIndex + 1).toShort(&converted); +#else + value = this->mArguments.at(longIndex).split( + ARGUMENT_LONG_ASSIGNMENT)[1].toShort(&converted); +#endif + + if (! converted) + value = defaultValue; + + if (NULL != QCoreApplication::instance()) + emit argumentValue(shortName, value); + return value; +} + +qint16 QArgs::value(const QChar& shortName, qint16 defaultValue) const +{ + qDebug() << "QArgs::value(QChar, qint16)" << shortName << defaultValue; + qint16 value(defaultValue); + int shortIndex(shortNameIndex(shortName)); + int longIndex(longNameIndex(shortName)); + bool converted(false); + + verifySupport(); + if ((-1 != shortIndex) && ((shortIndex + 1) < this->mArguments.size())) + value = this->mArguments.at(shortIndex + 1).toShort(&converted); + else if (-1 != longIndex) +#ifdef Q_OS_WIN32 + value = this->mArguments.at(longIndex + 1).toShort(&converted); +#else + value = this->mArguments.at(longIndex).split( + ARGUMENT_LONG_ASSIGNMENT)[1].toShort(&converted); +#endif + + if (! converted) + value = defaultValue; + + if (NULL != QCoreApplication::instance()) + emit argumentValue(shortName, value); + return value; +} + +qint32 QArgs::value(const QChar& shortName, qint32 defaultValue) const +{ + qDebug() << "QArgs::value(QChar, qint32)" << shortName << defaultValue; + qint32 value(defaultValue); + int shortIndex(shortNameIndex(shortName)); + int longIndex(longNameIndex(shortName)); + bool converted(false); + + verifySupport(); + if ((-1 != shortIndex) && ((shortIndex + 1) < this->mArguments.size())) + value = this->mArguments.at(shortIndex + 1).toInt(&converted); + else if (-1 != longIndex) +#ifdef Q_OS_WIN32 + value = this->mArguments.at(longIndex + 1).toInt(&converted); +#else + value = this->mArguments.at(longIndex).split( + ARGUMENT_LONG_ASSIGNMENT)[1].toInt(&converted); +#endif + + if (! converted) + value = defaultValue; + + if (NULL != QCoreApplication::instance()) + emit argumentValue(shortName, value); + return value; +} + +qint64 QArgs::value(const QChar& shortName, qint64 defaultValue) const +{ + qDebug() << "QArgs::value(QChar, qint64)" << shortName << defaultValue; + qint64 value(defaultValue); + int shortIndex(shortNameIndex(shortName)); + int longIndex(longNameIndex(shortName)); + bool converted(false); + + verifySupport(); + if ((-1 != shortIndex) && ((shortIndex + 1) < this->mArguments.size())) + value = this->mArguments.at(shortIndex + 1).toLongLong(&converted); + else if (-1 != longIndex) +#ifdef Q_OS_WIN32 + value = this->mArguments.at(longIndex + 1).toLongLong(&converted); +#else + value = this->mArguments.at(longIndex).split( + ARGUMENT_LONG_ASSIGNMENT)[1].toLongLong(&converted); +#endif + + if (! converted) + value = defaultValue; + + if (NULL != QCoreApplication::instance()) + emit argumentValue(shortName, value); + return value; +} + +quint8 QArgs::value(const QChar& shortName, quint8 defaultValue) const +{ + qDebug() << "QArgs::value(QChar, quint8)" << shortName << defaultValue; + quint8 value(defaultValue); + int shortIndex(shortNameIndex(shortName)); + int longIndex(longNameIndex(shortName)); + bool converted(false); + + verifySupport(); + if ((-1 != shortIndex) && ((shortIndex + 1) < this->mArguments.size())) + value = this->mArguments.at(shortIndex + 1).toUShort(&converted); + else if (-1 != longIndex) +#ifdef Q_OS_WIN32 + value = this->mArguments.at(longIndex + 1).toUShort(&converted); +#else + value = this->mArguments.at(longIndex).split( + ARGUMENT_LONG_ASSIGNMENT)[1].toUShort(&converted); +#endif + + if (! converted) + value = defaultValue; + + if (NULL != QCoreApplication::instance()) + emit argumentValue(shortName, value); + return value; +} + +quint16 QArgs::value(const QChar& shortName, quint16 defaultValue) const +{ + qDebug() << "QArgs::value(QChar, quint16)" << shortName << defaultValue; + quint16 value(defaultValue); + int shortIndex(shortNameIndex(shortName)); + int longIndex(longNameIndex(shortName)); + bool converted(false); + + verifySupport(); + if ((-1 != shortIndex) && ((shortIndex + 1) < this->mArguments.size())) + value = this->mArguments.at(shortIndex + 1).toUShort(&converted); + else if (-1 != longIndex) +#ifdef Q_OS_WIN32 + value = this->mArguments.at(longIndex + 1).toUShort(&converted); +#else + value = this->mArguments.at(longIndex).split( + ARGUMENT_LONG_ASSIGNMENT)[1].toUShort(&converted); +#endif + + if (! converted) + value = defaultValue; + + if (NULL != QCoreApplication::instance()) + emit argumentValue(shortName, value); + return value; +} + +quint32 QArgs::value(const QChar& shortName, quint32 defaultValue) const +{ + qDebug() << "QArgs::value(QChar, quint32)" << shortName << defaultValue; + quint32 value(defaultValue); + int shortIndex(shortNameIndex(shortName)); + int longIndex(longNameIndex(shortName)); + bool converted(false); + + verifySupport(); + if ((-1 != shortIndex) && ((shortIndex + 1) < this->mArguments.size())) + value = this->mArguments.at(shortIndex + 1).toUInt(&converted); + else if (-1 != longIndex) +#ifdef Q_OS_WIN32 + value = this->mArguments.at(longIndex + 1).toUInt(&converted); +#else + value = this->mArguments.at(longIndex).split( + ARGUMENT_LONG_ASSIGNMENT)[1].toUInt(&converted); +#endif + + if (! converted) + value = defaultValue; + + if (NULL != QCoreApplication::instance()) + emit argumentValue(shortName, value); + return value; +} + +quint64 QArgs::value(const QChar& shortName, quint64 defaultValue) const +{ + qDebug() << "QArgs::value(QChar, quint64)" << shortName << defaultValue; + quint64 value(defaultValue); + int shortIndex(shortNameIndex(shortName)); + int longIndex(longNameIndex(shortName)); + bool converted(false); + + verifySupport(); + if ((-1 != shortIndex) && ((shortIndex + 1) < this->mArguments.size())) + value = this->mArguments.at(shortIndex + 1).toULongLong(&converted); + else if (-1 != longIndex) +#ifdef Q_OS_WIN32 + value = this->mArguments.at(longIndex + 1).toULongLong(&converted); +#else + value = this->mArguments.at(longIndex).split( + ARGUMENT_LONG_ASSIGNMENT)[1].toULongLong(&converted); +#endif + + if (! converted) + value = defaultValue; + + if (NULL != QCoreApplication::instance()) + emit argumentValue(shortName, value); + return value; +} + +QChar QArgs::value(const QChar& shortName, + const QChar& defaultValue) const +{ + qDebug() << "QArgs::value(QChar, QChar)" << shortName << defaultValue; + QChar value; + QString valueHolder; + int shortIndex(shortNameIndex(shortName)); + int longIndex(longNameIndex(shortName)); + + verifySupport(); + if ((-1 != shortIndex) && ((shortIndex + 1) < this->mArguments.size())) + valueHolder = this->mArguments.at(shortIndex + 1); + else if (-1 != longIndex) +#ifdef Q_OS_WIN32 + valueHolder = this->mArguments.at(longIndex + 1); +#else + valueHolder = this->mArguments.at(longIndex).split( + ARGUMENT_LONG_ASSIGNMENT)[1]; +#endif + + if (valueHolder.isNull() || valueHolder.isEmpty()) + value = defaultValue; + else + value = valueHolder.at(0); + + if (NULL != QCoreApplication::instance()) + emit argumentValue(shortName, value); + return value; +} + +QString QArgs::value(const QChar& shortName, + const QString& defaultValue) const +{ + qDebug() << "QArgs::value(QChar, QString)" << shortName << defaultValue; + QString value; + int shortIndex(shortNameIndex(shortName)); + int longIndex(longNameIndex(shortName)); + + verifySupport(); + if ((-1 != shortIndex) && ((shortIndex + 1) < this->mArguments.size())) + value = this->mArguments.at(shortIndex + 1); + else if (-1 != longIndex) +#ifdef Q_OS_WIN32 + value = this->mArguments.at(longIndex + 1); +#else + value = this->mArguments.at(longIndex).split( + ARGUMENT_LONG_ASSIGNMENT)[1]; +#endif + + if (value.isNull() || value.isEmpty()) + value = defaultValue; + + if (NULL != QCoreApplication::instance()) + emit argumentValue(shortName, value); + return value; +} + +void QArgs::verifySupport() const +{ + const short SHORT_NAME_SIZE(2); + const short LONG_NAME_SIZE(3); + QChar shortName; + + if (! this->mAreArgumentsVerified) + { + // Only the help option is supported & user is trying to get a value. + if (1 == this->mSupported.count()) + throw logic_error(tr("No arguments listed as " + "being supported!").toStdString()); + + foreach (QString argument, this->mArguments) + { + if ((SHORT_NAME_SIZE == argument.count()) && + (argument[0] == ARGUMENT_MARKER) && + (argument[1].isLetter())) + shortName = argument.at(1); + else if ((LONG_NAME_SIZE >= argument.count()) && + (argument[0] == ARGUMENT_MARKER) && + (argument[1] == ARGUMENT_MARKER)) + { + argument = argument.remove(0, 2); + argument = argument.split(ARGUMENT_LONG_ASSIGNMENT)[0]; + shortName = '\0'; + foreach (Properties property, this->mSupported) + if (property.longName == argument) + { + shortName = property.shortName; + break; + } + } + else + continue; + + bool supported; + if (this->mIsCaseSensative) + supported = this->mSupported.contains(shortName); + else + supported = (this->mSupported.contains(shortName.toUpper()) + || this->mSupported.contains( + shortName.toLower())); + + if (! supported) + throw runtime_error(tr("Unrecognized Option '%1'").arg( + argument).toStdString()); + } + this->mAreArgumentsVerified = true; + } +} + +int QArgs::shortNameIndex(const QChar& name) const +{ + QRegExp indexTest(QString("%1%2").arg(ARGUMENT_MARKER).arg( + QRegExp::escape(name)), + this->mIsCaseSensative ? + Qt::CaseSensitive : Qt::CaseInsensitive); + int index(this->mArguments.indexOf(indexTest)); + +#ifdef Q_OS_WIN32 + if (SHORT_HELP == name) + index = this->mArguments.indexOf(QString("%1\%2").arg( + ARGUMENT_MARKER).arg(SHORT_HELP)); +#endif + qDebug() << "Short index of " << name << "is" << index; + return index; +} + +int QArgs::longNameIndex(const QChar& name) const +{ + int index(-1); + +#ifdef Q_OS_WIN32 + // Windows long options form is: /long-index-name value + qDebug() << "Windows long form:" << QString("%1%2").arg( + ARGUMENT_MARKER).arg( + this->mSupported.value(name).longName); + index = this->mArguments.indexOf( + QRegExp(QString("%1%2").arg(ARGUMENT_MARKER).arg( + this->mSupported.value(name).longName))); + + if (SHORT_HELP == name) + index = this->mArguments.indexOf(QRegExp(QString("%1%2").arg( + ARGUMENT_MARKER).arg(mSupported.value(name).longName))); +#else + // Unices long options form is: --long-index-name=value + index = (this->mArguments.indexOf( + QRegExp(QString("%1%2%3%4.*").arg( + ARGUMENT_MARKER).arg(ARGUMENT_MARKER).arg( + this->mSupported.value(name).longName).arg( + ARGUMENT_LONG_ASSIGNMENT)))); +#endif + + if (-1 == index) // Test for flag long name argument + index = this->mArguments.indexOf(QRegExp(QString("%1%2%3").arg( + ARGUMENT_MARKER).arg(ARGUMENT_MARKER).arg( + this->mSupported.value(name).longName))); + qDebug() << "Long index of " << name << "is" << index; + return index; +} diff -r 000000000000 -r 04ad7227e290 src/qargs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/qargs.h Sat Jun 14 13:17:37 2014 +0000 @@ -0,0 +1,820 @@ +/******************************************************************************* +*** This file is part of QtArgs. *** +*** *** +*** Copyright (C) 2011, 2012, 2014 *** +*** CodeGNU Solutions *** +*** *** +*** This program is free software: you can redistribute it and/or modify *** +*** it under the terms of the GNU Lesser General Public License as *** +*** published by the Free Software Foundation, either version 3 of the *** +*** License, or (at your option) any later version. *** +*** *** +*** This program 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. *** +*** See the GNU Lesser General Public License for more details. *** +*** *** +*** You should have received a copy of the GNU Lesser General Public *** +*** License along with this program. If not, see *** +*** . *** +*******************************************************************************/ +#ifndef QARGS_H_ +#define QARGS_H_ +/** + * @file qargs.h + * @brief Argument Processing + * @details Declartions for procsssing the command-line arguments. + */ + +#include +#include +#include +#include + +#include "qargs_global.h" + +class QChar; +class QString; +template < class KeyType, class ValueType > +class QMap; + + +/** + * @brief Value Type Converter + * @details Converts the supplied string into the type of the expected value. + * + * @param[in] value The value to be converted. + * @param[out] converted The location to place the converted value. + * + * @return True when the conversion is successful, false else-wise. + */ +template< typename Expected > +bool convertToValueType(const QString& value, Expected& converted); + +/** + * @brief Manage Command-line Arguments + * @details Provides the means to process arguments passed from the command-line + * in a type safe manner. The command-line arguments are supported in an + * Operating System specific manner: the slash '/' for Windows and a + * dash '-' for Unix based systems. A short named option starts with the + * argument marker followed immediately a single character then a space and + * the value for the argument. A long named option starts the same as the + * short named option character, but the marker character is repeated twice for + * Unicies and only once for Windows. The long named option is then followed by + * a word that describes the option or dash seperated list of words. For the + * Unicies the long named option is followed by the option long separator, by + * default the equal('=') sign. In Windows, the long option name is followed by + * a space. When procressing the arguments, the short named argument is + * regarded as having an higher precidence than the long named argument. + * Command-line help for all options is automatically generated, and available + * to the user in an operating system specific manner, i.e. Windows users can + * access help by using a question('?') mark and Unix based systems can access + * using 'h'. In addition to single value arguments, there is support for + * arguments which take more than one value. These arguments are start in the + * same maner as both short and long named options; however, they do not have + * a long option seperator, instead they are followed by the values with each + * value seperated by a space(' '). + */ +class QTARGS_SHARED_EXPORT QArgs: public QObject +{ + Q_OBJECT + +signals: + //{ Argument Value Retrieved Signals + /** + * @brief Provided Flag Argument + * @details The signal that is fired for an argument flag. + * + * @param[in] argument The short name option that was provided. + */ + void argumentValue(const QChar& argument) const; + /** + * @brief Provided Boolean Argument Value + * @details The signal that is fired when an argument is provided by a user + * with a boolean value. + * + * @param[in] argument The short name option that was provided. + * @param[in] value The contents supplied by the user, else the default + * value is used. + */ + void argumentValue(const QChar& argument, bool value) const; + /** + * @brief Provided Double Precision Argument Value + * @details The signal that is fired when an argument is provided by a user + * with a single or double precision value. + * + * @param[in] argument The short name option that was provided. + * @param[in] value The contents supplied by the user, else the default + * value is used. + */ + void argumentValue(const QChar& argument, qreal value) const; + /** + * @brief Provided Signed 8-bit Argument Value + * @details The signal that is fired when an argument is provided by a user + * with an 8-bit integer value. + * + * @param[in] argument The short name option that was provided. + * @param[in] value The contents supplied by the user, else the default + * value is used. + */ + void argumentValue(const QChar& argument, qint8 value) const; + /** + * @brief Provided Signed 16-bit Argument Value + * @details The signal that is fired when an argument is provided by a user + * with a 16-bit integer value. + * + * @param[in] argument The short name option that was provided. + * @param[in] value The contents supplied by the user, else the default + * value is used. + */ + void argumentValue(const QChar& argument, qint16 value) const; + /** + * @brief Provided Signed 32-bit Argument Value + * @details The signal that is fired when an argument is provided by a user + * with a 32-bit integer value. + * + * @param[in] argument The short name option that was provided. + * @param[in] value The contents supplied by the user, else the default + * value is used. + */ + void argumentValue(const QChar& argument, qint32 value) const; + /** + * @brief Provided Signed 64-bit Argument Value + * @details The signal that is fired when an argument is provided by a user + * with a 64-bit integer value. + * + * @param[in] argument The short name option that was provided. + * @param[in] value The contents supplied by the user, else the default + * value is used. + */ + void argumentValue(const QChar& argument, qint64 value) const; + /** + * @brief Provided Unsigned 8-bit Argument Value + * @details The signal that is fired when an argument is provided by a user + * with an unsigned 8-bit integer value. + * + * @param[in] argument The short name option that was provided. + * @param[in] value The contents supplied by the user, else the default + * value is used. + */ + void argumentValue(const QChar& argument, quint8 value) const; + /** + * @brief Provided Unsigned 16-bit Argument Value + * @details The signal that is fired when an argument is provided by a user + * with an unsigned 16-bit integer value. + * + * @param[in] argument The short name option that was provided. + * @param[in] value The contents supplied by the user, else the default + * value is used. + */ + void argumentValue(const QChar& argument, quint16 value) const; + /** + * @brief Provided Unsigned 32-bit Argument Value + * @details The signal that is fired when an argument is provided by a user + * with an unsigned 32-bit integer value. + * + * @param[in] argument The short name option that was provided. + * @param[in] value The contents supplied by the user, else the default + * value is used. + */ + void argumentValue(const QChar& argument, quint32 value) const; + /** + * @brief Provided Unsigned 64-bit Argument Value + * @details The signal that is fired when an argument is provided by a user + * with an unsigned 64-bit integer value. + * + * @param[in] argument The short name option that was provided. + * @param[in] value The contents supplied by the user, else the default + * value is used. + */ + void argumentValue(const QChar& argument, quint64 value) const; + /** + * @brief Provided Character Argument Value + * @details The signal that is fired when an argument is provided by a user + * with a character value. + * + * @param[in] argument The short name option that was provided. + * @param[in] value The contents supplied by the user, else the default + * value is used. + */ + void argumentValue(const QChar& argument, const QChar& value) const; + /** + * @brief Provided String Argument Value + * @details The signal that is fired when an argument is provided by a user + * with a string value. + * + * @param[in] argument The short name option that was provided. + * @param[in] value The contents supplied by the user, else the default + * value is used. + */ + void argumentValue(const QChar& argument, const QString& value) const; + //} + + + //{ User Flag Request Signals + /** + * @brief Argument Help Message + * @details The signal that is fired when the user flagged a request for + * the usage help of the application supported arguments. + * + * @param[in] text The full help message. + */ + void help(const QString& text) const; + /** + * @brief Legal Information + * @details The signal that is fired when the user flagged a request for + * information regarding the legal information of the library. + * + * @param[in] text The full legal information message. + */ + void about(const QString& text) const; + //} + +public: + /** + * @brief Short Name Caseing Options + * @details The possible option's for the case-sensativity of a short name. + */ + enum Sensitivity + { + /// The short name option is case-sensative. + CASE_SENSATIVE, + /// The short name option is not case-sensative. + CASE_INSENSATIVE + }; + /** + * @brief Supported Boolean Types + * @details Determines the types of boolean keywords which are supported as + * an option. The different types of boolean keywords may be combined + * together to allow support for more than one type at a time. + */ + enum BooleanSupport + { + /// Support boolean option values which may be "true" or "false". + TRUE_OR_FALSE = 0x1, + /// Support boolean option values which may be "yes" or "no". + YES_OR_NO = 0x2, + /// Support boolean option values which may be "on" or "off". + ON_OR_OFF = 0x4, + /// Support boolean option values which may be "t" or "f". + T_OR_F = 0x8, + /// Support boolean option values which may be "y" or "n". + Y_OR_N = 0x10, + /// Support boolean option values which may be "1" or "0". + ONE_OR_ZERO = 0x20, + /// Support all boolean option types. + ALL = 0xFF + }; + + /** + * @brief Command-line Resource Processor + * @details Handles the parsing and initialising of the options and values + * provided by the user from the command-line. The long named arguments the + * expected to have their values in the same array row as the long named + * argument for all Unicies but in the following row for Windows. The short + * named arguments are expected to always have their values in the + * following row. + * + * @param[in] argc The number of arguments from the command-line. + * @param[in] argv The arguments from the command-line. + * @param[in] caseing Determines the case sensativity of the short named + * options. + * + * @post All object members are initialised and ready for use. The object + * member for the argument properties contains a short named operating + * system specific help command line argument. The object member for + * locking is in the unlocked state. The object's argument list member is + * populated with a white-spaced trimmed list of the supplied values. + */ + QArgs(int argc, const char* argv[], Sensitivity caseing = CASE_SENSATIVE); + /** + * @brief Command-line Resource Processor + * @details Handles the parsing and initialising of the options and values + * provided by the user from the command-line. The long named arguments the + * expected to have their values in the same array row as the long named + * argument for all Unicies but in the following row for Windows. The short + * named arguments are expected to always have their values in the + * following row. + * + * @param[in] argc The number of arguments from the command-line. + * @param[in] argv The arguments from the command-line. + * @param[in] caseing Determines the case sensativity of the short named + * options. + * + * @post All object members are initialised and ready for use. The object + * member for the argument properties contains a short named operating + * system specific help command line argument. The object member for + * locking is in the unlocked state. The object's argument list member is + * populated with a white-spaced trimmed list of the supplied values. + */ + QArgs(int argc, char* argv[], Sensitivity caseing = CASE_SENSATIVE); + + + //{ Argument Functions + /** + * @brief Listing of Arguments + * @details Provides a list of all arguments as they were provided at the + * time of initialisation. + * + * @return The argument list member. + */ + const QStringList& arguments() const; + /** + * @brief Argument Indicator Mark + * @details Provides the indicator a user would use to identify an argument + * for his particular operating system. + * + * @return The marker for an argument prefix. + */ + const QChar& marker() const; + /** + * @brief Number of Arguments + * @details The number of actual arguments provided by the user on the + * command line. The argument count does not include in the totalling the + * values supplied on the command line, nor the name of the application + * when supplied by the operating system. + * + * @return Number of short and long named argument count. + */ + qint32 count() const; + /** + * @brief Create Supported Argument + * @details Provides the mechanism to indicate what options are supported by + * an application. The argument option's description is used to display the + * help information to the user. If the provided value is a null string, + * the argument will not appear in the help request to the user. + * + * @param[in] shortName The short name of the option. + * @param[in] longName The long name of the option. + * @param[in] description The usage description for the option. + * @param[in] takesValue Flag indicating the option requires a value, + * when true. + * @param[in] required A flag indicating the option is required by the + * application to run when true. + * + * @throw domain_error When the developer attempts to use either the sort + * or long option names which are reserved for + * requesting to display the help information. + * @throw logic_error When either the short or long option names are + * empty. + * @throw logic_error When either the short or long option names were + * already listed as supported. + * @throw logic_error When an attempt to add another argument option after + * the developer locked the argument support list. + * @throw runtime_error When an option is required by the user and the + * user did not supply either the short or long + * option. + * + * @post The object's supported argument list member contains the short-name + * argument and the associated expected properties. + */ + void addSupported(const QChar& shortName, const QString& longName, + const QString& description, bool takesValue = false, + bool required = false); + /** + * @brief Checks for Argument + * @details Tests for the existence of a short or long named argument in + * the arguments supplied by the user from the command-line. + * + * @param[in] shortName The character which identifies the short-named + * option. + * + * @return True if option is present either in short or long name form, + * false else-wise. + */ + bool hasArgument(const QChar& shortName) const; + /** + * @brief Lock-down Supported Arguments + * @details Prevents adding further supported arguments to the list of + * supported arguements. + * + * @post The object member for locking supported arguments is enabled. + */ + void lock(); + //} + + + //{ About & Help Functions + /** + * @brief Check Help Display Requested + * @details Determines if the user provided the help argument request on the + * command-line. The argument help request option is determined by the + * Operating System running the application. + * + * @return True if either the short or long named for the help argument + * is in the command line, false else-wise. + */ + bool hasHelp() const; + /** + * @brief Display Help Information + * @details Outputs all argument help information. Help information is + * written in the following format:\n + * usage: APPLICATION_NAME [options]\n + * Options: \n + * ARGUMENT <value> \\t DESCRIPTION + * + * @pre Standard output buffer is open and ready to be written. + * + * @post The standard output buffer is populated with all the arguments + * whose description is not null. Once the help argument text is placed + * on the buffer, the object's signal for help requested is fired. + */ + void showHelp() const; + /** + * @brief About QtArgs + * @details Output information regarding the copyright, + * license information, etc.. + * + * @pre Standard output buffer is ready for write. + * + * @post Output buffer contains the copyright and license information. + */ + void about() const; + //} + + + //{ Option Value Retreival Functions + /** + * @brief Argument Option Boolean Value + * @details Provides access to the value from a short or long named argument + * supplied by the user from the command-line. Once the value for the + * option is determined the signal for the argument value is fired. A + * command line option may be any of the supported boolean types or + * combinations thereof. In addition, all argument values provided by the + * user are verified for both being valid and required. + * + * @param[in] shortName The short-name of the argument option. + * @param[in] defaultValue The value to use when an argument is not + * supplied by the user from the command-line. + * @param[in] types The boolean group type supported for the option. + * + * @return The value supplied from the command-line which matches the short + * name or long name option and is a valid boolean group, else the default + * value is provided. + */ + bool value(const QChar& shortName, bool defaultValue, + BooleanSupport types = TRUE_OR_FALSE) const; + /** + * @brief Option Double Precision Value + * @details Provides access to the value from a short or long named argument + * supplied by the user from the command-line. Once the value for the + * option is determined the signal for the argument value is fired. In + * addition, all argument values provided by the user are verified for both + * being valid and required. + * + * @param[in] shortName The short-name of the argument option. + * @param[in] defaultValue The value to use when an argument is not + * supplied by the user from the command-line. + * + * @return Any value supplied from the command-line which matches the short + * name or long name option and is a valid single or double precision + * number, else the default value is provided. + */ + qreal value(const QChar& shortName, qreal defaultValue) const; + /** + * @brief Option Signed 8-bit Value + * @details Provides access to the value from a short or long named argument + * supplied by the user from the command-line. Once the value for the + * option is determined the signal for the argument value is fired. In + * addition, all argument values provided by the user are verified for both + * being valid and required. + * + * @param[in] shortName The short-name of the argument option. + * @param[in] defaultValue The value to use when an argument is not + * supplied by the user from the command-line. + * + * @return Any value supplied from the command-line which matches the short + * name or long name option and is a valid signed 8-bit integer number, + * else the default value is provided. + */ + qint8 value(const QChar& shortName, qint8 defaultValue) const; + /** + * @brief Option Signed 16-bit Value + * @details Provides access to the value from a short or long named argument + * supplied by the user from the command-line. Once the value for the + * option is determined the signal for the argument value is fired. In + * addition, all argument values provided by the user are verified for both + * being valid and required. + * + * @param[in] shortName The short-name of the argument option. + * @param[in] defaultValue The value to use when an argument is not + * supplied by the user from the command-line. + * + * @return Any value supplied from the command-line which matches the short + * name or long name option and is a valid signed 16-bit integer number, + * else the default value is provided. + */ + qint16 value(const QChar& shortName, qint16 defaultValue) const; + /** + * @brief Option Signed 32-bit Value + * @details Provides access to the value from a short or long named argument + * supplied by the user from the command-line. Once the value for the + * option is determined the signal for the argument value is fired. In + * addition, all argument values provided by the user are verified for both + * being valid and required. + * + * @param[in] shortName The short-name of the argument option. + * @param[in] defaultValue The value to use when an argument is not + * supplied by the user from the command-line. + * + * @return Any value supplied from the command-line which matches the short + * name or long name option and is a valid signed 32-bit integer number, + * else the default value is provided. + */ + qint32 value(const QChar& shortName, qint32 defaultValue) const; + /** + * @brief Option Signed 64-bit Value + * @details Provides access to the value from a short or long named argument + * supplied by the user from the command-line. Once the value for the + * option is determined the signal for the argument value is fired. In + * addition, all argument values provided by the user are verified for both + * being valid and required. + * + * @param[in] shortName The short-name of the argument option. + * @param[in] defaultValue The value to use when an argument is not + * supplied by the user from the command-line. + * + * @return Any value supplied from the command-line which matches the short + * name or long name option and is a valid signed 64-bit integer number, + * else the default value is provided. + */ + qint64 value(const QChar& shortName, qint64 defaultValue) const; + /** + * @brief Option Unsigned 8-bit Value + * @details Provides access to the value from a short or long named argument + * supplied by the user from the command-line. Once the value for the + * option is determined the signal for the argument value is fired. In + * addition, all argument values provided by the user are verified for both + * being valid and required. + * + * @param[in] shortName The short-name of the argument option. + * @param[in] defaultValue The value to use when an argument is not + * supplied by the user from the command-line. + * + * @return Any value supplied from the command-line which matches the short + * name or long name option and is a valid unsigned 8-bit integer number, + * else the default value is provided. + */ + quint8 value(const QChar& shortName, quint8 defaultValue) const; + /** + * @brief Option Unsigned 16-bit Value + * @details Provides access to the value from a short or long named argument + * supplied by the user from the command-line. Once the value for the + * option is determined the signal for the argument value is fired. In + * addition, all argument values provided by the user are verified for both + * being valid and required. + * + * @param[in] shortName The short-name of the argument option. + * @param[in] defaultValue The value to use when an argument is not + * supplied by the user from the command-line. + * + * @return Any value supplied from the command-line which matches the short + * name or long name option and is a valid unsigned 16-bit integer number, + * else the default value is provided. + */ + quint16 value(const QChar& shortName, quint16 defaultValue) const; + /** + * @brief Option Unsigned 32-bit Value + * @details Provides access to the value from a short or long named argument + * supplied by the user from the command-line. Once the value for the + * option is determined the signal for the argument value is fired. In + * addition, all argument values provided by the user are verified for both + * being valid and required. + * + * @param[in] shortName The short-name of the argument option. + * @param[in] defaultValue The value to use when an argument is not + * supplied by the user from the command-line. + * + * @return Any value supplied from the command-line which matches the short + * name or long name option and is a valid unsigned 32-bit integer number, + * else the default value is provided. + */ + quint32 value(const QChar& shortName, quint32 defaultValue) const; + /** + * @brief Option Unsigned 64-bit Value + * @details Provides access to the value from a short or long named argument + * supplied by the user from the command-line. Once the value for the + * option is determined the signal for the argument value is fired. In + * addition, all argument values provided by the user are verified for both + * being valid and required. + * + * @param[in] shortName The short-name of the argument option. + * @param[in] defaultValue The value to use when an argument is not + * supplied by the user from the command-line. + * + * @return Any value supplied from the command-line which matches the short + * name or long name option and is a valid unsigned 64-bit integer number, + * else the default value is provided. + */ + quint64 value(const QChar& shortName, quint64 defaultValue) const; + /** + * @brief Argument Option Character Value + * @details Provides access to the value from a short or long named argument + * supplied by the user from the command-line. Once the value for the + * option is determined the signal for the argument value is fired. In + * addition, all argument values provided by the user are verified for both + * being valid and required. + * + * @param[in] shortName The short-name of the argument option. + * @param[in] defaultValue The value to use when an argument is not + * supplied by the user from the command-line. + * + * @return Any value supplied from the command-line which matches the short + * name or long name option and is a valid character, else the default + * value is provided. + */ + QChar value(const QChar& shortName, const QChar& defaultValue) const; + /** + * @brief Argument Option String Value + * @details Provides access to the value from a short or long named argument + * supplied by the user from the command-line. Once the value for the + * option is determined the signal for the argument value is fired. In + * addition, all argument values provided by the user are verified for both + * being valid and required. + * + * @param[in] shortName The short-name of the argument option. + * @param[in] defaultValue The value to use when an argument is not + * supplied by the user from the command-line. + * + * @return Any value supplied from the command-line which matches the short + * name or long name option and is a valid string, else the default value + * is provided. + */ + QString value(const QChar& shortName, const QString& defaultValue) const; + /** + * @brief Argument Option Values + * @details Provides access to the values from a short or long named + * argument supplied by the user from the command-line. In addition, all + * argument values provided by the user are verified for both being valid + * and required. The default support for the expected types are: signed + * integers, unsigned integers, single precision, double precision, + * characters, and strings. + * + * @param[in] shortName The short-name of the argument option. + * @param[in] defaultValue The value to use when an argument is not + * supplied by the user from the command-line. + * + * @post Any errors with a specific supplied value is written to the + * standard error buffer. + * + * @return All values supplied from the command-line which match the short + * name or long name option and are valid, else only the default value + * is provided. + */ + template + QList< Expected > values(const QChar& shortName, + const Expected& defaultValue) const; + //} + +private: + //{ Members + /** + * @brief Argument Option Information + * @details Represents the characteristics an argument posses. + */ + struct Properties + { + /// The value used to identify an option by a short name. + QChar shortName; + /// The value used to identify an option by a long name. + QString longName; + /// Short sentence that describes the purpose of an option. + QString description; + /// A flag which indicates the option takes a value. When the value is + /// true, the option takes a value. + bool needsValue; + /// A flag which indicates the option is required to be supplied by the + /// user for the application to function properly. When the value is + /// true, the option is required. + bool required; + }; + /// Used to easily map the properties of an argument with it's short name. + typedef QMap< QChar, Properties > PropertyArguments; + + /// Holder for all the options supplied by the user from the command-line. + QStringList mArguments; + /// Holder for all the arguments and their properties that are supported + /// by an application. + PropertyArguments mSupported; + /// Flag which when true indicates that short names are case sensative. + bool mIsCaseSensative; + /// Flag which when true indicates no further options are allowed. + bool mIsLocked; + /// Flag which when true indicates the arguments were already verified. + mutable bool mAreArgumentsVerified; + + + /// The marker used on the command-line to identify an option. The marker + /// is specific to the host operating system, where a stroke ('/') is + /// supported for Windows systems and dash ('-') for Unix systems. + static const QChar& ARGUMENT_MARKER; + /// The marker used on the command-line to identify the separation of the + /// option value from the long name. This is traditionally the + /// equal ('=') sign. This is only used for Unicies. + static const QChar& ARGUMENT_LONG_ASSIGNMENT; + /// The Operating System specific marker used on the command-line by the + /// user to request the help information for all the arguments supported. + /// For Windows it is a question mark ('?'). For Unix systems it is a + /// the character 'h'. + static const QChar& SHORT_HELP; + /// The other Operating System specific marker used on the command-line + /// by the user to request the help information for all the arguments + /// supported. For Windows it is the character 'h'. For Unix systems it + /// is a question mark ('?'). + static const QChar& OTHER_OS_SHORT_HELP; + /// The specific word used on the command-line by the user to request + /// the help information for all the arguments supported. By default this + /// is the word "help". + static const QString& LONG_HELP; + /// The minimum number number of characters for a valid long option. + static const qint8 MINIMUM_LONG_OPTION; + //} + + //{ Member functions + /** + * @brief Verifies All Arguments + * @details All arguments provided by the user and which are supported by + * the developer are validated. This guarantees each of the options + * provided by the user are supported by the developer. After the initial + * call, all subsequent calls do not result in validation. + * + * @throw logic_error When verification is performed before any arguments + * are registered as being supported. + * @throw runtime_error When an argument is provided by the user that is + * not registered as being supported by the developer. + */ + void verifySupport() const; + /** + * @brief Index Of Argument + * @details Provides the index in the argument list of the argument provided + * by the user from the command-line. + * + * @pre All supported arguments must be established. + * + * @param[in] name The short-name option to locate. + * + * @return If the short-name argument is found, the index starting from zero + * is given, else-wise negative one (-1) is given. + */ + int shortNameIndex(const QChar& name) const; + /** + * @brief Index Of Argument + * @details Provides the index in the argument list of the argument provided + * by the user from the command-line. + * + * @pre All supported arguments must be established. + * + * @param[in] name The short-name option to locate. + * + * @return If the long-name argument is found, the index starting from zero + * is given, else-wise negative one (-1) is given. + */ + int longNameIndex(const QChar& name) const; + //} + + // Only automatically allow unit testing in the debug mode. +#ifndef QT_NO_DEBUG_OUTPUT + /// Allows the unit tests to make zero assumptions while running. + friend class QArgsUT; +#endif +}; + +template< typename Expected > +QList< Expected > QArgs::values(const QChar& shortName, + const Expected& defaultValue) const +{ + qDebug() << "QArgs::values(const QChar&, const Expected&)" << shortName + << defaultValue; + QList< Expected > values; + int shortIndex(shortNameIndex(shortName)), index, + longIndex(longNameIndex(shortName)); + + verifySupport(); + + if (-1 != shortIndex) + index = shortIndex + 1; + else if (-1 != longIndex) + index = longIndex + 1; + else + index = -1; + + Expected testValue; + do + { + if (convertToValueType(this->mArguments.at(index), testValue)) + values.append(testValue); + else + qWarning() << "Failed to convert " << this->mArguments.at(index) + << "into expected value type."; + ++index; + } + while ((index < this->mArguments.size()) + && (ARGUMENT_MARKER != this->mArguments.at(index).at(0))); + + if (values.isEmpty()) + values.append(defaultValue); + + return values; +} + +#endif diff -r 000000000000 -r 04ad7227e290 src/qargs.pro --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/qargs.pro Sat Jun 14 13:17:37 2014 +0000 @@ -0,0 +1,126 @@ +#******************************************************************************* +#** This file is part of QtArgs. *** +#** *** +#** Copyright (C) 2011, 2012, 2014 *** +#** CodeGNU Solutions *** +#** *** +#** This program is free software: you can redistribute it and/or modify *** +#** it under the terms of the GNU Lesser General Public License as *** +#** published by the Free Software Foundation, either version 3 of the *** +#** License, or (at your option) any later version. *** +#** *** +#** This program 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. *** +#** See the GNU Lesser General Public License for more details. *** +#** *** +#** You should have received a copy of the GNU Lesser General Public *** +#** License along with this program. If not, see *** +#** . *** +#******************************************************************************* +TEMPLATE = lib +QT -= gui +VERSION = 1.3.0 +DEFINES += \ + QTARGS_LIBRARY \ + LIBRARY_VERSION=$$quote('"\\"$${VERSION}\\""') \ + COPYRIGHT_YEARS=$$quote('"\\"2011 - 2014\\""') + +CONFIG += \ + qt \ + dynamic \ + exceptions \ + stl +CONFIG (debug, debug|release) { + !buildpass:message(Compiling QtArgs debug build.) + TARGET = qtargsd + DESTDIR = ../debug + OBJECTS_DIR = debug + CONFIG -= release + CONFIG += \ + warn_on \ + debug + linux-g++ { + !buildpass:message(Setting GCC debug flags.) + QMAKE_CXXFLAGS_DEBUG += \ + -std=c++98 \ # Conform to ISO standard + -pg \ # Enable code profiling + -fstack-protector-all \ # Check for buffer overflows + -Wall \ # Enable all normal code execution warnings + -Wextra \ # Enable extra warnings not enabled by Wall +# @bug Currently the build breaks due to QMapNode. +# -Wctor-dtor-privacy \ # Warn if a class seems unusable due to ctor + -Wold-style-cast \ # Warn C-style cast is used within a program. + -Woverloaded-virtual \ # Warn when a function declaration hides + # virtual functions from a base class + -Wswitch-enum \ # Warn whenever a switch statement has an index of + # enumerated type and lacks a case for one or more + # of the named codes of that enumeration. + -Wformat-security \ # Warn about uses of format functions + # that represent possible security problems. + -Wlogical-op \ # Warn about suspicious uses of + # logical operators in expressions. + -Wstack-protector \ # Warns about functions that will not + # be protected against stack smashing. + -g3 # Produce debugging information in the OS's native format + } + win32-g++ { + !buildpass:message(Setting MinGW debug flags.) + QMAKE_CXXFLAGS_DEBUG += \ + -Wall \ # Enable all normal code execution warnings + -Wextra \ # Enable extra warnings not enabled by Wall +# @bug Currently the build breaks due to QMapNode. +# -Wctor-dtor-privacy \ # Warn if a class seems unusable due to ctor + -Wold-style-cast \ # Warn C-style cast is used within a program. + -Woverloaded-virtual \ # Warn when a function declaration hides + # virtual functions from a base class + -Wswitch-enum \ # Warn whenever a switch statement has an index of + # enumerated type and lacks a case for one or more + # of the named codes of that enumeration. + -Wformat-security \ # Warn about uses of format functions + # that represent possible security problems. + -Wlogical-op \ # Warn about suspicious uses of + # logical operators in expressions. + -Wstack-protector # Warns about functions that will not + # be protected against stack smashing. + } + } else { + !buildpass:message(Compiling QtArgs release build.) + TARGET = qtargs + DESTDIR = ../release + OBJECTS_DIR = release + CONFIG -= debug + CONFIG += release + DEFINES += QT_NO_DEBUG_OUTPUT + linux-g++ { + !buildpass:message(Setting GCC release flags.) + QMAKE_CXXFLAGS_RELEASE += -O3 # Use all optimizations from O2 and more. + } +} +MOC_DIR = $$OBJECTS_DIR +UI_DIR = $$OBJECTS_DIR + +SOURCES += \ + qargs.cpp + +HEADERS += \ + qargs.h \ + qargs_global.h + +isEmpty(PREFIX) { + win32 { + PREFIX = $$quote(C:\\QtSDK\\QtArgs\\) + } else { + PREFIX = /usr + } +} +isEmpty(LIB_PATH) { + target.path += $${PREFIX}/lib +} else { + target.path += $${PREFIX}/$$(LIB_PATH) +} +headers.path += $${PREFIX}/include +headers.files += *.h +INSTALLS += \ + target \ + headers diff -r 000000000000 -r 04ad7227e290 src/qargs_global.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/qargs_global.h Sat Jun 14 13:17:37 2014 +0000 @@ -0,0 +1,55 @@ +/******************************************************************************* +*** This file is part of QtArgs. *** +*** *** +*** Copyright (C) 2011, 2012, 2014 *** +*** CodeGNU Solutions *** +*** *** +*** This program is free software: you can redistribute it and/or modify *** +*** it under the terms of the GNU Lesser General Public License as *** +*** published by the Free Software Foundation, either version 3 of the *** +*** License, or (at your option) any later version. *** +*** *** +*** This program 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. *** +*** See the GNU Lesser General Public License for more details. *** +*** *** +*** You should have received a copy of the GNU Lesser General Public *** +*** License along with this program. If not, see *** +*** . *** +*******************************************************************************/ +#ifndef QTARGS_GLOBAL_H_ +#define QTARGS_GLOBAL_H_ +/** + * @file qargs_global.h + * @brief Library Definition + * @details Definitions for the library import/exports definitions. + */ + +#include + + +/** + * @def QTARGS_SHARED_EXPORT + * @brief Export Classes + * @details A simple macro to ease exporting classes, structs, etc across + * various platforms without the caller needing to bother determining which + * action is being performed an export or import. During the build define the + * macro QTARGS_LIBRARY and the correct export settings will be used. + * + * @post The macro QTARGS_SHARED_EXPORT is defined with the appropriate + * export or import needed for the library based upon the build. + */ +#if defined(QTARGS_LIBRARY) +# define QTARGS_SHARED_EXPORT Q_DECL_EXPORT +#else +# define QTARGS_SHARED_EXPORT Q_DECL_IMPORT +#endif + +/** + * @mainpage QtArgs Developer Documentation + * + * These pages contain the documentation for a developer to use the libary. + */ + +#endif