/*
  File autogenerated by gengetopt version 2.22.5
  generated with the following command:
  gengetopt -iContexter.ggo --default-optional -u -N -e 

  The developers of gengetopt consider the fixed text that goes in all
  gengetopt output files to be in the public domain:
  we make no copyright claims on it.
*/

/* If we use autoconf.  */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef FIX_UNUSED
#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */
#endif

#include <getopt.h>

#include "cmdline.h"

const char *gengetopt_args_info_purpose = "Calculate gene/context association ratios";

const char *gengetopt_args_info_usage = "Usage: Contexter [OPTIONS]... [FILES]...";

const char *gengetopt_args_info_description = "";

const char *gengetopt_args_info_help[] = {
        "  -h, --help                  Print help and exit",
        "  -V, --version               Print version and exit",
        "\nMain:",
        "  -i, --input=filename        DAT/DAB file or context IDs and names",
        "\nInput:",
        "  -t, --dat                   Use DAT/DAB file input rather than Bayes nets  \n                                (default=off)",
        "  -d, --database=directory    Database directory  (default=`.')",
        "  -c, --contexts=filename     Context/gene mapping",
        "  -e, --context=INT           Context ID to process",
        "  -g, --genes=filename        Gene ID to name mapping",
        "  -N, --is_nibble=INT         Define whether the database is nibble type.  \n                                (default=`1')",
        "\nBayes nets:",
        "  -n, --networks=directory    Bayes net directory  (default=`.')",
        "  -b, --default=filename      Bayes net for no context",
        "  -x, --xdsl                  Use XDSL files instead of DSL  (default=on)",
        "  -m, --minimal_in            Read stored contexts and minimal Bayes nets  \n                                (default=off)",
        "  -M, --minimal_out=filename  Store contexts and minimal Bayes nets",
        "\nOptions:",
        "  -l, --lookup=STRING         Gene name to lookup",
        "  -p, --memmap                Memory map input  (default=off)",
        "  -v, --verbosity=INT         Message verbosity  (default=`5')",
        0
};

typedef enum {
    ARG_NO, ARG_FLAG, ARG_STRING, ARG_INT
} cmdline_parser_arg_type;

static
void clear_given(struct gengetopt_args_info *args_info);

static
void clear_args(struct gengetopt_args_info *args_info);

static int
cmdline_parser_internal(int argc, char **argv, struct gengetopt_args_info *args_info,
                        struct cmdline_parser_params *params, const char *additional_error);

static int
cmdline_parser_required2(struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error);

static char *
gengetopt_strdup(const char *s);

static
void clear_given(struct gengetopt_args_info *args_info) {
    args_info->help_given = 0;
    args_info->version_given = 0;
    args_info->input_given = 0;
    args_info->dat_given = 0;
    args_info->database_given = 0;
    args_info->contexts_given = 0;
    args_info->context_given = 0;
    args_info->genes_given = 0;
    args_info->is_nibble_given = 0;
    args_info->networks_given = 0;
    args_info->default_given = 0;
    args_info->xdsl_given = 0;
    args_info->minimal_in_given = 0;
    args_info->minimal_out_given = 0;
    args_info->lookup_given = 0;
    args_info->memmap_given = 0;
    args_info->verbosity_given = 0;
}

static
void clear_args(struct gengetopt_args_info *args_info) {
    FIX_UNUSED (args_info);
    args_info->input_arg = NULL;
    args_info->input_orig = NULL;
    args_info->dat_flag = 0;
    args_info->database_arg = gengetopt_strdup(".");
    args_info->database_orig = NULL;
    args_info->contexts_arg = NULL;
    args_info->contexts_orig = NULL;
    args_info->context_orig = NULL;
    args_info->genes_arg = NULL;
    args_info->genes_orig = NULL;
    args_info->is_nibble_arg = 1;
    args_info->is_nibble_orig = NULL;
    args_info->networks_arg = gengetopt_strdup(".");
    args_info->networks_orig = NULL;
    args_info->default_arg = NULL;
    args_info->default_orig = NULL;
    args_info->xdsl_flag = 1;
    args_info->minimal_in_flag = 0;
    args_info->minimal_out_arg = NULL;
    args_info->minimal_out_orig = NULL;
    args_info->lookup_arg = NULL;
    args_info->lookup_orig = NULL;
    args_info->memmap_flag = 0;
    args_info->verbosity_arg = 5;
    args_info->verbosity_orig = NULL;

}

