summaryrefslogtreecommitdiff
path: root/regress/bin/ksh
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2016-01-12 09:00:40 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2016-01-12 09:00:40 +0000
commitd8bf7832c5513cf3e0f1c1f5c359bca3cd7d51c2 (patch)
treead610919e24464f483d544cb3f03268f434b391e /regress/bin/ksh
parent477603ca30b8337ca13db56b7c24efdb841009c0 (diff)
The ksh(1) vi editing mode code is much harder to understand than
the emacs editing mode code, so add a testsuite before touching it. To avoid having to deal with the horrendous low-level terminal handling and high-level command execution code, write the tests in unit test style rather than in integration test style, by providing minimal glue to run vi.c stand-alone. In case relevant internal interfaces in sh.c, edit.c, and friends are changed, the glue may need adjustment. Not testing completion and history at this time, only line editing.
Diffstat (limited to 'regress/bin/ksh')
-rw-r--r--regress/bin/ksh/Makefile4
-rw-r--r--regress/bin/ksh/vi/Makefile17
-rw-r--r--regress/bin/ksh/vi/config.h3
-rw-r--r--regress/bin/ksh/vi/edit.h36
-rw-r--r--regress/bin/ksh/vi/sh.h57
-rw-r--r--regress/bin/ksh/vi/test_vi.c76
-rw-r--r--regress/bin/ksh/vi/vi.sh186
7 files changed, 378 insertions, 1 deletions
diff --git a/regress/bin/ksh/Makefile b/regress/bin/ksh/Makefile
index 013cb72e9ff..21760565ae6 100644
--- a/regress/bin/ksh/Makefile
+++ b/regress/bin/ksh/Makefile
@@ -1,4 +1,6 @@
-# $OpenBSD: Makefile,v 1.8 2013/12/02 20:39:44 millert Exp $
+# $OpenBSD: Makefile,v 1.9 2016/01/12 09:00:39 schwarze Exp $
+
+SUBDIR += vi
REGRESS_TARGETS=check
KSH=/bin/ksh
diff --git a/regress/bin/ksh/vi/Makefile b/regress/bin/ksh/vi/Makefile
new file mode 100644
index 00000000000..5f69a2df223
--- /dev/null
+++ b/regress/bin/ksh/vi/Makefile
@@ -0,0 +1,17 @@
+# $OpenBSD: Makefile,v 1.1 2016/01/12 09:00:39 schwarze Exp $
+#
+# Author: Ingo Schwarze <schwarze@openbsd.org>, 2016. Public Domain.
+
+REGRESS_TARGETS = check
+PROG = test_vi
+SRCS = vi.c test_vi.c
+CPPFLAGS = -iquote ${.CURDIR}
+CLEANFILES = vi.c
+
+check test:
+ sh ${.CURDIR}/vi.sh
+
+vi.c: ${.CURDIR}/../../../../bin/ksh/vi.c
+ cp ${.CURDIR}/../../../../bin/ksh/vi.c .
+
+.include <bsd.regress.mk>
diff --git a/regress/bin/ksh/vi/config.h b/regress/bin/ksh/vi/config.h
new file mode 100644
index 00000000000..cf13af79db5
--- /dev/null
+++ b/regress/bin/ksh/vi/config.h
@@ -0,0 +1,3 @@
+#define VI 1
+#define EDIT 1
+#define HISTORY 1
diff --git a/regress/bin/ksh/vi/edit.h b/regress/bin/ksh/vi/edit.h
new file mode 100644
index 00000000000..c79d20052e1
--- /dev/null
+++ b/regress/bin/ksh/vi/edit.h
@@ -0,0 +1,36 @@
+/*
+ * This file is in the public domain.
+ * It contains parts from ksh/config.h, which is in the public domain,
+ * and additions by Ingo Schwarze <schwarze@openbsd.org> (2016),
+ * who places the additions in the public domain, too.
+ */
+
+#define BEL 0x07
+
+/* tty driver characters we are interested in */
+typedef struct {
+ int erase;
+ int kill;
+ int werase;
+ int intr;
+ int quit;
+ int eof;
+} X_chars;
+
+extern X_chars edchars;
+
+#define x_getc() getchar()
+#define x_flush()
+#define x_putc(c) putchar(c)
+#define x_puts(s) fputs(s, stdout)
+#define x_mode(a)
+#define promptlen(s, a) strlen(s)
+#define x_do_comment(a, b, c) -1
+#define x_print_expansions(a, b, c)
+#define x_cf_glob(a, b, c, d, e, f, g, h) 0
+#define x_longest_prefix(a, b) 0
+#define x_basename(a, b) 0
+#define x_free_words(a, b)
+#define x_escape(a, b, c) -1
+
+int x_vi(char *, size_t);
diff --git a/regress/bin/ksh/vi/sh.h b/regress/bin/ksh/vi/sh.h
new file mode 100644
index 00000000000..1f4f02836f5
--- /dev/null
+++ b/regress/bin/ksh/vi/sh.h
@@ -0,0 +1,57 @@
+/*
+ * This file is in the public domain.
+ * It contains parts from ksh/*.h, which are in the public domain,
+ * and additions by Ingo Schwarze <schwarze@openbsd.org> (2016),
+ * who places the additions in the public domain, too.
+ */
+
+#include <stdlib.h> /* for malloc(3) */
+#include <stdio.h> /* for snprintf(3) */
+
+/* sh.h */
+#define Flag(f) 0
+#define letnum(c) (isalnum((unsigned char)(c)))
+#define MIN_EDIT_SPACE 7
+#define x_cols 80
+
+/* sh.h version.c */
+extern const char ksh_version[];
+
+/* shf.h shf.c */
+#define shf_snprintf snprintf
+
+/* table.h table.c */
+struct tbl { /* table item */
+ int flag; /* flags */
+ union {
+ char *s; /* string */
+ } val; /* value */
+};
+#define ISSET 0
+extern const char *prompt;
+#define ktsearch(a, b, c) NULL
+
+/* lex.h lex.c */
+struct source { int line; };
+extern struct source *source;
+void pprompt(const char *, int);
+
+/* sh.h alloc.c */
+#define alloc(s, a) malloc(s)
+#define aresize(p, s, a) realloc(p, s)
+#define afree(p, a) free(p)
+
+/* sh.h history.c */
+#define histsave(a, b, c)
+char **histpos(void);
+#define histnum(a) 0
+#define findhist(a, b, c, d) -1
+
+/* sh.h io.c */
+#define internal_errorf(i, s) warnx(s)
+
+/* sh.h main.c */
+#define unwind(a) errx(1, "unwind")
+
+/* sh.h trap.c */
+#define trapsig(a) errx(1, "trapsig")
diff --git a/regress/bin/ksh/vi/test_vi.c b/regress/bin/ksh/vi/test_vi.c
new file mode 100644
index 00000000000..86b9359a3de
--- /dev/null
+++ b/regress/bin/ksh/vi/test_vi.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Glue for unit tests of ksh(1) vi line editing mode.
+ * Takes input keystrokes from stdin.
+ * Only checks the final content of the line buffer
+ * and the bytes sent down to edit.c and shf.c,
+ * but not the operation of those low-level output routines.
+ */
+
+#include <err.h>
+#include <stdio.h>
+
+#include "edit.h"
+#include "sh.h"
+
+/* sh.h version.c */
+const char ksh_version[] = "@(#)PD KSH v5.2.14 99/07/13.2";
+
+/* table.h table.c */
+const char *prompt = " $ ";
+
+/* lex.h lex.c */
+static struct source __source;
+struct source *source = &__source;
+
+/* sh.h history.c */
+static char *history = NULL;
+
+/* edit.h edit.c */
+X_chars edchars = { 0x7f, 0x15, 0x17, 0x03, 0x1c, 0x04 };
+
+int
+main(void)
+{
+ char buf[2048]; /* vi.c CMDLEN */
+ int len;
+
+ if ((len = x_vi(buf, sizeof(buf))) == -1)
+ errx(1, "x_vi failed");
+
+ buf[len] = '\0';
+ fputs(buf, stdout);
+
+ return 0;
+}
+
+/* lex.h lex.c, used in vi_pprompt() */
+void
+pprompt(const char *cp, int ntruncate)
+{
+ while (ntruncate-- > 0 && *cp != '\0')
+ cp++;
+ fputs(cp, stdout);
+}
+
+/* sh.h history.c, used in vi_cmd() grabhist() grabsearch() */
+char **
+histpos(void)
+{
+ return &history;
+}
diff --git a/regress/bin/ksh/vi/vi.sh b/regress/bin/ksh/vi/vi.sh
new file mode 100644
index 00000000000..13f38991d8c
--- /dev/null
+++ b/regress/bin/ksh/vi/vi.sh
@@ -0,0 +1,186 @@
+#!/bin/sh
+#
+# Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+testseq()
+{
+ stdin=$1
+ expected=`echo "$2"`
+ result=`echo "$stdin" | ./test_vi`
+ if [ "$result" != "${expected}" ]; then
+ echo input:
+ echo ">>>$stdin<<<"
+ echo -n "$stdin" | hexdump -C
+ echo expected:
+ echo ">>>$expected<<<"
+ echo -n "$expected" | hexdump -C
+ echo result:
+ echo ">>>$result<<<"
+ echo -n "$result" | hexdump -C
+ exit 1;
+ fi
+}
+
+# ^H, ^?: Erase.
+testseq "ab\bc" " $ ab\b \bc\r\nac"
+testseq "ab\0177c" " $ ab\b \bc\r\nac"
+
+# ^J, ^M: End of line.
+testseq "a\nab" " $ a\r\na"
+testseq "a\rab" " $ a\r\na"
+testseq "a\0033\nab" " $ a\b\r\na"
+testseq "a\0033\rab" " $ a\b\r\na"
+
+# ^U: Kill.
+testseq "ab\0033ic\0025d" " $ ab\bcb\b\b\bb \b\b\bdb\b\r\ndb"
+
+# ^V: Literal next.
+testseq "a\0026\0033b" " $ a^\b^[b\r\na\0033b"
+
+# ^W: Word erase.
+testseq "one two\0027rep" " $ one two\b\b\b \b\b\brep\r\none rep"
+
+# A: Append at end of line.
+# 0: Move to column 0.
+testseq "one\00330A two" " $ one\b\b\bone two\r\none two"
+testseq "one\003302A two\0033" " $ one\b\b\bone two two\b\r\none two two"
+
+# a: Append.
+# .: Redo.
+testseq "ab\00330axy" " $ ab\b\baxb\byb\b\r\naxyb"
+testseq "ab\003302axy\0033" " $ ab\b\baxb\byb\bxyb\b\b\r\naxyxyb"
+testseq "ab\00330axy\0033." " $ ab\b\baxb\byb\b\byxyb\b\b\r\naxyxyb"
+
+# B: Move back big word.
+testseq "one 2.0\0033BD" " $ one 2.0\b\b\b \b\b\b\b\r\none "
+
+# b: Move back word.
+# C: Change to end of line.
+# D: Delete to end of line.
+testseq "one ab.cd\0033bDa.\00332bD" \
+ " $ one ab.cd\b\b \b\b\b..\b\b\b\b \b\b\b\b\b\r\none "
+testseq "one two\0033bCrep" " $ one two\b\b\b \b\b\brep\r\none rep"
+
+# c: Change region.
+testseq "one two\0033cbrep" " $ one two\b\b\bo \b\b\bro\beo\bpo\b\r\none repo"
+testseq "one two\00332chx" " $ one two\b\b\bo \b\b\bxo\b\r\none xo"
+
+# d: Delete region.
+testseq "one two\0033db" " $ one two\b\b\bo \b\b\b\r\none o"
+testseq "one two xy\00332db" \
+ " $ one two xy\b\b\b\b\b\by \b\b\b\b\b\b\r\none y"
+
+# E: Move to end of big word.
+testseq "1.00 two\00330ED" " $ 1.00 two\b\r $ 1.0 \b\b\b\b\b\b\r\n1.0"
+
+# e: Move to end of word.
+testseq "onex two\00330eD" " $ onex two\b\r $ one \b\b\b\b\b\b\r\none"
+
+# F: Find character backward.
+# ;: Repeat last search.
+# ,: Repeat last search in opposite direction.
+testseq "hello\00332FlD" " $ hello\b\b\b \b\b\b\b\r\nhe"
+testseq "hello\0033Flix\0033;ix" \
+ " $ hello\b\bxlo\b\b\b\bxlxlo\b\b\b\b\r\nhexlxlo"
+testseq "hello\00332Flix\00332,ix" \
+ " $ hello\b\b\bxllo\b\b\b\bxlxlo\b\b\r\nhexlxlo"
+
+# f: Find character forward.
+testseq "hello\003302flD" " $ hello\b\b\b\b\bhel \b\b\b\r\nhel"
+
+# h, ^H: Move left.
+# i: Insert.
+testseq "hello\00332hix" " $ hello\b\b\bxllo\b\b\b\r\nhexllo"
+testseq "hello\00332\b2ix\0033" \
+ " $ hello\b\b\bxllo\b\b\bxllo\b\b\b\b\r\nhexxllo"
+
+# I: Insert before first non-blank.
+# ^: Move to the first non-whitespace character.
+testseq " ab\0033Ixy" " $ ab\b\bxab\b\byab\b\b\r\n xyab"
+testseq " ab\00332Ixy\0033" " $ ab\b\bxab\b\byab\b\bxyab\b\b\b\r\n xyxyab"
+testseq " ab\0033^ixy" " $ ab\b\bxab\b\byab\b\b\r\n xyab"
+
+# L: Undefined command (beep).
+testseq "ab\0033Lx" " $ ab\b\a \b\b\r\na"
+
+# l, space: Move right.
+# ~: Change case.
+testseq "abc\003302l~" " $ abc\b\b\babC\b\r\nabC"
+testseq "abc\00330 rx" " $ abc\b\b\bax\b\r\naxc"
+
+# P: Paste at current position.
+testseq "abcde\0033hDhP" " $ abcde\b\b \b\b\b\bdebc\b\b\r\nadebc"
+testseq "abcde\0033hDh2P" " $ abcde\b\b \b\b\b\bdedebc\b\b\b\r\nadedebc"
+
+# p: Paste after current position.
+testseq "abcd\0033hDhp" " $ abcd\b\b \b\b\b\bacdb\b\b\r\nacdb"
+testseq "abcd\0033hDh2p" " $ abcd\b\b \b\b\b\bacdcdb\b\b\r\nacdcdb"
+
+# R: Replace.
+testseq "abcd\00332h2Rx\0033" " $ abcd\b\b\bxx\b\r\naxxd"
+testseq "abcdef\00334h2Rxy\0033" " $ abcdef\b\b\b\b\bxyxy\b\r\naxyxyf"
+
+# r: Replace character.
+testseq "abcd\00332h2rxiy" " $ abcd\b\b\bxx\byxd\b\b\r\naxyxd"
+
+# S: Substitute whole line.
+testseq "oldst\0033Snew" " $ oldst\b\b\b\b\b \r $ new\r\nnew"
+testseq "oldstr\033Snew" " $ oldstr\b\r $ \r $ new\r\nnew"
+
+# s: Substitute.
+testseq "abcd\00332h2sx" " $ abcd\b\b\bd \b\b\bxd\b\r\naxd"
+
+# T: Move backward after character.
+testseq "helloo\0033TlD" " $ helloo\b\b \b\b\b\r\nhell"
+testseq "hello\00332TlD" " $ hello\b\b \b\b\b\r\nhel"
+
+# t: Move forward before character.
+testseq "abc\00330tcD" " $ abc\b\b\ba \b\b\b\r\na"
+testseq "hello\003302tlD" " $ hello\b\b\b\b\bhe \b\b\b\b\r\nhe"
+
+# U: Undo all changes.
+testseq "test\0033U" " $ test\b\b\b\b \b\b\b\b\r\n"
+
+# u: Undo.
+testseq "test\0033hxu" " $ test\b\bt \b\bst\b\b\r\ntest"
+
+# W: Move forward big word.
+testseq "1.0 two\00330WD" " $ 1.0 two\b\r $ 1.0 \b\b\b\b\r\n1.0 "
+
+# w: Move forward word.
+testseq "ab cd ef\003302wD" " $ ab cd ef\b\r $ ab cd \b\b\b\r\nab cd "
+
+# X: Delete previous character.
+testseq "abcd\00332X" " $ abcd\b\b\bd \b\b\b\r\nad"
+
+# x: Delete character.
+# |: Move to column.
+testseq "abcd\00332|2x" " $ abcd\b\b\bd \b\b\b\r\nad"
+
+# Y: Yank to end of line.
+testseq "abcd\0033hYp" " $ abcd\b\bccdd\b\b\r\nabccdd"
+
+# y: Yank region.
+# $: Move to the last character.
+testseq "abcd\00332h2ylp" " $ abcd\b\b\bbbccd\b\b\b\r\nabbccd"
+testseq "abcd\00332h2yl\$p" " $ abcd\b\b\bbcdbc\b\r\nabcdbc"
+
+# %: Find match.
+testseq "(x)\0033%lrc" " $ (x)\b\b\b(c\b\r\n(c)"
+testseq "(x)\00330%hrc" " $ (x)\b\b\b(x\bc\b\r\n(c)"
+
+# ^L, ^R: Redraw.
+testseq "test\0033\0014" " $ test\b\r\n $ test\b\r\ntest"
+testseq "test\0033h\0022" " $ test\b\b\r\n $ test\b\b\r\ntest"