1
/* $NetBSD: eln.c,v 1.13 2011/08/16 16:25:15 christos Exp $ */
4
* Copyright (c) 2009 The NetBSD Foundation, Inc.
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
* 3. All advertising materials mentioning features or use of this software
16
* must display the following acknowledgement:
17
* This product includes software developed by the NetBSD
18
* Foundation, Inc. and its contributors.
19
* 4. Neither the name of The NetBSD Foundation nor the names of its
20
* contributors may be used to endorse or promote products derived
21
* from this software without specific prior written permission.
23
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
* POSSIBILITY OF SUCH DAMAGE.
36
#if !defined(lint) && !defined(SCCSID)
37
#endif /* not lint && not SCCSID */
47
el_getc(EditLine *el, char *cp)
52
num_read = el_wgetc (el, &wc);
61
el_push(EditLine *el, const char *str)
63
/* Using multibyte->wide string decoding works fine under single-byte
64
* character sets too, and Does The Right Thing. */
65
el_wpush(el, ct_decode_string(str, &el->el_lgcyconv));
70
el_gets(EditLine *el, int *nread)
74
tmp = el_wgets(el, nread);
75
return ct_encode_string(tmp, &el->el_lgcyconv);
80
el_parse(EditLine *el, int argc, const char *argv[])
83
const wchar_t **wargv;
85
wargv = (const wchar_t **)
86
ct_decode_argv(argc, argv, &el->el_lgcyconv);
89
ret = el_wparse(el, argc, wargv);
97
el_set(EditLine *el, int op, ...)
107
case EL_PROMPT: /* el_pfunc_t */
109
el_pfunc_t p = va_arg(ap, el_pfunc_t);
110
ret = prompt_set(el, p, 0, op, 0);
115
el_zfunc_t p = va_arg(ap, el_zfunc_t);
116
void *arg = va_arg(ap, void *);
117
ret = ch_resizefun(el, p, arg);
121
case EL_TERMINAL: /* const char * */
122
ret = el_wset(el, op, va_arg(ap, char *));
125
case EL_EDITOR: /* const wchar_t * */
126
ret = el_wset(el, op, ct_decode_string(va_arg(ap, char *),
130
case EL_SIGNAL: /* int */
134
ret = el_wset(el, op, va_arg(ap, int));
137
case EL_BIND: /* const char * list -> const wchar_t * list */
142
const char *argv[20];
144
const wchar_t **wargv;
145
for (i = 1; i < (int)__arraycount(argv); ++i)
146
if ((argv[i] = va_arg(ap, char *)) == NULL)
149
wargv = (const wchar_t **)
150
ct_decode_argv(i, argv, &el->el_lgcyconv);
156
* AFAIK we can't portably pass through our new wargv to
157
* el_wset(), so we have to reimplement the body of
158
* el_wset() for these ops.
162
wargv[0] = STR("bind");
163
ret = map_bind(el, i, wargv);
166
wargv[0] = STR("telltc");
167
ret = terminal_telltc(el, i, wargv);
170
wargv[0] = STR("settc");
171
ret = terminal_settc(el, i, wargv);
174
wargv[0] = STR("echotc");
175
ret = terminal_echotc(el, i, wargv);
178
wargv[0] = STR("setty");
179
ret = tty_stty(el, i, wargv);
188
/* XXX: do we need to change el_func_t too? */
189
case EL_ADDFN: { /* const char *, const char *, el_func_t */
194
args[0] = va_arg(ap, const char *);
195
args[1] = va_arg(ap, const char *);
196
func = va_arg(ap, el_func_t);
198
wargv = ct_decode_argv(2, args, &el->el_lgcyconv);
203
// XXX: The two strdup's leak
204
ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]),
209
case EL_HIST: { /* hist_fun_t, const char * */
210
hist_fun_t fun = va_arg(ap, hist_fun_t);
211
void *ptr = va_arg(ap, void *);
212
ret = hist_set(el, fun, ptr);
213
el->el_flags |= NARROW_HISTORY;
216
/* XXX: do we need to change el_rfunc_t? */
217
case EL_GETCFN: /* el_rfunc_t */
218
ret = el_wset(el, op, va_arg(ap, el_rfunc_t));
219
el->el_flags |= NARROW_READ;
221
case EL_CLIENTDATA: /* void * */
222
ret = el_wset(el, op, va_arg(ap, void *));
224
case EL_SETFP: { /* int, FILE * */
225
int what = va_arg(ap, int);
226
FILE *fp = va_arg(ap, FILE *);
227
ret = el_wset(el, op, what, fp);
230
case EL_PROMPT_ESC: /* el_pfunc_t, char */
231
case EL_RPROMPT_ESC: {
232
el_pfunc_t p = va_arg(ap, el_pfunc_t);
233
char c = (char)va_arg(ap, int);
234
ret = prompt_set(el, p, c, op, 0);
249
el_get(EditLine *el, int op, ...)
260
case EL_PROMPT: /* el_pfunc_t * */
262
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
263
ret = prompt_get(el, p, 0, op);
267
case EL_PROMPT_ESC: /* el_pfunc_t *, char **/
268
case EL_RPROMPT_ESC: {
269
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
270
char *c = va_arg(ap, char *);
272
ret = prompt_get(el, p, &wc, op);
278
const char **p = va_arg(ap, const char **);
280
ret = el_wget(el, op, &pw);
281
*p = ct_encode_string(pw, &el->el_lgcyconv);
282
if (!el->el_lgcyconv.csize)
287
case EL_TERMINAL: /* const char ** */
288
ret = el_wget(el, op, va_arg(ap, const char **));
291
case EL_SIGNAL: /* int * */
295
ret = el_wget(el, op, va_arg(ap, int *));
300
static char gettc[] = "gettc";
302
for (i = 1; i < (int)__arraycount(argv); ++i)
303
if ((argv[i] = va_arg(ap, char *)) == NULL)
306
ret = terminal_gettc(el, i, argv);
310
/* XXX: do we need to change el_rfunc_t? */
311
case EL_GETCFN: /* el_rfunc_t */
312
ret = el_wget(el, op, va_arg(ap, el_rfunc_t *));
315
case EL_CLIENTDATA: /* void ** */
316
ret = el_wget(el, op, va_arg(ap, void **));
319
case EL_GETFP: { /* int, FILE ** */
320
int what = va_arg(ap, int);
321
FILE **fpp = va_arg(ap, FILE **);
322
ret = el_wget(el, op, what, fpp);
337
el_line(EditLine *el)
339
const LineInfoW *winfo = el_wline(el);
340
LineInfo *info = &el->el_lgcylinfo;
344
info->buffer = ct_encode_string(winfo->buffer, &el->el_lgcyconv);
347
for (p = winfo->buffer; p < winfo->cursor; p++)
348
offset += ct_enc_width(*p);
349
info->cursor = info->buffer + offset;
352
for (p = winfo->buffer; p < winfo->lastchar; p++)
353
offset += ct_enc_width(*p);
354
info->lastchar = info->buffer + offset;
361
el_insertstr(EditLine *el, const char *str)
363
return el_winsertstr(el, ct_decode_string(str, &el->el_lgcyconv));