xref: /minix3/lib/libedit/TEST/tc1.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: tc1.c,v 1.6 2014/06/18 20:12:15 christos Exp $	*/
23e1db26aSLionel Sambuc 
33e1db26aSLionel Sambuc /*-
43e1db26aSLionel Sambuc  * Copyright (c) 1992, 1993
53e1db26aSLionel Sambuc  *	The Regents of the University of California.  All rights reserved.
63e1db26aSLionel Sambuc  *
73e1db26aSLionel Sambuc  * This code is derived from software contributed to Berkeley by
83e1db26aSLionel Sambuc  * Christos Zoulas of Cornell University.
93e1db26aSLionel Sambuc  *
103e1db26aSLionel Sambuc  * Redistribution and use in source and binary forms, with or without
113e1db26aSLionel Sambuc  * modification, are permitted provided that the following conditions
123e1db26aSLionel Sambuc  * are met:
133e1db26aSLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
143e1db26aSLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
153e1db26aSLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
163e1db26aSLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
173e1db26aSLionel Sambuc  *    documentation and/or other materials provided with the distribution.
183e1db26aSLionel Sambuc  * 3. Neither the name of the University nor the names of its contributors
193e1db26aSLionel Sambuc  *    may be used to endorse or promote products derived from this software
203e1db26aSLionel Sambuc  *    without specific prior written permission.
213e1db26aSLionel Sambuc  *
223e1db26aSLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
233e1db26aSLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
243e1db26aSLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
253e1db26aSLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
263e1db26aSLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
273e1db26aSLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
283e1db26aSLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
293e1db26aSLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
303e1db26aSLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
313e1db26aSLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
323e1db26aSLionel Sambuc  * SUCH DAMAGE.
333e1db26aSLionel Sambuc  */
343e1db26aSLionel Sambuc 
353e1db26aSLionel Sambuc #include "config.h"
363e1db26aSLionel Sambuc #ifndef lint
373e1db26aSLionel Sambuc __COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
383e1db26aSLionel Sambuc 	The Regents of the University of California.  All rights reserved.\n");
393e1db26aSLionel Sambuc #endif /* not lint */
403e1db26aSLionel Sambuc 
413e1db26aSLionel Sambuc #if !defined(lint) && !defined(SCCSID)
423e1db26aSLionel Sambuc #if 0
433e1db26aSLionel Sambuc static char sccsid[] = "@(#)test.c	8.1 (Berkeley) 6/4/93";
443e1db26aSLionel Sambuc #else
45*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: tc1.c,v 1.6 2014/06/18 20:12:15 christos Exp $");
463e1db26aSLionel Sambuc #endif
473e1db26aSLionel Sambuc #endif /* not lint && not SCCSID */
483e1db26aSLionel Sambuc 
493e1db26aSLionel Sambuc /*
503e1db26aSLionel Sambuc  * test.c: A little test program
513e1db26aSLionel Sambuc  */
523e1db26aSLionel Sambuc #include <stdio.h>
533e1db26aSLionel Sambuc #include <string.h>
543e1db26aSLionel Sambuc #include <signal.h>
553e1db26aSLionel Sambuc #include <sys/wait.h>
563e1db26aSLionel Sambuc #include <ctype.h>
573e1db26aSLionel Sambuc #include <stdlib.h>
583e1db26aSLionel Sambuc #include <unistd.h>
593e1db26aSLionel Sambuc #include <dirent.h>
603e1db26aSLionel Sambuc #include <locale.h>
613e1db26aSLionel Sambuc 
623e1db26aSLionel Sambuc #include "histedit.h"
633e1db26aSLionel Sambuc 
643e1db26aSLionel Sambuc static int continuation = 0;
653e1db26aSLionel Sambuc volatile sig_atomic_t gotsig = 0;
663e1db26aSLionel Sambuc 
673e1db26aSLionel Sambuc static	unsigned char	complete(EditLine *, int);
683e1db26aSLionel Sambuc 	int	main(int, char **);
693e1db26aSLionel Sambuc static	char   *prompt(EditLine *);
703e1db26aSLionel Sambuc static	void	sig(int);
713e1db26aSLionel Sambuc 
723e1db26aSLionel Sambuc static char *
prompt(EditLine * el)733e1db26aSLionel Sambuc prompt(EditLine *el)
743e1db26aSLionel Sambuc {
753e1db26aSLionel Sambuc 	static char a[] = "\1\033[7m\1Edit$\1\033[0m\1 ";
763e1db26aSLionel Sambuc 	static char b[] = "Edit> ";
773e1db26aSLionel Sambuc 
783e1db26aSLionel Sambuc 	return (continuation ? b : a);
793e1db26aSLionel Sambuc }
803e1db26aSLionel Sambuc 
813e1db26aSLionel Sambuc static void
sig(int i)823e1db26aSLionel Sambuc sig(int i)
833e1db26aSLionel Sambuc {
843e1db26aSLionel Sambuc 	gotsig = i;
853e1db26aSLionel Sambuc }
863e1db26aSLionel Sambuc 
873e1db26aSLionel Sambuc static unsigned char
complete(EditLine * el,int ch)883e1db26aSLionel Sambuc complete(EditLine *el, int ch)
893e1db26aSLionel Sambuc {
903e1db26aSLionel Sambuc 	DIR *dd = opendir(".");
913e1db26aSLionel Sambuc 	struct dirent *dp;
923e1db26aSLionel Sambuc 	const char* ptr;
933e1db26aSLionel Sambuc 	const LineInfo *lf = el_line(el);
943e1db26aSLionel Sambuc 	int len;
953e1db26aSLionel Sambuc 	int res = CC_ERROR;
963e1db26aSLionel Sambuc 
973e1db26aSLionel Sambuc 	/*
983e1db26aSLionel Sambuc 	 * Find the last word
993e1db26aSLionel Sambuc 	 */
1003e1db26aSLionel Sambuc 	for (ptr = lf->cursor - 1;
1013e1db26aSLionel Sambuc 	    !isspace((unsigned char)*ptr) && ptr > lf->buffer; ptr--)
1023e1db26aSLionel Sambuc 		continue;
1033e1db26aSLionel Sambuc 	len = lf->cursor - ++ptr;
1043e1db26aSLionel Sambuc 
1053e1db26aSLionel Sambuc 	for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
1063e1db26aSLionel Sambuc 		if (len > strlen(dp->d_name))
1073e1db26aSLionel Sambuc 			continue;
1083e1db26aSLionel Sambuc 		if (strncmp(dp->d_name, ptr, len) == 0) {
1093e1db26aSLionel Sambuc 			if (el_insertstr(el, &dp->d_name[len]) == -1)
1103e1db26aSLionel Sambuc 				res = CC_ERROR;
1113e1db26aSLionel Sambuc 			else
1123e1db26aSLionel Sambuc 				res = CC_REFRESH;
1133e1db26aSLionel Sambuc 			break;
1143e1db26aSLionel Sambuc 		}
1153e1db26aSLionel Sambuc 	}
1163e1db26aSLionel Sambuc 
1173e1db26aSLionel Sambuc 	closedir(dd);
1183e1db26aSLionel Sambuc 	return res;
1193e1db26aSLionel Sambuc }
1203e1db26aSLionel Sambuc 
1213e1db26aSLionel Sambuc int
main(int argc,char * argv[])1223e1db26aSLionel Sambuc main(int argc, char *argv[])
1233e1db26aSLionel Sambuc {
1243e1db26aSLionel Sambuc 	EditLine *el = NULL;
1253e1db26aSLionel Sambuc 	int num;
1263e1db26aSLionel Sambuc 	const char *buf;
1273e1db26aSLionel Sambuc 	Tokenizer *tok;
1283e1db26aSLionel Sambuc #if 0
1293e1db26aSLionel Sambuc 	int lastevent = 0;
1303e1db26aSLionel Sambuc #endif
1313e1db26aSLionel Sambuc 	int ncontinuation;
1323e1db26aSLionel Sambuc 	History *hist;
1333e1db26aSLionel Sambuc 	HistEvent ev;
1343e1db26aSLionel Sambuc 
1353e1db26aSLionel Sambuc 	(void) setlocale(LC_CTYPE, "");
1363e1db26aSLionel Sambuc 	(void) signal(SIGINT, sig);
1373e1db26aSLionel Sambuc 	(void) signal(SIGQUIT, sig);
1383e1db26aSLionel Sambuc 	(void) signal(SIGHUP, sig);
1393e1db26aSLionel Sambuc 	(void) signal(SIGTERM, sig);
1403e1db26aSLionel Sambuc 
1413e1db26aSLionel Sambuc 	hist = history_init();		/* Init the builtin history	*/
1423e1db26aSLionel Sambuc 					/* Remember 100 events		*/
1433e1db26aSLionel Sambuc 	history(hist, &ev, H_SETSIZE, 100);
1443e1db26aSLionel Sambuc 
1453e1db26aSLionel Sambuc 	tok  = tok_init(NULL);		/* Initialize the tokenizer	*/
1463e1db26aSLionel Sambuc 
1473e1db26aSLionel Sambuc 					/* Initialize editline		*/
1483e1db26aSLionel Sambuc 	el = el_init(*argv, stdin, stdout, stderr);
1493e1db26aSLionel Sambuc 
1503e1db26aSLionel Sambuc 	el_set(el, EL_EDITOR, "vi");	/* Default editor is vi		*/
1513e1db26aSLionel Sambuc 	el_set(el, EL_SIGNAL, 1);	/* Handle signals gracefully	*/
1523e1db26aSLionel Sambuc 	el_set(el, EL_PROMPT_ESC, prompt, '\1');/* Set the prompt function */
1533e1db26aSLionel Sambuc 
1543e1db26aSLionel Sambuc 			/* Tell editline to use this history interface	*/
1553e1db26aSLionel Sambuc 	el_set(el, EL_HIST, history, hist);
1563e1db26aSLionel Sambuc 
1573e1db26aSLionel Sambuc 					/* Add a user-defined function	*/
1583e1db26aSLionel Sambuc 	el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete);
1593e1db26aSLionel Sambuc 
1603e1db26aSLionel Sambuc 					/* Bind tab to it 		*/
1613e1db26aSLionel Sambuc 	el_set(el, EL_BIND, "^I", "ed-complete", NULL);
1623e1db26aSLionel Sambuc 
1633e1db26aSLionel Sambuc 	/*
1643e1db26aSLionel Sambuc 	 * Bind j, k in vi command mode to previous and next line, instead
1653e1db26aSLionel Sambuc 	 * of previous and next history.
1663e1db26aSLionel Sambuc 	 */
1673e1db26aSLionel Sambuc 	el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL);
1683e1db26aSLionel Sambuc 	el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL);
1693e1db26aSLionel Sambuc 
1703e1db26aSLionel Sambuc 	/*
1713e1db26aSLionel Sambuc 	 * Source the user's defaults file.
1723e1db26aSLionel Sambuc 	 */
1733e1db26aSLionel Sambuc 	el_source(el, NULL);
1743e1db26aSLionel Sambuc 
1753e1db26aSLionel Sambuc 	while ((buf = el_gets(el, &num)) != NULL && num != 0)  {
1763e1db26aSLionel Sambuc 		int ac, cc, co;
1773e1db26aSLionel Sambuc #ifdef DEBUG
1783e1db26aSLionel Sambuc 		int i;
1793e1db26aSLionel Sambuc #endif
1803e1db26aSLionel Sambuc 		const char **av;
1813e1db26aSLionel Sambuc 		const LineInfo *li;
1823e1db26aSLionel Sambuc 		li = el_line(el);
1833e1db26aSLionel Sambuc #ifdef DEBUG
1843e1db26aSLionel Sambuc 		(void) fprintf(stderr, "==> got %d %s", num, buf);
1853e1db26aSLionel Sambuc 		(void) fprintf(stderr, "  > li `%.*s_%.*s'\n",
1863e1db26aSLionel Sambuc 		    (li->cursor - li->buffer), li->buffer,
1873e1db26aSLionel Sambuc 		    (li->lastchar - 1 - li->cursor),
1883e1db26aSLionel Sambuc 		    (li->cursor >= li->lastchar) ? "" : li->cursor);
1893e1db26aSLionel Sambuc 
1903e1db26aSLionel Sambuc #endif
1913e1db26aSLionel Sambuc 		if (gotsig) {
192*0a6a1f1dSLionel Sambuc 			(void) fprintf(stderr, "Got signal %d.\n", (int)gotsig);
1933e1db26aSLionel Sambuc 			gotsig = 0;
1943e1db26aSLionel Sambuc 			el_reset(el);
1953e1db26aSLionel Sambuc 		}
1963e1db26aSLionel Sambuc 
1973e1db26aSLionel Sambuc 		if (!continuation && num == 1)
1983e1db26aSLionel Sambuc 			continue;
1993e1db26aSLionel Sambuc 
2003e1db26aSLionel Sambuc 		ac = cc = co = 0;
2013e1db26aSLionel Sambuc 		ncontinuation = tok_line(tok, li, &ac, &av, &cc, &co);
2023e1db26aSLionel Sambuc 		if (ncontinuation < 0) {
2033e1db26aSLionel Sambuc 			(void) fprintf(stderr, "Internal error\n");
2043e1db26aSLionel Sambuc 			continuation = 0;
2053e1db26aSLionel Sambuc 			continue;
2063e1db26aSLionel Sambuc 		}
2073e1db26aSLionel Sambuc #ifdef DEBUG
2083e1db26aSLionel Sambuc 		(void) fprintf(stderr, "  > nc %d ac %d cc %d co %d\n",
2093e1db26aSLionel Sambuc 		    ncontinuation, ac, cc, co);
2103e1db26aSLionel Sambuc #endif
2113e1db26aSLionel Sambuc #if 0
2123e1db26aSLionel Sambuc 		if (continuation) {
2133e1db26aSLionel Sambuc 			/*
2143e1db26aSLionel Sambuc 			 * Append to the right event in case the user
2153e1db26aSLionel Sambuc 			 * moved around in history.
2163e1db26aSLionel Sambuc 			 */
2173e1db26aSLionel Sambuc 			if (history(hist, &ev, H_SET, lastevent) == -1)
2183e1db26aSLionel Sambuc 				err(1, "%d: %s", lastevent, ev.str);
2193e1db26aSLionel Sambuc 			history(hist, &ev, H_ADD , buf);
2203e1db26aSLionel Sambuc 		} else {
2213e1db26aSLionel Sambuc 			history(hist, &ev, H_ENTER, buf);
2223e1db26aSLionel Sambuc 			lastevent = ev.num;
2233e1db26aSLionel Sambuc 		}
2243e1db26aSLionel Sambuc #else
2253e1db26aSLionel Sambuc 				/* Simpler */
2263e1db26aSLionel Sambuc 		history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf);
2273e1db26aSLionel Sambuc #endif
2283e1db26aSLionel Sambuc 
2293e1db26aSLionel Sambuc 		continuation = ncontinuation;
2303e1db26aSLionel Sambuc 		ncontinuation = 0;
2313e1db26aSLionel Sambuc 		if (continuation)
2323e1db26aSLionel Sambuc 			continue;
2333e1db26aSLionel Sambuc #ifdef DEBUG
2343e1db26aSLionel Sambuc 		for (i = 0; i < ac; i++) {
2353e1db26aSLionel Sambuc 			(void) fprintf(stderr, "  > arg# %2d ", i);
2363e1db26aSLionel Sambuc 			if (i != cc)
2373e1db26aSLionel Sambuc 				(void) fprintf(stderr, "`%s'\n", av[i]);
2383e1db26aSLionel Sambuc 			else
2393e1db26aSLionel Sambuc 				(void) fprintf(stderr, "`%.*s_%s'\n",
2403e1db26aSLionel Sambuc 				    co, av[i], av[i] + co);
2413e1db26aSLionel Sambuc 		}
2423e1db26aSLionel Sambuc #endif
2433e1db26aSLionel Sambuc 
2443e1db26aSLionel Sambuc 		if (strcmp(av[0], "history") == 0) {
2453e1db26aSLionel Sambuc 			int rv;
2463e1db26aSLionel Sambuc 
2473e1db26aSLionel Sambuc 			switch (ac) {
2483e1db26aSLionel Sambuc 			case 1:
2493e1db26aSLionel Sambuc 				for (rv = history(hist, &ev, H_LAST); rv != -1;
2503e1db26aSLionel Sambuc 				    rv = history(hist, &ev, H_PREV))
2513e1db26aSLionel Sambuc 					(void) fprintf(stdout, "%4d %s",
2523e1db26aSLionel Sambuc 					    ev.num, ev.str);
2533e1db26aSLionel Sambuc 				break;
2543e1db26aSLionel Sambuc 
2553e1db26aSLionel Sambuc 			case 2:
2563e1db26aSLionel Sambuc 				if (strcmp(av[1], "clear") == 0)
2573e1db26aSLionel Sambuc 					 history(hist, &ev, H_CLEAR);
2583e1db26aSLionel Sambuc 				else
2593e1db26aSLionel Sambuc 					 goto badhist;
2603e1db26aSLionel Sambuc 				break;
2613e1db26aSLionel Sambuc 
2623e1db26aSLionel Sambuc 			case 3:
2633e1db26aSLionel Sambuc 				if (strcmp(av[1], "load") == 0)
2643e1db26aSLionel Sambuc 					 history(hist, &ev, H_LOAD, av[2]);
2653e1db26aSLionel Sambuc 				else if (strcmp(av[1], "save") == 0)
2663e1db26aSLionel Sambuc 					 history(hist, &ev, H_SAVE, av[2]);
2673e1db26aSLionel Sambuc 				break;
2683e1db26aSLionel Sambuc 
2693e1db26aSLionel Sambuc 			badhist:
2703e1db26aSLionel Sambuc 			default:
2713e1db26aSLionel Sambuc 				(void) fprintf(stderr,
2723e1db26aSLionel Sambuc 				    "Bad history arguments\n");
2733e1db26aSLionel Sambuc 				break;
2743e1db26aSLionel Sambuc 			}
2753e1db26aSLionel Sambuc 		} else if (el_parse(el, ac, av) == -1) {
2763e1db26aSLionel Sambuc 			switch (fork()) {
2773e1db26aSLionel Sambuc 			case 0:
2783e1db26aSLionel Sambuc 				execvp(av[0], (char *const *)__UNCONST(av));
2793e1db26aSLionel Sambuc 				perror(av[0]);
2803e1db26aSLionel Sambuc 				_exit(1);
2813e1db26aSLionel Sambuc 				/*NOTREACHED*/
2823e1db26aSLionel Sambuc 				break;
2833e1db26aSLionel Sambuc 
2843e1db26aSLionel Sambuc 			case -1:
2853e1db26aSLionel Sambuc 				perror("fork");
2863e1db26aSLionel Sambuc 				break;
2873e1db26aSLionel Sambuc 
2883e1db26aSLionel Sambuc 			default:
2893e1db26aSLionel Sambuc 				if (wait(&num) == -1)
2903e1db26aSLionel Sambuc 					perror("wait");
2913e1db26aSLionel Sambuc 				(void) fprintf(stderr, "Exit %x\n", num);
2923e1db26aSLionel Sambuc 				break;
2933e1db26aSLionel Sambuc 			}
2943e1db26aSLionel Sambuc 		}
2953e1db26aSLionel Sambuc 
2963e1db26aSLionel Sambuc 		tok_reset(tok);
2973e1db26aSLionel Sambuc 	}
2983e1db26aSLionel Sambuc 
2993e1db26aSLionel Sambuc 	el_end(el);
3003e1db26aSLionel Sambuc 	tok_end(tok);
3013e1db26aSLionel Sambuc 	history_end(hist);
3023e1db26aSLionel Sambuc 
3033e1db26aSLionel Sambuc 	return (0);
3043e1db26aSLionel Sambuc }
305