1238438Sdteske/*	$NetBSD: tc1.c,v 1.7 2016/02/17 19:47:49 christos Exp $	*/
2238438Sdteske
3238438Sdteske/*-
4238438Sdteske * Copyright (c) 1992, 1993
5238438Sdteske *	The Regents of the University of California.  All rights reserved.
6238438Sdteske *
7238438Sdteske * This code is derived from software contributed to Berkeley by
8238438Sdteske * Christos Zoulas of Cornell University.
9238438Sdteske *
10238438Sdteske * Redistribution and use in source and binary forms, with or without
11238438Sdteske * modification, are permitted provided that the following conditions
12238438Sdteske * are met:
13238438Sdteske * 1. Redistributions of source code must retain the above copyright
14238438Sdteske *    notice, this list of conditions and the following disclaimer.
15238438Sdteske * 2. Redistributions in binary form must reproduce the above copyright
16238438Sdteske *    notice, this list of conditions and the following disclaimer in the
17238438Sdteske *    documentation and/or other materials provided with the distribution.
18238438Sdteske * 3. Neither the name of the University nor the names of its contributors
19238438Sdteske *    may be used to endorse or promote products derived from this software
20238438Sdteske *    without specific prior written permission.
21238438Sdteske *
22238438Sdteske * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23238438Sdteske * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24238438Sdteske * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25238438Sdteske * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26238438Sdteske * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27238438Sdteske * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28238438Sdteske * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29238438Sdteske * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30238438Sdteske * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31240684Sdteske * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32240684Sdteske * SUCH DAMAGE.
33240684Sdteske */
34240684Sdteske
35240684Sdteske#include "config.h"
36240684Sdteske#ifndef lint
37238438Sdteske__COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
38240684Sdteske	The Regents of the University of California.  All rights reserved.\n");
39238438Sdteske#endif /* not lint */
40238438Sdteske
41238438Sdteske#if !defined(lint) && !defined(SCCSID)
42238438Sdteske#if 0
43238438Sdteskestatic char sccsid[] = "@(#)test.c	8.1 (Berkeley) 6/4/93";
44238438Sdteske#else
45238438Sdteske__RCSID("$NetBSD: tc1.c,v 1.7 2016/02/17 19:47:49 christos Exp $");
46238438Sdteske#endif
47238438Sdteske#endif /* not lint && not SCCSID */
48238438Sdteske
49238438Sdteske/*
50240783Sdteske * test.c: A little test program
51238438Sdteske */
52238438Sdteske#include <sys/wait.h>
53238438Sdteske#include <ctype.h>
54238438Sdteske#include <dirent.h>
55238438Sdteske#include <locale.h>
56238438Sdteske#include <signal.h>
57238438Sdteske#include <stdio.h>
58238438Sdteske#include <stdlib.h>
59238438Sdteske#include <string.h>
60238438Sdteske#include <unistd.h>
61238438Sdteske
62238438Sdteske#include "histedit.h"
63243504Sdteske
64238438Sdteskestatic int continuation = 0;
65238438Sdteskevolatile sig_atomic_t gotsig = 0;
66238438Sdteske
67238438Sdteskestatic	unsigned char	complete(EditLine *, int);
68238438Sdteske	int	main(int, char **);
69238438Sdteskestatic	char   *prompt(EditLine *);
70238438Sdteskestatic	void	sig(int);
71238438Sdteske
72238438Sdteskestatic char *
73238438Sdteskeprompt(EditLine *el)
74238438Sdteske{
75238438Sdteske	static char a[] = "\1\033[7m\1Edit$\1\033[0m\1 ";
76243504Sdteske	static char b[] = "Edit> ";
77238438Sdteske
78238438Sdteske	return (continuation ? b : a);
79238438Sdteske}
80238438Sdteske
81238438Sdteskestatic void
82238438Sdteskesig(int i)
83238438Sdteske{
84238438Sdteske	gotsig = i;
85238438Sdteske}
86238438Sdteske
87238438Sdteskestatic unsigned char
88238438Sdteskecomplete(EditLine *el, int ch)
89238438Sdteske{
90238438Sdteske	DIR *dd = opendir(".");
91238438Sdteske	struct dirent *dp;
92238438Sdteske	const char* ptr;
93238438Sdteske	const LineInfo *lf = el_line(el);
94238438Sdteske	int len;
95238438Sdteske	int res = CC_ERROR;
96238438Sdteske
97238438Sdteske	/*
98238438Sdteske	 * Find the last word
99238438Sdteske	 */
100238438Sdteske	for (ptr = lf->cursor - 1;
101238438Sdteske	    !isspace((unsigned char)*ptr) && ptr > lf->buffer; ptr--)
102238438Sdteske		continue;
103238438Sdteske	len = lf->cursor - ++ptr;
104238438Sdteske
105238438Sdteske	for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
106243504Sdteske		if (len > strlen(dp->d_name))
107243504Sdteske			continue;
108243504Sdteske		if (strncmp(dp->d_name, ptr, len) == 0) {
109243504Sdteske			if (el_insertstr(el, &dp->d_name[len]) == -1)
110243504Sdteske				res = CC_ERROR;
111243504Sdteske			else
112243504Sdteske				res = CC_REFRESH;
113243504Sdteske			break;
114243504Sdteske		}
115238438Sdteske	}
116243504Sdteske
117243504Sdteske	closedir(dd);
118243504Sdteske	return res;
119238438Sdteske}
120238438Sdteske
121238438Sdteskeint
122238438Sdteskemain(int argc, char *argv[])
123238438Sdteske{
124238438Sdteske	EditLine *el = NULL;
125238438Sdteske	int num;
126238438Sdteske	const char *buf;
127238438Sdteske	Tokenizer *tok;
128243504Sdteske#if 0
129238438Sdteske	int lastevent = 0;
130243504Sdteske#endif
131243504Sdteske	int ncontinuation;
132243504Sdteske	History *hist;
133243504Sdteske	HistEvent ev;
134243504Sdteske
135243504Sdteske	(void) setlocale(LC_CTYPE, "");
136243504Sdteske	(void) signal(SIGINT, sig);
137243504Sdteske	(void) signal(SIGQUIT, sig);
138243504Sdteske	(void) signal(SIGHUP, sig);
139243504Sdteske	(void) signal(SIGTERM, sig);
140243504Sdteske
141243504Sdteske	hist = history_init();		/* Init the builtin history	*/
142243504Sdteske					/* Remember 100 events		*/
143243504Sdteske	history(hist, &ev, H_SETSIZE, 100);
144243504Sdteske
145243504Sdteske	tok  = tok_init(NULL);		/* Initialize the tokenizer	*/
146243504Sdteske
147238438Sdteske					/* Initialize editline		*/
148238438Sdteske	el = el_init(*argv, stdin, stdout, stderr);
149238438Sdteske
150243504Sdteske	el_set(el, EL_EDITOR, "vi");	/* Default editor is vi		*/
151243475Sdteske	el_set(el, EL_SIGNAL, 1);	/* Handle signals gracefully	*/
152243475Sdteske	el_set(el, EL_PROMPT_ESC, prompt, '\1');/* Set the prompt function */
153243475Sdteske
154243475Sdteske			/* Tell editline to use this history interface	*/
155243475Sdteske	el_set(el, EL_HIST, history, hist);
156243475Sdteske
157243504Sdteske					/* Add a user-defined function	*/
158243504Sdteske	el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete);
159243504Sdteske
160243504Sdteske					/* Bind tab to it		*/
161243504Sdteske	el_set(el, EL_BIND, "^I", "ed-complete", NULL);
162243504Sdteske
163243504Sdteske	/*
164243504Sdteske	 * Bind j, k in vi command mode to previous and next line, instead
165243504Sdteske	 * of previous and next history.
166243504Sdteske	 */
167243504Sdteske	el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL);
168243504Sdteske	el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL);
169243504Sdteske
170243504Sdteske	/*
171243504Sdteske	 * Source the user's defaults file.
172243475Sdteske	 */
173243504Sdteske	el_source(el, NULL);
174243475Sdteske
175243475Sdteske	while ((buf = el_gets(el, &num)) != NULL && num != 0)  {
176243475Sdteske		int ac, cc, co;
177243475Sdteske#ifdef DEBUG
178243475Sdteske		int i;
179243475Sdteske#endif
180243475Sdteske		const char **av;
181243475Sdteske		const LineInfo *li;
182243475Sdteske		li = el_line(el);
183243475Sdteske#ifdef DEBUG
184243475Sdteske		(void) fprintf(stderr, "==> got %d %s", num, buf);
185243475Sdteske		(void) fprintf(stderr, "  > li `%.*s_%.*s'\n",
186243475Sdteske		    (li->cursor - li->buffer), li->buffer,
187243475Sdteske		    (li->lastchar - 1 - li->cursor),
188243475Sdteske		    (li->cursor >= li->lastchar) ? "" : li->cursor);
189243475Sdteske
190243475Sdteske#endif
191243475Sdteske		if (gotsig) {
192243475Sdteske			(void) fprintf(stderr, "Got signal %d.\n", (int)gotsig);
193243475Sdteske			gotsig = 0;
194243475Sdteske			el_reset(el);
195243475Sdteske		}
196243475Sdteske
197243475Sdteske		if (!continuation && num == 1)
198243475Sdteske			continue;
199243475Sdteske
200243475Sdteske		ac = cc = co = 0;
201243475Sdteske		ncontinuation = tok_line(tok, li, &ac, &av, &cc, &co);
202243475Sdteske		if (ncontinuation < 0) {
203243475Sdteske			(void) fprintf(stderr, "Internal error\n");
204243475Sdteske			continuation = 0;
205243475Sdteske			continue;
206243475Sdteske		}
207243475Sdteske#ifdef DEBUG
208243475Sdteske		(void) fprintf(stderr, "  > nc %d ac %d cc %d co %d\n",
209243475Sdteske		    ncontinuation, ac, cc, co);
210243475Sdteske#endif
211243475Sdteske#if 0
212243475Sdteske		if (continuation) {
213243475Sdteske			/*
214243475Sdteske			 * Append to the right event in case the user
215243475Sdteske			 * moved around in history.
216243475Sdteske			 */
217243475Sdteske			if (history(hist, &ev, H_SET, lastevent) == -1)
218243475Sdteske				err(1, "%d: %s", lastevent, ev.str);
219243475Sdteske			history(hist, &ev, H_ADD , buf);
220243475Sdteske		} else {
221243475Sdteske			history(hist, &ev, H_ENTER, buf);
222243475Sdteske			lastevent = ev.num;
223243475Sdteske		}
224243475Sdteske#else
225243475Sdteske				/* Simpler */
226243475Sdteske		history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf);
227243475Sdteske#endif
228243475Sdteske
229243475Sdteske		continuation = ncontinuation;
230243475Sdteske		ncontinuation = 0;
231243475Sdteske		if (continuation)
232243475Sdteske			continue;
233243475Sdteske#ifdef DEBUG
234243475Sdteske		for (i = 0; i < ac; i++) {
235243475Sdteske			(void) fprintf(stderr, "  > arg# %2d ", i);
236243475Sdteske			if (i != cc)
237243475Sdteske				(void) fprintf(stderr, "`%s'\n", av[i]);
238243475Sdteske			else
239243475Sdteske				(void) fprintf(stderr, "`%.*s_%s'\n",
240243475Sdteske				    co, av[i], av[i] + co);
241243475Sdteske		}
242243475Sdteske#endif
243243475Sdteske
244243475Sdteske		if (strcmp(av[0], "history") == 0) {
245243475Sdteske			int rv;
246243504Sdteske
247243504Sdteske			switch (ac) {
248243475Sdteske			case 1:
249243475Sdteske				for (rv = history(hist, &ev, H_LAST); rv != -1;
250243475Sdteske				    rv = history(hist, &ev, H_PREV))
251243475Sdteske					(void) fprintf(stdout, "%4d %s",
252243475Sdteske					    ev.num, ev.str);
253243475Sdteske				break;
254243475Sdteske
255243475Sdteske			case 2:
256243475Sdteske				if (strcmp(av[1], "clear") == 0)
257243475Sdteske					 history(hist, &ev, H_CLEAR);
258243475Sdteske				else
259243475Sdteske					 goto badhist;
260243475Sdteske				break;
261243475Sdteske
262243475Sdteske			case 3:
263243475Sdteske				if (strcmp(av[1], "load") == 0)
264243475Sdteske					 history(hist, &ev, H_LOAD, av[2]);
265243475Sdteske				else if (strcmp(av[1], "save") == 0)
266243475Sdteske					 history(hist, &ev, H_SAVE, av[2]);
267243475Sdteske				break;
268243475Sdteske
269243475Sdteske			badhist:
270243475Sdteske			default:
271243475Sdteske				(void) fprintf(stderr,
272243475Sdteske				    "Bad history arguments\n");
273243475Sdteske				break;
274243475Sdteske			}
275243475Sdteske		} else if (el_parse(el, ac, av) == -1) {
276243475Sdteske			switch (fork()) {
277243475Sdteske			case 0:
278243475Sdteske				execvp(av[0], (char *const *)__UNCONST(av));
279243475Sdteske				perror(av[0]);
280243475Sdteske				_exit(1);
281243475Sdteske				/*NOTREACHED*/
282243475Sdteske				break;
283243504Sdteske
284243475Sdteske			case -1:
285243504Sdteske				perror("fork");
286243504Sdteske				break;
287243504Sdteske
288243504Sdteske			default:
289243504Sdteske				if (wait(&num) == -1)
290243504Sdteske					perror("wait");
291243504Sdteske				(void) fprintf(stderr, "Exit %x\n", num);
292243504Sdteske				break;
293243504Sdteske			}
294243504Sdteske		}
295243504Sdteske
296243504Sdteske		tok_reset(tok);
297243475Sdteske	}
298243475Sdteske
299243475Sdteske	el_end(el);
300243475Sdteske	tok_end(tok);
301243475Sdteske	history_end(hist);
302243475Sdteske
303243475Sdteske	return (0);
304243475Sdteske}
305243504Sdteske