| GCC Code Coverage Report | |||||||||||||||||||||
        
  | 
    |||||||||||||||||||||
| Line | Branch | Exec | Source | 
1  | 
    /* $OpenBSD: el.c,v 1.37 2017/04/12 18:24:37 tb Exp $ */  | 
    ||
2  | 
    /* $NetBSD: el.c,v 1.61 2011/01/27 23:11:40 christos Exp $ */  | 
    ||
3  | 
    |||
4  | 
    /*-  | 
    ||
5  | 
    * Copyright (c) 1992, 1993  | 
    ||
6  | 
    * The Regents of the University of California. All rights reserved.  | 
    ||
7  | 
    *  | 
    ||
8  | 
    * This code is derived from software contributed to Berkeley by  | 
    ||
9  | 
    * Christos Zoulas of Cornell University.  | 
    ||
10  | 
    *  | 
    ||
11  | 
    * Redistribution and use in source and binary forms, with or without  | 
    ||
12  | 
    * modification, are permitted provided that the following conditions  | 
    ||
13  | 
    * are met:  | 
    ||
14  | 
    * 1. Redistributions of source code must retain the above copyright  | 
    ||
15  | 
    * notice, this list of conditions and the following disclaimer.  | 
    ||
16  | 
    * 2. Redistributions in binary form must reproduce the above copyright  | 
    ||
17  | 
    * notice, this list of conditions and the following disclaimer in the  | 
    ||
18  | 
    * documentation and/or other materials provided with the distribution.  | 
    ||
19  | 
    * 3. Neither the name of the University nor the names of its contributors  | 
    ||
20  | 
    * may be used to endorse or promote products derived from this software  | 
    ||
21  | 
    * without specific prior written permission.  | 
    ||
22  | 
    *  | 
    ||
23  | 
    * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND  | 
    ||
24  | 
    * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  | 
    ||
25  | 
    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  | 
    ||
26  | 
    * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE  | 
    ||
27  | 
    * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  | 
    ||
28  | 
    * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  | 
    ||
29  | 
    * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  | 
    ||
30  | 
    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  | 
    ||
31  | 
    * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  | 
    ||
32  | 
    * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  | 
    ||
33  | 
    * SUCH DAMAGE.  | 
    ||
34  | 
    */  | 
    ||
35  | 
    |||
36  | 
    #include "config.h"  | 
    ||
37  | 
    |||
38  | 
    /*  | 
    ||
39  | 
    * el.c: EditLine interface functions  | 
    ||
40  | 
    */  | 
    ||
41  | 
    #include <sys/types.h>  | 
    ||
42  | 
    #include <ctype.h>  | 
    ||
43  | 
    #include <langinfo.h>  | 
    ||
44  | 
    #include <limits.h>  | 
    ||
45  | 
    #include <locale.h>  | 
    ||
46  | 
    #include <stdarg.h>  | 
    ||
47  | 
    #include <stdlib.h>  | 
    ||
48  | 
    #include <string.h>  | 
    ||
49  | 
    |||
50  | 
    #include "el.h"  | 
    ||
51  | 
    #include "parse.h"  | 
    ||
52  | 
    #include "read.h"  | 
    ||
53  | 
    |||
54  | 
    /* el_init():  | 
    ||
55  | 
    * Initialize editline and set default parameters.  | 
    ||
56  | 
    */  | 
    ||
57  | 
    EditLine *  | 
    ||
58  | 
    el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)  | 
    ||
