> In the long run, the error could be removed entirely by making > dired behave like the rest of mg -- that is, abort somewhere up > the stream if lalloc fails. This way the rest of the functions > will never have to worry about a NULL ltext.
Actually, this seems to be the case already. dired calls addline, which never adds a broken line to the buffer. dired_() on the other hand has a buffer on the stack, and if that didn't work, we'd never reach warpdot. The NULL check isn't needed. New version. Index: dired.c =================================================================== RCS file: /cvs/src/usr.bin/mg/dired.c,v retrieving revision 1.48 diff -u -p -r1.48 dired.c --- dired.c 23 Jan 2011 00:45:03 -0000 1.48 +++ dired.c 27 Aug 2011 13:04:49 -0000 @@ -36,6 +36,11 @@ static int d_rename(int, int); static int d_shell_command(int, int); static int d_create_directory(int, int); static int d_makename(struct line *, char *, size_t); +static int d_warpdot(const char *); +static int d_forwpage(int, int); +static int d_backpage(int, int); +static int d_forwline(int, int); +static int d_backline(int, int); static void reaper(int); extern struct keymap_s helpmap, cXmap, metamap; @@ -57,15 +62,15 @@ static PF dirednul[] = { static PF diredcl[] = { reposition, /* ^L */ d_findfile, /* ^M */ - forwline, /* ^N */ + d_forwline, /* ^N */ rescan, /* ^O */ - backline, /* ^P */ + d_backline, /* ^P */ rescan, /* ^Q */ backisearch, /* ^R */ forwisearch, /* ^S */ rescan, /* ^T */ universal_argument, /* ^U */ - forwpage, /* ^V */ + d_forwpage, /* ^V */ rescan, /* ^W */ NULL /* ^X */ }; @@ -77,7 +82,7 @@ static PF diredcz[] = { rescan, /* ^] */ rescan, /* ^^ */ rescan, /* ^_ */ - forwline, /* SP */ + d_forwline, /* SP */ d_shell_command, /* ! */ rescan, /* " */ rescan, /* # */ @@ -99,9 +104,9 @@ static PF diredc[] = { }; static PF diredn[] = { - forwline, /* n */ + d_forwline, /* n */ d_ffotherwindow, /* o */ - backline, /* p */ + d_backline, /* p */ rescan, /* q */ d_rename, /* r */ rescan, /* s */ @@ -116,13 +121,32 @@ static PF direddl[] = { d_undelbak /* del */ }; +static PF diredbp[] = { + d_backpage /* v */ +}; + +static PF dirednull[] = { + NULL +}; + #ifndef DIRED_XMAPS #define NDIRED_XMAPS 0 /* number of extra map sections */ #endif /* DIRED_XMAPS */ -static struct KEYMAPE (6 + NDIRED_XMAPS + IMAPEXT) diredmap = { - 6 + NDIRED_XMAPS, - 6 + NDIRED_XMAPS + IMAPEXT, +static struct KEYMAPE (1 + IMAPEXT) d_backpagemap = { + 1, + 1 + IMAPEXT, + rescan, + { + { + 'v', 'v', diredbp, NULL + } + } +}; + +static struct KEYMAPE (7 + NDIRED_XMAPS + IMAPEXT) diredmap = { + 7 + NDIRED_XMAPS, + 7 + NDIRED_XMAPS + IMAPEXT, rescan, { #ifndef NO_HELP @@ -138,6 +162,10 @@ static struct KEYMAPE (6 + NDIRED_XMAPS CCHR('L'), CCHR('X'), diredcl, (KEYMAP *) & cXmap }, { + CCHR('['), CCHR('['), dirednull, (KEYMAP *) & + d_backpagemap + }, + { CCHR('Z'), '+', diredcz, (KEYMAP *) & metamap }, { @@ -592,6 +620,59 @@ d_makename(struct line *lp, char *fn, si return ((lgetc(lp, 2) == 'd') ? TRUE : FALSE); } +static int +d_warpdot(const char *l_text) +{ + const char *tp = l_text; + int field = 0; + + /* + * Find the byte offset to the (space-delimited) filename + * field in formatted ls output. + */ + while (*tp != '\0') { + if (*tp == ' ') { + tp += strspn(tp, " "); + if (++field == 9) + break; + } + tp++; + } + return (tp - l_text); +} + +static int +d_forwpage(int f, int n) +{ + forwpage(f | FFRAND, n); + curwp->w_doto = d_warpdot(curwp->w_dotp->l_text); + return (TRUE); +} + +static int +d_backpage (int f, int n) +{ + backpage(f | FFRAND, n); + curwp->w_doto = d_warpdot(curwp->w_dotp->l_text); + return (TRUE); +} + +static int +d_forwline (int f, int n) +{ + forwline(f | FFRAND, n); + curwp->w_doto = d_warpdot(curwp->w_dotp->l_text); + return (TRUE); +} + +static int +d_backline (int f, int n) +{ + backline(f | FFRAND, n); + curwp->w_doto = d_warpdot(curwp->w_dotp->l_text); + return (TRUE); +} + /* * XXX dname needs to have enough place to store an additional '/'. */ @@ -649,9 +730,8 @@ dired_(char *dname) if ((strrchr(line,' ')) != NULL) { if (strcmp((strrchr(line,' '))," ..") == 0) warp = counter - 1; - } - if ((strrchr(line,' ')) != NULL) - bp->b_doto = strrchr(line,' ') - line + 1; + } + bp->b_doto = d_warpdot(line); if (pclose(dirpipe) == -1) { ewprintf("Problem closing pipe to ls : %s", strerror(errno));