[BACK]Return to arguments.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Annotation of src/usr.bin/tmux/arguments.c, Revision 1.1

1.1     ! nicm        1: /* $OpenBSD: cmd.c,v 1.48 2010/12/30 23:16:18 nicm Exp $ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net>
        !             5:  *
        !             6:  * Permission to use, copy, modify, and distribute this software for any
        !             7:  * purpose with or without fee is hereby granted, provided that the above
        !             8:  * copyright notice and this permission notice appear in all copies.
        !             9:  *
        !            10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            14:  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
        !            15:  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
        !            16:  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            17:  */
        !            18:
        !            19: #include <sys/types.h>
        !            20:
        !            21: #include <bitstring.h>
        !            22: #include <stdlib.h>
        !            23: #include <string.h>
        !            24:
        !            25: #include "tmux.h"
        !            26:
        !            27: /* Create an arguments set with no flags. */
        !            28: struct args *
        !            29: args_create(int argc, ...)
        !            30: {
        !            31:        struct args     *args;
        !            32:        va_list          ap;
        !            33:        int              i;
        !            34:
        !            35:        args = xcalloc(1, sizeof *args);
        !            36:        if ((args->flags = bit_alloc(SCHAR_MAX)) == NULL)
        !            37:                fatal("bit_alloc failed");
        !            38:
        !            39:        args->argc = argc;
        !            40:        if (argc == 0)
        !            41:                args->argv = NULL;
        !            42:        else
        !            43:                args->argv = xcalloc(argc, sizeof **args->argv);
        !            44:
        !            45:        va_start(ap, argc);
        !            46:        for (i = 0; i < argc; i++)
        !            47:                args->argv[i] = xstrdup(va_arg(ap, char *));
        !            48:        va_end(ap);
        !            49:
        !            50:        return (args);
        !            51: }
        !            52:
        !            53: /* Parse an argv and argc into a new argument set. */
        !            54: struct args *
        !            55: args_parse(const char *template, int argc, char **argv)
        !            56: {
        !            57:        struct args     *args;
        !            58:        char            *ptr;
        !            59:        int              opt;
        !            60:
        !            61:        args = xcalloc(1, sizeof *args);
        !            62:        if ((args->flags = bit_alloc(SCHAR_MAX)) == NULL)
        !            63:                fatal("bit_alloc failed");
        !            64:
        !            65:        optreset = 1;
        !            66:        optind = 1;
        !            67:
        !            68:        while ((opt = getopt(argc, argv, template)) != -1) {
        !            69:                if (opt < 0 || opt >= SCHAR_MAX)
        !            70:                        continue;
        !            71:                if (opt == '?' || (ptr = strchr(template, opt)) == NULL) {
        !            72:                        xfree(args->flags);
        !            73:                        xfree(args);
        !            74:                        return (NULL);
        !            75:                }
        !            76:
        !            77:                bit_set(args->flags, opt);
        !            78:                if (ptr[1] == ':') {
        !            79:                        if (args->values[opt] != NULL)
        !            80:                                xfree(args->values[opt]);
        !            81:                        args->values[opt] = xstrdup(optarg);
        !            82:                }
        !            83:        }
        !            84:        argc -= optind;
        !            85:        argv += optind;
        !            86:
        !            87:        args->argc = argc;
        !            88:        args->argv = cmd_copy_argv(argc, argv);
        !            89:
        !            90:        return (args);
        !            91: }
        !            92:
        !            93: /* Free an arguments set. */
        !            94: void
        !            95: args_free(struct args *args)
        !            96: {
        !            97:        u_int   i;
        !            98:
        !            99:        cmd_free_argv(args->argc, args->argv);
        !           100:
        !           101:        for (i = 0; i < SCHAR_MAX; i++) {
        !           102:                if (args->values[i] != NULL)
        !           103:                        xfree(args->values[i]);
        !           104:        }
        !           105:
        !           106:        xfree(args->flags);
        !           107:        xfree(args);
        !           108: }
        !           109:
        !           110: /* Print a set of arguments. */
        !           111: size_t
        !           112: args_print(struct args *args, char *buf, size_t len)
        !           113: {
        !           114:        size_t           off;
        !           115:        int              i;
        !           116:        const char      *quotes;
        !           117:
        !           118:        /* There must be at least one byte at the start. */
        !           119:        if (len == 0)
        !           120:                return (0);
        !           121:        off = 0;
        !           122:
        !           123:        /* Process the flags first. */
        !           124:        buf[off++] = '-';
        !           125:        for (i = 0; i < SCHAR_MAX; i++) {
        !           126:                if (!bit_test(args->flags, i) || args->values[i] != NULL)
        !           127:                        continue;
        !           128:
        !           129:                if (off == len - 1) {
        !           130:                        buf[off] = '\0';
        !           131:                        return (len);
        !           132:                }
        !           133:                buf[off++] = i;
        !           134:                buf[off] = '\0';
        !           135:        }
        !           136:        if (off == 1)
        !           137:                buf[--off] = '\0';
        !           138:
        !           139:        /* Then the flags with arguments. */
        !           140:        for (i = 0; i < SCHAR_MAX; i++) {
        !           141:                if (!bit_test(args->flags, i) || args->values[i] == NULL)
        !           142:                        continue;
        !           143:
        !           144:                if (off >= len) {
        !           145:                        /* snprintf will have zero terminated. */
        !           146:                        return (len);
        !           147:                }
        !           148:
        !           149:                if (strchr(args->values[i], ' ') != NULL)
        !           150:                        quotes = "\"";
        !           151:                else
        !           152:                        quotes = "";
        !           153:                off += xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
        !           154:                    off != 0 ? " " : "", i, quotes, args->values[i], quotes);
        !           155:        }
        !           156:
        !           157:        /* And finally the argument vector. */
        !           158:        for (i = 0; i < args->argc; i++) {
        !           159:                if (off >= len) {
        !           160:                        /* snprintf will have zero terminated. */
        !           161:                        return (len);
        !           162:                }
        !           163:
        !           164:                if (strchr(args->argv[i], ' ') != NULL)
        !           165:                        quotes = "\"";
        !           166:                else
        !           167:                        quotes = "";
        !           168:                off += xsnprintf(buf + off, len - off, "%s%s%s%s",
        !           169:                    off != 0 ? " " : "", quotes, args->argv[i], quotes);
        !           170:        }
        !           171:
        !           172:        return (off);
        !           173: }
        !           174:
        !           175: /* Return if an argument is present. */
        !           176: int
        !           177: args_has(struct args *args, u_char ch)
        !           178: {
        !           179:        return (bit_test(args->flags, ch));
        !           180: }
        !           181:
        !           182: /* Set argument value. */
        !           183: void
        !           184: args_set(struct args *args, u_char ch, const char *value)
        !           185: {
        !           186:        if (value != NULL) {
        !           187:                if (args->values[ch] != NULL)
        !           188:                        xfree(args->values[ch]);
        !           189:                args->values[ch] = xstrdup(value);
        !           190:        }
        !           191:        bit_set(args->flags, ch);
        !           192: }
        !           193:
        !           194: /* Get argument value. Will be NULL if it isn't present. */
        !           195: const char *
        !           196: args_get(struct args *args, u_char ch)
        !           197: {
        !           198:        return (args->values[ch]);
        !           199: }
        !           200:
        !           201: /* Convert an argument value to a number. */
        !           202: long long
        !           203: args_strtonum(struct args *args,
        !           204:     u_char ch, long long minval, long long maxval, char **cause)
        !           205: {
        !           206:        const char      *errstr;
        !           207:        long long        ll;
        !           208:
        !           209:        if (!args_has(args, ch)) {
        !           210:                *cause = xstrdup("missing");
        !           211:                return (0);
        !           212:        }
        !           213:
        !           214:        ll = strtonum(args->values[ch], minval, maxval, &errstr);
        !           215:        if (errstr != NULL) {
        !           216:                *cause = xstrdup(errstr);
        !           217:                return (0);
        !           218:        }
        !           219:
        !           220:        *cause = NULL;
        !           221:        return (ll);
        !           222: }