]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libedit/eln.c
Implement pci_enable_msi() and pci_disable_msi() in the LinuxKPI.
[FreeBSD/FreeBSD.git] / lib / libedit / eln.c
1 /*      $NetBSD: eln.c,v 1.28 2016/02/28 23:02:24 christos Exp $        */
2
3 /*-
4  * Copyright (c) 2009 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
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  *
16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 #include "config.h"
29 #if !defined(lint) && !defined(SCCSID)
30 __RCSID("$NetBSD: eln.c,v 1.28 2016/02/28 23:02:24 christos Exp $");
31 #endif /* not lint && not SCCSID */
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34
35 #include <errno.h>
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39
40 #include "el.h"
41
42 public int
43 el_getc(EditLine *el, char *cp)
44 {
45         int num_read;
46         wchar_t wc = 0;
47
48         num_read = el_wgetc(el, &wc);
49         *cp = '\0';
50         if (num_read <= 0)
51                 return num_read;
52         num_read = ct_wctob(wc);
53         if (num_read == EOF) {
54                 errno = ERANGE;
55                 return -1;
56         } else {
57                 *cp = (char)num_read;
58                 return 1;
59         }
60 }
61
62
63 #ifdef WIDECHAR
64 public void
65 el_push(EditLine *el, const char *str)
66 {
67         /* Using multibyte->wide string decoding works fine under single-byte
68          * character sets too, and Does The Right Thing. */
69         el_wpush(el, ct_decode_string(str, &el->el_lgcyconv));
70 }
71
72
73 public const char *
74 el_gets(EditLine *el, int *nread)
75 {
76         const wchar_t *tmp;
77
78         tmp = el_wgets(el, nread);
79         if (tmp != NULL) {
80             int i;
81             size_t nwread = 0;
82
83             for (i = 0; i < *nread; i++)
84                 nwread += ct_enc_width(tmp[i]);
85             *nread = (int)nwread;
86         }
87         return ct_encode_string(tmp, &el->el_lgcyconv);
88 }
89
90
91 public int
92 el_parse(EditLine *el, int argc, const char *argv[])
93 {
94         int ret;
95         const wchar_t **wargv;
96
97         wargv = (const wchar_t **)
98             ct_decode_argv(argc, argv, &el->el_lgcyconv);
99         if (!wargv)
100                 return -1;
101         ret = el_wparse(el, argc, wargv);
102         ct_free_argv(wargv);
103
104         return ret;
105 }
106
107
108 public int
109 el_set(EditLine *el, int op, ...)
110 {
111         va_list ap;
112         int ret;
113
114         if (!el)
115                 return -1;
116         va_start(ap, op);
117
118         switch (op) {
119         case EL_PROMPT:         /* el_pfunc_t */
120         case EL_RPROMPT: {
121                 el_pfunc_t p = va_arg(ap, el_pfunc_t);
122                 ret = prompt_set(el, p, 0, op, 0);
123                 break;
124         }
125
126         case EL_RESIZE: {
127                 el_zfunc_t p = va_arg(ap, el_zfunc_t);
128                 void *arg = va_arg(ap, void *);
129                 ret = ch_resizefun(el, p, arg);
130                 break;
131         }
132
133         case EL_ALIAS_TEXT: {
134                 el_afunc_t p = va_arg(ap, el_afunc_t);
135                 void *arg = va_arg(ap, void *);
136                 ret = ch_aliasfun(el, p, arg);
137                 break;
138         }
139
140         case EL_PROMPT_ESC:
141         case EL_RPROMPT_ESC: {
142                 el_pfunc_t p = va_arg(ap, el_pfunc_t);
143                 int c = va_arg(ap, int);
144
145                 ret = prompt_set(el, p, c, op, 0);
146                 break;
147         }
148
149         case EL_TERMINAL:       /* const char * */
150                 ret = el_wset(el, op, va_arg(ap, char *));
151                 break;
152
153         case EL_EDITOR:         /* const wchar_t * */
154                 ret = el_wset(el, op, ct_decode_string(va_arg(ap, char *),
155                     &el->el_lgcyconv));
156                 break;
157
158         case EL_SIGNAL:         /* int */
159         case EL_EDITMODE:
160         case EL_UNBUFFERED:
161         case EL_PREP_TERM:
162                 ret = el_wset(el, op, va_arg(ap, int));
163                 break;
164
165         case EL_BIND:   /* const char * list -> const wchar_t * list */
166         case EL_TELLTC:
167         case EL_SETTC:
168         case EL_ECHOTC:
169         case EL_SETTY: {
170                 const char *argv[20];
171                 int i;
172                 const wchar_t **wargv;
173                 for (i = 1; i < (int)__arraycount(argv) - 1; ++i)
174                         if ((argv[i] = va_arg(ap, const char *)) == NULL)
175                             break;
176                 argv[0] = argv[i] = NULL;
177                 wargv = (const wchar_t **)
178                     ct_decode_argv(i + 1, argv, &el->el_lgcyconv);
179                 if (!wargv) {
180                     ret = -1;
181                     goto out;
182                 }
183                 /*
184                  * AFAIK we can't portably pass through our new wargv to
185                  * el_wset(), so we have to reimplement the body of
186                  * el_wset() for these ops.
187                  */
188                 switch (op) {
189                 case EL_BIND:
190                         wargv[0] = STR("bind");
191                         ret = map_bind(el, i, wargv);
192                         break;
193                 case EL_TELLTC:
194                         wargv[0] = STR("telltc");
195                         ret = terminal_telltc(el, i, wargv);
196                         break;
197                 case EL_SETTC:
198                         wargv[0] = STR("settc");
199                         ret = terminal_settc(el, i, wargv);
200                         break;
201                 case EL_ECHOTC:
202                         wargv[0] = STR("echotc");
203                         ret = terminal_echotc(el, i, wargv);
204                         break;
205                 case EL_SETTY:
206                         wargv[0] = STR("setty");
207                         ret = tty_stty(el, i, wargv);
208                         break;
209                 default:
210                         ret = -1;
211                 }
212                 ct_free_argv(wargv);
213                 break;
214         }
215
216         /* XXX: do we need to change el_func_t too? */
217         case EL_ADDFN: {          /* const char *, const char *, el_func_t */
218                 const char *args[2];
219                 el_func_t func;
220                 wchar_t **wargv;
221
222                 args[0] = va_arg(ap, const char *);
223                 args[1] = va_arg(ap, const char *);
224                 func = va_arg(ap, el_func_t);
225
226                 wargv = ct_decode_argv(2, args, &el->el_lgcyconv);
227                 if (!wargv) {
228                     ret = -1;
229                     goto out;
230                 }
231                 /* XXX: The two strdup's leak */
232                 ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]),
233                     func);
234                 ct_free_argv(wargv);
235                 break;
236         }
237         case EL_HIST: {           /* hist_fun_t, const char * */
238                 hist_fun_t fun = va_arg(ap, hist_fun_t);
239                 void *ptr = va_arg(ap, void *);
240                 ret = hist_set(el, fun, ptr);
241                 el->el_flags |= NARROW_HISTORY;
242                 break;
243         }
244
245         case EL_GETCFN:         /* el_rfunc_t */
246                 ret = el_wset(el, op, va_arg(ap, el_rfunc_t));
247                 break;
248
249         case EL_CLIENTDATA:     /* void * */
250                 ret = el_wset(el, op, va_arg(ap, void *));
251                 break;
252
253         case EL_SETFP: {          /* int, FILE * */
254                 int what = va_arg(ap, int);
255                 FILE *fp = va_arg(ap, FILE *);
256                 ret = el_wset(el, op, what, fp);
257                 break;
258         }
259
260         case EL_REFRESH:
261                 re_clear_display(el);
262                 re_refresh(el);
263                 terminal__flush(el);
264                 ret = 0;
265                 break;
266
267         default:
268                 ret = -1;
269                 break;
270         }
271
272 out:
273         va_end(ap);
274         return ret;
275 }
276
277
278 public int
279 el_get(EditLine *el, int op, ...)
280 {
281         va_list ap;
282         int ret;
283
284         if (!el)
285                 return -1;
286
287         va_start(ap, op);
288
289         switch (op) {
290         case EL_PROMPT:         /* el_pfunc_t * */
291         case EL_RPROMPT: {
292                 el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
293                 ret = prompt_get(el, p, 0, op);
294                 break;
295         }
296
297         case EL_PROMPT_ESC: /* el_pfunc_t *, char **/
298         case EL_RPROMPT_ESC: {
299                 el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
300                 char *c = va_arg(ap, char *);
301                 wchar_t wc = 0;
302                 ret = prompt_get(el, p, &wc, op);
303                 *c = (char)wc;
304                 break;
305         }
306
307         case EL_EDITOR: {
308                 const char **p = va_arg(ap, const char **);
309                 const wchar_t *pw;
310                 ret = el_wget(el, op, &pw);
311                 *p = ct_encode_string(pw, &el->el_lgcyconv);
312                 if (!el->el_lgcyconv.csize)
313                         ret = -1;
314                 break;
315         }
316
317         case EL_TERMINAL:       /* const char ** */
318                 ret = el_wget(el, op, va_arg(ap, const char **));
319                 break;
320
321         case EL_SIGNAL:         /* int * */
322         case EL_EDITMODE:
323         case EL_UNBUFFERED:
324         case EL_PREP_TERM:
325                 ret = el_wget(el, op, va_arg(ap, int *));
326                 break;
327
328         case EL_GETTC: {
329                 char *argv[20];
330                 static char gettc[] = "gettc";
331                 int i;
332                 for (i = 1; i < (int)__arraycount(argv); ++i)
333                         if ((argv[i] = va_arg(ap, char *)) == NULL)
334                                 break;
335                 argv[0] = gettc;
336                 ret = terminal_gettc(el, i, argv);
337                 break;
338         }
339
340         case EL_GETCFN:         /* el_rfunc_t */
341                 ret = el_wget(el, op, va_arg(ap, el_rfunc_t *));
342                 break;
343
344         case EL_CLIENTDATA:     /* void ** */
345                 ret = el_wget(el, op, va_arg(ap, void **));
346                 break;
347
348         case EL_GETFP: {          /* int, FILE ** */
349                 int what = va_arg(ap, int);
350                 FILE **fpp = va_arg(ap, FILE **);
351                 ret = el_wget(el, op, what, fpp);
352                 break;
353         }
354
355         default:
356                 ret = -1;
357                 break;
358         }
359
360         va_end(ap);
361         return ret;
362 }
363
364
365 const LineInfo *
366 el_line(EditLine *el)
367 {
368         const LineInfoW *winfo = el_wline(el);
369         LineInfo *info = &el->el_lgcylinfo;
370         size_t offset;
371         const Char *p;
372
373         info->buffer   = ct_encode_string(winfo->buffer, &el->el_lgcyconv);
374
375         offset = 0;
376         for (p = winfo->buffer; p < winfo->cursor; p++)
377                 offset += ct_enc_width(*p);
378         info->cursor = info->buffer + offset;
379
380         offset = 0;
381         for (p = winfo->buffer; p < winfo->lastchar; p++)
382                 offset += ct_enc_width(*p);
383         info->lastchar = info->buffer + offset;
384
385         return info;
386 }
387
388
389 int
390 el_insertstr(EditLine *el, const char *str)
391 {
392         return el_winsertstr(el, ct_decode_string(str, &el->el_lgcyconv));
393 }
394 #endif /* WIDECHAR */