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