Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / lib / libedit / TEST / test.c
1 /*-
2  * Copyright (c) 1992, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Christos Zoulas of Cornell University.
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  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * @(#) Copyright (c) 1992, 1993 The Regents of the University of California.  All rights reserved.
37  * @(#)test.c   8.1 (Berkeley) 6/4/93
38  */
39
40 /*
41  * test.c: A little test program
42  */
43 #include "sys.h"
44 #include <stdio.h>
45 #include <string.h>
46 #include <signal.h>
47 #include <sys/wait.h>
48 #include <ctype.h>
49 #include <stdlib.h>
50 #include <unistd.h>
51 #include <dirent.h>
52
53 #include "histedit.h"
54 #include "tokenizer.h"
55
56 static int continuation = 0;
57 static EditLine *el = NULL;
58
59 static char *
60 /*ARGSUSED*/
61 prompt(el)
62     EditLine *el;
63 {
64     static char a[] = "Edit$";
65     static char b[] = "Edit>";
66     return continuation ? b : a;
67 }
68
69 static void
70 sig(i)
71     int i;
72 {
73     (void) fprintf(stderr, "Got signal %d.\n", i);
74     el_reset(el);
75 }
76
77 static unsigned char
78 /*ARGSUSED*/
79 complete(el, ch)
80     EditLine *el;
81     int ch;
82 {
83     DIR *dd = opendir(".");
84     struct dirent *dp;
85     const char* ptr;
86     const LineInfo *lf = el_line(el);
87     int len;
88
89     /*
90      * Find the last word
91      */
92     for (ptr = lf->cursor - 1; !isspace(*ptr) && ptr > lf->buffer; ptr--)
93         continue;
94     len = lf->cursor - ++ptr;
95
96     for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
97         if (len > strlen(dp->d_name))
98             continue;
99         if (strncmp(dp->d_name, ptr, len) == 0) {
100             closedir(dd);
101             if (el_insertstr(el, &dp->d_name[len]) == -1)
102                 return CC_ERROR;
103             else
104                 return CC_REFRESH;
105         }
106     }
107
108     closedir(dd);
109     return CC_ERROR;
110 }
111
112 int
113 /*ARGSUSED*/
114 main(argc, argv)
115     int argc;
116     char *argv[];
117 {
118     int num;
119     const char *buf;
120     Tokenizer *tok;
121     History *hist;
122
123     (void) signal(SIGINT, sig);
124     (void) signal(SIGQUIT, sig);
125     (void) signal(SIGHUP, sig);
126     (void) signal(SIGTERM, sig);
127
128     hist = history_init();              /* Init the builtin history     */
129     history(hist, H_EVENT, 100);        /* Remember 100 events          */
130
131     tok  = tok_init(NULL);              /* Initialize the tokenizer     */
132
133     el = el_init(*argv, stdin, stdout); /* Initialize editline          */
134
135     el_set(el, EL_EDITOR, "vi");        /* Default editor is vi         */
136     el_set(el, EL_SIGNAL, 1);           /* Handle signals gracefully    */
137     el_set(el, EL_PROMPT, prompt);      /* Set the prompt function      */
138
139     /* Tell editline to use this history interface                      */
140     el_set(el, EL_HIST, history, hist);
141
142     /* Add a user-defined function                                      */
143     el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete);
144
145     el_set(el, EL_BIND, "^I", "ed-complete", NULL);/* Bind tab to it    */
146
147     /*
148      * Bind j, k in vi command mode to previous and next line, instead
149      * of previous and next history.
150      */
151     el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL);
152     el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL);
153
154     /*
155      * Source the user's defaults file.
156      */
157     el_source(el, NULL);
158
159     while ((buf = el_gets(el, &num)) != NULL && num != 0)  {
160         int ac;
161         char **av;
162 #ifdef DEBUG
163         (void) fprintf(stderr, "got %d %s", num, buf);
164 #endif
165         if (!continuation && num == 1)
166             continue;
167         if (tok_line(tok, buf, &ac, &av) > 0) {
168             history(hist, continuation ? H_ADD : H_ENTER, buf);
169             continuation = 1;
170             continue;
171         }
172         history(hist, continuation ? H_ADD : H_ENTER, buf);
173
174         continuation = 0;
175
176         if (strcmp(av[0], "history") == 0) {
177             const struct HistEvent *he;
178
179             switch (ac) {
180             case 1:
181                 for (he = history(hist, H_LAST); he;
182                      he = history(hist, H_PREV))
183                     (void) fprintf(stdout, "%4d %s", he->num, he->str);
184                 break;
185
186             case 2:
187                 if (strcmp(av[1], "clear") == 0)
188                      history(hist, H_CLEAR);
189                 else
190                      goto badhist;
191                 break;
192
193             case 3:
194                 if (strcmp(av[1], "load") == 0)
195                      history(hist, H_LOAD, av[2]);
196                 else if (strcmp(av[1], "save") == 0)
197                      history(hist, H_SAVE, av[2]);
198                 break;
199
200             badhist:
201             default:
202                 (void) fprintf(stderr, "Bad history arguments\n");
203                 break;
204             }
205         }
206         else if (el_parse(el, ac, av) == -1) {
207             switch (fork()) {
208             case 0:
209                 execvp(av[0], av);
210                 perror(av[0]);
211                 _exit(1);
212                 /*NOTREACHED*/
213                 break;
214
215             case -1:
216                 perror("fork");
217                 break;
218
219             default:
220                 if (wait(&num) == -1)
221                     perror("wait");
222                 (void) fprintf(stderr, "Exit %x\n", num);
223                 break;
224             }
225         }
226         tok_reset(tok);
227     }
228
229     el_end(el);
230     tok_end(tok);
231     history_end(hist);
232
233     return 0;
234 }