svn commit: r352135 - in vendor/NetBSD/libedit/2019-09-10: . TEST readline
Baptiste Daroussin
bapt at FreeBSD.org
Tue Sep 10 13:56:37 UTC 2019
Author: bapt
Date: Tue Sep 10 13:56:36 2019
New Revision: 352135
URL: https://svnweb.freebsd.org/changeset/base/352135
Log:
Tag import of libedit snapshot 2019-09-10
Added:
vendor/NetBSD/libedit/2019-09-10/
- copied from r338453, vendor/NetBSD/libedit/dist/
vendor/NetBSD/libedit/2019-09-10/TEST/test_filecompletion.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/TEST/test_filecompletion.c
Replaced:
vendor/NetBSD/libedit/2019-09-10/TEST/Makefile
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/TEST/Makefile
vendor/NetBSD/libedit/2019-09-10/chared.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/chared.c
vendor/NetBSD/libedit/2019-09-10/chartype.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/chartype.c
vendor/NetBSD/libedit/2019-09-10/common.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/common.c
vendor/NetBSD/libedit/2019-09-10/editline.3
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/editline.3
vendor/NetBSD/libedit/2019-09-10/el.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/el.c
vendor/NetBSD/libedit/2019-09-10/el.h
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/el.h
vendor/NetBSD/libedit/2019-09-10/eln.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/eln.c
vendor/NetBSD/libedit/2019-09-10/filecomplete.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/filecomplete.c
vendor/NetBSD/libedit/2019-09-10/hist.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/hist.c
vendor/NetBSD/libedit/2019-09-10/history.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/history.c
vendor/NetBSD/libedit/2019-09-10/keymacro.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/keymacro.c
vendor/NetBSD/libedit/2019-09-10/literal.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/literal.c
vendor/NetBSD/libedit/2019-09-10/map.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/map.c
vendor/NetBSD/libedit/2019-09-10/parse.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/parse.c
vendor/NetBSD/libedit/2019-09-10/read.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/read.c
vendor/NetBSD/libedit/2019-09-10/readline.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/readline.c
vendor/NetBSD/libedit/2019-09-10/readline/readline.h
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/readline/readline.h
vendor/NetBSD/libedit/2019-09-10/refresh.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/refresh.c
vendor/NetBSD/libedit/2019-09-10/search.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/search.c
vendor/NetBSD/libedit/2019-09-10/shlib_version
- copied unchanged from r286801, vendor/NetBSD/libedit/dist/shlib_version
vendor/NetBSD/libedit/2019-09-10/terminal.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/terminal.c
vendor/NetBSD/libedit/2019-09-10/tty.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/tty.c
vendor/NetBSD/libedit/2019-09-10/tty.h
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/tty.h
vendor/NetBSD/libedit/2019-09-10/vi.c
- copied unchanged from r352134, vendor/NetBSD/libedit/dist/vi.c
Copied: vendor/NetBSD/libedit/2019-09-10/TEST/Makefile (from r352134, vendor/NetBSD/libedit/dist/TEST/Makefile)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ vendor/NetBSD/libedit/2019-09-10/TEST/Makefile Tue Sep 10 13:56:36 2019 (r352135, copy of r352134, vendor/NetBSD/libedit/dist/TEST/Makefile)
@@ -0,0 +1,13 @@
+# $NetBSD: Makefile,v 1.8 2017/10/15 18:59:00 abhinav Exp $
+
+NOMAN=1
+PROG=wtc1 test_filecompletion
+CPPFLAGS=-I${.CURDIR}/..
+LDADD+=-ledit -ltermlib
+DPADD+=${LIBEDIT} ${LIBTERMLIB}
+
+.ifdef DEBUG
+CPPFLAGS+=-DDEBUG
+.endif
+
+.include <bsd.prog.mk>
Copied: vendor/NetBSD/libedit/2019-09-10/TEST/test_filecompletion.c (from r352134, vendor/NetBSD/libedit/dist/TEST/test_filecompletion.c)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ vendor/NetBSD/libedit/2019-09-10/TEST/test_filecompletion.c Tue Sep 10 13:56:36 2019 (r352135, copy of r352134, vendor/NetBSD/libedit/dist/TEST/test_filecompletion.c)
@@ -0,0 +1,553 @@
+/* $NetBSD: test_filecompletion.c,v 1.5 2019/09/08 05:50:58 abhinav Exp $ */
+
+/*-
+ * Copyright (c) 2017 Abhinav Upadhyay <abhinav at NetBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <assert.h>
+#include <err.h>
+#include <stdio.h>
+#include <histedit.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include "filecomplete.h"
+#include "el.h"
+
+typedef struct {
+ const wchar_t *user_typed_text; /* The actual text typed by the user on the terminal */
+ const char *completion_function_input ; /*the text received by fn_filename_completion_function */
+ const char *expanded_text[2]; /* the value to which completion_function_input should be expanded */
+ const wchar_t *escaped_output; /* expected escaped value of expanded_text */
+} test_input;
+
+static test_input inputs[] = {
+ {
+ /* simple test for escaping angular brackets */
+ L"ls ang",
+ "ang",
+ {"ang<ular>test", NULL},
+ L"ls ang\\<ular\\>test "
+ },
+ {
+ /* test angular bracket inside double quotes: ls "dq_ang */
+ L"ls \"dq_ang",
+ "dq_ang",
+ {"dq_ang<ular>test", NULL},
+ L"ls \"dq_ang<ular>test\""
+ },
+ {
+ /* test angular bracket inside singlq quotes: ls "sq_ang */
+ L"ls 'sq_ang",
+ "sq_ang",
+ {"sq_ang<ular>test", NULL},
+ L"ls 'sq_ang<ular>test'"
+ },
+ {
+ /* simple test for backslash */
+ L"ls back",
+ "back",
+ {"backslash\\test", NULL},
+ L"ls backslash\\\\test "
+ },
+ {
+ /* backslash inside single quotes */
+ L"ls 'sback",
+ "sback",
+ {"sbackslash\\test", NULL},
+ L"ls 'sbackslash\\test'"
+ },
+ {
+ /* backslash inside double quotes */
+ L"ls \"dback",
+ "dback",
+ {"dbackslash\\test", NULL},
+ L"ls \"dbackslash\\\\test\""
+ },
+ {
+ /* test braces */
+ L"ls br",
+ "br",
+ {"braces{test}", NULL},
+ L"ls braces\\{test\\} "
+ },
+ {
+ /* test braces inside single quotes */
+ L"ls 'sbr",
+ "sbr",
+ {"sbraces{test}", NULL},
+ L"ls 'sbraces{test}'"
+ },
+ {
+ /* test braces inside double quotes */
+ L"ls \"dbr",
+ "dbr",
+ {"dbraces{test}", NULL},
+ L"ls \"dbraces{test}\""
+ },
+ {
+ /* test dollar */
+ L"ls doll",
+ "doll",
+ {"doll$artest", NULL},
+ L"ls doll\\$artest "
+ },
+ {
+ /* test dollar inside single quotes */
+ L"ls 'sdoll",
+ "sdoll",
+ {"sdoll$artest", NULL},
+ L"ls 'sdoll$artest'"
+ },
+ {
+ /* test dollar inside double quotes */
+ L"ls \"ddoll",
+ "ddoll",
+ {"ddoll$artest", NULL},
+ L"ls \"ddoll\\$artest\""
+ },
+ {
+ /* test equals */
+ L"ls eq",
+ "eq",
+ {"equals==test", NULL},
+ L"ls equals\\=\\=test "
+ },
+ {
+ /* test equals inside sinqle quotes */
+ L"ls 'seq",
+ "seq",
+ {"sequals==test", NULL},
+ L"ls 'sequals==test'"
+ },
+ {
+ /* test equals inside double quotes */
+ L"ls \"deq",
+ "deq",
+ {"dequals==test", NULL},
+ L"ls \"dequals==test\""
+ },
+ {
+ /* test \n */
+ L"ls new",
+ "new",
+ {"new\\nline", NULL},
+ L"ls new\\\\nline "
+ },
+ {
+ /* test \n inside single quotes */
+ L"ls 'snew",
+ "snew",
+ {"snew\nline", NULL},
+ L"ls 'snew\nline'"
+ },
+ {
+ /* test \n inside double quotes */
+ L"ls \"dnew",
+ "dnew",
+ {"dnew\nline", NULL},
+ L"ls \"dnew\nline\""
+ },
+ {
+ /* test single space */
+ L"ls spac",
+ "spac",
+ {"space test", NULL},
+ L"ls space\\ test "
+ },
+ {
+ /* test single space inside singlq quotes */
+ L"ls 's_spac",
+ "s_spac",
+ {"s_space test", NULL},
+ L"ls 's_space test'"
+ },
+ {
+ /* test single space inside double quotes */
+ L"ls \"d_spac",
+ "d_spac",
+ {"d_space test", NULL},
+ L"ls \"d_space test\""
+ },
+ {
+ /* test multiple spaces */
+ L"ls multi",
+ "multi",
+ {"multi space test", NULL},
+ L"ls multi\\ space\\ \\ test "
+ },
+ {
+ /* test multiple spaces inside single quotes */
+ L"ls 's_multi",
+ "s_multi",
+ {"s_multi space test", NULL},
+ L"ls 's_multi space test'"
+ },
+ {
+ /* test multiple spaces inside double quotes */
+ L"ls \"d_multi",
+ "d_multi",
+ {"d_multi space test", NULL},
+ L"ls \"d_multi space test\""
+ },
+ {
+ /* test double quotes */
+ L"ls doub",
+ "doub",
+ {"doub\"quotes", NULL},
+ L"ls doub\\\"quotes "
+ },
+ {
+ /* test double quotes inside single quotes */
+ L"ls 's_doub",
+ "s_doub",
+ {"s_doub\"quotes", NULL},
+ L"ls 's_doub\"quotes'"
+ },
+ {
+ /* test double quotes inside double quotes */
+ L"ls \"d_doub",
+ "d_doub",
+ {"d_doub\"quotes", NULL},
+ L"ls \"d_doub\\\"quotes\""
+ },
+ {
+ /* test multiple double quotes */
+ L"ls mud",
+ "mud",
+ {"mud\"qu\"otes\"", NULL},
+ L"ls mud\\\"qu\\\"otes\\\" "
+ },
+ {
+ /* test multiple double quotes inside single quotes */
+ L"ls 'smud",
+ "smud",
+ {"smud\"qu\"otes\"", NULL},
+ L"ls 'smud\"qu\"otes\"'"
+ },
+ {
+ /* test multiple double quotes inside double quotes */
+ L"ls \"dmud",
+ "dmud",
+ {"dmud\"qu\"otes\"", NULL},
+ L"ls \"dmud\\\"qu\\\"otes\\\"\""
+ },
+ {
+ /* test one single quote */
+ L"ls sing",
+ "sing",
+ {"single'quote", NULL},
+ L"ls single\\'quote "
+ },
+ {
+ /* test one single quote inside single quote */
+ L"ls 'ssing",
+ "ssing",
+ {"ssingle'quote", NULL},
+ L"ls 'ssingle'\\''quote'"
+ },
+ {
+ /* test one single quote inside double quote */
+ L"ls \"dsing",
+ "dsing",
+ {"dsingle'quote", NULL},
+ L"ls \"dsingle'quote\""
+ },
+ {
+ /* test multiple single quotes */
+ L"ls mu_sing",
+ "mu_sing",
+ {"mu_single''quotes''", NULL},
+ L"ls mu_single\\'\\'quotes\\'\\' "
+ },
+ {
+ /* test multiple single quotes inside single quote */
+ L"ls 'smu_sing",
+ "smu_sing",
+ {"smu_single''quotes''", NULL},
+ L"ls 'smu_single'\\'''\\''quotes'\\\'''\\'''"
+ },
+ {
+ /* test multiple single quotes inside double quote */
+ L"ls \"dmu_sing",
+ "dmu_sing",
+ {"dmu_single''quotes''", NULL},
+ L"ls \"dmu_single''quotes''\""
+ },
+ {
+ /* test parenthesis */
+ L"ls paren",
+ "paren",
+ {"paren(test)", NULL},
+ L"ls paren\\(test\\) "
+ },
+ {
+ /* test parenthesis inside single quote */
+ L"ls 'sparen",
+ "sparen",
+ {"sparen(test)", NULL},
+ L"ls 'sparen(test)'"
+ },
+ {
+ /* test parenthesis inside double quote */
+ L"ls \"dparen",
+ "dparen",
+ {"dparen(test)", NULL},
+ L"ls \"dparen(test)\""
+ },
+ {
+ /* test pipe */
+ L"ls pip",
+ "pip",
+ {"pipe|test", NULL},
+ L"ls pipe\\|test "
+ },
+ {
+ /* test pipe inside single quote */
+ L"ls 'spip",
+ "spip",
+ {"spipe|test", NULL},
+ L"ls 'spipe|test'",
+ },
+ {
+ /* test pipe inside double quote */
+ L"ls \"dpip",
+ "dpip",
+ {"dpipe|test", NULL},
+ L"ls \"dpipe|test\""
+ },
+ {
+ /* test tab */
+ L"ls ta",
+ "ta",
+ {"tab\ttest", NULL},
+ L"ls tab\\\ttest "
+ },
+ {
+ /* test tab inside single quote */
+ L"ls 'sta",
+ "sta",
+ {"stab\ttest", NULL},
+ L"ls 'stab\ttest'"
+ },
+ {
+ /* test tab inside double quote */
+ L"ls \"dta",
+ "dta",
+ {"dtab\ttest", NULL},
+ L"ls \"dtab\ttest\""
+ },
+ {
+ /* test back tick */
+ L"ls tic",
+ "tic",
+ {"tick`test`", NULL},
+ L"ls tick\\`test\\` "
+ },
+ {
+ /* test back tick inside single quote */
+ L"ls 'stic",
+ "stic",
+ {"stick`test`", NULL},
+ L"ls 'stick`test`'"
+ },
+ {
+ /* test back tick inside double quote */
+ L"ls \"dtic",
+ "dtic",
+ {"dtick`test`", NULL},
+ L"ls \"dtick\\`test\\`\""
+ },
+ {
+ /* test for @ */
+ L"ls at",
+ "at",
+ {"atthe at rate", NULL},
+ L"ls atthe\\@rate "
+ },
+ {
+ /* test for @ inside single quote */
+ L"ls 'sat",
+ "sat",
+ {"satthe at rate", NULL},
+ L"ls 'satthe at rate'"
+ },
+ {
+ /* test for @ inside double quote */
+ L"ls \"dat",
+ "dat",
+ {"datthe at rate", NULL},
+ L"ls \"datthe at rate\""
+ },
+ {
+ /* test ; */
+ L"ls semi",
+ "semi",
+ {"semi;colon;test", NULL},
+ L"ls semi\\;colon\\;test "
+ },
+ {
+ /* test ; inside single quote */
+ L"ls 'ssemi",
+ "ssemi",
+ {"ssemi;colon;test", NULL},
+ L"ls 'ssemi;colon;test'"
+ },
+ {
+ /* test ; inside double quote */
+ L"ls \"dsemi",
+ "dsemi",
+ {"dsemi;colon;test", NULL},
+ L"ls \"dsemi;colon;test\""
+ },
+ {
+ /* test & */
+ L"ls amp",
+ "amp",
+ {"ampers&and", NULL},
+ L"ls ampers\\&and "
+ },
+ {
+ /* test & inside single quote */
+ L"ls 'samp",
+ "samp",
+ {"sampers&and", NULL},
+ L"ls 'sampers&and'"
+ },
+ {
+ /* test & inside double quote */
+ L"ls \"damp",
+ "damp",
+ {"dampers&and", NULL},
+ L"ls \"dampers&and\""
+ },
+ {
+ /* test completion when cursor at \ */
+ L"ls foo\\",
+ "foo",
+ {"foo bar", NULL},
+ L"ls foo\\ bar "
+ },
+ {
+ /* test completion when cursor at single quote */
+ L"ls foo'",
+ "foo'",
+ {"foo bar", NULL},
+ L"ls foo\\ bar "
+ },
+ {
+ /* test completion when cursor at double quote */
+ L"ls foo\"",
+ "foo\"",
+ {"foo bar", NULL},
+ L"ls foo\\ bar "
+ },
+ {
+ /* test multiple completion matches */
+ L"ls fo",
+ "fo",
+ {"foo bar", "foo baz"},
+ L"ls foo\\ ba"
+ },
+ {
+ L"ls ba",
+ "ba",
+ {"bar <bar>", "bar <baz>"},
+ L"ls bar\\ \\<ba"
+ }
+};
+
+static const wchar_t break_chars[] = L" \t\n\"\\'`@$><=;|&{(";
+
+/*
+ * Custom completion function passed to fn_complet, NULLe.
+ * The function returns hardcoded completion matches
+ * based on the test cases present in inputs[] (above)
+ */
+static char *
+mycomplet_func(const char *text, int index)
+{
+ static int last_index = 0;
+ size_t i = 0;
+ if (last_index == 2) {
+ last_index = 0;
+ return NULL;
+ }
+
+ for (i = 0; i < sizeof(inputs)/sizeof(inputs[0]); i++) {
+ if (strcmp(text, inputs[i].completion_function_input) == 0) {
+ if (inputs[i].expanded_text[last_index] != NULL)
+ return strdup(inputs[i].expanded_text[last_index++]);
+ else {
+ last_index = 0;
+ return NULL;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+int
+main(int argc, char **argv)
+{
+ EditLine *el = el_init(argv[0], stdin, stdout, stderr);
+ size_t i;
+ size_t input_len;
+ el_line_t line;
+ wchar_t *buffer = malloc(64 * sizeof(*buffer));
+ if (buffer == NULL)
+ err(EXIT_FAILURE, "malloc failed");
+
+ for (i = 0; i < sizeof(inputs)/sizeof(inputs[0]); i++) {
+ memset(buffer, 0, 64 * sizeof(*buffer));
+ input_len = wcslen(inputs[i].user_typed_text);
+ wmemcpy(buffer, inputs[i].user_typed_text, input_len);
+ buffer[input_len] = 0;
+ line.buffer = buffer;
+ line.cursor = line.buffer + input_len ;
+ line.lastchar = line.cursor - 1;
+ line.limit = line.buffer + 64 * sizeof(*buffer);
+ el->el_line = line;
+ fn_complete(el, mycomplet_func, NULL, break_chars, NULL, NULL, 10, NULL, NULL, NULL, NULL);
+
+ /*
+ * fn_complete would have expanded and escaped the input in el->el_line.buffer.
+ * We need to assert that it matches with the expected value in our test data
+ */
+ printf("User input: %ls\t Expected output: %ls\t Generated output: %ls\n",
+ inputs[i].user_typed_text, inputs[i].escaped_output, el->el_line.buffer);
+ assert(wcscmp(el->el_line.buffer, inputs[i].escaped_output) == 0);
+ }
+ el_end(el);
+ return 0;
+
+}
Copied: vendor/NetBSD/libedit/2019-09-10/chared.c (from r352134, vendor/NetBSD/libedit/dist/chared.c)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ vendor/NetBSD/libedit/2019-09-10/chared.c Tue Sep 10 13:56:36 2019 (r352135, copy of r352134, vendor/NetBSD/libedit/dist/chared.c)
@@ -0,0 +1,747 @@
+/* $NetBSD: chared.c,v 1.59 2019/07/23 10:18:52 christos Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+#if !defined(lint) && !defined(SCCSID)
+#if 0
+static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: chared.c,v 1.59 2019/07/23 10:18:52 christos Exp $");
+#endif
+#endif /* not lint && not SCCSID */
+
+/*
+ * chared.c: Character editor utilities
+ */
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "el.h"
+#include "common.h"
+#include "fcns.h"
+
+/* value to leave unused in line buffer */
+#define EL_LEAVE 2
+
+/* cv_undo():
+ * Handle state for the vi undo command
+ */
+libedit_private void
+cv_undo(EditLine *el)
+{
+ c_undo_t *vu = &el->el_chared.c_undo;
+ c_redo_t *r = &el->el_chared.c_redo;
+ size_t size;
+
+ /* Save entire line for undo */
+ size = (size_t)(el->el_line.lastchar - el->el_line.buffer);
+ vu->len = (ssize_t)size;
+ vu->cursor = (int)(el->el_line.cursor - el->el_line.buffer);
+ (void)memcpy(vu->buf, el->el_line.buffer, size * sizeof(*vu->buf));
+
+ /* save command info for redo */
+ r->count = el->el_state.doingarg ? el->el_state.argument : 0;
+ r->action = el->el_chared.c_vcmd.action;
+ r->pos = r->buf;
+ r->cmd = el->el_state.thiscmd;
+ r->ch = el->el_state.thisch;
+}
+
+/* cv_yank():
+ * Save yank/delete data for paste
+ */
+libedit_private void
+cv_yank(EditLine *el, const wchar_t *ptr, int size)
+{
+ c_kill_t *k = &el->el_chared.c_kill;
+
+ (void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf));
+ k->last = k->buf + size;
+}
+
+
+/* c_insert():
+ * Insert num characters
+ */
+libedit_private void
+c_insert(EditLine *el, int num)
+{
+ wchar_t *cp;
+
+ if (el->el_line.lastchar + num >= el->el_line.limit) {
+ if (!ch_enlargebufs(el, (size_t)num))
+ return; /* can't go past end of buffer */
+ }
+
+ if (el->el_line.cursor < el->el_line.lastchar) {
+ /* if I must move chars */
+ for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
+ cp[num] = *cp;
+ }
+ el->el_line.lastchar += num;
+}
+
+
+/* c_delafter():
+ * Delete num characters after the cursor
+ */
+libedit_private void
+c_delafter(EditLine *el, int num)
+{
+
+ if (el->el_line.cursor + num > el->el_line.lastchar)
+ num = (int)(el->el_line.lastchar - el->el_line.cursor);
+
+ if (el->el_map.current != el->el_map.emacs) {
+ cv_undo(el);
+ cv_yank(el, el->el_line.cursor, num);
+ }
+
+ if (num > 0) {
+ wchar_t *cp;
+
+ for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
+ *cp = cp[num];
+
+ el->el_line.lastchar -= num;
+ }
+}
+
+
+/* c_delafter1():
+ * Delete the character after the cursor, do not yank
+ */
+libedit_private void
+c_delafter1(EditLine *el)
+{
+ wchar_t *cp;
+
+ for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
+ *cp = cp[1];
+
+ el->el_line.lastchar--;
+}
+
+
+/* c_delbefore():
+ * Delete num characters before the cursor
+ */
+libedit_private void
+c_delbefore(EditLine *el, int num)
+{
+
+ if (el->el_line.cursor - num < el->el_line.buffer)
+ num = (int)(el->el_line.cursor - el->el_line.buffer);
+
+ if (el->el_map.current != el->el_map.emacs) {
+ cv_undo(el);
+ cv_yank(el, el->el_line.cursor - num, num);
+ }
+
+ if (num > 0) {
+ wchar_t *cp;
+
+ for (cp = el->el_line.cursor - num;
+ &cp[num] <= el->el_line.lastchar;
+ cp++)
+ *cp = cp[num];
+
+ el->el_line.lastchar -= num;
+ }
+}
+
+
+/* c_delbefore1():
+ * Delete the character before the cursor, do not yank
+ */
+libedit_private void
+c_delbefore1(EditLine *el)
+{
+ wchar_t *cp;
+
+ for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
+ *cp = cp[1];
+
+ el->el_line.lastchar--;
+}
+
+
+/* ce__isword():
+ * Return if p is part of a word according to emacs
+ */
+libedit_private int
+ce__isword(wint_t p)
+{
+ return iswalnum(p) || wcschr(L"*?_-.[]~=", p) != NULL;
+}
+
+
+/* cv__isword():
+ * Return if p is part of a word according to vi
+ */
+libedit_private int
+cv__isword(wint_t p)
+{
+ if (iswalnum(p) || p == L'_')
+ return 1;
+ if (iswgraph(p))
+ return 2;
+ return 0;
+}
+
+
+/* cv__isWord():
+ * Return if p is part of a big word according to vi
+ */
+libedit_private int
+cv__isWord(wint_t p)
+{
+ return !iswspace(p);
+}
+
+
+/* c__prev_word():
+ * Find the previous word
+ */
+libedit_private wchar_t *
+c__prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
+{
+ p--;
+
+ while (n--) {
+ while ((p >= low) && !(*wtest)(*p))
+ p--;
+ while ((p >= low) && (*wtest)(*p))
+ p--;
+ }
+
+ /* cp now points to one character before the word */
+ p++;
+ if (p < low)
+ p = low;
+ /* cp now points where we want it */
+ return p;
+}
+
+
+/* c__next_word():
+ * Find the next word
+ */
+libedit_private wchar_t *
+c__next_word(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
+{
+ while (n--) {
+ while ((p < high) && !(*wtest)(*p))
+ p++;
+ while ((p < high) && (*wtest)(*p))
+ p++;
+ }
+ if (p > high)
+ p = high;
+ /* p now points where we want it */
+ return p;
+}
+
+/* cv_next_word():
+ * Find the next word vi style
+ */
+libedit_private wchar_t *
+cv_next_word(EditLine *el, wchar_t *p, wchar_t *high, int n,
+ int (*wtest)(wint_t))
+{
+ int test;
+
+ while (n--) {
+ test = (*wtest)(*p);
+ while ((p < high) && (*wtest)(*p) == test)
+ p++;
+ /*
+ * vi historically deletes with cw only the word preserving the
+ * trailing whitespace! This is not what 'w' does..
+ */
+ if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
+ while ((p < high) && iswspace(*p))
+ p++;
+ }
+
+ /* p now points where we want it */
+ if (p > high)
+ return high;
+ else
+ return p;
+}
+
+
+/* cv_prev_word():
+ * Find the previous word vi style
+ */
+libedit_private wchar_t *
+cv_prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
+{
+ int test;
+
+ p--;
+ while (n--) {
+ while ((p > low) && iswspace(*p))
+ p--;
+ test = (*wtest)(*p);
+ while ((p >= low) && (*wtest)(*p) == test)
+ p--;
+ }
+ p++;
+
+ /* p now points where we want it */
+ if (p < low)
+ return low;
+ else
+ return p;
+}
+
+
+/* cv_delfini():
+ * Finish vi delete action
+ */
+libedit_private void
+cv_delfini(EditLine *el)
+{
+ int size;
+ int action = el->el_chared.c_vcmd.action;
+
+ if (action & INSERT)
+ el->el_map.current = el->el_map.key;
+
+ if (el->el_chared.c_vcmd.pos == 0)
+ /* sanity */
+ return;
+
+ size = (int)(el->el_line.cursor - el->el_chared.c_vcmd.pos);
+ if (size == 0)
+ size = 1;
+ el->el_line.cursor = el->el_chared.c_vcmd.pos;
+ if (action & YANK) {
+ if (size > 0)
+ cv_yank(el, el->el_line.cursor, size);
+ else
+ cv_yank(el, el->el_line.cursor + size, -size);
+ } else {
+ if (size > 0) {
+ c_delafter(el, size);
+ re_refresh_cursor(el);
+ } else {
+ c_delbefore(el, -size);
+ el->el_line.cursor += size;
+ }
+ }
+ el->el_chared.c_vcmd.action = NOP;
+}
+
+
+/* cv__endword():
+ * Go to the end of this word according to vi
+ */
+libedit_private wchar_t *
+cv__endword(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
+{
+ int test;
+
+ p++;
+
+ while (n--) {
+ while ((p < high) && iswspace(*p))
+ p++;
+
+ test = (*wtest)(*p);
+ while ((p < high) && (*wtest)(*p) == test)
+ p++;
+ }
+ p--;
+ return p;
+}
+
+/* ch_init():
+ * Initialize the character editor
+ */
+libedit_private int
+ch_init(EditLine *el)
+{
+ el->el_line.buffer = el_calloc(EL_BUFSIZ,
+ sizeof(*el->el_line.buffer));
+ if (el->el_line.buffer == NULL)
+ return -1;
+
+ el->el_line.cursor = el->el_line.buffer;
+ el->el_line.lastchar = el->el_line.buffer;
+ el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
+
+ el->el_chared.c_undo.buf = el_calloc(EL_BUFSIZ,
+ sizeof(*el->el_chared.c_undo.buf));
+ if (el->el_chared.c_undo.buf == NULL)
+ return -1;
+ el->el_chared.c_undo.len = -1;
+ el->el_chared.c_undo.cursor = 0;
+ el->el_chared.c_redo.buf = el_calloc(EL_BUFSIZ,
+ sizeof(*el->el_chared.c_redo.buf));
+ if (el->el_chared.c_redo.buf == NULL)
+ return -1;
+ el->el_chared.c_redo.pos = el->el_chared.c_redo.buf;
+ el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ;
+ el->el_chared.c_redo.cmd = ED_UNASSIGNED;
+
+ el->el_chared.c_vcmd.action = NOP;
+ el->el_chared.c_vcmd.pos = el->el_line.buffer;
+
+ el->el_chared.c_kill.buf = el_calloc(EL_BUFSIZ,
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-vendor
mailing list