59  | 
    { | 
    ||
60  | 
    6  | 
    EditLine *el = (EditLine *) calloc(1, sizeof(EditLine));  | 
    |
61  | 
    |||
62  | 
    ✗✓ | 3  | 
    if (el == NULL)  | 
    
63  | 
    return NULL;  | 
    ||
64  | 
    |||
65  | 
    3  | 
    el->el_infile = fin;  | 
    |
66  | 
    3  | 
    el->el_outfile = fout;  | 
    |
67  | 
    3  | 
    el->el_errfile = ferr;  | 
    |
68  | 
    |||
69  | 
    ✓✗ | 9  | 
    el->el_infd = fileno(fin);  | 
    
70  | 
    ✓✗ | 9  | 
    el->el_outfd = fileno(fout);  | 
    
71  | 
    ✓✗ | 9  | 
    el->el_errfd = fileno(ferr);  | 
    
72  | 
    |||
73  | 
    3  | 
    el->el_prog = wcsdup(ct_decode_string(prog, &el->el_scratch));  | 
    |
74  | 
    ✗✓ | 3  | 
    	if (el->el_prog == NULL) { | 
    
75  | 
    free(el);  | 
    ||
76  | 
    return NULL;  | 
    ||
77  | 
    }  | 
    ||
78  | 
    |||
79  | 
    /*  | 
    ||
80  | 
    * Initialize all the modules. Order is important!!!  | 
    ||
81  | 
    */  | 
    ||
82  | 
    3  | 
    el->el_flags = 0;  | 
    |
83  | 
    ✓✗ | 3  | 
    	if (setlocale(LC_CTYPE, NULL) != NULL){ | 
    
84  | 
    ✗✓ | 3  | 
    if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)  | 
    
85  | 
    el->el_flags |= CHARSET_IS_UTF8;  | 
    ||
86  | 
    }  | 
    ||
87  | 
    |||
88  | 
    ✗✓ | 3  | 
    	if (terminal_init(el) == -1) { | 
    
89  | 
    free(el->el_prog);  | 
    ||
90  | 
    free(el);  | 
    ||
91  | 
    return NULL;  | 
    ||
92  | 
    }  | 
    ||
93  | 
    3  | 
    (void) keymacro_init(el);  | 
    |
94  | 
    3  | 
    (void) map_init(el);  | 
    |
95  | 
    ✓✓ | 3  | 
    if (tty_init(el) == -1)  | 
    
96  | 
    1  | 
    el->el_flags |= NO_TTY;  | 
    |
97  | 
    3  | 
    (void) ch_init(el);  | 
    |
98  | 
    3  | 
    (void) search_init(el);  | 
    |
99  | 
    3  | 
    (void) hist_init(el);  | 
    |
100  | 
    3  | 
    (void) prompt_init(el);  | 
    |
101  | 
    3  | 
    (void) sig_init(el);  | 
    |
102  | 
    ✗✓ | 3  | 
    	if (read_init(el) == -1) { | 
    
103  | 
    el_end(el);  | 
    ||
104  | 
    return NULL;  | 
    ||
105  | 
    }  | 
    ||
106  | 
    3  | 
    return el;  | 
    |
107  | 
    3  | 
    }  | 
    |
108  | 
    |||
109  | 
    |||
110  | 
    /* el_end():  | 
    ||
111  | 
    * Clean up.  | 
    ||
112  | 
    */  | 
    ||
113  | 
    void  | 
    ||
114  | 
    el_end(EditLine *el)  | 
    ||
115  | 
    { | 
    ||
116  | 
    |||
117  | 
    if (el == NULL)  | 
    ||
118  | 
    return;  | 
    ||
119  | 
    |||
120  | 
    el_reset(el);  | 
    ||
121  | 
    |||
122  | 
    terminal_end(el);  | 
    ||
123  | 
    keymacro_end(el);  | 
    ||
124  | 
    map_end(el);  | 
    ||
125  | 
    tty_end(el);  | 
    ||
126  | 
    ch_end(el);  | 
    ||
127  | 
    read_end(el->el_read);  | 
    ||
128  | 
    search_end(el);  | 
    ||
129  | 
    hist_end(el);  | 
    ||
130  | 
    prompt_end(el);  | 
    ||
131  | 
    sig_end(el);  | 
    ||
132  | 
    |||
133  | 
    free(el->el_prog);  | 
    ||
134  | 
    free(el->el_scratch.cbuff);  | 
    ||
135  | 
    free(el->el_scratch.wbuff);  | 
    ||
136  | 
    free(el->el_lgcyconv.cbuff);  | 
    ||
137  | 
    free(el->el_lgcyconv.wbuff);  | 
    ||
138  | 
    free(el);  | 
    ||
139  | 
    }  | 
    ||
140  | 
    |||
141  | 
    |||
142  | 
    /* el_reset():  | 
    ||
143  | 
    * Reset the tty and the parser  | 
    ||
144  | 
    */  | 
    ||
145  | 
    void  | 
    ||
146  | 
    el_reset(EditLine *el)  | 
    ||
