123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- #include <sys/types.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include "tmux.h"
- struct args_entry {
- u_char flag;
- char *value;
- RB_ENTRY(args_entry) entry;
- };
- struct args_entry *args_find(struct args *, u_char);
- RB_GENERATE(args_tree, args_entry, entry, args_cmp);
- int
- args_cmp(struct args_entry *a1, struct args_entry *a2)
- {
- return (a1->flag - a2->flag);
- }
- struct args *
- args_create(int argc, ...)
- {
- struct args *args;
- va_list ap;
- int i;
- args = xcalloc(1, sizeof *args);
- args->argc = argc;
- if (argc == 0)
- args->argv = NULL;
- else
- args->argv = xcalloc(argc, sizeof *args->argv);
- va_start(ap, argc);
- for (i = 0; i < argc; i++)
- args->argv[i] = xstrdup(va_arg(ap, char *));
- va_end(ap);
- return (args);
- }
- struct args_entry *
- args_find(struct args *args, u_char ch)
- {
- struct args_entry entry;
- entry.flag = ch;
- return (RB_FIND(args_tree, &args->tree, &entry));
- }
- struct args *
- args_parse(const char *template, int argc, char **argv)
- {
- struct args *args;
- int opt;
- args = xcalloc(1, sizeof *args);
- optreset = 1;
- optind = 1;
- while ((opt = getopt(argc, argv, template)) != -1) {
- if (opt < 0)
- continue;
- if (opt == '?' || strchr(template, opt) == NULL) {
- args_free(args);
- return (NULL);
- }
- args_set(args, opt, optarg);
- }
- argc -= optind;
- argv += optind;
- args->argc = argc;
- args->argv = cmd_copy_argv(argc, argv);
- return (args);
- }
- void
- args_free(struct args *args)
- {
- struct args_entry *entry;
- struct args_entry *entry1;
- cmd_free_argv(args->argc, args->argv);
- RB_FOREACH_SAFE(entry, args_tree, &args->tree, entry1) {
- RB_REMOVE(args_tree, &args->tree, entry);
- free(entry->value);
- free(entry);
- }
- free(args);
- }
- static void printflike(3, 4)
- args_print_add(char **buf, size_t *len, const char *fmt, ...)
- {
- va_list ap;
- char *s;
- size_t slen;
- va_start(ap, fmt);
- slen = xvasprintf(&s, fmt, ap);
- va_end(ap);
- *len += slen;
- *buf = xrealloc(*buf, *len);
- strlcat(*buf, s, *len);
- free(s);
- }
- char *
- args_print(struct args *args)
- {
- size_t len;
- char *buf;
- int i;
- struct args_entry *entry;
- len = 1;
- buf = xcalloc(1, len);
-
- RB_FOREACH(entry, args_tree, &args->tree) {
- if (entry->value != NULL)
- continue;
- if (*buf == '\0')
- args_print_add(&buf, &len, "-");
- args_print_add(&buf, &len, "%c", entry->flag);
- }
-
- RB_FOREACH(entry, args_tree, &args->tree) {
- if (entry->value == NULL)
- continue;
- if (*buf != '\0')
- args_print_add(&buf, &len, " -%c ", entry->flag);
- else
- args_print_add(&buf, &len, "-%c ", entry->flag);
- if (strchr(entry->value, ' ') != NULL)
- args_print_add(&buf, &len, "\"%s\"", entry->value);
- else
- args_print_add(&buf, &len, "%s", entry->value);
- }
-
- for (i = 0; i < args->argc; i++) {
- if (*buf != '\0')
- args_print_add(&buf, &len, " ");
- if (strchr(args->argv[i], ' ') != NULL)
- args_print_add(&buf, &len, "\"%s\"", args->argv[i]);
- else
- args_print_add(&buf, &len, "%s", args->argv[i]);
- }
- return (buf);
- }
- int
- args_has(struct args *args, u_char ch)
- {
- return (args_find(args, ch) == NULL ? 0 : 1);
- }
- void
- args_set(struct args *args, u_char ch, const char *value)
- {
- struct args_entry *entry;
-
- if ((entry = args_find(args, ch)) != NULL) {
- free(entry->value);
- entry->value = NULL;
- } else {
- entry = xcalloc(1, sizeof *entry);
- entry->flag = ch;
- RB_INSERT(args_tree, &args->tree, entry);
- }
- if (value != NULL)
- entry->value = xstrdup(value);
- }
- const char *
- args_get(struct args *args, u_char ch)
- {
- struct args_entry *entry;
- if ((entry = args_find(args, ch)) == NULL)
- return (NULL);
- return (entry->value);
- }
- long long
- args_strtonum(struct args *args, u_char ch, long long minval, long long maxval,
- char **cause)
- {
- const char *errstr;
- long long ll;
- struct args_entry *entry;
- if ((entry = args_find(args, ch)) == NULL) {
- *cause = xstrdup("missing");
- return (0);
- }
- ll = strtonum(entry->value, minval, maxval, &errstr);
- if (errstr != NULL) {
- *cause = xstrdup(errstr);
- return (0);
- }
- *cause = NULL;
- return (ll);
- }
|