3169a20717114c8aeb62318e4627339ff6217514
[asterisk/asterisk.git] / main / editline / TEST / test.c
1 /*      $NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem 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 "config.h"
40 #ifndef lint
41 __COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
42         The Regents of the University of California.  All rights reserved.\n");
43 #endif /* not lint */
44
45 #if !defined(lint) && !defined(SCCSID)
46 #if 0
47 static char sccsid[] = "@(#)test.c      8.1 (Berkeley) 6/4/93";
48 #else
49 __RCSID("$NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $");
50 #endif
51 #endif /* not lint && not SCCSID */
52
53 /*
54  * test.c: A little test program
55  */
56 #include <stdio.h>
57 #include <string.h>
58 #include <signal.h>
59 #include <sys/wait.h>
60 #include <ctype.h>
61 #include <stdlib.h>
62 #include <unistd.h>
63 #include <dirent.h>
64
65 #include "histedit.h"
66 #include "tokenizer.h"
67
68 static int continuation = 0;
69 static EditLine *el = NULL;
70
71 static  u_char  complete(EditLine *, int);
72         int     main(int, char **);
73 static  char   *prompt(EditLine *);
74 static  void    sig(int);
75
76 static char *
77 prompt(EditLine *el)
78 {
79         static char a[] = "Edit$";
80         static char b[] = "Edit>";
81
82         return (continuation ? b : a);
83 }
84
85 static void
86 sig(int i)
87 {
88
89         (void) fprintf(stderr, "Got signal %d.\n", i);
90         el_reset(el);
91 }
92
93 static unsigned char
94 complete(EditLine *el, int ch)
95 {
96         DIR *dd = opendir(".");
97         struct dirent *dp;
98         const char* ptr;
99         const LineInfo *lf = el_line(el);
100         int len;
101
102         /*
103          * Find the last word
104          */
105         for (ptr = lf->cursor - 1; !isspace(*ptr) && ptr > lf->buffer; ptr--)
106                 continue;
107         len = lf->cursor - ++ptr;
108
109         for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
110                 if (len > strlen(dp->d_name))
111                         continue;
112                 if (strncmp(dp->d_name, ptr, len) == 0) {
113                         closedir(dd);
114                         if (el_insertstr(el, &dp->d_name[len]) == -1)
115                                 return (CC_ERROR);
116                         else
117                                 return (CC_REFRESH);
118                 }
119         }
120
121         closedir(dd);
122         return (CC_ERROR);
123 }
124
125 int
126 main(int argc, char *argv[])
127 {
128         int num;
129         const char *buf;
130         Tokenizer *tok;
131 #if 0
132         int lastevent = 0;
133 #endif
134         int ncontinuation;
135         History *hist;
136         HistEvent ev;
137
138         (void) signal(SIGINT, sig);
139         (void) signal(SIGQUIT, sig);
140         (void) signal(SIGHUP, sig);
141         (void) signal(SIGTERM, sig);
142
143         hist = history_init();          /* Init the builtin history     */
144                                         /* Remember 100 events          */
145         history(hist, &ev, H_SETSIZE, 100);
146
147         tok  = tok_init(NULL);          /* Initialize the tokenizer     */
148
149                                         /* Initialize editline          */
150         el = el_init(*argv, stdin, stdout, stderr);
151
152         el_set(el, EL_EDITOR, "vi");    /* Default editor is vi         */
153         el_set(el, EL_SIGNAL, 1);       /* Handle signals gracefully    */
154         el_set(el, EL_PROMPT, prompt);  /* Set the prompt function      */
155
156                         /* Tell editline to use this history interface  */
157         el_set(el, EL_HIST, history, hist);
158
159                                         /* Add a user-defined function  */
160         el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete);
161
162                                         /* Bind tab to it               */
163         el_set(el, EL_BIND, "^I", "ed-complete", NULL);
164
165         /*
166          * Bind j, k in vi command mode to previous and next line, instead
167          * of previous and next history.
168          */
169         el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL);
170         el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL);
171
172         /*
173          * Source the user's defaults file.
174          */
175         el_source(el, NULL);
176
177         while ((buf = el_gets(el, &num)) != NULL && num != 0)  {
178                 int ac;
179                 const char **av;
180 #ifdef DEBUG
181                 (void) fprintf(stderr, "got %d %s", num, buf);
182 #endif
183                 if (!continuation && num == 1)
184                         continue;
185
186                 ncontinuation = tok_line(tok, buf, &ac, &av) > 0;
187 #if 0
188                 if (continuation) {
189                         /*
190                          * Append to the right event in case the user
191                          * moved around in history.
192                          */
193                         if (history(hist, &ev, H_SET, lastevent) == -1)
194                                 err(1, "%d: %s\n", lastevent, ev.str);
195                         history(hist, &ev, H_ADD , buf);
196                 } else {
197                         history(hist, &ev, H_ENTER, buf);
198                         lastevent = ev.num;
199                 }
200 #else
201                                 /* Simpler */
202                 history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf);
203 #endif
204
205                 continuation = ncontinuation;
206                 ncontinuation = 0;
207
208                 if (strcmp(av[0], "history") == 0) {
209                         int rv;
210
211                         switch (ac) {
212                         case 1:
213                                 for (rv = history(hist, &ev, H_LAST); rv != -1;
214                                     rv = history(hist, &ev, H_PREV))
215                                         (void) fprintf(stdout, "%4d %s",
216                                             ev.num, ev.str);
217                                 break;
218
219                         case 2:
220                                 if (strcmp(av[1], "clear") == 0)
221                                          history(hist, &ev, H_CLEAR);
222                                 else
223                                          goto badhist;
224                                 break;
225
226                         case 3:
227                                 if (strcmp(av[1], "load") == 0)
228                                          history(hist, &ev, H_LOAD, av[2]);
229                                 else if (strcmp(av[1], "save") == 0)
230                                          history(hist, &ev, H_SAVE, av[2]);
231                                 break;
232
233                         badhist:
234                         default:
235                                 (void) fprintf(stderr,
236                                     "Bad history arguments\n");
237                                 break;
238                         }
239                 } else if (el_parse(el, ac, av) == -1) {
240                         switch (fork()) {
241                         case 0:
242                                 execvp(av[0], (char *const *)av);
243                                 perror(av[0]);
244                                 _exit(1);
245                                 /*NOTREACHED*/
246                                 break;
247
248                         case -1:
249                                 perror("fork");
250                                 break;
251
252                         default:
253                                 if (wait(&num) == -1)
254                                         perror("wait");
255                                 (void) fprintf(stderr, "Exit %x\n", num);
256                                 break;
257                         }
258                 }
259
260                 tok_reset(tok);
261         }
262
263         el_end(el);
264         tok_end(tok);
265         history_end(hist);
266
267         return (0);
268 }