147  | 
    { | 
    ||
148  | 
    |||
149  | 
    tty_cookedmode(el);  | 
    ||
150  | 
    ch_reset(el); /* XXX: Do we want that? */  | 
    ||
151  | 
    }  | 
    ||
152  | 
    |||
153  | 
    |||
154  | 
    /* el_set():  | 
    ||
155  | 
    * set the editline parameters  | 
    ||
156  | 
    */  | 
    ||
157  | 
    int  | 
    ||
158  | 
    el_wset(EditLine *el, int op, ...)  | 
    ||
159  | 
    { | 
    ||
160  | 
    12  | 
    va_list ap;  | 
    |
161  | 
    int rv = 0;  | 
    ||
162  | 
    |||
163  | 
    ✗✓ | 6  | 
    if (el == NULL)  | 
    
164  | 
    return -1;  | 
    ||
165  | 
    6  | 
    va_start(ap, op);  | 
    |
166  | 
    |||
167  | 
    ✗✗✗✗ ✗✗✓✓ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗  | 
    6  | 
    	switch (op) { | 
    
168  | 
    case EL_PROMPT:  | 
    ||
169  | 
    	case EL_RPROMPT: { | 
    ||
170  | 
    el_pfunc_t p = va_arg(ap, el_pfunc_t);  | 
    ||
171  | 
    |||
172  | 
    rv = prompt_set(el, p, 0, op, 1);  | 
    ||
173  | 
    break;  | 
    ||
174  | 
    }  | 
    ||
175  | 
    |||
176  | 
    	case EL_RESIZE: { | 
    ||
177  | 
    el_zfunc_t p = va_arg(ap, el_zfunc_t);  | 
    ||
178  | 
    void *arg = va_arg(ap, void *);  | 
    ||
179  | 
    rv = ch_resizefun(el, p, arg);  | 
    ||
180  | 
    break;  | 
    ||
181  | 
    }  | 
    ||
182  | 
    |||
183  | 
    case EL_PROMPT_ESC:  | 
    ||
184  | 
    	case EL_RPROMPT_ESC: { | 
    ||
185  | 
    el_pfunc_t p = va_arg(ap, el_pfunc_t);  | 
    ||
186  | 
    int c = va_arg(ap, int);  | 
    ||
187  | 
    |||
188  | 
    rv = prompt_set(el, p, c, op, 1);  | 
    ||
189  | 
    break;  | 
    ||
190  | 
    }  | 
    ||
191  | 
    |||
192  | 
    case EL_TERMINAL:  | 
    ||
193  | 
    rv = terminal_set(el, va_arg(ap, char *));  | 
    ||
194  | 
    break;  | 
    ||
195  | 
    |||
196  | 
    case EL_EDITOR:  | 
    ||
197  | 
    ✓✗ | 9  | 
    rv = map_set_editor(el, va_arg(ap, wchar_t *));  | 
    
198  | 
    3  | 
    break;  | 
    |
199  | 
    |||
200  | 
    case EL_SIGNAL:  | 
    ||
201  | 
    ✓✗ | 12  | 
    if (va_arg(ap, int))  | 
    
202  | 
    3  | 
    el->el_flags |= HANDLE_SIGNALS;  | 
    |
203  | 
    else  | 
    ||
204  | 
    3  | 
    el->el_flags &= ~HANDLE_SIGNALS;  | 
    |
205  | 
    3  | 
    break;  | 
    |
206  | 
    |||
207  | 
    case EL_BIND:  | 
    ||
208  | 
    case EL_TELLTC:  | 
    ||
209  | 
    case EL_SETTC:  | 
    ||
210  | 
    case EL_ECHOTC:  | 
    ||
211  | 
    case EL_SETTY:  | 
    ||
212  | 
    	{ | 
    ||
213  | 
    const wchar_t *argv[20];  | 
    ||
214  | 
    int i;  | 
    ||
215  | 
    |||
216  | 
    for (i = 1; i < 20; i++)  | 
    ||
217  | 
    if ((argv[i] = va_arg(ap, wchar_t *)) == NULL)  | 
    ||
218  | 
    break;  | 
    ||
219  | 
    |||
220  | 
    		switch (op) { | 
    ||
221  | 
    case EL_BIND:  | 
    ||
222  | 
    argv[0] = L"bind";  | 
    ||
223  | 
    rv = map_bind(el, i, argv);  | 
    ||
224  | 
    break;  | 
    ||
225  | 
    |||
226  | 
    case EL_TELLTC:  | 
    ||
227  | 
    argv[0] = L"telltc";  | 
    ||
228  | 
    rv = terminal_telltc(el, i, argv);  | 
    ||
229  | 
    break;  | 
    ||
230  | 
    |||
231  | 
    case EL_SETTC:  | 
    ||
232  | 
    argv[0] = L"settc";  | 
    ||
233  | 
    rv = terminal_settc(el, i, argv);  | 
    ||
234  | 
    break;  | 
    ||
235  | 
    |||
236  | 
    case EL_ECHOTC:  | 
    ||
237  | 
    argv[0] = L"echotc";  | 
    ||
238  | 
    rv = terminal_echotc(el, i, argv);  | 
    ||
239  | 
    break;  | 
    ||
240  | 
    |||
241  | 
    case EL_SETTY:  | 
    ||
242  | 
    argv[0] = L"setty";  | 
    ||
243  | 
    rv = tty_stty(el, i, argv);  | 
    ||
244  | 
    break;  | 
    ||
245  | 
    |||
246  | 
    default:  | 
    ||
247  | 
    rv = -1;  | 
    ||
248  | 
    EL_ABORT((el->el_errfile, "Bad op %d\n", op));  | 
    ||
249  | 
    break;  | 
    ||
250  | 
    }  | 
    ||
251  | 
    break;  | 
    ||
252  | 
    }  | 
    ||
253  | 
    |||
254  | 
    case EL_ADDFN:  | 
    ||
255  | 
    	{ | 
    ||
256  | 
    wchar_t *name = va_arg(ap, wchar_t *);  | 
    ||
257  | 
    wchar_t *help = va_arg(ap, wchar_t *);  | 
    ||
258  | 
    el_func_t func = va_arg(ap, el_func_t);  | 
    ||
259  | 
    |||
260  | 
    rv = map_addfunc(el, name, help, func);  | 
    ||
261  | 
    break;  | 
    ||
262  | 
    }  | 
    ||
263  | 
    |||
264  | 
    case EL_HIST:  | 
    ||
265  | 
    	{ | 
    ||
266  | 
    hist_fun_t func = va_arg(ap, hist_fun_t);  | 
    ||
267  | 
    void *ptr = va_arg(ap, void *);  | 
    ||
268  | 
    |||
269  | 
    rv = hist_set(el, func, ptr);  | 
    ||
270  | 
    if (!(el->el_flags & CHARSET_IS_UTF8))  | 
    ||
271  | 
    el->el_flags &= ~NARROW_HISTORY;  | 
    ||
272  | 
    break;  | 
    ||
273  | 
    }  | 
    ||
274  | 
    |||
275  | 
    case EL_EDITMODE:  | 
    ||
276  | 
    if (va_arg(ap, int))  | 
    ||
277  | 
    el->el_flags &= ~EDIT_DISABLED;  | 
    ||
278  | 
    else  | 
    ||
279  | 
    el->el_flags |= EDIT_DISABLED;  | 
    ||
280  | 
    rv = 0;  | 
    ||
281  | 
    break;  | 
    ||
282  | 
    |||
283  | 
    case EL_GETCFN:  | 
    ||
284  | 
    	{ | 
    ||
285  | 
    el_rfunc_t rc = va_arg(ap, el_rfunc_t);  | 
    ||
286  | 
    rv = el_read_setfn(el->el_read, rc);  | 
    ||
287  | 
    break;  | 
    ||
288  | 
    }  | 
    ||
289  | 
    |||
290  | 
    case EL_CLIENTDATA:  | 
    ||
291  | 
    el->el_data = va_arg(ap, void *);  | 
    ||
292  | 
    break;  | 
    ||
293  | 
    |||
294  | 
    case EL_UNBUFFERED:  | 
    ||
295  | 
    rv = va_arg(ap, int);  | 
    ||
296  | 
    		if (rv && !(el->el_flags & UNBUFFERED)) { | 
    ||
297  | 
    el->el_flags |= UNBUFFERED;  | 
    ||
298  | 
    read_prepare(el);  | 
    ||
299  | 
    		} else if (!rv && (el->el_flags & UNBUFFERED)) { | 
    ||
300  | 
    el->el_flags &= ~UNBUFFERED;  | 
    ||
301  | 
    read_finish(el);  | 
    ||
302  | 
    }  | 
    ||
303  | 
    rv = 0;  | 
    ||
304  | 
    break;  | 
    ||
305  | 
    |||
306  | 
    case EL_PREP_TERM:  | 
    ||
307  | 
    rv = va_arg(ap, int);  | 
    ||
308  | 
    if (rv)  | 
    ||
309  | 
    (void) tty_rawmode(el);  | 
    ||
310  | 
    else  | 
    ||
311  | 
    (void) tty_cookedmode(el);  | 
    ||
312  | 
    rv = 0;  | 
    ||
313  | 
    break;  | 
    ||
314  | 
    |||
315  | 
    case EL_SETFP:  | 
    ||
316  | 
    	{ | 
    ||
317  | 
    FILE *fp;  | 
    ||
318  | 
    int what;  | 
    ||
319  | 
    |||
320  | 
    what = va_arg(ap, int);  | 
    ||
321  | 
    fp = va_arg(ap, FILE *);  | 
    ||
322  | 
    |||
323  | 
    rv = 0;  | 
    ||
324  | 
    		switch (what) { | 
    ||
325  | 
    case 0:  | 
    ||
326  | 
    el->el_infile = fp;  | 
    ||
327  | 
    el->el_infd = fileno(fp);  | 
    ||
328  | 
    break;  | 
    ||
329  | 
    case 1:  | 
    ||
330  | 
    el->el_outfile = fp;  | 
    ||
331  | 
    el->el_outfd = fileno(fp);  | 
    ||
332  | 
    break;  | 
    ||
333  | 
    case 2:  | 
    ||
334  | 
    el->el_errfile = fp;  | 
    ||
335  | 
    el->el_errfd = fileno(fp);  | 
    ||
336  | 
    break;  | 
    ||
337  | 
    default:  | 
    ||
338  | 
    rv = -1;  | 
    ||
339  | 
    break;  | 
    ||
340  | 
    }  | 
    ||
341  | 
    break;  | 
    ||
342  | 
    }  | 
    ||
343  | 
    |||
344  | 
    case EL_REFRESH:  | 
    ||
345  | 
    re_clear_display(el);  | 
    ||
346  | 
    re_refresh(el);  | 
    ||
347  | 
    terminal__flush(el);  | 
    ||
348  | 
    break;  | 
    ||
349  | 
    |||
350  | 
    default:  | 
    ||
351  | 
    rv = -1;  | 
    ||
352  | 
    break;  | 
    ||
353  | 
    }  | 
    ||
354  | 
    |||
355  | 
    6  | 
    va_end(ap);  | 
    |
356  | 
    6  | 
    return rv;  | 
    |
357  | 
    6  | 
    }  | 
    |
