summaryrefslogtreecommitdiffstats
path: root/third_party/heimdal/lib/libedit/src/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/heimdal/lib/libedit/src/parse.c')
-rw-r--r--third_party/heimdal/lib/libedit/src/parse.c289
1 files changed, 289 insertions, 0 deletions
diff --git a/third_party/heimdal/lib/libedit/src/parse.c b/third_party/heimdal/lib/libedit/src/parse.c
new file mode 100644
index 0000000..fdd0d84
--- /dev/null
+++ b/third_party/heimdal/lib/libedit/src/parse.c
@@ -0,0 +1,289 @@
+/* $NetBSD: parse.c,v 1.40 2016/05/09 21:46:56 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[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: parse.c,v 1.40 2016/05/09 21:46:56 christos Exp $");
+#endif
+#endif /* not lint && not SCCSID */
+
+/*
+ * parse.c: parse an editline extended command
+ *
+ * commands are:
+ *
+ * bind
+ * echotc
+ * edit
+ * gettc
+ * history
+ * settc
+ * setty
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include "el.h"
+#include "parse.h"
+
+static const struct {
+ const wchar_t *name;
+ int (*func)(EditLine *, int, const wchar_t **);
+} cmds[] = {
+ { L"bind", map_bind },
+ { L"echotc", terminal_echotc },
+ { L"edit", el_editmode },
+ { L"history", hist_command },
+ { L"telltc", terminal_telltc },
+ { L"settc", terminal_settc },
+ { L"setty", tty_stty },
+ { NULL, NULL }
+};
+
+
+/* parse_line():
+ * Parse a line and dispatch it
+ */
+libedit_private int
+parse_line(EditLine *el, const wchar_t *line)
+{
+ const wchar_t **argv;
+ int argc;
+ TokenizerW *tok;
+
+ tok = tok_winit(NULL);
+ tok_wstr(tok, line, &argc, &argv);
+ argc = el_wparse(el, argc, argv);
+ tok_wend(tok);
+ return argc;
+}
+
+
+/* el_parse():
+ * Command dispatcher
+ */
+int
+el_wparse(EditLine *el, int argc, const wchar_t *argv[])
+{
+ const wchar_t *ptr;
+ int i;
+
+ if (argc < 1)
+ return -1;
+ ptr = wcschr(argv[0], L':');
+ if (ptr != NULL) {
+ wchar_t *tprog;
+ size_t l;
+
+ if (ptr == argv[0])
+ return 0;
+ l = (size_t)(ptr - argv[0] - 1);
+ tprog = el_malloc((l + 1) * sizeof(*tprog));
+ if (tprog == NULL)
+ return 0;
+ (void) wcsncpy(tprog, argv[0], l);
+ tprog[l] = '\0';
+ ptr++;
+ l = (size_t)el_match(el->el_prog, tprog);
+ el_free(tprog);
+ if (!l)
+ return 0;
+ } else
+ ptr = argv[0];
+
+ for (i = 0; cmds[i].name != NULL; i++)
+ if (wcscmp(cmds[i].name, ptr) == 0) {
+ i = (*cmds[i].func) (el, argc, argv);
+ return -i;
+ }
+ return -1;
+}
+
+
+/* parse__escape():
+ * Parse a string of the form ^<char> \<odigit> \<char> \U+xxxx and return
+ * the appropriate character or -1 if the escape is not valid
+ */
+libedit_private int
+parse__escape(const wchar_t **ptr)
+{
+ const wchar_t *p;
+ wint_t c;
+
+ p = *ptr;
+
+ if (p[1] == 0)
+ return -1;
+
+ if (*p == '\\') {
+ p++;
+ switch (*p) {
+ case 'a':
+ c = '\007'; /* Bell */
+ break;
+ case 'b':
+ c = '\010'; /* Backspace */
+ break;
+ case 't':
+ c = '\011'; /* Horizontal Tab */
+ break;
+ case 'n':
+ c = '\012'; /* New Line */
+ break;
+ case 'v':
+ c = '\013'; /* Vertical Tab */
+ break;
+ case 'f':
+ c = '\014'; /* Form Feed */
+ break;
+ case 'r':
+ c = '\015'; /* Carriage Return */
+ break;
+ case 'e':
+ c = '\033'; /* Escape */
+ break;
+ case 'U': /* Unicode \U+xxxx or \U+xxxxx format */
+ {
+ int i;
+ const wchar_t hex[] = L"0123456789ABCDEF";
+ const wchar_t *h;
+ ++p;
+ if (*p++ != '+')
+ return -1;
+ c = 0;
+ for (i = 0; i < 5; ++i) {
+ h = wcschr(hex, *p++);
+ if (!h && i < 4)
+ return -1;
+ else if (h)
+ c = (c << 4) | ((int)(h - hex));
+ else
+ --p;
+ }
+ if (c > 0x10FFFF) /* outside valid character range */
+ return -1;
+ break;
+ }
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ {
+ int cnt, ch;
+
+ for (cnt = 0, c = 0; cnt < 3; cnt++) {
+ ch = *p++;
+ if (ch < '0' || ch > '7') {
+ p--;
+ break;
+ }
+ c = (c << 3) | (ch - '0');
+ }
+ if ((c & (wint_t)0xffffff00) != (wint_t)0)
+ return -1;
+ --p;
+ break;
+ }
+ default:
+ c = *p;
+ break;
+ }
+ } else if (*p == '^') {
+ p++;
+ c = (*p == '?') ? '\177' : (*p & 0237);
+ } else
+ c = *p;
+ *ptr = ++p;
+ return c;
+}
+
+/* parse__string():
+ * Parse the escapes from in and put the raw string out
+ */
+libedit_private wchar_t *
+parse__string(wchar_t *out, const wchar_t *in)
+{
+ wchar_t *rv = out;
+ int n;
+
+ for (;;)
+ switch (*in) {
+ case '\0':
+ *out = '\0';
+ return rv;
+
+ case '\\':
+ case '^':
+ if ((n = parse__escape(&in)) == -1)
+ return NULL;
+ *out++ = (wchar_t)n;
+ break;
+
+ case 'M':
+ if (in[1] == '-' && in[2] != '\0') {
+ *out++ = '\033';
+ in += 2;
+ break;
+ }
+ /*FALLTHROUGH*/
+
+ default:
+ *out++ = *in++;
+ break;
+ }
+}
+
+
+/* parse_cmd():
+ * Return the command number for the command string given
+ * or -1 if one is not found
+ */
+libedit_private int
+parse_cmd(EditLine *el, const wchar_t *cmd)
+{
+ el_bindings_t *b = el->el_map.help;
+ size_t i;
+
+ for (i = 0; i < el->el_map.nfunc; i++)
+ if (wcscmp(b[i].name, cmd) == 0)
+ return b[i].func;
+ return -1;
+}