{
struct stream s;
s.len = end - start;
- s.body = xmalloc(s.len);
+ s.body = xmalloc(s.len+1);
fseek(f, start, 0);
if (fread(s.body, 1, s.len, f) != (size_t)s.len)
die();
+ /* ensure string is 'nul' terminated - for sscanf */
+ s.body[s.len] = 0;
return s;
}
struct merge *m)
{
pos->o++;
- while (1) {
+ while (pos->m < 0 || m[pos->m].type != End) {
int l = 0; /* Length remaining in current merge section */
if (pos->m >= 0)
switch (pos->s) {
struct merge *m)
{
if (pos->s == 0) {
- if (ends_mline(fm.list[m[pos->m].a + pos->o]))
+ if (m[pos->m].a + pos->o < fm.elcnt &&
+ ends_mline(fm.list[m[pos->m].a + pos->o]))
pos->lineno--;
if (pos->lineno & 1)
pos->lineno--;
*/
static int visible(int mode, struct merge *m, struct mpos *pos)
{
- enum mergetype type = m[pos->p.m].type;
+ enum mergetype type;
int stream = pos->p.s;
unsigned int ignore;
if (mode == 0)
return -1;
+ if (pos->p.m < 0)
+ type = End;
+ else
+ type = m[pos->p.m].type;
/* mode can be any combination of ORIG RESULT BEFORE AFTER */
switch (type) {
case End: /* The END is always visible */
struct elmnt e;
int unmatched = 0;
+ if (pos.p.m < 0)
+ return 0;
do {
if (m[pos.p.m].type == Changed && !m[pos.p.m].ignored)
rv |= CHANGES;
rv |= WIGGLED;
} else if (m[pos.p.m].type == Unmatched)
unmatched = 1;
+
if (m[pos.p.m].in_conflict &&
+ ((m[pos.p.m].type == Changed && !m[pos.p.m].ignored) ||
+ m[pos.p.m].type == Unchanged) &&
(pos.p.o < m[pos.p.m].lo ||
pos.p.o > m[pos.p.m].hi))
rv |= CONFLICTED | CHANGES;
sprintf(saveall_buf, saveall_msg,
cnt, cnt == 1 ? "" : "s", cnt+any);
ans = help_window(saveall_query, NULL, 1);
- }
+ } else
+ ans = 0;
if (ans < 0)
break;
if (ans) {