358  | 
    |||
359  | 
    |||
360  | 
    /* el_get():  | 
    ||
361  | 
    * retrieve the editline parameters  | 
    ||
362  | 
    */  | 
    ||
363  | 
    int  | 
    ||
364  | 
    el_wget(EditLine *el, int op, ...)  | 
    ||
365  | 
    { | 
    ||
366  | 
    6  | 
    va_list ap;  | 
    |
367  | 
    int rv;  | 
    ||
368  | 
    |||
369  | 
    ✗✓ | 3  | 
    if (el == NULL)  | 
    
370  | 
    return -1;  | 
    ||
371  | 
    |||
372  | 
    3  | 
    va_start(ap, op);  | 
    |
373  | 
    |||
374  | 
    ✗✗✗✗ ✗✗✗✓ ✗✗✗✗ ✗✗  | 
    3  | 
    	switch (op) { | 
    
375  | 
    case EL_PROMPT:  | 
    ||
376  | 
    	case EL_RPROMPT: { | 
    ||
377  | 
    el_pfunc_t *p = va_arg(ap, el_pfunc_t *);  | 
    ||
378  | 
    rv = prompt_get(el, p, 0, op);  | 
    ||
379  | 
    break;  | 
    ||
380  | 
    }  | 
    ||
381  | 
    case EL_PROMPT_ESC:  | 
    ||
382  | 
    	case EL_RPROMPT_ESC: { | 
    ||
383  | 
    el_pfunc_t *p = va_arg(ap, el_pfunc_t *);  | 
    ||
384  | 
    wchar_t *c = va_arg(ap, wchar_t *);  | 
    ||
385  | 
    |||
386  | 
    rv = prompt_get(el, p, c, op);  | 
    ||
387  | 
    break;  | 
    ||
388  | 
    }  | 
    ||
389  | 
    |||
390  | 
    case EL_EDITOR:  | 
    ||
391  | 
    rv = map_get_editor(el, va_arg(ap, const wchar_t **));  | 
    ||
392  | 
    break;  | 
    ||
393  | 
    |||
394  | 
    case EL_SIGNAL:  | 
    ||
395  | 
    *va_arg(ap, int *) = (el->el_flags & HANDLE_SIGNALS);  | 
    ||
396  | 
    rv = 0;  | 
    ||
397  | 
    break;  | 
    ||
398  | 
    |||
399  | 
    case EL_EDITMODE:  | 
    ||
400  | 
    *va_arg(ap, int *) = !(el->el_flags & EDIT_DISABLED);  | 
    ||
401  | 
    rv = 0;  | 
    ||
402  | 
    break;  | 
    ||
403  | 
    |||
404  | 
    case EL_TERMINAL:  | 
    ||
405  | 
    ✓✗ | 9  | 
    terminal_get(el, va_arg(ap, const char **));  | 
    
406  | 
    rv = 0;  | 
    ||
407  | 
    3  | 
    break;  | 
    |
408  | 
    |||
409  | 
    case EL_GETTC:  | 
    ||
410  | 
    	{ | 
    ||
411  | 
    static char name[] = "gettc";  | 
    ||
412  | 
    char *argv[20];  | 
    ||
413  | 
    int i;  | 
    ||
414  | 
    |||
415  | 
    for (i = 1; i < (int)(sizeof(argv) / sizeof(argv[0])); i++)  | 
    ||
416  | 
    if ((argv[i] = va_arg(ap, char *)) == NULL)  | 
    ||
417  | 
    break;  | 
    ||
418  | 
    |||
419  | 
    		switch (op) { | 
    ||
420  | 
    case EL_GETTC:  | 
    ||
421  | 
    argv[0] = name;  | 
    ||
422  | 
    rv = terminal_gettc(el, i, argv);  | 
    ||
423  | 
    break;  | 
    ||
424  | 
    |||
425  | 
    default:  | 
    ||
426  | 
    rv = -1;  | 
    ||
427  | 
    EL_ABORT((el->el_errfile, "Bad op %d\n", op));  | 
    ||
428  | 
    break;  | 
    ||
429  | 
    }  | 
    ||
430  | 
    break;  | 
    ||
431  | 
    }  | 
    ||
432  | 
    |||
433  | 
    case EL_GETCFN:  | 
    ||
434  | 
    *va_arg(ap, el_rfunc_t *) = el_read_getfn(el->el_read);  | 
    ||
435  | 
    rv = 0;  | 
    ||
436  | 
    break;  | 
    ||
437  | 
    |||
438  | 
    case EL_CLIENTDATA:  | 
    ||
439  | 
    *va_arg(ap, void **) = el->el_data;  | 
    ||
440  | 
    rv = 0;  | 
    ||
441  | 
    break;  | 
    ||
442  | 
    |||
443  | 
    case EL_UNBUFFERED:  | 
    ||
444  | 
    *va_arg(ap, int *) = (!(el->el_flags & UNBUFFERED));  | 
    ||
445  | 
    rv = 0;  | 
    ||
446  | 
    break;  | 
    ||
447  | 
    |||
448  | 
    case EL_GETFP:  | 
    ||
449  | 
    	{ | 
    ||
450  | 
    int what;  | 
    ||
451  | 
    FILE **fpp;  | 
    ||
452  | 
    |||
453  | 
    what = va_arg(ap, int);  | 
    ||
454  | 
    fpp = va_arg(ap, FILE **);  | 
    ||
455  | 
    rv = 0;  | 
    ||
456  | 
    		switch (what) { | 
    ||
457  | 
    case 0:  | 
    ||
458  | 
    *fpp = el->el_infile;  | 
    ||
459  | 
    break;  | 
    ||
460  | 
    case 1:  | 
    ||
461  | 
    *fpp = el->el_outfile;  | 
    ||
462  | 
    break;  | 
    ||
463  | 
    case 2:  | 
    ||
464  | 
    *fpp = el->el_errfile;  | 
    ||
465  | 
    break;  | 
    ||
466  | 
    default:  | 
    ||
467  | 
    rv = -1;  | 
    ||
468  | 
    break;  | 
    ||
469  | 
    }  | 
    ||
470  | 
    break;  | 
    ||
471  | 
    }  | 
    ||
472  | 
    default:  | 
    ||
473  | 
    rv = -1;  | 
    ||
474  | 
    break;  | 
    ||
475  | 
    }  | 
    ||
476  | 
    3  | 
    va_end(ap);  | 
    |
477  | 
    |||
478  | 
    3  | 
    return rv;  | 
    |
479  | 
    3  | 
    }  | 
    |
