112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*	$NetBSD: parse.c,v 1.26 2011/08/16 16:25:15 christos Exp $	*/
212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*-
412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Copyright (c) 1992, 1993
512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	The Regents of the University of California.  All rights reserved.
612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * This code is derived from software contributed to Berkeley by
812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Christos Zoulas of Cornell University.
912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
1012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Redistribution and use in source and binary forms, with or without
1112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * modification, are permitted provided that the following conditions
1212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * are met:
1312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 1. Redistributions of source code must retain the above copyright
1412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    notice, this list of conditions and the following disclaimer.
1512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 2. Redistributions in binary form must reproduce the above copyright
1612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    notice, this list of conditions and the following disclaimer in the
1712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    documentation and/or other materials provided with the distribution.
1812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 3. Neither the name of the University nor the names of its contributors
1912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    may be used to endorse or promote products derived from this software
2012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    without specific prior written permission.
2112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
2212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * SUCH DAMAGE.
3312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
3412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
3512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "config.h"
3612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if !defined(lint) && !defined(SCCSID)
3712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if 0
3812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialastatic char sccsid[] = "@(#)parse.c	8.1 (Berkeley) 6/4/93";
3912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#else
4012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala__RCSID("$NetBSD: parse.c,v 1.26 2011/08/16 16:25:15 christos Exp $");
4112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
4212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* not lint && not SCCSID */
4312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
4412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*
4512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * parse.c: parse an editline extended command
4612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
4712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * commands are:
4812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
4912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	bind
5012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	echotc
5112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	edit
5212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	gettc
5312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	history
5412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	settc
5512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	setty
5612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
5712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "el.h"
5812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <stdlib.h>
5912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
6012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate const struct {
6112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const Char *name;
6212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int (*func)(EditLine *, int, const Char **);
6312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} cmds[] = {
6412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ STR("bind"),  	map_bind	},
6512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ STR("echotc"),	terminal_echotc	},
6612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ STR("edit"),  	el_editmode	},
6712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ STR("history"),	hist_command	},
6812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ STR("telltc"),	terminal_telltc	},
6912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ STR("settc"),	        terminal_settc	},
7012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ STR("setty"),	        tty_stty	},
7112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ NULL,		        NULL		}
7212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala};
7312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
7412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
7512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* parse_line():
7612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Parse a line and dispatch it
7712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
7812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
7912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaparse_line(EditLine *el, const Char *line)
8012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
8112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const Char **argv;
8212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int argc;
8312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	TYPE(Tokenizer) *tok;
8412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
8512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	tok = FUN(tok,init)(NULL);
8612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	FUN(tok,str)(tok, line, &argc, &argv);
8712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	argc = FUN(el,parse)(el, argc, argv);
8812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	FUN(tok,end)(tok);
8912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return argc;
9012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
9112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
9212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
9312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* el_parse():
9412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Command dispatcher
9512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
9612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialapublic int
9712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd FialaFUN(el,parse)(EditLine *el, int argc, const Char *argv[])
9812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
9912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const Char *ptr;
10012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int i;
10112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
10212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (argc < 1)
10312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
10412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ptr = Strchr(argv[0], ':');
10512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (ptr != NULL) {
10612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Char *tprog;
10712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		size_t l;
10812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
10912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (ptr == argv[0])
11012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return 0;
11112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		l = (size_t)(ptr - argv[0] - 1);
11212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		tprog = el_malloc((l + 1) * sizeof(*tprog));
11312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (tprog == NULL)
11412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return 0;
11512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) Strncpy(tprog, argv[0], l);
11612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		tprog[l] = '\0';
11712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ptr++;
11812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		l = (size_t)el_match(el->el_prog, tprog);
11912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el_free(tprog);
12012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (!l)
12112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return 0;
12212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else
12312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ptr = argv[0];
12412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
12512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (i = 0; cmds[i].name != NULL; i++)
12612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (Strcmp(cmds[i].name, ptr) == 0) {
12712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			i = (*cmds[i].func) (el, argc, argv);
12812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -i;
12912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
13012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return -1;
13112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
13212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
13312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
13412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* parse__escape():
13512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Parse a string of the form ^<char> \<odigit> \<char> \U+xxxx and return
13612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	the appropriate character or -1 if the escape is not valid
13712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
13812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
13912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaparse__escape(const Char **ptr)
14012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
14112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const Char *p;
14212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Int c;
14312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
14412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	p = *ptr;
14512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
14612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (p[1] == 0)
14712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
14812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
14912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (*p == '\\') {
15012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		p++;
15112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		switch (*p) {
15212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case 'a':
15312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			c = '\007';	/* Bell */
15412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
15512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case 'b':
15612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			c = '\010';	/* Backspace */
15712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
15812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case 't':
15912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			c = '\011';	/* Horizontal Tab */
16012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
16112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case 'n':
16212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			c = '\012';	/* New Line */
16312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
16412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case 'v':
16512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			c = '\013';	/* Vertical Tab */
16612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
16712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case 'f':
16812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			c = '\014';	/* Form Feed */
16912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
17012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case 'r':
17112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			c = '\015';	/* Carriage Return */
17212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
17312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case 'e':
17412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			c = '\033';	/* Escape */
17512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
17612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                case 'U':               /* Unicode \U+xxxx or \U+xxxxx format */
17712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                {
17812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                        int i;
17912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                        const Char hex[] = STR("0123456789ABCDEF");
18012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                        const Char *h;
18112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                        ++p;
18212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                        if (*p++ != '+')
18312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                return -1;
18412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			c = 0;
18512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                        for (i = 0; i < 5; ++i) {
18612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                h = Strchr(hex, *p++);
18712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                if (!h && i < 4)
18812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                        return -1;
18912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                else if (h)
19012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                        c = (c << 4) | ((int)(h - hex));
19112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                else
19212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                        --p;
19312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                        }
19412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                        if (c > 0x10FFFF) /* outside valid character range */
19512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                return -1;
19612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                        break;
19712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                }
19812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case '0':
19912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case '1':
20012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case '2':
20112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case '3':
20212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case '4':
20312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case '5':
20412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case '6':
20512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case '7':
20612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		{
20712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			int cnt, ch;
20812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
20912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			for (cnt = 0, c = 0; cnt < 3; cnt++) {
21012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				ch = *p++;
21112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				if (ch < '0' || ch > '7') {
21212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					p--;
21312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					break;
21412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				}
21512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				c = (c << 3) | (ch - '0');
21612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
21712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if ((c & (wint_t)0xffffff00) != (wint_t)0)
21812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				return -1;
21912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			--p;
22012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
22112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
22212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		default:
22312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			c = *p;
22412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
22512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
22612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else if (*p == '^') {
22712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		p++;
22812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		c = (*p == '?') ? '\177' : (*p & 0237);
22912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else
23012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		c = *p;
23112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	*ptr = ++p;
23212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return c;
23312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
23412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
23512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* parse__string():
23612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Parse the escapes from in and put the raw string out
23712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
23812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected Char *
23912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaparse__string(Char *out, const Char *in)
24012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
24112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Char *rv = out;
24212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int n;
24312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
24412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (;;)
24512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		switch (*in) {
24612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case '\0':
24712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			*out = '\0';
24812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return rv;
24912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
25012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case '\\':
25112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case '^':
25212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if ((n = parse__escape(&in)) == -1)
25312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				return NULL;
25412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			*out++ = n;
25512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
25612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
25712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case 'M':
25812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (in[1] == '-' && in[2] != '\0') {
25912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				*out++ = '\033';
26012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				in += 2;
26112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				break;
26212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
26312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/*FALLTHROUGH*/
26412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
26512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		default:
26612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			*out++ = *in++;
26712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
26812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
26912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
27012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
27112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
27212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* parse_cmd():
27312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Return the command number for the command string given
27412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	or -1 if one is not found
27512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
27612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
27712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaparse_cmd(EditLine *el, const Char *cmd)
27812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
27912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el_bindings_t *b;
28012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
28112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (b = el->el_map.help; b->name != NULL; b++)
28212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (Strcmp(b->name, cmd) == 0)
28312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return b->func;
28412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return -1;
28512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
286