Example #1
0
void nn_parse_options (struct nn_commandline *cline,
                       void *target, int argc, char **argv)
{
    struct nn_parse_context ctx;
    int num_options;

    ctx.def = cline;
    ctx.options = cline->options;
    ctx.target = target;
    ctx.argc = argc;
    ctx.argv = argv;
    ctx.requires = cline->required_options;

    for (num_options = 0; ctx.options[num_options].longname; ++num_options);
    ctx.last_option_usage = calloc (sizeof (char *), num_options);
    if  (!ctx.last_option_usage)
        nn_memory_error (&ctx);

    ctx.mask = 0;
    ctx.args_left = argc - 1;
    ctx.arg = argv;

    nn_parse_arg0 (&ctx);

    while (nn_get_arg (&ctx)) {
        nn_parse_arg (&ctx);
    }

    nn_check_requires (&ctx);

    free (ctx.last_option_usage);

}
Example #2
0
static void nn_append_string (struct nn_parse_context *ctx,
                             struct nn_option *opt, char *str)
{
    struct nn_string_list *lst;

    lst = (struct nn_string_list *)(
        ((char *)ctx->target) + opt->offset);
    if (lst->items) {
        lst->num += 1;
        lst->items = realloc (lst->items, sizeof (char *) * lst->num);
    } else {
        lst->items = malloc (sizeof (char *));
        lst->num = 1;
    }
    if (!lst->items) {
        nn_memory_error (ctx);
    }
    lst->items[lst->num-1] = str;
}
Example #3
0
static void nn_process_option (struct nn_parse_context *ctx,
                               int opt_index, char *argument)
{
    struct nn_option *opt;
    struct nn_enum_item *items;
    char *endptr;
    struct nn_blob *blob;
    FILE *file;
    char *data;
    size_t data_len;
    size_t data_buf;
    size_t bytes_read;

    opt = &ctx->options[opt_index];
    if (ctx->mask & opt->conflicts_mask) {
        nn_option_conflict (ctx, opt_index);
    }
    ctx->mask |= opt->mask_set;

    switch (opt->type) {
    case NN_OPT_HELP:
        nn_print_help (ctx, stdout);
        exit (0);
        return;
    case NN_OPT_INT:
        *(long *)(((char *)ctx->target) + opt->offset) = strtol (argument,
                &endptr, 0);
        if (endptr == argument || *endptr != 0) {
            nn_option_error ("requires integer argument",
                             ctx, opt_index);
        }
        return;
    case NN_OPT_INCREMENT:
        *(int *)(((char *)ctx->target) + opt->offset) += 1;
        return;
    case NN_OPT_DECREMENT:
        *(int *)(((char *)ctx->target) + opt->offset) -= 1;
        return;
    case NN_OPT_ENUM:
        items = (struct nn_enum_item *)opt->pointer;
        for (; items->name; ++items) {
            if (!strcmp (items->name, argument)) {
                *(int *)(((char *)ctx->target) + opt->offset) = \
                        items->value;
                return;
            }
        }
        nn_invalid_enum_value (ctx, opt_index, argument);
        return;
    case NN_OPT_SET_ENUM:
        *(int *)(((char *)ctx->target) + opt->offset) = \
                *(int *)(opt->pointer);
        return;
    case NN_OPT_STRING:
        *(char **)(((char *)ctx->target) + opt->offset) = argument;
        return;
    case NN_OPT_BLOB:
        blob = (struct nn_blob *)(((char *)ctx->target) + opt->offset);
        blob->data = argument;
        blob->length = strlen (argument);
        blob->need_free = 0;
        return;
    case NN_OPT_FLOAT:
#if defined NN_HAVE_WINDOWS
        *(float *)(((char *)ctx->target) + opt->offset) =
            (float) atof (argument);
#else
        *(float *)(((char *)ctx->target) + opt->offset) =
            strtof (argument, &endptr);
        if (endptr == argument || *endptr != 0) {
            nn_option_error ("requires float point argument",
                             ctx, opt_index);
        }
#endif
        return;
    case NN_OPT_LIST_APPEND:
        nn_append_string (ctx, opt, argument);
        return;
    case NN_OPT_LIST_APPEND_FMT:
        data_buf = strlen (argument) + strlen (opt->pointer);
        data = malloc (data_buf);
#if defined NN_HAVE_WINDOWS
        data_len = _snprintf_s (data, data_buf, _TRUNCATE, opt->pointer,
                                argument);
#else
        data_len = snprintf (data, data_buf, opt->pointer, argument);
#endif
        assert (data_len < data_buf);
        nn_append_string (ctx, opt, data);
        nn_append_string_to_free (ctx, opt, data);
        return;
    case NN_OPT_READ_FILE:
        if (!strcmp (argument, "-")) {
            file = stdin;
        } else {
            file = fopen (argument, "r");
            if (!file) {
                fprintf (stderr, "Error opening file ``%s'': %s\n",
                         argument, strerror (errno));
                exit (2);
            }
        }
        data = malloc (4096);
        if (!data)
            nn_memory_error (ctx);
        data_len = 0;
        data_buf = 4096;
        for (;;) {
            bytes_read = fread (data + data_len, 1, data_buf - data_len,
                                file);
            data_len += bytes_read;
            if (feof (file))
                break;
            if (data_buf - data_len < 1024) {
                if (data_buf < (1 << 20)) {
                    data_buf *= 2;  /* grow twice until not too big */
                } else {
                    data_buf += 1 << 20;  /* grow 1 Mb each time */
                }
                data = realloc (data, data_buf);
                if (!data)
                    nn_memory_error (ctx);
            }
        }
        if (data_len != data_buf) {
            data = realloc (data, data_len);
            assert (data);
        }
        if (ferror (file)) {
#if defined _MSC_VER
#pragma warning (push)
#pragma warning (disable:4996)
#endif
            fprintf (stderr, "Error reading file ``%s'': %s\n",
                     argument, strerror (errno));
#if defined _MSC_VER
#pragma warning (pop)
#endif
            exit (2);
        }
        if (file != stdin) {
            fclose (file);
        }
        blob = (struct nn_blob *)(((char *)ctx->target) + opt->offset);
        blob->data = data;
        blob->length = data_len;
        blob->need_free = 1;
        return;
    }
    abort ();
}