"Fossies" - the Fresh Open Source Software Archive

Member "tnftp-20200705/libedit/parse.c" (4 Jul 2020, 6324 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 "parse.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 20151004_vs_20200705.

    1 /*  $NetBSD: parse.c,v 1.9 2020/07/04 13:43:21 lukem Exp $  */
    2 /*  from    NetBSD: parse.c,v 1.42 2019/07/23 10:18:52 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 #if 0 /* tnftp */
   39 #if !defined(lint) && !defined(SCCSID)
   40 #if 0
   41 static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
   42 #else
   43 __RCSID(" NetBSD: parse.c,v 1.42 2019/07/23 10:18:52 christos Exp  ");
   44 #endif
   45 #endif /* not lint && not SCCSID */
   46 #endif /* tnftp */
   47 
   48 /*
   49  * parse.c: parse an editline extended command
   50  *
   51  * commands are:
   52  *
   53  *  bind
   54  *  echotc
   55  *  edit
   56  *  gettc
   57  *  history
   58  *  settc
   59  *  setty
   60  */
   61 #if 0 /* tnftp */
   62 #include <stdlib.h>
   63 #include <string.h>
   64 #endif /* tnftp */
   65 
   66 #include "el.h"
   67 #include "parse.h"
   68 
   69 static const struct {
   70     const wchar_t *name;
   71     int (*func)(EditLine *, int, const wchar_t **);
   72 } cmds[] = {
   73     { L"bind",      map_bind    },
   74     { L"echotc",        terminal_echotc },
   75     { L"edit",      el_editmode },
   76     { L"history",       hist_command    },
   77     { L"telltc",        terminal_telltc },
   78     { L"settc",     terminal_settc  },
   79     { L"setty",     tty_stty    },
   80     { NULL,         NULL        }
   81 };
   82 
   83 
   84 /* parse_line():
   85  *  Parse a line and dispatch it
   86  */
   87 libedit_private int
   88 parse_line(EditLine *el, const wchar_t *line)
   89 {
   90     const wchar_t **argv;
   91     int argc;
   92     TokenizerW *tok;
   93 
   94     tok = tok_winit(NULL);
   95     tok_wstr(tok, line, &argc, &argv);
   96     argc = el_wparse(el, argc, argv);
   97     tok_wend(tok);
   98     return argc;
   99 }
  100 
  101 
  102 /* el_parse():
  103  *  Command dispatcher
  104  */
  105 int
  106 el_wparse(EditLine *el, int argc, const wchar_t *argv[])
  107 {
  108     const wchar_t *ptr;
  109     int i;
  110 
  111     if (argc < 1)
  112         return -1;
  113     ptr = wcschr(argv[0], L':');
  114     if (ptr != NULL) {
  115         wchar_t *tprog;
  116         size_t l;
  117 
  118         if (ptr == argv[0])
  119             return 0;
  120         l = (size_t)(ptr - argv[0]);
  121         tprog = el_calloc(l + 1, sizeof(*tprog));
  122         if (tprog == NULL)
  123             return 0;
  124         (void) wcsncpy(tprog, argv[0], l);
  125         tprog[l] = '\0';
  126         ptr++;
  127         l = (size_t)el_match(el->el_prog, tprog);
  128         el_free(tprog);
  129         if (!l)
  130             return 0;
  131     } else
  132         ptr = argv[0];
  133 
  134     for (i = 0; cmds[i].name != NULL; i++)
  135         if (wcscmp(cmds[i].name, ptr) == 0) {
  136             i = (*cmds[i].func) (el, argc, argv);
  137             return -i;
  138         }
  139     return -1;
  140 }
  141 
  142 
  143 /* parse__escape():
  144  *  Parse a string of the form ^<char> \<odigit> \<char> \U+xxxx and return
  145  *  the appropriate character or -1 if the escape is not valid
  146  */
  147 libedit_private int
  148 parse__escape(const wchar_t **ptr)
  149 {
  150     const wchar_t *p;
  151     wint_t c;
  152 
  153     p = *ptr;
  154 
  155     if (p[1] == 0)
  156         return -1;
  157 
  158     if (*p == '\\') {
  159         p++;
  160         switch (*p) {
  161         case 'a':
  162             c = '\007'; /* Bell */
  163             break;
  164         case 'b':
  165             c = '\010'; /* Backspace */
  166             break;
  167         case 't':
  168             c = '\011'; /* Horizontal Tab */
  169             break;
  170         case 'n':
  171             c = '\012'; /* New Line */
  172             break;
  173         case 'v':
  174             c = '\013'; /* Vertical Tab */
  175             break;
  176         case 'f':
  177             c = '\014'; /* Form Feed */
  178             break;
  179         case 'r':
  180             c = '\015'; /* Carriage Return */
  181             break;
  182         case 'e':
  183             c = '\033'; /* Escape */
  184             break;
  185         case 'U':       /* Unicode \U+xxxx or \U+xxxxx format */
  186         {
  187             int i;
  188             const wchar_t hex[] = L"0123456789ABCDEF";
  189             const wchar_t *h;
  190             ++p;
  191             if (*p++ != '+')
  192                 return -1;
  193             c = 0;
  194             for (i = 0; i < 5; ++i) {
  195                 h = wcschr(hex, *p++);
  196                 if (!h && i < 4)
  197                     return -1;
  198                 else if (h)
  199                     c = (c << 4) | ((int)(h - hex));
  200                 else
  201                     --p;
  202             }
  203             if (c > 0x10FFFF) /* outside valid character range */
  204                 return -1;
  205             break;
  206         }
  207         case '0':
  208         case '1':
  209         case '2':
  210         case '3':
  211         case '4':
  212         case '5':
  213         case '6':
  214         case '7':
  215         {
  216             int cnt, ch;
  217 
  218             for (cnt = 0, c = 0; cnt < 3; cnt++) {
  219                 ch = *p++;
  220                 if (ch < '0' || ch > '7') {
  221                     p--;
  222                     break;
  223                 }
  224                 c = (c << 3) | (ch - '0');
  225             }
  226             if ((c & (wint_t)0xffffff00) != (wint_t)0)
  227                 return -1;
  228             --p;
  229             break;
  230         }
  231         default:
  232             c = *p;
  233             break;
  234         }
  235     } else if (*p == '^') {
  236         p++;
  237         c = (*p == '?') ? '\177' : (*p & 0237);
  238     } else
  239         c = *p;
  240     *ptr = ++p;
  241     return c;
  242 }
  243 
  244 /* parse__string():
  245  *  Parse the escapes from in and put the raw string out
  246  */
  247 libedit_private wchar_t *
  248 parse__string(wchar_t *out, const wchar_t *in)
  249 {
  250     wchar_t *rv = out;
  251     int n;
  252 
  253     for (;;)
  254         switch (*in) {
  255         case '\0':
  256             *out = '\0';
  257             return rv;
  258 
  259         case '\\':
  260         case '^':
  261             if ((n = parse__escape(&in)) == -1)
  262                 return NULL;
  263             *out++ = (wchar_t)n;
  264             break;
  265 
  266         case 'M':
  267             if (in[1] == '-' && in[2] != '\0') {
  268                 *out++ = '\033';
  269                 in += 2;
  270                 break;
  271             }
  272             /*FALLTHROUGH*/
  273 
  274         default:
  275             *out++ = *in++;
  276             break;
  277         }
  278 }
  279 
  280 
  281 /* parse_cmd():
  282  *  Return the command number for the command string given
  283  *  or -1 if one is not found
  284  */
  285 libedit_private int
  286 parse_cmd(EditLine *el, const wchar_t *cmd)
  287 {
  288     el_bindings_t *b = el->el_map.help;
  289     size_t i;
  290 
  291     for (i = 0; i < el->el_map.nfunc; i++)
  292         if (wcscmp(b[i].name, cmd) == 0)
  293             return b[i].func;
  294     return -1;
  295 }