static
void init_args_info(struct gengetopt_args_info *args_info) {


    args_info->help_help = gengetopt_args_info_help[0];
    args_info->version_help = gengetopt_args_info_help[1];
    args_info->input_help = gengetopt_args_info_help[3];
    args_info->dat_help = gengetopt_args_info_help[5];
    args_info->database_help = gengetopt_args_info_help[6];
    args_info->contexts_help = gengetopt_args_info_help[7];
    args_info->context_help = gengetopt_args_info_help[8];
    args_info->genes_help = gengetopt_args_info_help[9];
    args_info->is_nibble_help = gengetopt_args_info_help[10];
    args_info->networks_help = gengetopt_args_info_help[12];
    args_info->default_help = gengetopt_args_info_help[13];
    args_info->xdsl_help = gengetopt_args_info_help[14];
    args_info->minimal_in_help = gengetopt_args_info_help[15];
    args_info->minimal_out_help = gengetopt_args_info_help[16];
    args_info->lookup_help = gengetopt_args_info_help[18];
    args_info->memmap_help = gengetopt_args_info_help[19];
    args_info->verbosity_help = gengetopt_args_info_help[20];

}

void
cmdline_parser_print_version(void) {
    printf("%s %s\n",
           (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE),
           CMDLINE_PARSER_VERSION);
}

static void print_help_common(void) {
    cmdline_parser_print_version();

    if (strlen(gengetopt_args_info_purpose) > 0)
        printf("\n%s\n", gengetopt_args_info_purpose);

    if (strlen(gengetopt_args_info_usage) > 0)
        printf("\n%s\n", gengetopt_args_info_usage);

    printf("\n");

    if (strlen(gengetopt_args_info_description) > 0)
        printf("%s\n\n", gengetopt_args_info_description);
}

void
cmdline_parser_print_help(void) {
    int i = 0;
    print_help_common();
    while (gengetopt_args_info_help[i])
        printf("%s\n", gengetopt_args_info_help[i++]);
}

void
cmdline_parser_init(struct gengetopt_args_info *args_info) {
    clear_given(args_info);
    clear_args(args_info);
    init_args_info(args_info);

    args_info->inputs = 0;
    args_info->inputs_num = 0;
}

void
cmdline_parser_params_init(struct cmdline_parser_params *params) {
    if (params) {
        params->override = 0;
        params->initialize = 1;
        params->check_required = 1;
        params->check_ambiguity = 0;
        params->print_errors = 1;
    }
}

struct cmdline_parser_params *
cmdline_parser_params_create(void) {
    struct cmdline_parser_params *params =
            (struct cmdline_parser_params *) malloc(sizeof(struct cmdline_parser_params));
    cmdline_parser_params_init(params);
    return params;
}

static void
free_string_field(char **s) {
    if (*s) {
        free(*s);
        *s = 0;
    }
}


static void
cmdline_parser_release(struct gengetopt_args_info *args_info) {
    unsigned int i;
    free_string_field(&(args_info->input_arg));
    free_string_field(&(args_info->input_orig));
    free_string_field(&(args_info->database_arg));
    free_string_field(&(args_info->database_orig));
    free_string_field(&(args_info->contexts_arg));
    free_string_field(&(args_info->contexts_orig));
    free_string_field(&(args_info->context_orig));
    free_string_field(&(args_info->genes_arg));
    free_string_field(&(args_info->genes_orig));
    free_string_field(&(args_info->is_nibble_orig));
    free_string_field(&(args_info->networks_arg));
    free_string_field(&(args_info->networks_orig));
    free_string_field(&(args_info->default_arg));
    free_string_field(&(args_info->default_orig));
    free_string_field(&(args_info->minimal_out_arg));
    free_string_field(&(args_info->minimal_out_orig));
    free_string_field(&(args_info->lookup_arg));
    free_string_field(&(args_info->lookup_orig));
    free_string_field(&(args_info->verbosity_orig));


    for (i = 0; i < args_info->inputs_num; ++i)
        free(args_info->inputs[i]);

    if (args_info->inputs_num)
        free(args_info->inputs);

    clear_given(args_info);
}


