X-Git-Url: http://git.efficios.com/?p=argpar.git;a=blobdiff_plain;f=argpar%2Fargpar.c;h=ba577976a789f71d667e4f1b35be322de91bd6e6;hp=5a8a302de8d063dc7ef6426f2be1eb4dfca39793;hb=d1f7bbdbd28b96b360e815f28697a2f81d699cb4;hpb=2af370d0a1dd610f66232e2bacc75e4b40ffca0d diff --git a/argpar/argpar.c b/argpar/argpar.c index 5a8a302..ba57797 100644 --- a/argpar/argpar.c +++ b/argpar/argpar.c @@ -61,6 +61,12 @@ struct argpar_iter { * argpar_iter_next() call. */ const char *short_opt_ch; + + /* Temporary character buffer which only grows */ + struct { + size_t size; + char *data; + } tmp_buf; }; /* Base parsing item */ @@ -400,7 +406,6 @@ enum parse_orig_arg_opt_ret { PARSE_ORIG_ARG_OPT_RET_OK, PARSE_ORIG_ARG_OPT_RET_ERROR_UNKNOWN_OPT = -1, PARSE_ORIG_ARG_OPT_RET_ERROR_MISSING_OPT_ARG = -2, - PARSE_ORIG_ARG_OPT_RET_ERROR_INVALID_ARG = -3, PARSE_ORIG_ARG_OPT_RET_ERROR_UNEXPECTED_OPT_ARG = -4, PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY = -5, }; @@ -418,11 +423,7 @@ enum parse_orig_arg_opt_ret parse_short_opts(const char * const short_opts, const struct argpar_opt_descr *descr; struct argpar_item_opt *opt_item; - if (strlen(short_opts) == 0) { - try_append_string_printf(error, "Invalid argument"); - ret = PARSE_ORIG_ARG_OPT_RET_ERROR_INVALID_ARG; - goto error; - } + ARGPAR_ASSERT(strlen(short_opts) != 0); if (!iter->short_opt_ch) { iter->short_opt_ch = short_opts; @@ -499,7 +500,6 @@ enum parse_orig_arg_opt_ret parse_long_opt(const char * const long_opt_arg, struct argpar_iter * const iter, char ** const error, struct argpar_item ** const item) { - const size_t max_len = 127; enum parse_orig_arg_opt_ret ret = PARSE_ORIG_ARG_OPT_RET_OK; const struct argpar_opt_descr *descr; struct argpar_item_opt *opt_item; @@ -511,17 +511,10 @@ enum parse_orig_arg_opt_ret parse_long_opt(const char * const long_opt_arg, /* Position of first `=`, if any */ const char *eq_pos; - /* Buffer holding option name when `long_opt_arg` contains `=` */ - char buf[max_len + 1]; - /* Option name */ const char *long_opt_name = long_opt_arg; - if (strlen(long_opt_arg) == 0) { - try_append_string_printf(error, "Invalid argument"); - ret = PARSE_ORIG_ARG_OPT_RET_ERROR_INVALID_ARG; - goto error; - } + ARGPAR_ASSERT(strlen(long_opt_arg) != 0); /* Find the first `=` in original argument */ eq_pos = strchr(long_opt_arg, '='); @@ -529,16 +522,19 @@ enum parse_orig_arg_opt_ret parse_long_opt(const char * const long_opt_arg, const size_t long_opt_name_size = eq_pos - long_opt_arg; /* Isolate the option name */ - if (long_opt_name_size > max_len) { - try_append_string_printf(error, - "Invalid argument `--%s`", long_opt_arg); - ret = PARSE_ORIG_ARG_OPT_RET_ERROR_INVALID_ARG; - goto error; + while (long_opt_name_size > iter->tmp_buf.size - 1) { + iter->tmp_buf.size *= 2; + iter->tmp_buf.data = ARGPAR_REALLOC(iter->tmp_buf.data, + char, iter->tmp_buf.size); + if (!iter->tmp_buf.data) { + ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY; + goto error; + } } - memcpy(buf, long_opt_arg, long_opt_name_size); - buf[long_opt_name_size] = '\0'; - long_opt_name = buf; + memcpy(iter->tmp_buf.data, long_opt_arg, long_opt_name_size); + iter->tmp_buf.data[long_opt_name_size] = '\0'; + long_opt_name = iter->tmp_buf.data; } /* Find corresponding option descriptor */ @@ -658,7 +654,7 @@ struct argpar_iter *argpar_iter_create(const unsigned int argc, const char * const * const argv, const struct argpar_opt_descr * const descrs) { - struct argpar_iter * const iter = ARGPAR_ZALLOC(struct argpar_iter); + struct argpar_iter *iter = ARGPAR_ZALLOC(struct argpar_iter); if (!iter) { goto end; @@ -667,6 +663,13 @@ struct argpar_iter *argpar_iter_create(const unsigned int argc, iter->argc = argc; iter->argv = argv; iter->descrs = descrs; + iter->tmp_buf.size = 128; + iter->tmp_buf.data = ARGPAR_CALLOC(char, iter->tmp_buf.size); + if (!iter->tmp_buf.data) { + argpar_iter_destroy(iter); + iter = NULL; + goto end; + } end: return iter; @@ -675,7 +678,10 @@ end: ARGPAR_HIDDEN void argpar_iter_destroy(struct argpar_iter * const iter) { - free(iter); + if (iter) { + free(iter->tmp_buf.data); + free(iter); + } } ARGPAR_HIDDEN @@ -703,9 +709,10 @@ enum argpar_iter_next_status argpar_iter_next( next_orig_arg = iter->i < (iter->argc - 1) ? iter->argv[iter->i + 1] : NULL; - if (orig_arg[0] != '-') { + if (strcmp(orig_arg, "-") == 0 || strcmp(orig_arg, "--") == 0 || + orig_arg[0] != '-') { /* Non-option argument */ - struct argpar_item_non_opt * const non_opt_item = + const struct argpar_item_non_opt * const non_opt_item = create_non_opt_item(orig_arg, iter->i, iter->non_opt_index); @@ -731,7 +738,6 @@ enum argpar_iter_next_status argpar_iter_next( break; case PARSE_ORIG_ARG_OPT_RET_ERROR_UNKNOWN_OPT: case PARSE_ORIG_ARG_OPT_RET_ERROR_MISSING_OPT_ARG: - case PARSE_ORIG_ARG_OPT_RET_ERROR_INVALID_ARG: case PARSE_ORIG_ARG_OPT_RET_ERROR_UNEXPECTED_OPT_ARG: try_prepend_while_parsing_arg_to_error(error, iter->i, orig_arg); @@ -743,9 +749,6 @@ enum argpar_iter_next_status argpar_iter_next( case PARSE_ORIG_ARG_OPT_RET_ERROR_MISSING_OPT_ARG: status = ARGPAR_ITER_NEXT_STATUS_ERROR_MISSING_OPT_ARG; break; - case PARSE_ORIG_ARG_OPT_RET_ERROR_INVALID_ARG: - status = ARGPAR_ITER_NEXT_STATUS_ERROR_INVALID_ARG; - break; case PARSE_ORIG_ARG_OPT_RET_ERROR_UNEXPECTED_OPT_ARG: status = ARGPAR_ITER_NEXT_STATUS_ERROR_UNEXPECTED_OPT_ARG; break; @@ -766,7 +769,7 @@ end: } ARGPAR_HIDDEN -unsigned int argpar_iter_get_ingested_orig_args( +unsigned int argpar_iter_ingested_orig_args( const struct argpar_iter * const iter) { return iter->i; @@ -802,14 +805,13 @@ struct argpar_parse_ret argpar_parse(const unsigned int argc, switch (status) { case ARGPAR_ITER_NEXT_STATUS_ERROR_MISSING_OPT_ARG: - case ARGPAR_ITER_NEXT_STATUS_ERROR_INVALID_ARG: case ARGPAR_ITER_NEXT_STATUS_ERROR_UNEXPECTED_OPT_ARG: case ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY: goto error; case ARGPAR_ITER_NEXT_STATUS_ERROR_UNKNOWN_OPT: if (fail_on_unknown_opt) { parse_ret.ingested_orig_args = - argpar_iter_get_ingested_orig_args(iter); + argpar_iter_ingested_orig_args(iter); goto error; } @@ -832,7 +834,7 @@ struct argpar_parse_ret argpar_parse(const unsigned int argc, success: ARGPAR_ASSERT(!parse_ret.error); - parse_ret.ingested_orig_args = argpar_iter_get_ingested_orig_args(iter); + parse_ret.ingested_orig_args = argpar_iter_ingested_orig_args(iter); goto end; error: