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-all mailing list