static void
write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) {
    FIX_UNUSED (values);
    if (arg) {
        fprintf(outfile, "%s=\"%s\"\n", opt, arg);
    } else {
        fprintf(outfile, "%s\n", opt);
    }
}


int
cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) {
    int i = 0;

    if (!outfile) {
        fprintf(stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE);
        return EXIT_FAILURE;
    }

    if (args_info->help_given)
        write_into_file(outfile, "help", 0, 0);
    if (args_info->version_given)
        write_into_file(outfile, "version", 0, 0);
    if (args_info->input_given)
        write_into_file(outfile, "input", args_info->input_orig, 0);
    if (args_info->dat_given)
        write_into_file(outfile, "dat", 0, 0);
    if (args_info->database_given)
        write_into_file(outfile, "database", args_info->database_orig, 0);
    if (args_info->contexts_given)
        write_into_file(outfile, "contexts", args_info->contexts_orig, 0);
    if (args_info->context_given)
        write_into_file(outfile, "context", args_info->context_orig, 0);
    if (args_info->genes_given)
        write_into_file(outfile, "genes", args_info->genes_orig, 0);
    if (args_info->is_nibble_given)
        write_into_file(outfile, "is_nibble", args_info->is_nibble_orig, 0);
    if (args_info->networks_given)
        write_into_file(outfile, "networks", args_info->networks_orig, 0);
    if (args_info->default_given)
        write_into_file(outfile, "default", args_info->default_orig, 0);
    if (args_info->xdsl_given)
        write_into_file(outfile, "xdsl", 0, 0);
    if (args_info->minimal_in_given)
        write_into_file(outfile, "minimal_in", 0, 0);
    if (args_info->minimal_out_given)
        write_into_file(outfile, "minimal_out", args_info->minimal_out_orig, 0);
    if (args_info->lookup_given)
        write_into_file(outfile, "lookup", args_info->lookup_orig, 0);
    if (args_info->memmap_given)
        write_into_file(outfile, "memmap", 0, 0);
    if (args_info->verbosity_given)
        write_into_file(outfile, "verbosity", args_info->verbosity_orig, 0);


    i = EXIT_SUCCESS;
    return i;
}

int
cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) {
    FILE *outfile;
    int i = 0;

    outfile = fopen(filename, "w");

    if (!outfile) {
        fprintf(stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename);
        return EXIT_FAILURE;
    }

    i = cmdline_parser_dump(outfile, args_info);
    fclose(outfile);

    return i;
}

void
cmdline_parser_free(struct gengetopt_args_info *args_info) {
    cmdline_parser_release(args_info);
}

/** @brief replacement of strdup, which is not standard */
char *
gengetopt_strdup(const char *s) {
    char *result = 0;
    if (!s)
        return result;

    result = (char *) malloc(strlen(s) + 1);
    if (result == (char *) 0)
        return (char *) 0;
    strcpy(result, s);
    return result;
}

int
cmdline_parser(int argc, char **argv, struct gengetopt_args_info *args_info) {
    return cmdline_parser2(argc, argv, args_info, 0, 1, 1);
}

int
cmdline_parser_ext(int argc, char **argv, struct gengetopt_args_info *args_info,
                   struct cmdline_parser_params *params) {
    int result;
    result = cmdline_parser_internal(argc, argv, args_info, params, 0);

    return result;
}

int
cmdline_parser2(int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize,
                int check_required) {
    int result;
    struct cmdline_parser_params params;

    params.override = override;
    params.initialize = initialize;
    params.check_required = check_required;
    params.check_ambiguity = 0;
    params.print_errors = 1;

    result = cmdline_parser_internal(argc, argv, args_info, &params, 0);

    return result;
}

int
cmdline_parser_required(struct gengetopt_args_info *args_info, const char *prog_name) {
    int result = EXIT_SUCCESS;

    if (cmdline_parser_required2(args_info, prog_name, 0) > 0)
        result = EXIT_FAILURE;

    return result;
}

int
cmdline_parser_required2(struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error) {
    int error = 0;
    FIX_UNUSED (additional_error);

    /* checks for required options */
    if (!args_info->contexts_given) {
        fprintf(stderr, "%s: '--contexts' ('-c') option required%s\n", prog_name,
                (additional_error ? additional_error : ""));
        error = 1;
    }

    if (!args_info->context_given) {
        fprintf(stderr, "%s: '--context' ('-e') option required%s\n", prog_name,
                (additional_error ? additional_error : ""));
        error = 1;
    }


    /* checks for dependences among options */

    return error;
}


