aboutsummaryrefslogblamecommitdiffstats
path: root/src/libargparser/argparser.h
blob: af8477a2e1c6ce6816e1c2ef1a5e7e508d280cc2 (plain) (tree)







































































































































































































































































































                                                                                                  
/**
 * argparser – command line argument parser library
 * 
 * Copyright © 2013, 2014  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 Affero 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 Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef ARGPARSER_H
#define ARGPARSER_H


#include <stddef.h>



/**
 * Option types
 */
typedef enum args_option_type
  {
    /**
     * The option never takes any arguments
     */
    ARGUMENTLESS,
    
    /**
     * The option takes the next argument
     */
    ARGUMENTED,
    
    /**
     * The option may have an argument, either sticky
     * or otherwise accepted by `stickless`
     */
    OPTARGUMENTED,
    
    /**
     * The option takes all following options
     */
    VARIADIC
    
  } args_option_type_t;



typedef struct args_option
{
  /**
   * The type of the option
   */
  args_option_type_t type;
  
  /**
   * Alterative option names
   */
  const char** alternatives;
  
  /**
   * Number of elements in `alternatives`
   */
  size_t alternatives_count;
  
  /**
   * Standard option name
   */
  const char* standard;
  
  /**
   * Argument name, not for argumentless options
   */
  const char* argument;
  
  /**
   * Help text, multi-line
   */
  const char* help;
  
  /**
   * User-data used by methods associated with the option
   */
  void* user_data;
  
  /**
   * Invoked when the option is used
   * 
   * @param  user_data  User-data
   * @param  standard   The used option alternative
   * @param  used       The standard option alternative
   */
  void (*trigger)(void* user_data, const char* standard, const char* used);
  
  /**
   * Invoked when the option is used
   * 
   * @param  user_data  User-data
   * @param  standard   The used option alternative
   * @param  used       The standard option alternative
   * @param  value      The used value
   */
  void (*trigger_v)(void* user_data, const char* standard, const char* used, char* value);
  
  /**
   * Should return true if the next argument can used for the argument without being sticky
   * 
   * @param   user_data  User-data
   * @param   argument   The next argument
   * @return             Whether the argument can be used without being sticky
   */
  int (*stickless)(void* user_data, const char* argument);
  
  /**
   * Should return true if the next argument can used for the argument
   * 
   * @param   user_data  User-data
   * @param   value      The next argument
   * @return             Whether the argument can be used
   */
  int (*variadic_end)(void* user_data, char* value);
  
} args_option_t;


/**
 * Settings for argument parser
 */
typedef struct args_settings
{
  /**
   * Whether the Linux VT is being used
   */
  int linuxvt;
  
  /**
   * Whether to use single dash/plus long options
   */
  int alternative;
  
  /**
   * The name of the executed command, will be freed by the parser
   */
  char* program;
  
  /**
   * Short, single-line, description of the program
   */
  const char* description;
  
  /**
   * Formated, multi-line, usage text, `NULL` if none
   */
  const char* usage;
  
  /**
   * Long, multi-line, description of the program, `NULL` if none
   */
  const char* longdescription;
  
  /**
   * The error output stream
   */
  FILE* error_out;
  
  /**
   * The warning output stream
   */
  FILE* warning_out;
  
  /**
   * The help output stream
   */
  FILE* help_out;
  
  /**
   * Abbreviated option expander, `null` for disabled
   * 
   * @param   argument  The option that not recognised
   * @param   options   All recognised options
   * @param   count     The number of elements in `options`
   * @return            The only possible expansion, otherwise `NULL`
   */
  const char* (*abbreviations)(const char* stub, const char** options, size_t count);
  
} args_settings_t;


/**
 * The state of the parser
 */
typedef struct args_state
{
  /**
  * The passed arguments
  */
  char** arguments;
  
  /**
   * The number of passed arguments
   */
  size_t arguments_count;
  
  /**
   * The number of unrecognised arguments
   */
  size_t unrecognised_count;
  
  /**
   * The concatenation of `files` with blankspaces as delimiters, `null` if no files
   */
  char* message;
  
  /**
   * The arguments passed that is not tied to an option
   */
  char** files;
  
  /**
   * The number of elements in `args_files`
   */
  size_t files_count;
  
} args_state_t;



/**
 * Dummy trigger
 * 
 * @param  user_data  User-data
 * @param  used       The used option alternative
 * @param  standard   The standard option alternative
 */
void args_noop_trigger(void* user_data, const char* used, const char* standard);

/**
 * Dummy trigger
 * 
 * @param  user_data  User-data
 * @param  used       The used option alternative
 * @param  standard   The standard option alternative
 * @param  value      The used value
 */
void args_noop_trigger_v(void* user_data, const char* used, const char* standard, char* value);

/**
 * Stickless evaluator to always evaluates to false
 * 
 * @param   user_data  User-data
 * @param   argument   The next argument
 * @return             Whether the argument can be used without being sticky
 */
int args_no_stickless(void* user_data, const char* value);

/**
 * Default stickless evaluator
 * 
 * @param   user_data  User-data
 * @param   argument   The next argument
 * @return             Whether the argument can be used without being sticky
 */
int args_default_stickless(void* user_data, const char* argument);

/**
 * Evalutator for end argument of variadic options that always evalutes to false
 * 
 * @param   user_data  User-data
 * @param   value      The  next argument
 * @return             Whether the argument can be used without being sticky
 */
int args_no_variadic_end(void* user_data, char* value);

/**
 * The standard abbrevation expander
 * 
 * @param   argument  The option that not recognised
 * @param   options   All recognised options
 * @param   count     The number of elements in `options`
 * @return            The only possible expansion, otherwise `null`
 */
const char* args_standard_abbreviations(const char* argument, const char** options, size_t count);


#endif