480  | 
    |||
481  | 
    |||
482  | 
    /* el_line():  | 
    ||
483  | 
    * Return editing info  | 
    ||
484  | 
    */  | 
    ||
485  | 
    const LineInfoW *  | 
    ||
486  | 
    el_wline(EditLine *el)  | 
    ||
487  | 
    { | 
    ||
488  | 
    |||
489  | 
    12  | 
    return (const LineInfoW *)(void *)&el->el_line;  | 
    |
490  | 
    }  | 
    ||
491  | 
    |||
492  | 
    |||
493  | 
    /* el_source():  | 
    ||
494  | 
    * Source a file  | 
    ||
495  | 
    */  | 
    ||
496  | 
    int  | 
    ||
497  | 
    el_source(EditLine *el, const char *fname)  | 
    ||
498  | 
    { | 
    ||
499  | 
    FILE *fp;  | 
    ||
500  | 
    6  | 
    size_t len;  | 
    |
501  | 
    ssize_t slen;  | 
    ||
502  | 
    3  | 
    char *ptr;  | 
    |
503  | 
    #ifdef HAVE_ISSETUGID  | 
    ||
504  | 
    3  | 
    char path[PATH_MAX];  | 
    |
505  | 
    #endif  | 
    ||
506  | 
    const wchar_t *dptr;  | 
    ||
507  | 
    |||
508  | 
    fp = NULL;  | 
    ||
509  | 
    ✓✗ | 3  | 
    	if (fname == NULL) { | 
    
510  | 
    #ifdef HAVE_ISSETUGID  | 
    ||
511  | 
    static const char elpath[] = "/.editrc";  | 
    ||
512  | 
    |||
513  | 
    ✗✓ | 3  | 
    if (issetugid())  | 
    
514  | 
    return -1;  | 
    ||
515  | 
    ✗✓ | 3  | 
    		if ((ptr = getenv("HOME")) == NULL) | 
    
516  | 
    return -1;  | 
    ||
517  | 
    ✗✓ | 3  | 
    if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))  | 
    