static char *package_name = 0;

/**
 * @brief updates an option
 * @param field the generic pointer to the field to update
 * @param orig_field the pointer to the orig field
 * @param field_given the pointer to the number of occurrence of this option
 * @param prev_given the pointer to the number of occurrence already seen
 * @param value the argument for this option (if null no arg was specified)
 * @param possible_values the possible values for this option (if specified)
 * @param default_value the default value (in case the option only accepts fixed values)
 * @param arg_type the type of this option
 * @param check_ambiguity @see cmdline_parser_params.check_ambiguity
 * @param override @see cmdline_parser_params.override
 * @param no_free whether to free a possible previous value
 * @param multiple_option whether this is a multiple option
 * @param long_opt the corresponding long option
 * @param short_opt the corresponding short option (or '-' if none)
 * @param additional_error possible further error specification
 */
static
int update_arg(void *field, char **orig_field,
               unsigned int *field_given, unsigned int *prev_given,
               char *value, const char *possible_values[],
               const char *default_value,
               cmdline_parser_arg_type arg_type,
               int check_ambiguity, int override,
               int no_free, int multiple_option,
               const char *long_opt, char short_opt,
               const char *additional_error) {
    char *stop_char = 0;
    const char *val = value;
    int found;
    char **string_field;
    FIX_UNUSED (field);

    stop_char = 0;
    found = 0;

    if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) {
        if (short_opt != '-')
            fprintf(stderr, "%s: `--%s' (`-%c') option given more than once%s\n",
                    package_name, long_opt, short_opt,
                    (additional_error ? additional_error : ""));
        else
            fprintf(stderr, "%s: `--%s' option given more than once%s\n",
                    package_name, long_opt,
                    (additional_error ? additional_error : ""));
        return 1; /* failure */
    }

    FIX_UNUSED (default_value);

    if (field_given && *field_given && !override)
        return 0;
    if (prev_given)
        (*prev_given)++;
    if (field_given)
        (*field_given)++;
    if (possible_values)
        val = possible_values[found];

    switch (arg_type) {
        case ARG_FLAG:
            *((int *) field) = !*((int *) field);
            break;
        case ARG_INT:
            if (val) *((int *) field) = strtol(val, &stop_char, 0);
            break;
        case ARG_STRING:
            if (val) {
                string_field = (char **) field;
                if (!no_free && *string_field)
                    free(*string_field); /* free previous string */
                *string_field = gengetopt_strdup(val);
            }
            break;
        default:
            break;
    };

    /* check numeric conversion */
    switch (arg_type) {
        case ARG_INT:
            if (val && !(stop_char && *stop_char == '\0')) {
                fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
                return 1; /* failure */
            }
            break;
        default:;
    };

    /* store the original value */
    switch (arg_type) {
        case ARG_NO:
        case ARG_FLAG:
            break;
        default:
            if (value && orig_field) {
                if (no_free) {
                    *orig_field = value;
                } else {
                    if (*orig_field)
                        free(*orig_field); /* free previous string */
                    *orig_field = gengetopt_strdup(value);
                }
            }
    };

    return 0; /* OK */
}


