=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/arguments.c,v retrieving revision 1.41 retrieving revision 1.42 diff -c -r1.41 -r1.42 *** src/usr.bin/tmux/arguments.c 2021/08/21 10:28:05 1.41 --- src/usr.bin/tmux/arguments.c 2021/08/21 18:39:07 1.42 *************** *** 1,4 **** ! /* $OpenBSD: arguments.c,v 1.41 2021/08/21 10:28:05 nicm Exp $ */ /* * Copyright (c) 2010 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: arguments.c,v 1.42 2021/08/21 18:39:07 nicm Exp $ */ /* * Copyright (c) 2010 Nicholas Marriott *************** *** 18,26 **** #include #include #include - #include #include #include "tmux.h" --- 18,26 ---- #include + #include #include #include #include #include "tmux.h" *************** *** 66,71 **** --- 66,85 ---- return (RB_FIND(args_tree, &args->tree, &entry)); } + /* Get value as string. */ + static char * + args_value_as_string(struct args_value *value) + { + switch (value->type) { + case ARGS_NONE: + return (xstrdup("")); + case ARGS_COMMANDS: + return (cmd_list_print(value->cmdlist, 0)); + case ARGS_STRING: + return (xstrdup(value->string)); + } + } + /* Create an empty arguments set. */ struct args * args_create(void) *************** *** 77,116 **** return (args); } ! /* Parse an argv and argc into a new argument set. */ struct args * ! args_parse(const struct args_parse *parse, int argc, char **argv) { ! struct args *args; ! int opt; ! optreset = 1; ! optind = 1; ! optarg = NULL; args = args_create(); ! while ((opt = getopt(argc, argv, parse->template)) != -1) { ! if (opt < 0) ! continue; ! if (opt == '?' || strchr(parse->template, opt) == NULL) { ! args_free(args); ! return (NULL); } - args_set(args, opt, optarg); - optarg = NULL; } ! argc -= optind; ! argv += optind; ! args->argc = argc; ! args->argv = cmd_copy_argv(argc, argv); ! if ((parse->lower != -1 && argc < parse->lower) || ! (parse->upper != -1 && argc > parse->upper)) { args_free(args); return (NULL); } return (args); } /* Free an arguments set. */ --- 91,197 ---- return (args); } ! /* Parse arguments into a new argument set. */ struct args * ! args_parse(const struct args_parse *parse, struct args_value *values, ! u_int count) { ! struct args *args; ! u_int i; ! struct args_value *value; ! u_char flag, argument; ! const char *found, *string; ! char *s; ! if (count == 0) ! return (args_create()); args = args_create(); ! for (i = 1; i < count; /* nothing */) { ! value = &values[i]; ! ! s = args_value_as_string(value); ! log_debug("%s: %u = %s", __func__, i, s); ! free(s); ! ! if (value->type != ARGS_STRING) ! break; ! ! string = value->string; ! if (*string++ != '-' || *string == '\0') ! break; ! i++; ! if (string[0] == '-' && string[1] == '\0') ! break; ! ! for (;;) { ! flag = *string++; ! if (flag == '\0') ! break; ! if (!isalnum(flag)) { ! args_free(args); ! return (NULL); ! } ! found = strchr(parse->template, flag); ! if (found == NULL) { ! args_free(args); ! return (NULL); ! } ! argument = *++found; ! if (argument != ':') { ! log_debug("%s: add -%c", __func__, flag); ! args_set(args, flag, NULL); ! continue; ! } ! if (*string != '\0') ! s = xstrdup(string); ! else { ! if (i == count) { ! args_free(args); ! return (NULL); ! } ! s = args_value_as_string(&values[i++]); ! } ! log_debug("%s: add -%c = %s", __func__, flag, s); ! args_set(args, flag, s); ! free(s); ! break; } } ! log_debug("%s: flags end at %u of %u", __func__, i, count); ! if (i != count) { ! for (/* nothing */; i < count; i++) { ! value = &values[i]; ! s = args_value_as_string(value); ! log_debug("%s: %u = %s", __func__, i, s); ! cmd_append_argv(&args->argc, &args->argv, s); ! free(s); ! } ! } ! if ((parse->lower != -1 && args->argc < parse->lower) || ! (parse->upper != -1 && args->argc > parse->upper)) { args_free(args); return (NULL); } return (args); + } + + /* Free a value. */ + void + args_free_value(struct args_value *value) + { + switch (value->type) { + case ARGS_NONE: + break; + case ARGS_STRING: + free(value->string); + break; + case ARGS_COMMANDS: + cmd_list_free(value->cmdlist); + break; + } } /* Free an arguments set. */