Correct error checking
[tig] / tig.c
diff --git a/tig.c b/tig.c
index 1192c23..851503f 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -164,6 +164,27 @@ chomp_string(char *name)
        return name;
 }
 
+static bool
+string_nformat(char *buf, size_t bufsize, int *bufpos, const char *fmt, ...)
+{
+       va_list args;
+       int pos = bufpos ? *bufpos : 0;
+
+       va_start(args, fmt);
+       pos += vsnprintf(buf + pos, bufsize - pos, fmt, args);
+       va_end(args);
+
+       if (bufpos)
+               *bufpos = pos;
+
+       return pos >= bufsize ? FALSE : TRUE;
+}
+
+#define string_format(buf, fmt, args...) \
+       string_nformat(buf, sizeof(buf), NULL, fmt, args)
+
+#define string_format_from(buf, from, fmt, args...) \
+       string_nformat(buf, sizeof(buf), from, fmt, args)
 
 /* Shell quoting
  *
@@ -799,8 +820,7 @@ load_options(void)
        config_lineno = 0;
        config_errors = FALSE;
 
-       if (!home ||
-           snprintf(buf, sizeof(buf), "%s/.tigrc", home) >= sizeof(buf))
+       if (!home || !string_format(buf, "%s/.tigrc", home))
                return ERR;
 
        /* It's ok that the file doesn't exist. */
@@ -877,7 +897,7 @@ struct view_ops {
        /* Draw one line; @lineno must be < view->height. */
        bool (*draw)(struct view *view, struct line *line, unsigned int lineno);
        /* Read one line; updates view->line. */
-       bool (*read)(struct view *view, struct line *prev, char *data);
+       bool (*read)(struct view *view, char *data);
        /* Depending on view, change display based on current line. */
        bool (*enter)(struct view *view, struct line *line);
 };
@@ -1272,8 +1292,7 @@ begin_update(struct view *view)
        } else {
                const char *format = view->cmd_env ? view->cmd_env : view->cmd_fmt;
 
-               if (snprintf(view->cmd, sizeof(view->cmd), format,
-                            id, id, id, id, id) >= sizeof(view->cmd))
+               if (!string_format(view->cmd, format, id, id, id, id, id))
                        return FALSE;
        }
 
@@ -1348,14 +1367,10 @@ update_view(struct view *view)
        while ((line = fgets(buffer, sizeof(buffer), view->pipe))) {
                int linelen = strlen(line);
 
-               struct line *prev = view->lines
-                                 ? &view->line[view->lines - 1]
-                                 : NULL;
-
                if (linelen)
                        line[linelen - 1] = 0;
 
-               if (!view->ops->read(view, prev, line))
+               if (!view->ops->read(view, line))
                        goto alloc_error;
 
                if (lines-- == 1)
@@ -1725,24 +1740,15 @@ add_pager_refs(struct view *view, struct line *line)
                return;
 
        do {
-               char *begin = "", *end = "";
-
-               if (refs[refpos]->tag) {
-                       begin = "[";
-                       end = "]";
-               }
+               struct ref *ref = refs[refpos];
+               char *fmt = ref->tag ? "%s[%s]" : "%s%s";
 
-               bufpos += snprintf(buf + bufpos, sizeof(buf) - bufpos,
-                                  "%s%s%s%s", sep, begin, refs[refpos]->name,
-                                  end);
-               if (bufpos >= sizeof(buf))
-                       break;
+               if (!string_format_from(buf, &bufpos, fmt, sep, ref->name))
+                       return;
                sep = ", ";
        } while (refs[refpos++]->next);
 
-       if (!bufpos ||
-           bufpos >= sizeof(buf) ||
-           !realloc_lines(view, view->line_size + 1))
+       if (!realloc_lines(view, view->line_size + 1))
                return;
 
        line = &view->line[view->lines];
@@ -1755,7 +1761,7 @@ add_pager_refs(struct view *view, struct line *line)
 }
 
 static bool
-pager_read(struct view *view, struct line *prev, char *data)
+pager_read(struct view *view, char *data)
 {
        struct line *line = &view->line[view->lines];
 
@@ -1921,10 +1927,11 @@ main_draw(struct view *view, struct line *line, unsigned int lineno)
 
 /* Reads git log --pretty=raw output and parses it into the commit struct. */
 static bool
-main_read(struct view *view, struct line *prev, char *line)
+main_read(struct view *view, char *line)
 {
        enum line_type type = get_line_type(line);
-       struct commit *commit;
+       struct commit *commit = view->lines
+                             ? view->line[view->lines - 1].data : NULL;
 
        switch (type) {
        case LINE_COMMIT:
@@ -1944,11 +1951,9 @@ main_read(struct view *view, struct line *prev, char *line)
                char *ident = line + STRING_SIZE("author ");
                char *end = strchr(ident, '<');
 
-               if (!prev)
+               if (!commit)
                        break;
 
-               commit = prev->data;
-
                if (end) {
                        for (; end > ident && isspace(end[-1]); end--) ;
                        *end = 0;
@@ -1987,11 +1992,9 @@ main_read(struct view *view, struct line *prev, char *line)
                break;
        }
        default:
-               if (!prev)
+               if (!commit)
                        break;
 
-               commit = prev->data;
-
                /* Fill in the commit title if it has not already been set. */
                if (commit->title[0])
                        break;
@@ -2163,8 +2166,7 @@ get_key(enum request request)
                if (!seq)
                        seq = "'?'";
 
-               pos += snprintf(buf + pos, sizeof(buf) - pos, "%s%s", sep, seq);
-               if (pos >= sizeof(buf))
+               if (!string_format_from(buf, &pos, "%s%s", sep, seq))
                        return "Too many keybindings!";
                sep = ", ";
        }
@@ -2192,23 +2194,22 @@ static void load_help_page(void)
                return;
        }
 
-       pager_read(view, NULL, "Quick reference for tig keybindings:");
+       pager_read(view, "Quick reference for tig keybindings:");
 
        for (i = 0; i < ARRAY_SIZE(req_info); i++) {
                char *key;
 
                if (!req_info[i].request) {
-                       pager_read(view, NULL, "");
-                       pager_read(view, NULL, req_info[i].help);
+                       pager_read(view, "");
+                       pager_read(view, req_info[i].help);
                        continue;
                }
 
                key = get_key(req_info[i].request);
-               if (snprintf(buf, sizeof(buf), "%-25s %s", key, req_info[i].help)
-                   >= sizeof(buf))
+               if (!string_format(buf, "%-25s %s", key, req_info[i].help))
                        continue;
 
-               pager_read(view, NULL, buf);
+               pager_read(view, buf);
        }
 }