+ parse_orig_arg_opt_ret_t ret = PARSE_ORIG_ARG_OPT_RET_OK;
+ const argpar_opt_descr_t *descr;
+ argpar_item_opt_t *opt_item;
+ bool used_next_orig_arg = false;
+
+ /* Option's argument, if any */
+ const char *opt_arg = NULL;
+
+ /* Position of first `=`, if any */
+ const char *eq_pos;
+
+ /* Option name */
+ const char *long_opt_name = long_opt_arg;
+
+ ARGPAR_ASSERT(strlen(long_opt_arg) != 0);
+
+ /* Find the first `=` in original argument */
+ eq_pos = strchr(long_opt_arg, '=');
+ if (eq_pos) {
+ const size_t long_opt_name_size = eq_pos - long_opt_arg;
+
+ /* Isolate the option name */
+ while (long_opt_name_size > iter->tmp_buf.size - 1) {
+ const size_t new_size = iter->tmp_buf.size * 2;
+ char * const new_data = ARGPAR_REALLOC(iter->tmp_buf.data, char, new_size);
+
+ if (!new_data) {
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
+ goto error;
+ }
+
+ iter->tmp_buf.size = new_size;
+ iter->tmp_buf.data = new_data;
+ }
+
+ 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 */
+ descr = find_descr(descrs, '\0', long_opt_name);
+ if (!descr) {
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
+
+ if (set_error(error, ARGPAR_ERROR_TYPE_UNKNOWN_OPT, long_opt_name, NULL, false)) {
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
+ }
+
+ goto error;
+ }
+
+ /* Find option's argument if any */
+ if (descr->with_arg) {
+ if (eq_pos) {
+ /* `--long-opt=arg` style */
+ opt_arg = eq_pos + 1;
+ } else {
+ /* `--long-opt arg` style */
+ if (!next_orig_arg) {
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
+
+ if (set_error(error, ARGPAR_ERROR_TYPE_MISSING_OPT_ARG, NULL, descr, false)) {
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
+ }
+
+ goto error;
+ }
+
+ opt_arg = next_orig_arg;
+ used_next_orig_arg = true;
+ }
+ } else if (eq_pos) {
+ /*
+ * Unexpected `--opt=arg` style for a long option which
+ * doesn't accept an argument.
+ */
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
+
+ if (set_error(error, ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG, NULL, descr, false)) {
+ ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
+ }
+
+ goto error;
+ }
+
+ /* Create and append option argument */
+ opt_item = create_opt_item(descr, opt_arg);
+ if (!opt_item) {
+ goto error;
+ }
+
+ if (used_next_orig_arg) {
+ iter->i += 2;
+ } else {
+ iter->i++;
+ }
+
+ *item = &opt_item->base;
+ goto end;