Annotation of embedaddon/tmux/cfg.c, revision 1.1.1.1

1.1       misho       1: /* $OpenBSD$ */
                      2: 
                      3: /*
                      4:  * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
                      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 <ctype.h>
                     22: #include <errno.h>
                     23: #include <stdio.h>
                     24: #include <stdlib.h>
                     25: #include <string.h>
                     26: #include <unistd.h>
                     27: 
                     28: #include "tmux.h"
                     29: 
                     30: static char     *cfg_file;
                     31: int              cfg_finished;
                     32: static char    **cfg_causes;
                     33: static u_int     cfg_ncauses;
                     34: struct client   *cfg_client;
                     35: 
                     36: static enum cmd_retval
                     37: cfg_done(__unused struct cmdq_item *item, __unused void *data)
                     38: {
                     39:        if (cfg_finished)
                     40:                return (CMD_RETURN_NORMAL);
                     41:        cfg_finished = 1;
                     42: 
                     43:        if (!RB_EMPTY(&sessions))
                     44:                cfg_show_causes(RB_MIN(sessions, &sessions));
                     45: 
                     46:        if (cfg_client != NULL)
                     47:                server_client_unref(cfg_client);
                     48:        return (CMD_RETURN_NORMAL);
                     49: }
                     50: 
                     51: void
                     52: set_cfg_file(const char *path)
                     53: {
                     54:        free(cfg_file);
                     55:        cfg_file = xstrdup(path);
                     56: }
                     57: 
                     58: void
                     59: start_cfg(void)
                     60: {
                     61:        const char      *home;
                     62:        int              quiet = 0;
                     63: 
                     64:        cfg_client = TAILQ_FIRST(&clients);
                     65:        if (cfg_client != NULL)
                     66:                cfg_client->references++;
                     67: 
                     68:        load_cfg(TMUX_CONF, cfg_client, NULL, 1);
                     69: 
                     70:        if (cfg_file == NULL && (home = find_home()) != NULL) {
                     71:                xasprintf(&cfg_file, "%s/.tmux.conf", home);
                     72:                quiet = 1;
                     73:        }
                     74:        if (cfg_file != NULL)
                     75:                load_cfg(cfg_file, cfg_client, NULL, quiet);
                     76: 
                     77:        cmdq_append(cfg_client, cmdq_get_callback(cfg_done, NULL));
                     78: }
                     79: 
                     80: int
                     81: load_cfg(const char *path, struct client *c, struct cmdq_item *item, int quiet)
                     82: {
                     83:        FILE                    *f;
                     84:        const char               delim[3] = { '\\', '\\', '\0' };
                     85:        u_int                    found = 0;
                     86:        size_t                   line = 0;
                     87:        char                    *buf, *cause1, *p, *q, *s;
                     88:        struct cmd_list         *cmdlist;
                     89:        struct cmdq_item        *new_item;
                     90:        int                      condition = 0;
                     91:        struct format_tree      *ft;
                     92: 
                     93:        log_debug("loading %s", path);
                     94:        if ((f = fopen(path, "rb")) == NULL) {
                     95:                if (errno == ENOENT && quiet)
                     96:                        return (0);
                     97:                cfg_add_cause("%s: %s", path, strerror(errno));
                     98:                return (-1);
                     99:        }
                    100: 
                    101:        while ((buf = fparseln(f, NULL, &line, delim, 0)) != NULL) {
                    102:                log_debug("%s: %s", path, buf);
                    103: 
                    104:                p = buf;
                    105:                while (isspace((u_char)*p))
                    106:                        p++;
                    107:                if (*p == '\0') {
                    108:                        free(buf);
                    109:                        continue;
                    110:                }
                    111:                q = p + strlen(p) - 1;
                    112:                while (q != p && isspace((u_char)*q))
                    113:                        *q-- = '\0';
                    114: 
                    115:                if (condition != 0 && strcmp(p, "%endif") == 0) {
                    116:                        condition = 0;
                    117:                        continue;
                    118:                }
                    119:                if (strncmp(p, "%if ", 4) == 0) {
                    120:                        if (condition != 0) {
                    121:                                cfg_add_cause("%s:%zu: nested %%if", path,
                    122:                                    line);
                    123:                                continue;
                    124:                        }
                    125:                        ft = format_create(NULL, FORMAT_NONE, FORMAT_NOJOBS);
                    126: 
                    127:                        s = p + 3;
                    128:                        while (isspace((u_char)*s))
                    129:                                s++;
                    130:                        s = format_expand(ft, s);
                    131:                        if (*s != '\0' && (s[0] != '0' || s[1] != '\0'))
                    132:                                condition = 1;
                    133:                        else
                    134:                                condition = -1;
                    135:                        free(s);
                    136: 
                    137:                        format_free(ft);
                    138:                        continue;
                    139:                }
                    140:                if (condition == -1)
                    141:                        continue;
                    142: 
                    143:                cmdlist = cmd_string_parse(p, path, line, &cause1);
                    144:                if (cmdlist == NULL) {
                    145:                        free(buf);
                    146:                        if (cause1 == NULL)
                    147:                                continue;
                    148:                        cfg_add_cause("%s:%zu: %s", path, line, cause1);
                    149:                        free(cause1);
                    150:                        continue;
                    151:                }
                    152:                free(buf);
                    153: 
                    154:                if (cmdlist == NULL)
                    155:                        continue;
                    156:                new_item = cmdq_get_command(cmdlist, NULL, NULL, 0);
                    157:                if (item != NULL)
                    158:                        cmdq_insert_after(item, new_item);
                    159:                else
                    160:                        cmdq_append(c, new_item);
                    161:                cmd_list_free(cmdlist);
                    162: 
                    163:                found++;
                    164:        }
                    165:        fclose(f);
                    166: 
                    167:        return (found);
                    168: }
                    169: 
                    170: void
                    171: cfg_add_cause(const char *fmt, ...)
                    172: {
                    173:        va_list  ap;
                    174:        char    *msg;
                    175: 
                    176:        va_start(ap, fmt);
                    177:        xvasprintf(&msg, fmt, ap);
                    178:        va_end(ap);
                    179: 
                    180:        cfg_ncauses++;
                    181:        cfg_causes = xreallocarray(cfg_causes, cfg_ncauses, sizeof *cfg_causes);
                    182:        cfg_causes[cfg_ncauses - 1] = msg;
                    183: }
                    184: 
                    185: void
                    186: cfg_print_causes(struct cmdq_item *item)
                    187: {
                    188:        u_int    i;
                    189: 
                    190:        for (i = 0; i < cfg_ncauses; i++) {
                    191:                cmdq_print(item, "%s", cfg_causes[i]);
                    192:                free(cfg_causes[i]);
                    193:        }
                    194: 
                    195:        free(cfg_causes);
                    196:        cfg_causes = NULL;
                    197:        cfg_ncauses = 0;
                    198: }
                    199: 
                    200: void
                    201: cfg_show_causes(struct session *s)
                    202: {
                    203:        struct window_pane      *wp;
                    204:        u_int                    i;
                    205: 
                    206:        if (s == NULL || cfg_ncauses == 0)
                    207:                return;
                    208:        wp = s->curw->window->active;
                    209: 
                    210:        window_pane_set_mode(wp, &window_copy_mode);
                    211:        window_copy_init_for_output(wp);
                    212:        for (i = 0; i < cfg_ncauses; i++) {
                    213:                window_copy_add(wp, "%s", cfg_causes[i]);
                    214:                free(cfg_causes[i]);
                    215:        }
                    216: 
                    217:        free(cfg_causes);
                    218:        cfg_causes = NULL;
                    219:        cfg_ncauses = 0;
                    220: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>