518  | 
    return -1;  | 
    ||
519  | 
    ✗✓ | 3  | 
    if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))  | 
    
520  | 
    return -1;  | 
    ||
521  | 
    fname = path;  | 
    ||
522  | 
    #else  | 
    ||
523  | 
    /*  | 
    ||
524  | 
    * If issetugid() is missing, always return an error, in order  | 
    ||
525  | 
    * to keep from inadvertently opening up the user to a security  | 
    ||
526  | 
    * hole.  | 
    ||
527  | 
    */  | 
    ||
528  | 
    return -1;  | 
    ||
529  | 
    #endif  | 
    ||
530  | 
    3  | 
    }  | 
    |
531  | 
    ✓✗ | 3  | 
    if (fp == NULL)  | 
    
532  | 
    3  | 
    fp = fopen(fname, "r");  | 
    |
533  | 
    ✓✗ | 3  | 
    if (fp == NULL)  | 
    
534  | 
    3  | 
    return -1;  | 
    |
535  | 
    |||
536  | 
    ptr = NULL;  | 
    ||
537  | 
    len = 0;  | 
    ||
538  | 
    	while ((slen = getline(&ptr, &len, fp)) != -1) { | 
    ||
539  | 
    if (*ptr == '\n')  | 
    ||
540  | 
    continue; /* Empty line. */  | 
    ||
541  | 
    if (slen > 0 && ptr[--slen] == '\n')  | 
    ||
542  | 
    ptr[slen] = '\0';  | 
    ||
543  | 
    |||
544  | 
    dptr = ct_decode_string(ptr, &el->el_scratch);  | 
    ||
545  | 
    if (!dptr)  | 
    ||
546  | 
    continue;  | 
    ||
547  | 
    /* loop until first non-space char or EOL */  | 
    ||
548  | 
    while (*dptr != '\0' && iswspace(*dptr))  | 
    ||
549  | 
    dptr++;  | 
    ||
550  | 
    if (*dptr == '#')  | 
    ||
551  | 
    continue; /* ignore, this is a comment line */  | 
    ||
552  | 
    		if (parse_line(el, dptr) == -1) { | 
    ||
553  | 
    free(ptr);  | 
    ||
554  | 
    (void) fclose(fp);  | 
    ||
555  | 
    return -1;  | 
    ||
556  | 
    }  | 
    ||
557  | 
    }  | 
    ||
