Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libedit/TEST/tc1.c
39586 views
1
/* $NetBSD: tc1.c,v 1.7 2016/02/17 19:47:49 christos 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. Neither the name of the University nor the names of its contributors
19
* may be used to endorse or promote products derived from this software
20
* without specific prior written permission.
21
*
22
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
* SUCH DAMAGE.
33
*/
34
35
#include "config.h"
36
#ifndef lint
37
__COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
38
The Regents of the University of California. All rights reserved.\n");
39
#endif /* not lint */
40
41
#if !defined(lint) && !defined(SCCSID)
42
#if 0
43
static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93";
44
#else
45
__RCSID("$NetBSD: tc1.c,v 1.7 2016/02/17 19:47:49 christos Exp $");
46
#endif
47
#endif /* not lint && not SCCSID */
48
49
/*
50
* test.c: A little test program
51
*/
52
#include <sys/wait.h>
53
#include <ctype.h>
54
#include <dirent.h>
55
#include <locale.h>
56
#include <signal.h>
57
#include <stdio.h>
58
#include <stdlib.h>
59
#include <string.h>
60
#include <unistd.h>
61
62
#include "histedit.h"
63
64
static int continuation = 0;
65
volatile sig_atomic_t gotsig = 0;
66
67
static unsigned char complete(EditLine *, int);
68
int main(int, char **);
69
static char *prompt(EditLine *);
70
static void sig(int);
71
72
static char *
73
prompt(EditLine *el)
74
{
75
static char a[] = "\1\033[7m\1Edit$\1\033[0m\1 ";
76
static char b[] = "Edit> ";
77
78
return (continuation ? b : a);
79
}
80
81
static void
82
sig(int i)
83
{
84
gotsig = i;
85
}
86
87
static unsigned char
88
complete(EditLine *el, int ch)
89
{
90
DIR *dd = opendir(".");
91
struct dirent *dp;
92
const char* ptr;
93
const LineInfo *lf = el_line(el);
94
int len;
95
int res = CC_ERROR;
96
97
/*
98
* Find the last word
99
*/
100
for (ptr = lf->cursor - 1;
101
!isspace((unsigned char)*ptr) && ptr > lf->buffer; ptr--)
102
continue;
103
len = lf->cursor - ++ptr;
104
105
for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
106
if (len > strlen(dp->d_name))
107
continue;
108
if (strncmp(dp->d_name, ptr, len) == 0) {
109
if (el_insertstr(el, &dp->d_name[len]) == -1)
110
res = CC_ERROR;
111
else
112
res = CC_REFRESH;
113
break;
114
}
115
}
116
117
closedir(dd);
118
return res;
119
}
120
121
int
122
main(int argc, char *argv[])
123
{
124
EditLine *el = NULL;
125
int num;
126
const char *buf;
127
Tokenizer *tok;
128
#if 0
129
int lastevent = 0;
130
#endif
131
int ncontinuation;
132
History *hist;
133
HistEvent ev;
134
135
(void) setlocale(LC_CTYPE, "");
136
(void) signal(SIGINT, sig);
137
(void) signal(SIGQUIT, sig);
138
(void) signal(SIGHUP, sig);
139
(void) signal(SIGTERM, sig);
140
141
hist = history_init(); /* Init the builtin history */
142
/* Remember 100 events */
143
history(hist, &ev, H_SETSIZE, 100);
144
145
tok = tok_init(NULL); /* Initialize the tokenizer */
146
147
/* Initialize editline */
148
el = el_init(*argv, stdin, stdout, stderr);
149
150
el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */
151
el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */
152
el_set(el, EL_PROMPT_ESC, prompt, '\1');/* Set the prompt function */
153
154
/* Tell editline to use this history interface */
155
el_set(el, EL_HIST, history, hist);
156
157
/* Add a user-defined function */
158
el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete);
159
160
/* Bind tab to it */
161
el_set(el, EL_BIND, "^I", "ed-complete", NULL);
162
163
/*
164
* Bind j, k in vi command mode to previous and next line, instead
165
* of previous and next history.
166
*/
167
el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL);
168
el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL);
169
170
/*
171
* Source the user's defaults file.
172
*/
173
el_source(el, NULL);
174
175
while ((buf = el_gets(el, &num)) != NULL && num != 0) {
176
int ac, cc, co;
177
#ifdef DEBUG
178
int i;
179
#endif
180
const char **av;
181
const LineInfo *li;
182
li = el_line(el);
183
#ifdef DEBUG
184
(void) fprintf(stderr, "==> got %d %s", num, buf);
185
(void) fprintf(stderr, " > li `%.*s_%.*s'\n",
186
(li->cursor - li->buffer), li->buffer,
187
(li->lastchar - 1 - li->cursor),
188
(li->cursor >= li->lastchar) ? "" : li->cursor);
189
190
#endif
191
if (gotsig) {
192
(void) fprintf(stderr, "Got signal %d.\n", (int)gotsig);
193
gotsig = 0;
194
el_reset(el);
195
}
196
197
if (!continuation && num == 1)
198
continue;
199
200
ac = cc = co = 0;
201
ncontinuation = tok_line(tok, li, &ac, &av, &cc, &co);
202
if (ncontinuation < 0) {
203
(void) fprintf(stderr, "Internal error\n");
204
continuation = 0;
205
continue;
206
}
207
#ifdef DEBUG
208
(void) fprintf(stderr, " > nc %d ac %d cc %d co %d\n",
209
ncontinuation, ac, cc, co);
210
#endif
211
#if 0
212
if (continuation) {
213
/*
214
* Append to the right event in case the user
215
* moved around in history.
216
*/
217
if (history(hist, &ev, H_SET, lastevent) == -1)
218
err(1, "%d: %s", lastevent, ev.str);
219
history(hist, &ev, H_ADD , buf);
220
} else {
221
history(hist, &ev, H_ENTER, buf);
222
lastevent = ev.num;
223
}
224
#else
225
/* Simpler */
226
history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf);
227
#endif
228
229
continuation = ncontinuation;
230
ncontinuation = 0;
231
if (continuation)
232
continue;
233
#ifdef DEBUG
234
for (i = 0; i < ac; i++) {
235
(void) fprintf(stderr, " > arg# %2d ", i);
236
if (i != cc)
237
(void) fprintf(stderr, "`%s'\n", av[i]);
238
else
239
(void) fprintf(stderr, "`%.*s_%s'\n",
240
co, av[i], av[i] + co);
241
}
242
#endif
243
244
if (strcmp(av[0], "history") == 0) {
245
int rv;
246
247
switch (ac) {
248
case 1:
249
for (rv = history(hist, &ev, H_LAST); rv != -1;
250
rv = history(hist, &ev, H_PREV))
251
(void) fprintf(stdout, "%4d %s",
252
ev.num, ev.str);
253
break;
254
255
case 2:
256
if (strcmp(av[1], "clear") == 0)
257
history(hist, &ev, H_CLEAR);
258
else
259
goto badhist;
260
break;
261
262
case 3:
263
if (strcmp(av[1], "load") == 0)
264
history(hist, &ev, H_LOAD, av[2]);
265
else if (strcmp(av[1], "save") == 0)
266
history(hist, &ev, H_SAVE, av[2]);
267
break;
268
269
badhist:
270
default:
271
(void) fprintf(stderr,
272
"Bad history arguments\n");
273
break;
274
}
275
} else if (el_parse(el, ac, av) == -1) {
276
switch (fork()) {
277
case 0:
278
execvp(av[0], (char *const *)__UNCONST(av));
279
perror(av[0]);
280
_exit(1);
281
/*NOTREACHED*/
282
break;
283
284
case -1:
285
perror("fork");
286
break;
287
288
default:
289
if (wait(&num) == -1)
290
perror("wait");
291
(void) fprintf(stderr, "Exit %x\n", num);
292
break;
293
}
294
}
295
296
tok_reset(tok);
297
}
298
299
el_end(el);
300
tok_end(tok);
301
history_end(hist);
302
303
return (0);
304
}
305
306