112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*	$NetBSD: eln.c,v 1.14 2012/03/11 21:15:25 christos Exp $	*/
212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*-
412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Copyright (c) 2009 The NetBSD Foundation, Inc.
512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * All rights reserved.
612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Redistribution and use in source and binary forms, with or without
812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * modification, are permitted provided that the following conditions
912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * are met:
1012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 1. Redistributions of source code must retain the above copyright
1112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    notice, this list of conditions and the following disclaimer.
1212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 2. Redistributions in binary form must reproduce the above copyright
1312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    notice, this list of conditions and the following disclaimer in the
1412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    documentation and/or other materials provided with the distribution.
1512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 3. All advertising materials mentioning features or use of this software
1612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    must display the following acknowledgement:
1712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *        This product includes software developed by the NetBSD
1812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *        Foundation, Inc. and its contributors.
1912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 4. Neither the name of The NetBSD Foundation nor the names of its
2012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    contributors may be used to endorse or promote products derived
2112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    from this software without specific prior written permission.
2212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
2312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * POSSIBILITY OF SUCH DAMAGE.
3412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
3512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "config.h"
3612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if !defined(lint) && !defined(SCCSID)
3712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala__RCSID("$NetBSD: eln.c,v 1.14 2012/03/11 21:15:25 christos Exp $");
3812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* not lint && not SCCSID */
3912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
4012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "histedit.h"
4112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "el.h"
4212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "read.h"
4312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <stdarg.h>
4412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <stdio.h>
4512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <stdlib.h>
4612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
4712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialapublic int
4812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialael_getc(EditLine *el, char *cp)
4912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
5012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int num_read;
5112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	wchar_t wc = 0;
5212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
5312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!(el->el_flags & CHARSET_IS_UTF8))
5412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_flags |= IGNORE_EXTCHARS;
5512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	num_read = el_wgetc (el, &wc);
5612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!(el->el_flags & CHARSET_IS_UTF8))
5712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_flags &= ~IGNORE_EXTCHARS;
5812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
5912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (num_read > 0)
6012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		*cp = (char)wc;
6112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return num_read;
6212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
6312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
6412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
6512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialapublic void
6612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialael_push(EditLine *el, const char *str)
6712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
6812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* Using multibyte->wide string decoding works fine under single-byte
6912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	 * character sets too, and Does The Right Thing. */
7012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el_wpush(el, ct_decode_string(str, &el->el_lgcyconv));
7112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
7212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
7312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
7412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialapublic const char *
7512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialael_gets(EditLine *el, int *nread)
7612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
7712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const wchar_t *tmp;
7812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
7912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_flags |= IGNORE_EXTCHARS;
8012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	tmp = el_wgets(el, nread);
8112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_flags &= ~IGNORE_EXTCHARS;
8212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return ct_encode_string(tmp, &el->el_lgcyconv);
8312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
8412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
8512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
8612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialapublic int
8712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialael_parse(EditLine *el, int argc, const char *argv[])
8812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
8912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int ret;
9012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const wchar_t **wargv;
9112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
9212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	wargv = (const wchar_t **)
9312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    ct_decode_argv(argc, argv, &el->el_lgcyconv);
9412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!wargv)
9512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
9612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ret = el_wparse(el, argc, wargv);
9712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ct_free_argv(wargv);
9812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
9912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return ret;
10012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
10112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
10212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
10312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialapublic int
10412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialael_set(EditLine *el, int op, ...)
10512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
10612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	va_list ap;
10712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int ret;
10812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
10912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!el)
11012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
11112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	va_start(ap, op);
11212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
11312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	switch (op) {
11412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_PROMPT:         /* el_pfunc_t */
11512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_RPROMPT: {
11612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el_pfunc_t p = va_arg(ap, el_pfunc_t);
11712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = prompt_set(el, p, 0, op, 0);
11812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
11912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
12012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
12112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_RESIZE: {
12212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el_zfunc_t p = va_arg(ap, el_zfunc_t);
12312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		void *arg = va_arg(ap, void *);
12412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = ch_resizefun(el, p, arg);
12512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
12612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
12712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
12812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_TERMINAL:       /* const char * */
12912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = el_wset(el, op, va_arg(ap, char *));
13012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
13112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
13212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_EDITOR:		/* const wchar_t * */
13312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = el_wset(el, op, ct_decode_string(va_arg(ap, char *),
13412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    &el->el_lgcyconv));
13512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
13612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
13712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_SIGNAL:         /* int */
13812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_EDITMODE:
13912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_UNBUFFERED:
14012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_PREP_TERM:
14112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = el_wset(el, op, va_arg(ap, int));
14212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
14312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
14412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_BIND:   /* const char * list -> const wchar_t * list */
14512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_TELLTC:
14612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_SETTC:
14712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_ECHOTC:
14812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_SETTY: {
14912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		const char *argv[20];
15012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		int i;
15112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		const wchar_t **wargv;
15212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (i = 1; i < (int)__arraycount(argv); ++i)
15312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if ((argv[i] = va_arg(ap, char *)) == NULL)
15412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    break;
15512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		argv[0] = NULL;
15612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		wargv = (const wchar_t **)
15712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    ct_decode_argv(i + 1, argv, &el->el_lgcyconv);
15812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (!wargv) {
15912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    ret = -1;
16012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    goto out;
16112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
16212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/*
16312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * AFAIK we can't portably pass through our new wargv to
16412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * el_wset(), so we have to reimplement the body of
16512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * el_wset() for these ops.
16612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 */
16712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		switch (op) {
16812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case EL_BIND:
16912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			wargv[0] = STR("bind");
17012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ret = map_bind(el, i, wargv);
17112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
17212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case EL_TELLTC:
17312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			wargv[0] = STR("telltc");
17412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ret = terminal_telltc(el, i, wargv);
17512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
17612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case EL_SETTC:
17712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			wargv[0] = STR("settc");
17812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ret = terminal_settc(el, i, wargv);
17912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
18012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case EL_ECHOTC:
18112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			wargv[0] = STR("echotc");
18212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ret = terminal_echotc(el, i, wargv);
18312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
18412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case EL_SETTY:
18512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			wargv[0] = STR("setty");
18612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ret = tty_stty(el, i, wargv);
18712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
18812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		default:
18912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ret = -1;
19012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
19112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ct_free_argv(wargv);
19212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
19312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
19412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
19512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* XXX: do we need to change el_func_t too? */
19612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_ADDFN: {          /* const char *, const char *, el_func_t */
19712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		const char *args[2];
19812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el_func_t func;
19912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		wchar_t **wargv;
20012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
20112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		args[0] = va_arg(ap, const char *);
20212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		args[1] = va_arg(ap, const char *);
20312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		func = va_arg(ap, el_func_t);
20412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
20512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		wargv = ct_decode_argv(2, args, &el->el_lgcyconv);
20612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (!wargv) {
20712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    ret = -1;
20812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    goto out;
20912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
21012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		// XXX: The two strdup's leak
21112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]),
21212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    func);
21312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ct_free_argv(wargv);
21412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
21512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
21612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_HIST: {           /* hist_fun_t, const char * */
21712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		hist_fun_t fun = va_arg(ap, hist_fun_t);
21812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		void *ptr = va_arg(ap, void *);
21912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = hist_set(el, fun, ptr);
22012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_flags |= NARROW_HISTORY;
22112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
22212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
22312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* XXX: do we need to change el_rfunc_t? */
22412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_GETCFN:         /* el_rfunc_t */
22512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = el_wset(el, op, va_arg(ap, el_rfunc_t));
22612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_flags |= NARROW_READ;
22712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
22812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_CLIENTDATA:     /* void * */
22912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = el_wset(el, op, va_arg(ap, void *));
23012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
23112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_SETFP: {          /* int, FILE * */
23212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		int what = va_arg(ap, int);
23312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		FILE *fp = va_arg(ap, FILE *);
23412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = el_wset(el, op, what, fp);
23512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
23612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
23712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_PROMPT_ESC: /* el_pfunc_t, char */
23812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_RPROMPT_ESC: {
23912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el_pfunc_t p = va_arg(ap, el_pfunc_t);
24012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		char c = (char)va_arg(ap, int);
24112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = prompt_set(el, p, c, op, 0);
24212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
24312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
24412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	default:
24512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = -1;
24612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
24712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
24812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
24912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaout:
25012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	va_end(ap);
25112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return ret;
25212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
25312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
25412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
25512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialapublic int
25612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialael_get(EditLine *el, int op, ...)
25712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
25812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	va_list ap;
25912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int ret;
26012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
26112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!el)
26212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
26312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
26412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	va_start(ap, op);
26512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
26612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	switch (op) {
26712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_PROMPT:         /* el_pfunc_t * */
26812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_RPROMPT: {
26912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
27012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = prompt_get(el, p, 0, op);
27112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
27212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
27312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
27412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_PROMPT_ESC: /* el_pfunc_t *, char **/
27512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_RPROMPT_ESC: {
27612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
27712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		char *c = va_arg(ap, char *);
27812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		wchar_t wc = 0;
27912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = prompt_get(el, p, &wc, op);
28012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		*c = (char)wc;
28112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
28212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
28312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
28412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_EDITOR: {
28512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		const char **p = va_arg(ap, const char **);
28612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		const wchar_t *pw;
28712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = el_wget(el, op, &pw);
28812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		*p = ct_encode_string(pw, &el->el_lgcyconv);
28912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (!el->el_lgcyconv.csize)
29012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ret = -1;
29112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
29212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
29312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
29412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_TERMINAL:       /* const char ** */
29512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = el_wget(el, op, va_arg(ap, const char **));
29612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
29712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
29812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_SIGNAL:         /* int * */
29912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_EDITMODE:
30012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_UNBUFFERED:
30112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_PREP_TERM:
30212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = el_wget(el, op, va_arg(ap, int *));
30312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
30412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
30512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_GETTC: {
30612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		char *argv[20];
30712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		static char gettc[] = "gettc";
30812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		int i;
30912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (i = 1; i < (int)__arraycount(argv); ++i)
31012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if ((argv[i] = va_arg(ap, char *)) == NULL)
31112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				break;
31212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		argv[0] = gettc;
31312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = terminal_gettc(el, i, argv);
31412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
31512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
31612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
31712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* XXX: do we need to change el_rfunc_t? */
31812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_GETCFN:         /* el_rfunc_t */
31912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = el_wget(el, op, va_arg(ap, el_rfunc_t *));
32012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
32112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
32212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_CLIENTDATA:     /* void ** */
32312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = el_wget(el, op, va_arg(ap, void **));
32412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
32512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
32612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case EL_GETFP: {          /* int, FILE ** */
32712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		int what = va_arg(ap, int);
32812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		FILE **fpp = va_arg(ap, FILE **);
32912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = el_wget(el, op, what, fpp);
33012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
33112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
33212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
33312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	default:
33412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		ret = -1;
33512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
33612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
33712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
33812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	va_end(ap);
33912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return ret;
34012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
34112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
34212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
34312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaconst LineInfo *
34412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialael_line(EditLine *el)
34512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
34612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const LineInfoW *winfo = el_wline(el);
34712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	LineInfo *info = &el->el_lgcylinfo;
34812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	size_t offset;
34912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const Char *p;
35012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
35112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	info->buffer   = ct_encode_string(winfo->buffer, &el->el_lgcyconv);
35212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
35312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	offset = 0;
35412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (p = winfo->buffer; p < winfo->cursor; p++)
35512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		offset += ct_enc_width(*p);
35612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	info->cursor = info->buffer + offset;
35712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
35812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	offset = 0;
35912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (p = winfo->buffer; p < winfo->lastchar; p++)
36012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		offset += ct_enc_width(*p);
36112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	info->lastchar = info->buffer + offset;
36212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
36312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return info;
36412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
36512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
36612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
36712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaint
36812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialael_insertstr(EditLine *el, const char *str)
36912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
37012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return el_winsertstr(el, ct_decode_string(str, &el->el_lgcyconv));
37112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
372