"Fossies" - the Fresh Open Source Software Archive

Member "tnftp-20200705/libedit/eln.c" (4 Jul 2020, 8633 Bytes) of package /linux/privat/tnftp-20200705.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "eln.c" see the Fossies "Dox" file reference documentation.

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