int
cmdline_parser_internal(
        int argc, char **argv, struct gengetopt_args_info *args_info,
        struct cmdline_parser_params *params, const char *additional_error) {
    int c;    /* Character of the parsed option.  */

    int error = 0;
    struct gengetopt_args_info local_args_info;

    int override;
    int initialize;
    int check_required;
    int check_ambiguity;

    package_name = argv[0];

    override = params->override;
    initialize = params->initialize;
    check_required = params->check_required;
    check_ambiguity = params->check_ambiguity;

    if (initialize)
        cmdline_parser_init(args_info);

    cmdline_parser_init(&local_args_info);

    optarg = 0;
    optind = 0;
    opterr = params->print_errors;
    optopt = '?';

    while (1) {
        int option_index = 0;

        static struct option long_options[] = {
                {"help",        0, NULL, 'h'},
                {"version",     0, NULL, 'V'},
                {"input",       1, NULL, 'i'},
                {"dat",         0, NULL, 't'},
                {"database",    1, NULL, 'd'},
                {"contexts",    1, NULL, 'c'},
                {"context",     1, NULL, 'e'},
                {"genes",       1, NULL, 'g'},
                {"is_nibble",   1, NULL, 'N'},
                {"networks",    1, NULL, 'n'},
                {"default",     1, NULL, 'b'},
                {"xdsl",        0, NULL, 'x'},
                {"minimal_in",  0, NULL, 'm'},
                {"minimal_out", 1, NULL, 'M'},
                {"lookup",      1, NULL, 'l'},
                {"memmap",      0, NULL, 'p'},
                {"verbosity",   1, NULL, 'v'},
                {0,             0, 0,    0}
        };

        c = getopt_long(argc, argv, "hVi:td:c:e:g:N:n:b:xmM:l:pv:", long_options, &option_index);

        if (c == -1) break;    /* Exit from `while (1)' loop.  */

        switch (c) {
            case 'h':    /* Print help and exit.  */
                cmdline_parser_print_help();
                cmdline_parser_free(&local_args_info);
                exit(EXIT_SUCCESS);

            case 'V':    /* Print version and exit.  */


                if (update_arg(0,
                               0, &(args_info->version_given),
                               &(local_args_info.version_given), optarg, 0, 0, ARG_NO,
                               check_ambiguity, override, 0, 0,
                               "version", 'V',
                               additional_error))
                    goto failure;
                cmdline_parser_free(&local_args_info);
                return 0;

                break;
            case 'i':    /* DAT/DAB file or context IDs and names.  */


                if (update_arg((void *) &(args_info->input_arg),
                               &(args_info->input_orig), &(args_info->input_given),
                               &(local_args_info.input_given), optarg, 0, 0, ARG_STRING,
                               check_ambiguity, override, 0, 0,
                               "input", 'i',
                               additional_error))
                    goto failure;

                break;
            case 't':    /* Use DAT/DAB file input rather than Bayes nets.  */


                if (update_arg((void *) &(args_info->dat_flag), 0, &(args_info->dat_given),
                               &(local_args_info.dat_given), optarg, 0, 0, ARG_FLAG,
                               check_ambiguity, override, 1, 0, "dat", 't',
                               additional_error))
                    goto failure;

                break;
            case 'd':    /* Database directory.  */


                if (update_arg((void *) &(args_info->database_arg),
                               &(args_info->database_orig), &(args_info->database_given),
                               &(local_args_info.database_given), optarg, 0, ".", ARG_STRING,
                               check_ambiguity, override, 0, 0,
                               "database", 'd',
                               additional_error))
                    goto failure;

                break;
            case 'c':    /* Context/gene mapping.  */


                if (update_arg((void *) &(args_info->contexts_arg),
                               &(args_info->contexts_orig), &(args_info->contexts_given),
                               &(local_args_info.contexts_given), optarg, 0, 0, ARG_STRING,
                               check_ambiguity, override, 0, 0,
                               "contexts", 'c',
                               additional_error))
                    goto failure;

                break;
            case 'e':    /* Context ID to process.  */


                if (update_arg((void *) &(args_info->context_arg),
                               &(args_info->context_orig), &(args_info->context_given),
                               &(local_args_info.context_given), optarg, 0, 0, ARG_INT,
                               check_ambiguity, override, 0, 0,
                               "context", 'e',
                               additional_error))
                    goto failure;

                break;
            case 'g':    /* Gene ID to name mapping.  */


                if (update_arg((void *) &(args_info->genes_arg),
                               &(args_info->genes_orig), &(args_info->genes_given),
                               &(local_args_info.genes_given), optarg, 0, 0, ARG_STRING,
                               check_ambiguity, override, 0, 0,
                               "genes", 'g',
                               additional_error))
                    goto failure;

                break;
            case 'N':    /* Define whether the database is nibble type..  */


                if (update_arg((void *) &(args_info->is_nibble_arg),
                               &(args_info->is_nibble_orig), &(args_info->is_nibble_given),
                               &(local_args_info.is_nibble_given), optarg, 0, "1", ARG_INT,
                               check_ambiguity, override, 0, 0,
                               "is_nibble", 'N',
                               additional_error))
                    goto failure;

                break;
            case 'n':    /* Bayes net directory.  */


                if (update_arg((void *) &(args_info->networks_arg),
                               &(args_info->networks_orig), &(args_info->networks_given),
                               &(local_args_info.networks_given), optarg, 0, ".", ARG_STRING,
                               check_ambiguity, override, 0, 0,
                               "networks", 'n',
                               additional_error))
                    goto failure;

                break;
            case 'b':    /* Bayes net for no context.  */


                if (update_arg((void *) &(args_info->default_arg),
                               &(args_info->default_orig), &(args_info->default_given),
                               &(local_args_info.default_given), optarg, 0, 0, ARG_STRING,
                               check_ambiguity, override, 0, 0,
                               "default", 'b',
                               additional_error))
                    goto failure;

                break;
            case 'x':    /* Use XDSL files instead of DSL.  */


                if (update_arg((void *) &(args_info->xdsl_flag), 0, &(args_info->xdsl_given),
                               &(local_args_info.xdsl_given), optarg, 0, 0, ARG_FLAG,
                               check_ambiguity, override, 1, 0, "xdsl", 'x',
                               additional_error))
                    goto failure;

                break;
            case 'm':    /* Read stored contexts and minimal Bayes nets.  */


                if (update_arg((void *) &(args_info->minimal_in_flag), 0, &(args_info->minimal_in_given),
                               &(local_args_info.minimal_in_given), optarg, 0, 0, ARG_FLAG,
                               check_ambiguity, override, 1, 0, "minimal_in", 'm',
                               additional_error))
                    goto failure;

                break;
            case 'M':    /* Store contexts and minimal Bayes nets.  */


                if (update_arg((void *) &(args_info->minimal_out_arg),
                               &(args_info->minimal_out_orig), &(args_info->minimal_out_given),
                               &(local_args_info.minimal_out_given), optarg, 0, 0, ARG_STRING,
                               check_ambiguity, override, 0, 0,
                               "minimal_out", 'M',
                               additional_error))
                    goto failure;

                break;
            case 'l':    /* Gene name to lookup.  */


                if (update_arg((void *) &(args_info->lookup_arg),
                               &(args_info->lookup_orig), &(args_info->lookup_given),
                               &(local_args_info.lookup_given), optarg, 0, 0, ARG_STRING,
                               check_ambiguity, override, 0, 0,
                               "lookup", 'l',
                               additional_error))
                    goto failure;

                break;
            case 'p':    /* Memory map input.  */


                if (update_arg((void *) &(args_info->memmap_flag), 0, &(args_info->memmap_given),
                               &(local_args_info.memmap_given), optarg, 0, 0, ARG_FLAG,
                               check_ambiguity, override, 1, 0, "memmap", 'p',
                               additional_error))
                    goto failure;

                break;
            case 'v':    /* Message verbosity.  */


                if (update_arg((void *) &(args_info->verbosity_arg),
                               &(args_info->verbosity_orig), &(args_info->verbosity_given),
                               &(local_args_info.verbosity_given), optarg, 0, "5", ARG_INT,
                               check_ambiguity, override, 0, 0,
                               "verbosity", 'v',
                               additional_error))
                    goto failure;

                break;

            case 0:    /* Long option with no short option */
            case '?':    /* Invalid option.  */
                /* `getopt_long' already printed an error message.  */
                goto failure;

            default:    /* bug: option not considered.  */
                fprintf(stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c,
                        (additional_error ? additional_error : ""));
                abort();
        } /* switch */
    } /* while */



    if (check_required) {
        error += cmdline_parser_required2(args_info, argv[0], additional_error);
    }

    cmdline_parser_release(&local_args_info);

    if (error)
        return (EXIT_FAILURE);

    if (optind < argc) {
        int i = 0;
        int found_prog_name = 0;
        /* whether program name, i.e., argv[0], is in the remaining args
           (this may happen with some implementations of getopt,
            but surely not with the one included by gengetopt) */

        i = optind;
        while (i < argc)
            if (argv[i++] == argv[0]) {
                found_prog_name = 1;
                break;
            }
        i = 0;

        args_info->inputs_num = argc - optind - found_prog_name;
        args_info->inputs =
                (char **) (malloc((args_info->inputs_num) * sizeof(char *)));
        while (optind < argc)
            if (argv[optind++] != argv[0])
                args_info->inputs[i++] = gengetopt_strdup(argv[optind - 1]);
    }

    return 0;

    failure:

    cmdline_parser_release(&local_args_info);
    return (EXIT_FAILURE);
}
