Imported Upstream version 20110905
Andreas Beckmann
9 years ago
15 | 15 | |
16 | 16 | CC= gcc |
17 | 17 | CFLAGS?= -O2 -pipe |
18 | CFLAGS+= -g -Wall -Werror | |
18 | CFLAGS+= -g -Wall -Werror -Wno-error=unused-but-set-variable | |
19 | 19 | LIBS= -lncurses |
20 | 20 | |
21 | 21 | INSTALL= /usr/bin/install |
0 | /* $OpenBSD: buffer.c,v 1.75 2011/01/18 17:35:42 lum Exp $ */ | |
0 | /* $OpenBSD: buffer.c,v 1.77 2011/01/23 00:45:03 kjell Exp $ */ | |
1 | 1 | |
2 | 2 | /* This file is in the public domain. */ |
3 | 3 |
59 | 59 | #endif |
60 | 60 | return 0;} |
61 | 61 | EOF |
62 | ! gcc -Wall testfile.c -o testfile 2>&3 | |
62 | ! ${CC:-gcc} -Wall testfile.c -o testfile 2>&3 | |
63 | 63 | } |
64 | 64 | |
65 | 65 | note 'internal arc4random' |
68 | 68 | int main(void) |
69 | 69 | {arc4random();return 0;} |
70 | 70 | EOF |
71 | if gcc testfile.c -o testfile 2>&3; then | |
71 | if ${CC:-gcc} testfile.c -o testfile 2>&3; then | |
72 | 72 | echo Found. |
73 | 73 | add_inc HAVE_ARC4RANDOM |
74 | 74 | else |
80 | 80 | int main(void) |
81 | 81 | {arc4random();return 0;} |
82 | 82 | EOF |
83 | if gcc -larc4random testfile.c -o testfile 2>&3; then | |
83 | if ${CC:-gcc} -larc4random testfile.c -o testfile 2>&3; then | |
84 | 84 | echo Found. |
85 | 85 | add_inc HAVE_ARC4RANDOM_EXT |
86 | 86 | extralibs="$extralibs -larc4random" |
96 | 96 | int main(void) |
97 | 97 | {strtonum(NULL, 1, 1, NULL);return 0;} |
98 | 98 | EOF |
99 | if gcc -Wall testfile.c -o testfile 2>&3; then | |
99 | if ${CC:-gcc} -Wall testfile.c -o testfile 2>&3; then | |
100 | 100 | echo 'Found.' |
101 | 101 | else |
102 | 102 | echo 'Not Found, adding.' |
111 | 111 | int main(void) |
112 | 112 | {strlcpy(NULL, NULL, 1);return 0;} |
113 | 113 | EOF |
114 | if gcc -Wall testfile.c -o testfile 2>&3; then | |
114 | if ${CC:-gcc} -Wall testfile.c -o testfile 2>&3; then | |
115 | 115 | echo 'Found.' |
116 | 116 | else |
117 | 117 | echo 'Not Found, adding.' |
125 | 125 | int main(void) |
126 | 126 | {strlcat(NULL, NULL, 1);return 0;} |
127 | 127 | EOF |
128 | if gcc -Wall testfile.c -o testfile 2>&3; then | |
128 | if ${CC:-gcc} -Wall testfile.c -o testfile 2>&3; then | |
129 | 129 | echo 'Found.' |
130 | 130 | else |
131 | 131 | echo 'Not Found, adding.' |
139 | 139 | int main(void) |
140 | 140 | {fgetln(NULL, NULL);return 0;} |
141 | 141 | EOF |
142 | if gcc -Wall testfile.c -o testfile 2>&3; then | |
142 | if ${CC:-gcc} -Wall testfile.c -o testfile 2>&3; then | |
143 | 143 | echo 'Found.' |
144 | 144 | else |
145 | 145 | echo 'Not Found, adding.' |
155 | 155 | int main(void) |
156 | 156 | {return 0;} |
157 | 157 | EOF |
158 | if gcc -Wno-strict-aliasing testfile.c -o testfile 2>&3; then | |
158 | if ${CC:-gcc} -Wno-strict-aliasing testfile.c -o testfile 2>&3; then | |
159 | 159 | echo 'Works OK.' |
160 | 160 | extraflags="$extraflags -Wno-strict-aliasing" |
161 | 161 | else |
209 | 209 | int main(void) |
210 | 210 | {return 0;} |
211 | 211 | EOF |
212 | if gcc -Wall testfile.c -o testfile 2>&3; then | |
212 | if ${CC:-gcc} -Wall testfile.c -o testfile 2>&3; then | |
213 | 213 | if [ -x testfile.exe ]; then |
214 | 214 | echo 'Yes.' |
215 | 215 | exe_ext='.exe' |
224 | 224 | |
225 | 225 | # Suppress DLL auto-import error when linking on Cygwin |
226 | 226 | if uname -s | grep -q '^CYGWIN' ; then |
227 | extralibs="$extralibs -Wl,--enable-auto-import" | |
227 | extralibs="$extralibs -Wl,--enable-auto-import -Wno-char-subscripts" | |
228 | 228 | fi |
229 | 229 | |
230 | 230 |
0 | /* $OpenBSD: def.h,v 1.115 2011/01/18 16:25:40 kjell Exp $ */ | |
0 | /* $OpenBSD: def.h,v 1.116 2011/01/23 00:45:03 kjell Exp $ */ | |
1 | 1 | |
2 | 2 | /* This file is in the public domain. */ |
3 | 3 | |
360 | 360 | int makebkfile(int, int); |
361 | 361 | int writeout(struct buffer *, char *); |
362 | 362 | void upmodes(struct buffer *); |
363 | size_t xbasename(char *, const char *, size_t); | |
363 | 364 | |
364 | 365 | /* line.c X */ |
365 | 366 | struct line *lalloc(int); |
0 | /* $OpenBSD: dired.c,v 1.47 2011/01/18 17:35:42 lum Exp $ */ | |
0 | /* $OpenBSD: dired.c,v 1.50 2011/08/31 03:40:53 lum Exp $ */ | |
1 | 1 | |
2 | 2 | /* This file is in the public domain. */ |
3 | 3 | |
4 | 4 | /* dired module for mg 2a |
5 | 5 | * by Robert A. Larson |
6 | 6 | */ |
7 | ||
8 | #include "libgen.h" | |
9 | 7 | |
10 | 8 | #include "def.h" |
11 | 9 | #include "funmap.h" |
21 | 19 | #include <signal.h> |
22 | 20 | #include <fcntl.h> |
23 | 21 | #include <errno.h> |
22 | #include <libgen.h> | |
23 | #include <stdarg.h> | |
24 | 24 | |
25 | 25 | void dired_init(void); |
26 | 26 | static int dired(int, int); |
33 | 33 | static int d_copy(int, int); |
34 | 34 | static int d_del(int, int); |
35 | 35 | static int d_rename(int, int); |
36 | static int d_exec(int, struct buffer *, const char *, const char *, ...); | |
36 | 37 | static int d_shell_command(int, int); |
37 | 38 | static int d_create_directory(int, int); |
38 | 39 | static int d_makename(struct line *, char *, size_t); |
40 | static int d_warpdot(struct line *, int *); | |
41 | static int d_forwpage(int, int); | |
42 | static int d_backpage(int, int); | |
43 | static int d_forwline(int, int); | |
44 | static int d_backline(int, int); | |
39 | 45 | static void reaper(int); |
40 | 46 | |
41 | 47 | extern struct keymap_s helpmap, cXmap, metamap; |
57 | 63 | static PF diredcl[] = { |
58 | 64 | reposition, /* ^L */ |
59 | 65 | d_findfile, /* ^M */ |
60 | forwline, /* ^N */ | |
66 | d_forwline, /* ^N */ | |
61 | 67 | rescan, /* ^O */ |
62 | backline, /* ^P */ | |
68 | d_backline, /* ^P */ | |
63 | 69 | rescan, /* ^Q */ |
64 | 70 | backisearch, /* ^R */ |
65 | 71 | forwisearch, /* ^S */ |
66 | 72 | rescan, /* ^T */ |
67 | 73 | universal_argument, /* ^U */ |
68 | forwpage, /* ^V */ | |
74 | d_forwpage, /* ^V */ | |
69 | 75 | rescan, /* ^W */ |
70 | 76 | NULL /* ^X */ |
71 | 77 | }; |
77 | 83 | rescan, /* ^] */ |
78 | 84 | rescan, /* ^^ */ |
79 | 85 | rescan, /* ^_ */ |
80 | forwline, /* SP */ | |
86 | d_forwline, /* SP */ | |
81 | 87 | d_shell_command, /* ! */ |
82 | 88 | rescan, /* " */ |
83 | 89 | rescan, /* # */ |
99 | 105 | }; |
100 | 106 | |
101 | 107 | static PF diredn[] = { |
102 | forwline, /* n */ | |
108 | d_forwline, /* n */ | |
103 | 109 | d_ffotherwindow, /* o */ |
104 | backline, /* p */ | |
110 | d_backline, /* p */ | |
105 | 111 | rescan, /* q */ |
106 | 112 | d_rename, /* r */ |
107 | 113 | rescan, /* s */ |
116 | 122 | d_undelbak /* del */ |
117 | 123 | }; |
118 | 124 | |
125 | static PF diredbp[] = { | |
126 | d_backpage /* v */ | |
127 | }; | |
128 | ||
129 | static PF dirednull[] = { | |
130 | NULL | |
131 | }; | |
132 | ||
119 | 133 | #ifndef DIRED_XMAPS |
120 | 134 | #define NDIRED_XMAPS 0 /* number of extra map sections */ |
121 | 135 | #endif /* DIRED_XMAPS */ |
122 | 136 | |
123 | static struct KEYMAPE (6 + NDIRED_XMAPS + IMAPEXT) diredmap = { | |
124 | 6 + NDIRED_XMAPS, | |
125 | 6 + NDIRED_XMAPS + IMAPEXT, | |
137 | static struct KEYMAPE (1 + IMAPEXT) d_backpagemap = { | |
138 | 1, | |
139 | 1 + IMAPEXT, | |
140 | rescan, | |
141 | { | |
142 | { | |
143 | 'v', 'v', diredbp, NULL | |
144 | } | |
145 | } | |
146 | }; | |
147 | ||
148 | static struct KEYMAPE (7 + NDIRED_XMAPS + IMAPEXT) diredmap = { | |
149 | 7 + NDIRED_XMAPS, | |
150 | 7 + NDIRED_XMAPS + IMAPEXT, | |
126 | 151 | rescan, |
127 | 152 | { |
128 | 153 | #ifndef NO_HELP |
136 | 161 | #endif /* !NO_HELP */ |
137 | 162 | { |
138 | 163 | CCHR('L'), CCHR('X'), diredcl, (KEYMAP *) & cXmap |
164 | }, | |
165 | { | |
166 | CCHR('['), CCHR('['), dirednull, (KEYMAP *) & | |
167 | d_backpagemap | |
139 | 168 | }, |
140 | 169 | { |
141 | 170 | CCHR('Z'), '+', diredcz, (KEYMAP *) & metamap |
165 | 194 | funmap_add(d_findfile, "dired-find-file"); |
166 | 195 | funmap_add(d_ffotherwindow, "dired-find-file-other-window"); |
167 | 196 | funmap_add(d_del, "dired-flag-file-deleted"); |
197 | funmap_add(d_forwline, "dired-next-line"); | |
168 | 198 | funmap_add(d_otherwindow, "dired-other-window"); |
199 | funmap_add(d_backline, "dired-previous-line"); | |
169 | 200 | funmap_add(d_rename, "dired-rename-file"); |
201 | funmap_add(d_backpage, "dired-scroll-down"); | |
202 | funmap_add(d_forwpage, "dired-scroll-up"); | |
170 | 203 | funmap_add(d_undel, "dired-unflag"); |
171 | 204 | maps_add((KEYMAP *)&diredmap, "dired"); |
172 | 205 | dobindkey(fundamental_map, "dired", "^Xd"); |
335 | 368 | d_expunge(int f, int n) |
336 | 369 | { |
337 | 370 | struct line *lp, *nlp; |
338 | char fname[NFILEN]; | |
371 | char fname[NFILEN], sname[NFILEN]; | |
339 | 372 | |
340 | 373 | for (lp = bfirstlp(curbp); lp != curbp->b_headp; lp = nlp) { |
341 | 374 | nlp = lforw(lp); |
346 | 379 | return (FALSE); |
347 | 380 | case FALSE: |
348 | 381 | if (unlink(fname) < 0) { |
349 | ewprintf("Could not delete '%s'", | |
350 | basename(fname)); | |
382 | (void)xbasename(sname, fname, NFILEN); | |
383 | ewprintf("Could not delete '%s'", sname); | |
351 | 384 | return (FALSE); |
352 | 385 | } |
353 | 386 | break; |
354 | 387 | case TRUE: |
355 | 388 | if (rmdir(fname) < 0) { |
356 | ewprintf("Could not delete directory '%s'", | |
357 | basename(fname)); | |
389 | (void)xbasename(sname, fname, NFILEN); | |
390 | ewprintf("Could not delete directory " | |
391 | "'%s'", sname); | |
358 | 392 | return (FALSE); |
359 | 393 | } |
360 | 394 | break; |
371 | 405 | int |
372 | 406 | d_copy(int f, int n) |
373 | 407 | { |
374 | char frname[NFILEN], toname[NFILEN], *bufp; | |
408 | char frname[NFILEN], toname[NFILEN], sname[NFILEN], *bufp; | |
375 | 409 | int ret; |
376 | 410 | size_t off; |
377 | 411 | struct buffer *bp; |
385 | 419 | ewprintf("Directory name too long"); |
386 | 420 | return (FALSE); |
387 | 421 | } |
388 | if ((bufp = eread("Copy %s to: ", toname, sizeof(toname), | |
389 | EFDEF | EFNEW | EFCR, basename(frname))) == NULL) | |
422 | (void)xbasename(sname, frname, NFILEN); | |
423 | bufp = eread("Copy %s to: ", toname, sizeof(toname), | |
424 | EFDEF | EFNEW | EFCR, sname); | |
425 | if (bufp == NULL) | |
390 | 426 | return (ABORT); |
391 | 427 | else if (bufp[0] == '\0') |
392 | 428 | return (FALSE); |
405 | 441 | int ret; |
406 | 442 | size_t off; |
407 | 443 | struct buffer *bp; |
444 | char sname[NFILEN]; | |
408 | 445 | |
409 | 446 | if (d_makename(curwp->w_dotp, frname, sizeof(frname)) != FALSE) { |
410 | 447 | ewprintf("Not a file"); |
415 | 452 | ewprintf("Directory name too long"); |
416 | 453 | return (FALSE); |
417 | 454 | } |
418 | if ((bufp = eread("Rename %s to: ", toname, | |
419 | sizeof(toname), EFDEF | EFNEW | EFCR, basename(frname))) == NULL) | |
455 | (void)xbasename(sname, frname, NFILEN); | |
456 | bufp = eread("Rename %s to: ", toname, | |
457 | sizeof(toname), EFDEF | EFNEW | EFCR, sname); | |
458 | if (bufp == NULL) | |
420 | 459 | return (ABORT); |
421 | 460 | else if (bufp[0] == '\0') |
422 | 461 | return (FALSE); |
445 | 484 | int |
446 | 485 | d_shell_command(int f, int n) |
447 | 486 | { |
448 | char command[512], fname[MAXPATHLEN], buf[BUFSIZ], *bufp, *cp; | |
449 | int infd, fds[2]; | |
450 | pid_t pid; | |
451 | struct sigaction olda, newa; | |
487 | char command[512], fname[MAXPATHLEN], *bufp; | |
452 | 488 | struct buffer *bp; |
453 | 489 | struct mgwin *wp; |
454 | FILE *fin; | |
490 | char sname[NFILEN]; | |
455 | 491 | |
456 | 492 | bp = bfind("*Shell Command Output*", TRUE); |
457 | 493 | if (bclear(bp) != TRUE) |
463 | 499 | } |
464 | 500 | |
465 | 501 | command[0] = '\0'; |
466 | if ((bufp = eread("! on %s: ", command, sizeof(command), EFNEW, | |
467 | basename(fname))) == NULL) | |
468 | return (ABORT); | |
469 | infd = open(fname, O_RDONLY); | |
470 | if (infd == -1) { | |
502 | (void)xbasename(sname, fname, NFILEN); | |
503 | bufp = eread("! on %s: ", command, sizeof(command), EFNEW, sname); | |
504 | if (bufp == NULL) | |
505 | return (ABORT); | |
506 | ||
507 | if (d_exec(0, bp, fname, "sh", "-c", command, NULL) != TRUE) | |
508 | return (ABORT); | |
509 | ||
510 | if ((wp = popbuf(bp, WNONE)) == NULL) | |
511 | return (ABORT); /* XXX - free the buffer?? */ | |
512 | curwp = wp; | |
513 | curbp = wp->w_bufp; | |
514 | return (TRUE); | |
515 | } | |
516 | ||
517 | /* | |
518 | * Pipe input file to cmd and insert the command's output in the | |
519 | * given buffer. Each line will be prefixed with the given | |
520 | * number of spaces. | |
521 | */ | |
522 | static int | |
523 | d_exec(int space, struct buffer *bp, const char *input, const char *cmd, ...) | |
524 | { | |
525 | char buf[BUFSIZ]; | |
526 | va_list ap; | |
527 | struct sigaction olda, newa; | |
528 | char **argv = NULL, *cp; | |
529 | FILE *fin; | |
530 | int fds[2] = { -1, -1 }; | |
531 | int infd = -1; | |
532 | int ret = (ABORT), n; | |
533 | pid_t pid; | |
534 | ||
535 | if (sigaction(SIGCHLD, NULL, &olda) == -1) | |
536 | return (ABORT); | |
537 | ||
538 | /* Find the number of arguments. */ | |
539 | va_start(ap, cmd); | |
540 | for (n = 2; va_arg(ap, char *) != NULL; n++) | |
541 | ; | |
542 | va_end(ap); | |
543 | ||
544 | /* Allocate and build the argv. */ | |
545 | if ((argv = calloc(n, sizeof(*argv))) == NULL) { | |
546 | ewprintf("Can't allocate argv : %s", strerror(errno)); | |
547 | goto out; | |
548 | } | |
549 | ||
550 | n = 1; | |
551 | argv[0] = (char *)cmd; | |
552 | va_start(ap, cmd); | |
553 | while ((argv[n] = va_arg(ap, char *)) != NULL) | |
554 | n++; | |
555 | va_end(ap); | |
556 | ||
557 | if (input == NULL) | |
558 | input = "/dev/null"; | |
559 | ||
560 | if ((infd = open(input, O_RDONLY)) == -1) { | |
471 | 561 | ewprintf("Can't open input file : %s", strerror(errno)); |
472 | return (FALSE); | |
473 | } | |
562 | goto out; | |
563 | } | |
564 | ||
474 | 565 | if (pipe(fds) == -1) { |
475 | 566 | ewprintf("Can't create pipe : %s", strerror(errno)); |
476 | close(infd); | |
477 | return (FALSE); | |
567 | goto out; | |
478 | 568 | } |
479 | 569 | |
480 | 570 | newa.sa_handler = reaper; |
481 | 571 | newa.sa_flags = 0; |
482 | if (sigaction(SIGCHLD, &newa, &olda) == -1) { | |
483 | close(infd); | |
484 | close(fds[0]); | |
485 | close(fds[1]); | |
486 | return (ABORT); | |
487 | } | |
488 | pid = fork(); | |
572 | if (sigaction(SIGCHLD, &newa, NULL) == -1) | |
573 | goto out; | |
574 | ||
575 | if ((pid = fork()) == -1) { | |
576 | ewprintf("Can't fork"); | |
577 | goto out; | |
578 | } | |
579 | ||
489 | 580 | switch (pid) { |
490 | case -1: | |
491 | ewprintf("Can't fork"); | |
492 | return (ABORT); | |
493 | case 0: | |
581 | case 0: /* Child */ | |
494 | 582 | close(fds[0]); |
495 | 583 | dup2(infd, STDIN_FILENO); |
496 | 584 | dup2(fds[1], STDOUT_FILENO); |
497 | 585 | dup2(fds[1], STDERR_FILENO); |
498 | execl("/bin/sh", "sh", "-c", bufp, (char *)NULL); | |
586 | if (execvp(argv[0], argv) == -1) | |
587 | ewprintf("Can't exec %s: %s", argv[0], strerror(errno)); | |
499 | 588 | exit(1); |
500 | 589 | break; |
501 | default: | |
590 | default: /* Parent */ | |
502 | 591 | close(infd); |
503 | 592 | close(fds[1]); |
504 | fin = fdopen(fds[0], "r"); | |
505 | if (fin == NULL) /* "r" is surely a valid mode! */ | |
506 | panic("can't happen"); | |
593 | infd = fds[1] = -1; | |
594 | if ((fin = fdopen(fds[0], "r")) == NULL) | |
595 | goto out; | |
507 | 596 | while (fgets(buf, sizeof(buf), fin) != NULL) { |
508 | 597 | cp = strrchr(buf, '\n'); |
509 | 598 | if (cp == NULL && !feof(fin)) { /* too long a line */ |
510 | 599 | int c; |
511 | addlinef(bp, "%s...", buf); | |
600 | addlinef(bp, "%*s%s...", space, "", buf); | |
512 | 601 | while ((c = getc(fin)) != EOF && c != '\n') |
513 | 602 | ; |
514 | 603 | continue; |
515 | 604 | } else if (cp) |
516 | 605 | *cp = '\0'; |
517 | addline(bp, buf); | |
606 | addlinef(bp, "%*s%s", space, "", buf); | |
518 | 607 | } |
519 | 608 | fclose(fin); |
520 | close(fds[0]); | |
521 | 609 | break; |
522 | 610 | } |
523 | wp = popbuf(bp, WNONE); | |
524 | if (wp == NULL) | |
525 | return (ABORT); /* XXX - free the buffer?? */ | |
526 | curwp = wp; | |
527 | curbp = wp->w_bufp; | |
611 | ret = (TRUE); | |
612 | ||
613 | out: | |
528 | 614 | if (sigaction(SIGCHLD, &olda, NULL) == -1) |
529 | 615 | ewprintf("Warning, couldn't reset previous signal handler"); |
530 | return (TRUE); | |
616 | if (fds[0] != -1) | |
617 | close(fds[0]); | |
618 | if (fds[1] != -1) | |
619 | close(fds[1]); | |
620 | if (infd != -1) | |
621 | close(infd); | |
622 | if (argv != NULL) | |
623 | free(argv); | |
624 | return ret; | |
531 | 625 | } |
532 | 626 | |
533 | 627 | /* ARGSUSED */ |
555 | 649 | return (showbuffer(bp, curwp, WFFULL | WFMODE)); |
556 | 650 | } |
557 | 651 | |
558 | #define NAME_FIELD 8 | |
559 | ||
560 | 652 | static int |
561 | 653 | d_makename(struct line *lp, char *fn, size_t len) |
562 | 654 | { |
563 | int i; | |
564 | char *p, *ep; | |
565 | ||
566 | if (strlcpy(fn, curbp->b_fname, len) >= len) | |
567 | return (FALSE); | |
568 | if ((p = lp->l_text) == NULL) | |
569 | return (ABORT); | |
570 | ep = lp->l_text + llength(lp); | |
571 | p++; /* skip action letter, if any */ | |
572 | for (i = 0; i < NAME_FIELD; i++) { | |
573 | while (p < ep && isspace(*p)) | |
574 | p++; | |
575 | while (p < ep && !isspace(*p)) | |
576 | p++; | |
577 | while (p < ep && isspace(*p)) | |
578 | p++; | |
579 | if (p == ep) | |
580 | return (ABORT); | |
581 | } | |
582 | if (strlcat(fn, p, len) >= len) | |
583 | return (FALSE); | |
655 | int start, nlen; | |
656 | char *namep; | |
657 | ||
658 | if (d_warpdot(lp, &start) == FALSE) | |
659 | return (ABORT); | |
660 | namep = &lp->l_text[start]; | |
661 | nlen = llength(lp) - start; | |
662 | ||
663 | if (snprintf(fn, len, "%s%.*s", curbp->b_fname, nlen, namep) >= len) | |
664 | return (ABORT); /* Name is too long. */ | |
665 | ||
666 | /* Return TRUE if the entry is a directory. */ | |
584 | 667 | return ((lgetc(lp, 2) == 'd') ? TRUE : FALSE); |
668 | } | |
669 | ||
670 | #define NAME_FIELD 9 | |
671 | ||
672 | static int | |
673 | d_warpdot(struct line *dotp, int *doto) | |
674 | { | |
675 | char *tp = dotp->l_text; | |
676 | int off = 0, field = 0, len; | |
677 | ||
678 | /* | |
679 | * Find the byte offset to the (space-delimited) filename | |
680 | * field in formatted ls output. | |
681 | */ | |
682 | len = llength(dotp); | |
683 | while (off < len) { | |
684 | if (tp[off++] == ' ') { | |
685 | if (++field == NAME_FIELD) { | |
686 | *doto = off; | |
687 | return (TRUE); | |
688 | } | |
689 | /* Skip the space. */ | |
690 | while (off < len && tp[off] == ' ') | |
691 | off++; | |
692 | } | |
693 | } | |
694 | /* We didn't find the field. */ | |
695 | *doto = 0; | |
696 | return (FALSE); | |
697 | } | |
698 | ||
699 | static int | |
700 | d_forwpage(int f, int n) | |
701 | { | |
702 | forwpage(f | FFRAND, n); | |
703 | return (d_warpdot(curwp->w_dotp, &curwp->w_doto)); | |
704 | } | |
705 | ||
706 | static int | |
707 | d_backpage (int f, int n) | |
708 | { | |
709 | backpage(f | FFRAND, n); | |
710 | return (d_warpdot(curwp->w_dotp, &curwp->w_doto)); | |
711 | } | |
712 | ||
713 | static int | |
714 | d_forwline (int f, int n) | |
715 | { | |
716 | forwline(f | FFRAND, n); | |
717 | return (d_warpdot(curwp->w_dotp, &curwp->w_doto)); | |
718 | } | |
719 | ||
720 | static int | |
721 | d_backline (int f, int n) | |
722 | { | |
723 | backline(f | FFRAND, n); | |
724 | return (d_warpdot(curwp->w_dotp, &curwp->w_doto)); | |
585 | 725 | } |
586 | 726 | |
587 | 727 | /* |
591 | 731 | dired_(char *dname) |
592 | 732 | { |
593 | 733 | struct buffer *bp; |
594 | FILE *dirpipe; | |
595 | char line[256]; | |
596 | int len, ret, counter, warp; | |
597 | counter = 0; | |
598 | warp = 0; | |
734 | int len, i; | |
599 | 735 | |
600 | 736 | if ((fopen(dname,"r")) == NULL) { |
601 | 737 | if (errno == EACCES) |
620 | 756 | return (NULL); |
621 | 757 | bp->b_flag |= BFREADONLY; |
622 | 758 | |
623 | #ifdef GNU_LS | |
624 | # ifdef __CYGWIN__ | |
625 | /* On Windows platforms the user or group name can be two | |
626 | * words, such as "Domain Users" or "First Last." So, we must | |
627 | * use the --numeric-uid-gid option of ls, or else we don't | |
628 | * know where the filename starts. | |
629 | */ | |
630 | ret = snprintf(line, sizeof(line), | |
631 | "ls -aln --time-style='+%%b %%d %%H:%%M' '%s'", dname); | |
632 | # else | |
633 | ret = snprintf(line, sizeof(line), | |
634 | "ls -al --time-style='+%%b %%d %%H:%%M' '%s'", dname); | |
635 | # endif | |
636 | #else | |
637 | ret = snprintf(line, sizeof(line), "ls -al '%s'", dname); | |
638 | #endif /* GNU_LS */ | |
639 | ||
640 | if (ret < 0 || ret >= sizeof(line)) { | |
641 | ewprintf("Path too long"); | |
759 | if ((d_exec(2, bp, NULL, "ls", "-al", dname, NULL)) != TRUE) | |
642 | 760 | return (NULL); |
643 | } | |
644 | if ((dirpipe = popen(line, "r")) == NULL) { | |
645 | ewprintf("Problem opening pipe to ls"); | |
646 | return (NULL); | |
647 | } | |
648 | line[0] = line[1] = ' '; | |
649 | while (fgets(&line[2], sizeof(line) - 2, dirpipe) != NULL) { | |
650 | line[strcspn(line, "\n")] = '\0'; /* remove ^J */ | |
651 | (void) addline(bp, line); | |
652 | if ((strrchr(line,' ')) != NULL) { | |
653 | counter++; | |
654 | if ((strcmp((strrchr(line,' '))," ..")) == 0) | |
655 | warp = counter; | |
656 | } | |
657 | } | |
658 | if ((strrchr(line,' ')) != NULL) { | |
659 | if (strcmp((strrchr(line,' '))," ..") == 0) | |
660 | warp = counter - 1; | |
661 | } | |
662 | if ((strrchr(line,' ')) != NULL) | |
663 | bp->b_doto = strrchr(line,' ') - line + 1; | |
664 | if (pclose(dirpipe) == -1) { | |
665 | ewprintf("Problem closing pipe to ls : %s", | |
666 | strerror(errno)); | |
667 | return (NULL); | |
668 | } | |
761 | ||
762 | /* Find the line with ".." on it. */ | |
669 | 763 | bp->b_dotp = bfirstlp(bp); |
670 | while (warp--) | |
671 | bp->b_dotp = lforw(bp->b_dotp); | |
764 | for (i = 0; i < bp->b_lines; i++) { | |
765 | bp->b_dotp = lforw(bp->b_dotp); | |
766 | if (d_warpdot(bp->b_dotp, &bp->b_doto) == FALSE) | |
767 | continue; | |
768 | if (strcmp(ltext(bp->b_dotp) + bp->b_doto, "..") == 0) | |
769 | break; | |
770 | } | |
771 | ||
772 | /* We want dot on the entry right after "..", if possible. */ | |
773 | if (++i < bp->b_lines - 2) | |
774 | bp->b_dotp = lforw(bp->b_dotp); | |
775 | d_warpdot(bp->b_dotp, &bp->b_doto); | |
776 | ||
672 | 777 | (void)strlcpy(bp->b_fname, dname, sizeof(bp->b_fname)); |
673 | 778 | (void)strlcpy(bp->b_cwd, dname, sizeof(bp->b_cwd)); |
674 | 779 | if ((bp->b_modes[1] = name_mode("dired")) == NULL) { |
0 | /* $OpenBSD: extend.c,v 1.50 2006/12/30 14:11:06 martin Exp $ */ | |
0 | /* $OpenBSD: extend.c,v 1.51 2011/01/21 19:10:13 kjell Exp $ */ | |
1 | 1 | |
2 | 2 | /* This file is in the public domain. */ |
3 | 3 | |
4 | 4 | /* |
5 | 5 | * Extended (M-X) commands, rebinding, and startup file processing. |
6 | 6 | */ |
7 | #include <sys/types.h> | |
8 | #include <ctype.h> | |
9 | ||
10 | 7 | #include "chrdef.h" |
11 | 8 | #include "def.h" |
12 | 9 | #include "kbd.h" |
13 | 10 | #include "funmap.h" |
11 | ||
12 | #include <sys/types.h> | |
13 | #include <ctype.h> | |
14 | 14 | |
15 | 15 | #ifndef NO_MACRO |
16 | 16 | #include "macro.h" |
0 | /* $OpenBSD: file.c,v 1.73 2011/01/18 16:29:37 kjell Exp $ */ | |
0 | /* $OpenBSD: file.c,v 1.76 2011/08/31 08:58:29 lum Exp $ */ | |
1 | 1 | |
2 | 2 | /* This file is in the public domain. */ |
3 | 3 | |
5 | 5 | * File commands. |
6 | 6 | */ |
7 | 7 | |
8 | #include "libgen.h" | |
9 | 8 | #include "def.h" |
10 | 9 | |
11 | static char *xdirname(const char *); | |
10 | #include <libgen.h> | |
11 | ||
12 | size_t xdirname(char *, const char *, size_t); | |
12 | 13 | |
13 | 14 | /* |
14 | 15 | * Insert a file into the current buffer. Real easy - just call the |
210 | 211 | if (bclear(curbp) != TRUE) |
211 | 212 | return (TRUE); |
212 | 213 | /* Clear readonly. May be set by autoexec path */ |
213 | curbp->b_flag &=~ BFREADONLY; | |
214 | curbp->b_flag &= ~BFREADONLY; | |
214 | 215 | if ((status = insertfile(fname, fname, TRUE)) != TRUE) { |
215 | 216 | ewprintf("File is not readable: %s", fname); |
216 | 217 | return (FALSE); |
290 | 291 | int nbytes, s, nline = 0, siz, x, x2; |
291 | 292 | int opos; /* offset we started at */ |
292 | 293 | int oline; /* original line number */ |
293 | char *dp; | |
294 | 294 | |
295 | 295 | if (replacebuf == TRUE) |
296 | 296 | x = undo_enable(FFRAND, 0); |
309 | 309 | bp = curbp; |
310 | 310 | if (newname != NULL) { |
311 | 311 | (void)strlcpy(bp->b_fname, newname, sizeof(bp->b_fname)); |
312 | dp = xdirname(newname); | |
313 | (void)strlcpy(bp->b_cwd, dp, sizeof(bp->b_cwd)); | |
312 | (void)xdirname(bp->b_cwd, newname, sizeof(bp->b_cwd)); | |
314 | 313 | (void)strlcat(bp->b_cwd, "/", sizeof(bp->b_cwd)); |
315 | free(dp); | |
316 | 314 | } |
317 | 315 | |
318 | 316 | /* hard file open */ |
333 | 331 | goto cleanup; |
334 | 332 | } |
335 | 333 | killbuffer(bp); |
336 | if ((bp = dired_(fname)) == NULL) | |
334 | bp = dired_(fname); | |
335 | undo_enable(FFRAND, x); | |
336 | if (bp == NULL) | |
337 | 337 | return (FALSE); |
338 | undo_enable(FFRAND, x); | |
339 | 338 | curbp = bp; |
340 | 339 | return (showbuffer(bp, curwp, WFFULL | WFMODE)); |
341 | 340 | } else { |
342 | dp = xdirname(fname); | |
343 | (void)strlcpy(bp->b_cwd, dp, sizeof(bp->b_cwd)); | |
341 | (void)xdirname(bp->b_cwd, fname, sizeof(bp->b_cwd)); | |
344 | 342 | (void)strlcat(bp->b_cwd, "/", sizeof(bp->b_cwd)); |
345 | free(dp); | |
346 | 343 | } |
347 | 344 | opos = curwp->w_doto; |
348 | 345 | oline = curwp->w_dotline; |
416 | 413 | } |
417 | 414 | endoffile: |
418 | 415 | /* ignore errors */ |
419 | ffclose(NULL); | |
416 | (void)ffclose(NULL); | |
420 | 417 | /* don't zap an error */ |
421 | 418 | if (s == FIOEOF) { |
422 | 419 | if (nline == 1) |
573 | 570 | "Save anyway")) != TRUE) |
574 | 571 | return (s); |
575 | 572 | } |
576 | ||
573 | ||
577 | 574 | if (makebackup && (bp->b_flag & BFBAK)) { |
578 | 575 | s = fbackupfile(bp->b_fname); |
579 | 576 | /* hard error */ |
637 | 634 | s = ffclose(bp); |
638 | 635 | if (s == FIOSUC) |
639 | 636 | ewprintf("Wrote %s", fn); |
640 | } else | |
641 | /* ignore close error if it is a write error */ | |
637 | } else { | |
638 | /* print a message indicating write error */ | |
642 | 639 | (void)ffclose(bp); |
640 | ewprintf("Unable to write %s", fn); | |
641 | } | |
643 | 642 | (void)fupdstat(bp); |
644 | 643 | return (s == FIOSUC); |
645 | 644 | } |
659 | 658 | } |
660 | 659 | |
661 | 660 | /* |
662 | * Same as dirname, except an empty string is returned in | |
661 | * dirname using strlcpy semantic. | |
662 | * Like dirname() except an empty string is returned in | |
663 | 663 | * place of "/". This means we can always add a trailing |
664 | 664 | * slash and be correct. |
665 | * Unlike dirname, we allocate. Caller must free. | |
666 | */ | |
667 | static char * | |
668 | xdirname(const char *path) | |
669 | { | |
670 | char *dp; | |
671 | ||
672 | dp = strdup(path); | |
673 | dp = dirname(dp); | |
674 | if (*dp && dp[0] == '/' && dp[1] == '\0') | |
675 | return (strdup("")); | |
676 | ||
677 | return (strdup(dp)); | |
678 | } | |
665 | * Address portability issues by copying argument | |
666 | * before using. Some implementations modify the input string. | |
667 | */ | |
668 | size_t | |
669 | xdirname(char *dp, const char *path, size_t dplen) | |
670 | { | |
671 | char ts[NFILEN]; | |
672 | size_t len; | |
673 | ||
674 | (void)strlcpy(ts, path, NFILEN); | |
675 | len = strlcpy(dp, dirname(ts), dplen); | |
676 | if (dplen > 0 && dp[0] == '/' && dp[1] == '\0') { | |
677 | dp[0] = '\0'; | |
678 | len = 0; | |
679 | } | |
680 | return (len); | |
681 | } | |
682 | ||
683 | /* | |
684 | * basename using strlcpy/strlcat semantic. | |
685 | * Address portability issue by copying argument | |
686 | * before using: some implementations modify the input string. | |
687 | */ | |
688 | size_t | |
689 | xbasename(char *bp, const char *path, size_t bplen) | |
690 | { | |
691 | char ts[NFILEN]; | |
692 | ||
693 | (void)strlcpy(ts, path, NFILEN); | |
694 | return (strlcpy(bp, basename(ts), bplen)); | |
695 | } |
0 | /* $OpenBSD: fileio.c,v 1.82 2008/09/15 16:11:35 kjell Exp $ */ | |
0 | /* $OpenBSD: fileio.c,v 1.85 2011/08/31 08:58:29 lum Exp $ */ | |
1 | 1 | |
2 | 2 | /* This file is in the public domain. */ |
3 | 3 | |
5 | 5 | * POSIX fileio.c |
6 | 6 | */ |
7 | 7 | #include "def.h" |
8 | ||
9 | 8 | |
10 | 9 | #include <sys/types.h> |
11 | 10 | #include <sys/stat.h> |
83 | 82 | return (FIOERR); |
84 | 83 | } |
85 | 84 | ffstat(bp); |
86 | ffclose(bp); | |
85 | (void)ffclose(bp); | |
87 | 86 | return (FIOSUC); |
88 | 87 | } |
89 | 88 | |
130 | 129 | |
131 | 130 | /* |
132 | 131 | * Close a file. |
133 | * XXX - Should look at the status. | |
134 | 132 | */ |
135 | 133 | /* ARGSUSED */ |
136 | 134 | int |
137 | 135 | ffclose(struct buffer *bp) |
138 | 136 | { |
139 | (void) fclose(ffp); | |
140 | return (FIOSUC); | |
137 | if (fclose(ffp) == 0) | |
138 | return (FIOSUC); | |
139 | return (FIOERR); | |
141 | 140 | } |
142 | 141 | |
143 | 142 | /* |
0 | .\" $OpenBSD: mg.1,v 1.42 2008/11/06 14:04:48 sobrado Exp $ | |
0 | .\" $OpenBSD: mg.1,v 1.55 2011/09/02 02:37:52 lum Exp $ | |
1 | 1 | .\" This file is in the public domain. |
2 | 2 | .\" |
3 | .Dd $Mdocdate: January 2 2011 $ | |
3 | .Dd $Mdocdate: September 5 2011 $ | |
4 | 4 | .Dt MG 1 |
5 | 5 | .Os |
6 | 6 | .Sh NAME |
73 | 73 | .Nm , |
74 | 74 | not buffer-specific, as in other emacs flavours. |
75 | 75 | .Sh DEFAULT KEY BINDINGS |
76 | Normal editing commands are very similar to Gnu Emacs. | |
76 | Normal editing commands are very similar to GNU Emacs. | |
77 | 77 | In the following examples, C-x means Control-x, and M-x means Meta-x, |
78 | where the Meta key may be either a special key on your keyboard | |
78 | where the Meta key may be either a special key on the keyboard | |
79 | 79 | or the ALT key; otherwise ESC followed by the key X works as well. |
80 | 80 | .Pp |
81 | 81 | .Bl -tag -width xxxxxxxxxx -compact |
219 | 219 | end-of-buffer |
220 | 220 | .It M-\e |
221 | 221 | delete-horizontal-space |
222 | .It M-^ | |
223 | join-line | |
222 | 224 | .It M-b |
223 | 225 | backward-word |
224 | 226 | .It M-c |
229 | 231 | forward-word |
230 | 232 | .It M-l |
231 | 233 | downcase-word |
234 | .It M-m | |
235 | back-to-indentation | |
232 | 236 | .It M-q |
233 | 237 | fill-paragraph |
234 | 238 | .It M-r |
303 | 307 | to a new line. |
304 | 308 | .It auto-indent-mode |
305 | 309 | Toggle indent mode, where indentation is preserved after a newline. |
310 | .It back-to-indentation | |
311 | Move the dot to the first non-whitespace character on the current line. | |
306 | 312 | .It backward-char |
307 | 313 | Move cursor backwards one character. |
308 | 314 | .It backward-kill-word |
440 | 446 | Justify a paragraph, wrapping text at the current fill column. |
441 | 447 | .It find-file |
442 | 448 | Select a file for editing. |
443 | First check if you can find the file | |
444 | in another buffer; if you can find it, just switch to the buffer. | |
445 | If you cannot find the file, create a new buffer, read in the | |
449 | First check if the file can be found | |
450 | in another buffer; if it is there, just switch to that buffer. | |
451 | If the file cannot be found, create a new buffer, read in the | |
446 | 452 | file from disk, and switch to the new buffer. |
447 | 453 | .It find-file-read-only |
448 | 454 | Same as find-file, except the new buffer is set to read-only. |
505 | 511 | isearch ignores any explicit arguments. |
506 | 512 | If invoked during macro definition or evaluation, the non-incremental |
507 | 513 | search-forward is invoked instead. |
514 | .It join-line | |
515 | Join the current line to the previous. | |
516 | If called with an argument, | |
517 | join the next line to the current one. | |
508 | 518 | .It just-one-space |
509 | 519 | Delete any whitespace around dot, then insert a space. |
510 | 520 | .It keyboard-quit |
764 | 774 | upper case. |
765 | 775 | .It upcase-word |
766 | 776 | Move the cursor forward by the specified number of words. |
767 | As you move, convert any characters to upper case. | |
777 | As it moves, convert any characters to upper case. | |
768 | 778 | .It what-cursor-position |
769 | 779 | Display a bunch of useful information about the current location of |
770 | 780 | dot. |
793 | 803 | .Pa .mg-TERM . |
794 | 804 | Here, |
795 | 805 | .Ev TERM |
796 | represents the name of your terminal type; e.g., if your terminal type | |
806 | represents the name of the terminal type; e.g., if the terminal type | |
797 | 807 | is set to |
798 | 808 | .Dq vt100 , |
799 | 809 | .Nm |
815 | 825 | auto-execute *.c c-mode |
816 | 826 | .Ed |
817 | 827 | .Sh FILES |
818 | .Bl -tag -width ~/.mg-TERM -compact | |
828 | .Bl -tag -width /usr/share/doc/mg/tutorial -compact | |
819 | 829 | .It Pa ~/.mg |
820 | 830 | normal startup file |
821 | 831 | .It Pa ~/.mg-TERM |
822 | 832 | terminal-specific startup file |
833 | .It Pa /usr/share/doc/mg/tutorial | |
834 | concise tutorial | |
823 | 835 | .El |
824 | 836 | .Sh SEE ALSO |
825 | 837 | .Xr vi 1 |
826 | 838 | .Sh CAVEATS |
827 | 839 | Since it is written completely in C, there is currently no |
828 | language in which you can write extensions; | |
829 | however, you can rebind keys and change certain parameters | |
840 | language in which extensions can be written; | |
841 | however, keys can be rebound and certain parameters can be changed | |
830 | 842 | in startup files. |
831 | 843 | .Pp |
832 | 844 | In order to use 8-bit characters (such as German umlauts), the Meta key |
0 | /* $OpenBSD: random.c,v 1.29 2011/01/19 16:11:38 kjell Exp $ */ | |
0 | /* $OpenBSD: random.c,v 1.30 2011/01/21 19:10:13 kjell Exp $ */ | |
1 | 1 | |
2 | 2 | /* This file is in the public domain. */ |
3 | 3 | |
9 | 9 | */ |
10 | 10 | |
11 | 11 | #include "def.h" |
12 | ||
12 | 13 | #include <ctype.h> |
13 | 14 | |
14 | 15 | /* |
0 | /* $OpenBSD: re_search.c,v 1.25 2009/06/04 02:23:37 kjell Exp $ */ | |
0 | /* $OpenBSD: re_search.c,v 1.26 2011/01/21 19:10:13 kjell Exp $ */ | |
1 | 1 | |
2 | 2 | /* This file is in the public domain. */ |
3 | 3 |
0 | /* $OpenBSD: search.c,v 1.37 2009/06/04 02:23:37 kjell Exp $ */ | |
0 | /* $OpenBSD: search.c,v 1.38 2011/01/21 19:10:13 kjell Exp $ */ | |
1 | 1 | |
2 | 2 | /* This file is in the public domain. */ |
3 | 3 | |
11 | 11 | */ |
12 | 12 | |
13 | 13 | #include "def.h" |
14 | ||
14 | 15 | #include <ctype.h> |
15 | 16 | |
16 | 17 | #ifndef NO_MACRO |
0 | /* $OpenBSD: theo.c,v 1.120 2010/08/03 22:12:27 henning Exp $ */ | |
0 | /* $OpenBSD: theo.c,v 1.121 2011/07/08 00:27:59 djm Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2002 Artur Grabowski <art@openbsd.org> |
3 | 3 | * All rights reserved. |
205 | 205 | "You aren't being conservative -- you are trying to be a caveman.", |
206 | 206 | "nfs loves everyone", |
207 | 207 | "basically, dung beetles fucking. that's what kerberosV + openssl is like", |
208 | "I would rather run Windows than use vi." | |
208 | "I would rather run Windows than use vi.", | |
209 | "if you assign that responsibility to non-hikers I will walk over and cripple you now." | |
209 | 210 | }; |
210 | 211 | |
211 | 212 | static const int ntalk = sizeof(talk)/sizeof(talk[0]); |
0 | $Id: tutorial,v 1.4 2011/01/20 04:35:22 han Exp $ | |
0 | $Id: tutorial,v 1.5 2011/09/05 19:23:46 han Exp $ | |
1 | 1 | |
2 | 2 | The mg Tutorial |
3 | 3 | --------------- |
242 | 242 | In the middle of the screen, you should see the word "(fundamental)" which |
243 | 243 | indicates that the current editing mode is "fundamental-mode". The mg editor |
244 | 244 | also supports a c-mode that is more suited to editing C code. There are also |
245 | some other useful editing modes for different situations. See the man pages | |
245 | some other useful editing modes for different situations. See the man page | |
246 | 246 | for mg(1) to learn about the various editing modes. |
247 | 247 | |
248 | 248 | Opening and Saving Files |
315 | 315 | For instance, to replace text, you can type M-x repl TAB enter to execute |
316 | 316 | the replace-text command. To cancel this command, type C-g. |
317 | 317 | |
318 | To see a list of all available mg(1) commands, consult the man pages. | |
318 | To see a list of all available mg(1) commands, consult the man page. | |
319 | 319 | |
320 | 320 | Exiting mg |
321 | 321 | ---------- |
331 | 331 | ---------- |
332 | 332 | |
333 | 333 | This tutorial is meant to get new users up and running with mg. There is more |
334 | information available via the mg(1) man pages. If you have any suggestions for | |
334 | information available via the mg(1) man page. If you have any suggestions for | |
335 | 335 | improvement, please don't hesitate to drop a message or (better still) submit |
336 | a diff listing. | |
336 | a diff to tech@openbsd.org. | |
337 | 337 | |
338 | 338 | History |
339 | 339 | ------- |
359 | 359 | ----------- |
360 | 360 | |
361 | 361 | Original Author of this document: Mayukh Bose, |
362 | Date last updated: 2008-07-29 | |
362 | Date last updated: 2011-09-02 | |
363 | 363 | |
364 | 364 | Copyright |
365 | 365 | --------- |
0 | /* $OpenBSD: window.c,v 1.27 2009/06/04 23:39:37 kjell Exp $ */ | |
0 | /* $OpenBSD: window.c,v 1.28 2011/08/01 12:15:23 lum Exp $ */ | |
1 | 1 | |
2 | 2 | /* This file is in the public domain. */ |
3 | 3 | |
120 | 120 | return (TRUE); |
121 | 121 | } |
122 | 122 | |
123 | /* not in Gnu Emacs */ | |
123 | /* not in GNU Emacs */ | |
124 | 124 | /* |
125 | 125 | * This command makes the previous window (previous => up the screen) the |
126 | 126 | * current window. There are no errors, although the command does not do |
0 | /* $OpenBSD: yank.c,v 1.9 2009/06/05 18:02:06 kjell Exp $ */ | |
0 | /* $OpenBSD: yank.c,v 1.10 2011/07/15 16:50:52 deraadt Exp $ */ | |
1 | 1 | |
2 | 2 | /* This file is in the public domain. */ |
3 | 3 | |
168 | 168 | chunk = 1; |
169 | 169 | } |
170 | 170 | } else if (n > 0) { |
171 | chunk = llength(curwp->w_dotp) - curwp->w_doto + 1; | |
171 | chunk = llength(curwp->w_dotp) - curwp->w_doto; | |
172 | 172 | nextp = lforw(curwp->w_dotp); |
173 | if (nextp != curbp->b_headp) | |
174 | chunk++; /* newline */ | |
175 | if (nextp == curbp->b_headp) | |
176 | goto done; /* EOL */ | |
173 | 177 | i = n; |
174 | 178 | while (--i) { |
179 | chunk += llength(nextp); | |
180 | nextp = lforw(nextp); | |
181 | if (nextp != curbp->b_headp) | |
182 | chunk++; /* newline */ | |
175 | 183 | if (nextp == curbp->b_headp) |
176 | break; | |
177 | chunk += llength(nextp) + 1; | |
178 | nextp = lforw(nextp); | |
184 | break; /* EOL */ | |
179 | 185 | } |
180 | 186 | } else { |
181 | 187 | /* n <= 0 */ |
183 | 189 | curwp->w_doto = 0; |
184 | 190 | i = n; |
185 | 191 | while (i++) { |
186 | if (lback(curwp->w_dotp) == curbp->b_headp) | |
187 | break; | |
192 | if (lforw(curwp->w_dotp)) | |
193 | chunk++; | |
188 | 194 | curwp->w_dotp = lback(curwp->w_dotp); |
189 | 195 | curwp->w_rflag |= WFMOVE; |
190 | chunk += llength(curwp->w_dotp) + 1; | |
196 | chunk += llength(curwp->w_dotp); | |
191 | 197 | } |
192 | 198 | } |
193 | 199 | /* |
194 | 200 | * KFORW here is a bug. Should be KBACK/KFORW, but we need to |
195 | 201 | * rewrite the ldelete code (later)? |
196 | 202 | */ |
197 | return (ldelete(chunk, KFORW)); | |
203 | done: | |
204 | if (chunk) | |
205 | return (ldelete(chunk, KFORW)); | |
206 | return (TRUE); | |
198 | 207 | } |
199 | 208 | |
200 | 209 | /* |