The warpdot() has at least one issue. It leads to
segfaults if you try to open a directory like (BCD).
Try mkdir \(BCD\) and then reading the contents
of it.
Here's what I get:
drwxr-xr-x 2 root wheel 512 Aug 25 01:09 sh: syntax error: `('
unexpected-rw-r--r-- 1 root wheel 0 Aug 24 18:39 (x
Segmentation fault (core dumped) 0 Aug 27 20:01 .
# -rw-r--r-- 1 root wheel 4 Aug 24 18:40 .(x
Here's one of my diffs:
Index: src/usr.bin/mg/dired.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/dired.c,v
retrieving revision 1.48
diff -u -p -r1.48 dired.c
--- src/usr.bin/mg/dired.c 23 Jan 2011 00:45:03 -0000 1.48
+++ src/usr.bin/mg/dired.c 27 Aug 2011 15:59:07 -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(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,83 @@ d_makename(struct line *lp, char *fn, si
return ((lgetc(lp, 2) == 'd') ? TRUE : FALSE);
}
+static int
+d_warpdot(char *l_text)
+{
+ char *track, *anchor;
+ int col = 0;
+ int i = 0;
+ anchor = NULL;
+ track = l_text;
+
+ while (*track != '\0') {
+ if((i = strspn(track, " ")) > 0) {
+ track += i;
+ if (++col == 9) {
+ anchor = track;
+ break;
+ }
+ }
+ track++;
+ }
+ if (anchor == NULL)
+ return (-1);
+ else
+ return (track - l_text);
+}
+
+static int
+d_forwpage(int f, int n)
+{
+ int i;
+
+ forwpage(f | FFRAND, n);
+ if ((i = d_warpdot(curwp->w_dotp->l_text)) == -1)
+ curwp->w_doto = 0;
+ else
+ curwp->w_doto = i;
+ return TRUE;
+}
+
+static int
+d_backpage (int f, int n)
+{
+ int i;
+
+ backpage(f | FFRAND, n);
+ if ((i = d_warpdot(curwp->w_dotp->l_text)) == -1)
+ curwp->w_doto = 0;
+ else
+ curwp->w_doto = i;
+ return TRUE;
+}
+
+static int
+d_forwline (int f, int n)
+{
+ int i;
+
+ forwline(f | FFRAND, n);
+ if ((i = d_warpdot(curwp->w_dotp->l_text)) == -1)
+ curwp->w_doto = 0;
+ else
+ curwp->w_doto = i;
+ return TRUE;
+}
+
+static int
+d_backline (int f, int n)
+{
+ int i;
+
+ backline(f | FFRAND, n);
+ if ((i = d_warpdot(curwp->w_dotp->l_text)) == -1)
+ curwp->w_doto = 0;
+ else
+ curwp->w_doto = i;
+ return TRUE;
+}
+
/*
* XXX dname needs to have enough place to store an additional '/'.
*/
@@ -601,7 +706,7 @@ dired_(char *dname)
struct buffer *bp;
FILE *dirpipe;
char line[256];
- int len, ret, counter, warp;
+ int len, ret, counter, warp, i;
counter = 0;
warp = 0;
@@ -649,9 +754,11 @@ 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;
+ }
+ if ((i = d_warpdot(line)) == -1)
+ bp->b_doto = 0;
+ else
+ bp->b_doto = i;
if (pclose(dirpipe) == -1) {
ewprintf("Problem closing pipe to ls : %s",
strerror(errno));
Here's the output:
ed
mg doesn't segfault.
Here's a snippet from ntpd.c
if ((pw = getpwnam(NTPD_USER)) == NULL)
errx(1, "unknown user %s", NTPD_USER);
When you're designing functions, you should account for
error values as well. -1 is used by most code written
from scratch in base. Your warpdot() works differently
and doesn't quite conform to style. You're assigning
a value to a variable without checking if this is correct
or not. This style is hard to read according to me.
mg wasn't written from scratch by the openbsd ppl. It was
imported. By Making minimum assumptions, and inserting
checks wherever sensible, makes mg easier to extend & debug :)