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 <[email protected]>
+ * 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@rate", NULL},
+               L"ls atthe\\@rate "
+       },
+       {
+               /* test for @ inside single quote */
+               L"ls 'sat",
+               "sat",
+               {"satthe@rate", NULL},
+               L"ls 'satthe@rate'"
+       },
+       {
+               /* test for @ inside double quote */
+               L"ls \"dat",
+               "dat",
+               {"datthe@rate", NULL},
+               L"ls \"datthe@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 ***
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to