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
*
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. */
/* 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);
};
} 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;
}
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)
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];
}
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];
/* 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:
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;
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;
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 = ", ";
}
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);
}
}