558  | 
    free(ptr);  | 
    ||
559  | 
    (void) fclose(fp);  | 
    ||
560  | 
    return 0;  | 
    ||
561  | 
    3  | 
    }  | 
    |
562  | 
    |||
563  | 
    |||
564  | 
    /* el_resize():  | 
    ||
565  | 
    * Called from program when terminal is resized  | 
    ||
566  | 
    */  | 
    ||
567  | 
    void  | 
    ||
568  | 
    el_resize(EditLine *el)  | 
    ||
569  | 
    { | 
    ||
570  | 
    int lins, cols;  | 
    ||
571  | 
    sigset_t oset, nset;  | 
    ||
572  | 
    |||
573  | 
    (void) sigemptyset(&nset);  | 
    ||
574  | 
    (void) sigaddset(&nset, SIGWINCH);  | 
    ||
575  | 
    (void) sigprocmask(SIG_BLOCK, &nset, &oset);  | 
    ||
576  | 
    |||
577  | 
    /* get the correct window size */  | 
    ||
578  | 
    if (terminal_get_size(el, &lins, &cols))  | 
    ||
579  | 
    terminal_change_size(el, lins, cols);  | 
    ||
580  | 
    |||
581  | 
    (void) sigprocmask(SIG_SETMASK, &oset, NULL);  | 
    ||
582  | 
    }  | 
    ||
