/**
* argparser – command line argument parser library
*
* Copyright © 2013 Mattias Andrée (maandree@member.fsf.org)
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
/**
* Option structure
*/
typedef struct
{
/**
* The type of the option, either of: `ARGUMENTLESS`, `ARGUMENTED`, `VARIADIC`
*/
long type;
/**
* Alterative option names
*/
char** alternatives;
/**
* Number of elements in `alternatives`
*/
long alternatives_count;
/**
* Standard option name
*/
char* standard;
/**
* Argument name, not for argumentless options
*/
char* argument;
/**
* Help text, multi-line
*/
char* help;
} args_Option;
/**
* char* to void* map structure
*/
typedef struct
{
/**
* Available keys
*/
char** keys;
/**
* The number of available keys
*/
long key_count;
/**
* Indefinite depth array with 17 elements per level, the last being the value at the position
*/
void** data;
} args_Map;
/**
* Array with associated length
*/
typedef struct
{
/**
* The values
*/
void** values;
/**
* The length of `values`
*/
long count;
} args_Array;
/**
* The name of the executed command
*/
char* args_program;
/**
* Short, single-line, description of the program
*/
char* args_description;
/**
* Formated, multi-line, usage text, `null` if none
*/
char* args_usage;
/**
* Long, multi-line, description of the program, `null` if none
*/
char* args_longdescription;
/**
* The error output stream
*/
FILE* args_out;
/**
* The passed arguments
*/
char** args_arguments;
/**
* The number of passed arguments
*/
long args_arguments_count;
/**
* The number of unrecognised arguments
*/
long args_unrecognised_count;
/**
* The concatination of `files` with blankspaces as delimiters, `null` if no files
*/
char* args_message;
/**
* The arguments passed that is not tied to an option
*/
char** args_files;
/**
* The number of elements in `args_files`
*/
long args_files_count;
/**
* Initialiser.
* The short description is printed on same line as the program name
*
* @param description Short, single-line, description of the program
* @param usage Formated, multi-line, usage text, may be `null`
* @param longdescription Long, multi-line, description of the program, may be `null`
* @param program The name of the program, `null` for automatic
* @param usestderr Whether to use stderr instead of stdout
*/
extern void args_init(char* description, char* usage, char* longdscription, char* program, long usestderr);
/**
* Disposes of all resources, run this when you are done
*/
extern void args_dispose();
/**
* Creates, but does not add, a option that takes no arguments
*
* @param standard The index of the standard alternative name
* @param count... The alterntive names
* @return The created option
*/
extern args_Option args_new_argumentless(int standard, int count, ...);
/**
* Creates, but does not add, a option that takes one argument per use
*
* @param argument The new of the argument
* @param standard The index of the standard alternative name
* @param count... The alterntive names
* @return The created option
*/
extern args_Option args_new_argumented(char* argument, int standard, int count, ...);
/**
* Creates, but does not add, a option that takes all following arguments
*
* @param argument The new of the argument
* @param standard The index of the standard alternative name
* @param count... The alterntive names
* @return The created option
*/
extern args_Option args_new_variadic(char* argument, int standard, int count, ...);
/**
* Gets an array of all options
*
* @return All options
*/
extern args_Option* args_get_options();
/**
* Gets the number of elements in the array returned by `args_get_options`
*
* @return The number of elements in the array returned by `args_get_options`
*/
extern long args_get_options_count();
/**
* Gets the option with a specific index
*
* @param index The option's index
* @return The option
*/
extern args_Option args_options_get(long index);
/**
* Gets the type of a option with a specific index
*
* @param index The option's index
* @return The option's type
*/
extern long args_options_get_type(long index);
/**
* Gets the number of alternative option names for a option with a specific index
*
* @param index The option's index
* @return The option's number of alternative option names
*/
extern long args_options_get_alternatives_count(long index);
/**
* Gets the alternative option names for a option with a specific index
*
* @param index The option's index
* @return The option's alternative option names
*/
extern char** args_options_get_alternatives(long index);
/**
* Gets the argument name for a option with a specific index
*
* @param index The option's index
* @return The option's argument name
*/
extern char* args_options_get_argument(long index);
/**
* Gets the standard option name for a option with a specific index
*
* @param index The option's index
* @return The option's standard option name
*/
extern char* args_options_get_standard(long index);
/**
* Gets the help text for a option with a specific index
*
* @param index The option's index
* @return The option's help text
*/
extern char* args_options_get_help(long index);
/**
* Gets the available options
*
* @return The available options
*/
extern char** args_get_opts();
/**
* Gets the number of available options
*
* @return The number of available options
*/
extern long args_get_opts_count();
/**
* Gets whether an option is available
*
* @param name The option
* @return Whether an option is available
*/
extern long args_opts_contains(char* name);
/**
* Initialise an option
*
* @param name The option
*/
extern void args_opts_new(char* name);
/**
* Appends a value to an option
*
* @param name The option
* @param value The new value
*/
extern void args_opts_append(char* name, char* value);
/**
* Removes all values from an option
*
* @param name The option
*/
extern void args_opts_clear(char* name);
/**
* Gets the values for an option
*
* @param name The option
* @return The values
*/
extern char** args_opts_get(char* name);
/**
* Gets the number of values for an option
*
* @param name The option
* @return The number of values
*/
extern long args_opts_get_count(char* name);
/**
* Sets the values for an option
*
* @param name The option
* @param count The values
*/
extern void args_opts_put(char* name, char** values);
/**
* Sets the number of values for an option
*
* @param name The option
* @param count The number of values
*/
extern void args_opts_put_count(char* name, long count);
/**
* Checks whether an option is used
*
* @param name The option
* @return Whether the option is used
*/
extern long args_opts_used(char* name);
/**
* Gets all alternativ names that exists for all options combined
*
* @return All alternativ names that exists for all options
*/
extern char** args_get_optmap();
/**
* Gets the number of elements returned by `args_get_optmap`
*
* @return The number of elements returned by `args_get_optmap`
*/
extern long args_get_optmap_count();
/**
* Maps alternative name for a option
*
* @param name The option's alternative name
* @param index The option's index
*/
extern void args_optmap_put(char* name, long index);
/**
* Gets the option with a specific alternative name
*
* @param name The option's alternative name
* @return The option
*/
extern args_Option args_optmap_get(char* name);
/**
* Gets the index of a option with a specific alternative name
*
* @param name The option's alternative name
* @return The option's index, negative if not found
*/
extern long args_optmap_get_index(char* name);
/**
* Checks whether an options with a specific alternative name exists
*
* @param name One of the names of the option
* @return Whether the option exists
*/
extern long args_optmap_contains(char* name);
/**
* Gets the type of a option with a specific alternative name
*
* @param name The option's alternative name
* @return The option's type
*/
extern long args_optmap_get_type(char* name);
/**
* Gets the standard option name for a option with a specific alternative name
*
* @param name The option's alternative name
* @return The option's standard option name
*/
extern char* args_optmap_get_standard(char* name);
/**
* Adds an option
*
* @param option The option
* @param help Help text, multi-line, `null` if hidden
*/
extern void args_add_option(args_Option option, char* help);
/**
* Gets the name of the parent process
*
* @param levels The number of parents to walk, 0 for self, and 1 for direct parent
* @return The name of the parent process, `null` if not found
*/
extern char* args_parent_name(long levels);
/**
* Checks the correctness of the number of used non-option arguments
*
* @param min The minimum number of files
* @return Whether the usage was correct
*/
extern long args_test_files_min(long min);
/**
* Checks the correctness of the number of used non-option arguments
*
* @param max The maximum number of files
* @return Whether the usage was correct
*/
extern long args_test_files_max(long max);
/**
* Checks the correctness of the number of used non-option arguments
*
* @param min The minimum number of files
* @param max The maximum number of files
* @return Whether the usage was correct
*/
extern long args_test_files(long min, long max);
/**
* Checks for out of context option usage
*
* @param allowed Allowed options, will be sorted
* @param allowed_count The number of elements in `allowed`
* @return Whether only allowed options was used
*/
extern long args_test_allowed(char** allowed, long allowed_count);
/**
* Checks for option conflicts
*
* @param exclusives Exclusive options, will be sorted
* @param exclusives_count The number of elements in `exclusives`
* @return Whether at most one exclusive option was used
*/
extern long args_test_exclusiveness(char** exclusives, long exclusives_count);
/**
* Maps up options that are alternatives to the first alternative for each option
*/
extern void args_support_alternatives();
/**
* Prints a colourful help message
*/
extern void args_help();
/**
* Parse arguments
*
* @param argc The number of elements in `argv`
* @param argv The command line arguments, it should include the execute file at index 0
* @return Whether no unrecognised option is used
*/
extern long args_parse(int argc, char** argv);