diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2010-06-30 19:12:55 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2010-06-30 19:12:55 +0000 |
commit | 7d45cd200192690f14f5236f5236109ff5c2918d (patch) | |
tree | a2babc9150c1aa4d1e0190cc0b4e7f9ce6aacc7d /usr.bin/mg | |
parent | fd958fd3dc98447a7b243a4eaf0190304f53bf61 (diff) |
you keep saying LIST_END. I do not think it means what you think it
means.
If we hit an OOM condition, mg started to try and dump the older undo buffer
entries in order to be able to continue. OTOH, it was grabbing this entry with
LIST_END, which like all *_END() list macros evaluates to NULL.
Do what we actually want and switch that list to a TAILQ and use
TAILQ_LAST to grab the last entry.
Wrote this a loooooong time ago after a mail from Matthew Dempsky on
bugs@. ok kjell@, beck@ also looked at this months ago and thought it
was alright.
Diffstat (limited to 'usr.bin/mg')
-rw-r--r-- | usr.bin/mg/buffer.c | 9 | ||||
-rw-r--r-- | usr.bin/mg/def.h | 7 | ||||
-rw-r--r-- | usr.bin/mg/undo.c | 42 |
3 files changed, 30 insertions, 28 deletions
diff --git a/usr.bin/mg/buffer.c b/usr.bin/mg/buffer.c index 948ce608942..4e8134e080a 100644 --- a/usr.bin/mg/buffer.c +++ b/usr.bin/mg/buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.c,v 1.73 2009/06/05 18:37:13 deraadt Exp $ */ +/* $OpenBSD: buffer.c,v 1.74 2010/06/30 19:12:54 oga Exp $ */ /* This file is in the public domain. */ @@ -198,9 +198,10 @@ killbuffer(struct buffer *bp) bp1->b_altb = (bp->b_altb == bp1) ? NULL : bp->b_altb; bp1 = bp1->b_bufp; } - rec = LIST_FIRST(&bp->b_undo); + rec = TAILQ_FIRST(&bp->b_undo); + while (rec != NULL) { - next = LIST_NEXT(rec, next); + next = TAILQ_NEXT(rec, next); free_undo_record(rec); rec = next; } @@ -535,7 +536,7 @@ bnew(const char *bname) bp->b_nwnd = 0; bp->b_headp = lp; bp->b_nmodes = defb_nmodes; - LIST_INIT(&bp->b_undo); + TAILQ_INIT(&bp->b_undo); bp->b_undoptr = NULL; memset(&bp->b_undopos, 0, sizeof(bp->b_undopos)); i = 0; diff --git a/usr.bin/mg/def.h b/usr.bin/mg/def.h index b1f2af8b008..f6e8a0eb599 100644 --- a/usr.bin/mg/def.h +++ b/usr.bin/mg/def.h @@ -1,4 +1,4 @@ -/* $OpenBSD: def.h,v 1.112 2009/06/05 18:02:06 kjell Exp $ */ +/* $OpenBSD: def.h,v 1.113 2010/06/30 19:12:54 oga Exp $ */ /* This file is in the public domain. */ @@ -234,6 +234,7 @@ struct mgwin { #define WEPHEM 0x01 /* Window is ephemeral. */ struct undo_rec; +TAILQ_HEAD(undoq, undo_rec); /* * Text is kept in buffers. A buffer header, described @@ -260,7 +261,7 @@ struct buffer { char b_fname[NFILEN]; /* File name */ char b_cwd[NFILEN]; /* working directory */ struct fileinfo b_fi; /* File attributes */ - LIST_HEAD(, undo_rec) b_undo; /* Undo actions list */ + struct undoq b_undo; /* Undo actions list */ int b_undopos; /* Where we were during last undo */ struct undo_rec *b_undoptr; int b_dotline; /* Line number of dot */ @@ -287,7 +288,7 @@ struct buffer { * This structure holds information about recent actions for the Undo command. */ struct undo_rec { - LIST_ENTRY(undo_rec) next; + TAILQ_ENTRY(undo_rec) next; enum { INSERT = 1, DELETE, diff --git a/usr.bin/mg/undo.c b/usr.bin/mg/undo.c index c3e13b9b1c7..1efd2a1851c 100644 --- a/usr.bin/mg/undo.c +++ b/usr.bin/mg/undo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: undo.c,v 1.49 2009/06/05 18:02:06 kjell Exp $ */ +/* $OpenBSD: undo.c,v 1.50 2010/06/30 19:12:54 oga Exp $ */ /* * This file is in the public domain */ @@ -11,7 +11,7 @@ /* * Local variables */ -static LIST_HEAD(, undo_rec) undo_free; +static struct undoq undo_free; static int undo_free_num; static int boundary_flag = TRUE; static int undo_enable_flag = TRUE; @@ -82,9 +82,10 @@ new_undo_record(void) { struct undo_rec *rec; - rec = LIST_FIRST(&undo_free); + rec = TAILQ_FIRST(&undo_free); if (rec != NULL) { - LIST_REMOVE(rec, next); /* Remove it from the free-list */ + /* Remove it from the free-list */ + TAILQ_REMOVE(&undo_free, rec, next); undo_free_num--; } else { if ((rec = malloc(sizeof(*rec))) == NULL) @@ -104,7 +105,7 @@ free_undo_record(struct undo_rec *rec) * On the first run, do initialisation of the free list. */ if (initialised == 0) { - LIST_INIT(&undo_free); + TAILQ_INIT(&undo_free); initialised = 1; } if (rec->content != NULL) { @@ -117,7 +118,7 @@ free_undo_record(struct undo_rec *rec) } undo_free_num++; - LIST_INSERT_HEAD(&undo_free, rec, next); + TAILQ_INSERT_HEAD(&undo_free, rec, next); } /* @@ -129,10 +130,10 @@ drop_oldest_undo_record(void) { struct undo_rec *rec; - rec = LIST_END(&curbp->b_undo); + rec = TAILQ_LAST(&curbp->b_undo, undoq); if (rec != NULL) { undo_free_num--; - LIST_REMOVE(rec, next); + TAILQ_REMOVE(&curbp->b_undo, rec, next); free_undo_record(rec); return (1); } @@ -144,7 +145,7 @@ lastrectype(void) { struct undo_rec *rec; - if ((rec = LIST_FIRST(&curbp->b_undo)) != NULL) + if ((rec = TAILQ_FIRST(&curbp->b_undo)) != NULL) return (rec->type); return (0); } @@ -227,7 +228,7 @@ undo_add_boundary(int f, int n) rec = new_undo_record(); rec->type = BOUNDARY; - LIST_INSERT_HEAD(&curbp->b_undo, rec, next); + TAILQ_INSERT_HEAD(&curbp->b_undo, rec, next); return (TRUE); } @@ -243,7 +244,7 @@ undo_add_modified(void) rec = new_undo_record(); rec->type = MODIFIED; - LIST_INSERT_HEAD(&curbp->b_undo, rec, next); + TAILQ_INSERT_HEAD(&curbp->b_undo, rec, next); return; } @@ -266,7 +267,7 @@ undo_add_insert(struct line *lp, int offset, int size) /* * We try to reuse the last undo record to `compress' things. */ - rec = LIST_FIRST(&curbp->b_undo); + rec = TAILQ_FIRST(&curbp->b_undo); if (rec != NULL && rec->type == INSERT) { if (rec->pos + rec->region.r_size == pos) { rec->region.r_size += reg.r_size; @@ -285,7 +286,7 @@ undo_add_insert(struct line *lp, int offset, int size) undo_add_boundary(FFRAND, 1); - LIST_INSERT_HEAD(&curbp->b_undo, rec, next); + TAILQ_INSERT_HEAD(&curbp->b_undo, rec, next); return (TRUE); } @@ -311,7 +312,7 @@ undo_add_delete(struct line *lp, int offset, int size, int isreg) if (offset == llength(lp)) /* if it's a newline... */ undo_add_boundary(FFRAND, 1); - else if ((rec = LIST_FIRST(&curbp->b_undo)) != NULL) { + else if ((rec = TAILQ_FIRST(&curbp->b_undo)) != NULL) { /* * Separate this command from the previous one if we're not * just before the previous record... @@ -340,7 +341,7 @@ undo_add_delete(struct line *lp, int offset, int size, int isreg) if (isreg || lastrectype() != DELETE) undo_add_boundary(FFRAND, 1); - LIST_INSERT_HEAD(&curbp->b_undo, rec, next); + TAILQ_INSERT_HEAD(&curbp->b_undo, rec, next); return (TRUE); } @@ -393,8 +394,7 @@ undo_dump(int f, int n) } num = 0; - for (rec = LIST_FIRST(&curbp->b_undo); rec != NULL; - rec = LIST_NEXT(rec, next)) { + TAILQ_FOREACH(rec, &curbp->b_undo, next) { num++; snprintf(buf, sizeof(buf), "%d:\t %s at %d ", num, @@ -477,7 +477,7 @@ undo(int f, int n) /* first invocation, make ptr point back to the top of the list */ if ((ptr == NULL && nulled == TRUE) || rptcount == 0) { - ptr = LIST_FIRST(&curbp->b_undo); + ptr = TAILQ_FIRST(&curbp->b_undo); nulled = TRUE; } @@ -485,8 +485,8 @@ undo(int f, int n) while (n--) { /* if we have a spurious boundary, free it and move on.... */ while (ptr && ptr->type == BOUNDARY) { - nptr = LIST_NEXT(ptr, next); - LIST_REMOVE(ptr, next); + nptr = TAILQ_NEXT(ptr, next); + TAILQ_REMOVE(&curbp->b_undo, ptr, next); free_undo_record(ptr); ptr = nptr; } @@ -565,7 +565,7 @@ undo(int f, int n) } /* And move to next record */ - ptr = LIST_NEXT(ptr, next); + ptr = TAILQ_NEXT(ptr, next); } while (ptr != NULL && !done); boundary_flag = save; |