583  | 
    |||
584  | 
    |||
585  | 
    /* el_beep():  | 
    ||
586  | 
    * Called from the program to beep  | 
    ||
587  | 
    */  | 
    ||
588  | 
    void  | 
    ||
589  | 
    el_beep(EditLine *el)  | 
    ||
590  | 
    { | 
    ||
591  | 
    |||
592  | 
    terminal_beep(el);  | 
    ||
593  | 
    }  | 
    ||
594  | 
    |||
595  | 
    |||
596  | 
    /* el_editmode()  | 
    ||
597  | 
    * Set the state of EDIT_DISABLED from the `edit' command.  | 
    ||
598  | 
    */  | 
    ||
599  | 
    protected int  | 
    ||
600  | 
    /*ARGSUSED*/  | 
    ||
601  | 
    el_editmode(EditLine *el, int argc, const wchar_t **argv)  | 
    ||
602  | 
    { | 
    ||
603  | 
    const wchar_t *how;  | 
    ||
604  | 
    |||
605  | 
    if (argv == NULL || argc != 2 || argv[1] == NULL)  | 
    ||
606  | 
    return -1;  | 
    ||
607  | 
    |||
608  | 
    how = argv[1];  | 
    ||
609  | 
    	if (wcscmp(how, L"on") == 0) { | 
    ||
610  | 
    el->el_flags &= ~EDIT_DISABLED;  | 
    ||
611  | 
    tty_rawmode(el);  | 
    ||
612  | 
    	} else if (wcscmp(how, L"off") == 0) { | 
    ||
613  | 
    tty_cookedmode(el);  | 
    ||
614  | 
    el->el_flags |= EDIT_DISABLED;  | 
    ||
615  | 
    }  | 
    ||
616  | 
    	else { | 
    ||
617  | 
    (void) fprintf(el->el_errfile, "edit: Bad value `%ls'.\n",  | 
    ||
618  | 
    how);  | 
    ||
619  | 
    return -1;  | 
    ||
620  | 
    }  | 
    ||
621  | 
    return 0;  | 
    ||
622  | 
    }  | 
    
| Generated by: GCOVR (Version 3.3) |