root/src/noitedit/parse.c

Revision 2c4eb5b5fbb052c18d52a989026b447982cc17c3, 5.6 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

pull header-space into the noitedir dir, this makes it stand apart from libedit more trivially.

  • Property mode set to 100644
Line 
1 /*      $NetBSD: parse.c,v 1.14 2001/01/23 15:55:30 jdolecek Exp $      */
2
3 /*-
4  * Copyright (c) 1992, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Christos Zoulas of Cornell University.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  */
38
39 #include "noitedit/compat.h"
40 #if !defined(lint) && !defined(SCCSID)
41 #if 0
42 static char sccsid[] = "@(#)parse.c     8.1 (Berkeley) 6/4/93";
43 #else
44 __RCSID("$NetBSD: parse.c,v 1.14 2001/01/23 15:55:30 jdolecek Exp $");
45 #endif
46 #endif /* not lint && not SCCSID */
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 #include "noitedit/sys.h"
62 #include "noitedit/el.h"
63 #include "noitedit/tokenizer.h"
64 #include <stdlib.h>
65
66 private const struct {
67         char *name;
68         int (*func)(EditLine *, int, char **);
69 } cmds[] = {
70         { "bind",       map_bind        },
71         { "echotc",     term_echotc     },
72         { "edit",       el_editmode     },
73         { "history",    hist_list       },
74         { "telltc",     term_telltc     },
75         { "settc",      term_settc      },
76         { "setty",      tty_stty        },
77         { NULL,         NULL            }
78 };
79
80
81 /* parse_line():
82  *      Parse a line and dispatch it
83  */
84 protected int
85 parse_line(EditLine *el, const char *line)
86 {
87         char **argv;
88         int argc;
89         Tokenizer *tok;
90
91         tok = tok_init(NULL);
92         tok_line(tok, line, &argc, &argv);
93         argc = el_parse(el, argc, argv);
94         tok_end(tok);
95         return (argc);
96 }
97
98
99 /* el_parse():
100  *      Command dispatcher
101  */
102 public int
103 el_parse(EditLine *el, int argc, char *argv[])
104 {
105         char *ptr;
106         int i;
107
108         if (argc < 1)
109                 return (-1);
110         ptr = strchr(argv[0], ':');
111         if (ptr != NULL) {
112                 char *tprog;
113                 size_t l;
114
115                 if (ptr == argv[0])
116                         return (0);
117                 l = ptr - argv[0] - 1;
118                 tprog = (char *) el_malloc(l + 1);
119                 if (tprog == NULL)
120                         return (0);
121                 (void) strncpy(tprog, argv[0], l);
122                 tprog[l] = '\0';
123                 ptr++;
124                 l = el_match(el->el_prog, tprog);
125                 el_free(tprog);
126                 if (!l)
127                         return (0);
128         } else
129                 ptr = argv[0];
130
131         for (i = 0; cmds[i].name != NULL; i++)
132                 if (strcmp(cmds[i].name, ptr) == 0) {
133                         i = (*cmds[i].func) (el, argc, argv);
134                         return (-i);
135                 }
136         return (-1);
137 }
138
139
140 /* parse__escape():
141  *      Parse a string of the form ^<char> \<odigit> \<char> and return
142  *      the appropriate character or -1 if the escape is not valid
143  */
144 protected int
145 parse__escape(const char **const ptr)
146 {
147         const char *p;
148         int c;
149
150         p = *ptr;
151
152         if (p[1] == 0)
153                 return (-1);
154
155         if (*p == '\\') {
156                 p++;
157                 switch (*p) {
158                 case 'a':
159                         c = '\007';     /* Bell */
160                         break;
161                 case 'b':
162                         c = '\010';     /* Backspace */
163                         break;
164                 case 't':
165                         c = '\011';     /* Horizontal Tab */
166                         break;
167                 case 'n':
168                         c = '\012';     /* New Line */
169                         break;
170                 case 'v':
171                         c = '\013';     /* Vertical Tab */
172                         break;
173                 case 'f':
174                         c = '\014';     /* Form Feed */
175                         break;
176                 case 'r':
177                         c = '\015';     /* Carriage Return */
178                         break;
179                 case 'e':
180                         c = '\033';     /* Escape */
181                         break;
182                 case '0':
183                 case '1':
184                 case '2':
185                 case '3':
186                 case '4':
187                 case '5':
188                 case '6':
189                 case '7':
190                 {
191                         int cnt, ch;
192
193                         for (cnt = 0, c = 0; cnt < 3; cnt++) {
194                                 ch = *p++;
195                                 if (ch < '0' || ch > '7') {
196                                         p--;
197                                         break;
198                                 }
199                                 c = (c << 3) | (ch - '0');
200                         }
201                         if ((c & 0xffffff00) != 0)
202                                 return (-1);
203                         --p;
204                         break;
205                 }
206                 default:
207                         c = *p;
208                         break;
209                 }
210         } else if (*p == '^' && isalpha((unsigned char) p[1])) {
211                 p++;
212                 c = (*p == '?') ? '\177' : (*p & 0237);
213         } else
214                 c = *p;
215         *ptr = ++p;
216         return (c);
217 }
218 /* parse__string():
219  *      Parse the escapes from in and put the raw string out
220  */
221 protected char *
222 parse__string(char *out, const char *in)
223 {
224         char *rv = out;
225         int n;
226
227         for (;;)
228                 switch (*in) {
229                 case '\0':
230                         *out = '\0';
231                         return (rv);
232
233                 case '\\':
234                 case '^':
235                         if ((n = parse__escape(&in)) == -1)
236                                 return (NULL);
237                         *out++ = n;
238                         break;
239
240                 default:
241                         *out++ = *in++;
242                         break;
243                 }
244 }
245
246
247 /* parse_cmd():
248  *      Return the command number for the command string given
249  *      or -1 if one is not found
250  */
251 protected int
252 parse_cmd(EditLine *el, const char *cmd)
253 {
254         el_bindings_t *b;
255
256         for (b = el->el_map.help; b->name != NULL; b++)
257                 if (strcmp(b->name, cmd) == 0)
258                         return (b->func);
259         return (-1);
260 }
Note: See TracBrowser for help on using the browser.