11573Srgrimes/*- 21573Srgrimes * Copyright (c) 1992, 1993 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * This code is derived from software contributed to Berkeley by 61573Srgrimes * Christos Zoulas of Cornell University. 71573Srgrimes * 81573Srgrimes * Redistribution and use in source and binary forms, with or without 91573Srgrimes * modification, are permitted provided that the following conditions 101573Srgrimes * are met: 111573Srgrimes * 1. Redistributions of source code must retain the above copyright 121573Srgrimes * notice, this list of conditions and the following disclaimer. 131573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141573Srgrimes * notice, this list of conditions and the following disclaimer in the 151573Srgrimes * documentation and/or other materials provided with the distribution. 16148834Sstefanf * 3. Neither the name of the University nor the names of its contributors 171573Srgrimes * may be used to endorse or promote products derived from this software 181573Srgrimes * without specific prior written permission. 191573Srgrimes * 201573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 211573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 241573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301573Srgrimes * SUCH DAMAGE. 311573Srgrimes */ 321573Srgrimes 3384260Sobrien#include <sys/cdefs.h> 341573Srgrimes#ifndef lint 3584260Sobrien__COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\ 3684260Sobrien The Regents of the University of California. All rights reserved.\n"); 371573Srgrimes#endif /* not lint */ 381573Srgrimes 391573Srgrimes#if !defined(lint) && !defined(SCCSID) 401573Srgrimesstatic char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93"; 411573Srgrimes#endif /* not lint && not SCCSID */ 42268502Spfg__RCSID("$NetBSD: test.c,v 1.3 2009/07/17 12:25:52 christos Exp $"); 4384260Sobrien__FBSDID("$FreeBSD$"); 441573Srgrimes 451573Srgrimes/* 461573Srgrimes * test.c: A little test program 471573Srgrimes */ 481573Srgrimes#include "sys.h" 491573Srgrimes#include <stdio.h> 501573Srgrimes#include <string.h> 511573Srgrimes#include <signal.h> 521573Srgrimes#include <sys/wait.h> 531573Srgrimes#include <ctype.h> 541573Srgrimes#include <stdlib.h> 551573Srgrimes#include <unistd.h> 561573Srgrimes#include <dirent.h> 571573Srgrimes 581573Srgrimes#include "histedit.h" 591573Srgrimes 601573Srgrimesstatic int continuation = 0; 61148834Sstefanfvolatile sig_atomic_t gotsig = 0; 621573Srgrimes 63148834Sstefanfstatic unsigned char complete(EditLine *, int); 6484260Sobrien int main(int, char **); 6584260Sobrienstatic char *prompt(EditLine *); 6684260Sobrienstatic void sig(int); 6784260Sobrien 681573Srgrimesstatic char * 6984260Sobrienprompt(EditLine *el) 701573Srgrimes{ 71268502Spfg static char a[] = "\1\e[7m\1Edit$\1\e[0m\1 "; 72148834Sstefanf static char b[] = "Edit> "; 7384260Sobrien 7484260Sobrien return (continuation ? b : a); 751573Srgrimes} 761573Srgrimes 771573Srgrimesstatic void 7884260Sobriensig(int i) 791573Srgrimes{ 80148834Sstefanf gotsig = i; 811573Srgrimes} 821573Srgrimes 831573Srgrimesstatic unsigned char 8484260Sobriencomplete(EditLine *el, int ch) 851573Srgrimes{ 8684260Sobrien DIR *dd = opendir("."); 8784260Sobrien struct dirent *dp; 8884260Sobrien const char* ptr; 8984260Sobrien const LineInfo *lf = el_line(el); 9084260Sobrien int len; 911573Srgrimes 9284260Sobrien /* 9384260Sobrien * Find the last word 9484260Sobrien */ 95148834Sstefanf for (ptr = lf->cursor - 1; 96148834Sstefanf !isspace((unsigned char)*ptr) && ptr > lf->buffer; ptr--) 9784260Sobrien continue; 9884260Sobrien len = lf->cursor - ++ptr; 991573Srgrimes 10084260Sobrien for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) { 10184260Sobrien if (len > strlen(dp->d_name)) 10284260Sobrien continue; 10384260Sobrien if (strncmp(dp->d_name, ptr, len) == 0) { 10484260Sobrien closedir(dd); 10584260Sobrien if (el_insertstr(el, &dp->d_name[len]) == -1) 10684260Sobrien return (CC_ERROR); 10784260Sobrien else 10884260Sobrien return (CC_REFRESH); 10984260Sobrien } 1101573Srgrimes } 1111573Srgrimes 11284260Sobrien closedir(dd); 11384260Sobrien return (CC_ERROR); 1141573Srgrimes} 1151573Srgrimes 1161573Srgrimesint 11784260Sobrienmain(int argc, char *argv[]) 1181573Srgrimes{ 119148834Sstefanf EditLine *el = NULL; 12084260Sobrien int num; 12184260Sobrien const char *buf; 12284260Sobrien Tokenizer *tok; 123148834Sstefanf#if 0 124148834Sstefanf int lastevent = 0; 125148834Sstefanf#endif 126148834Sstefanf int ncontinuation; 12784260Sobrien History *hist; 12884260Sobrien HistEvent ev; 1291573Srgrimes 13084260Sobrien (void) signal(SIGINT, sig); 13184260Sobrien (void) signal(SIGQUIT, sig); 13284260Sobrien (void) signal(SIGHUP, sig); 13384260Sobrien (void) signal(SIGTERM, sig); 1341573Srgrimes 13584260Sobrien hist = history_init(); /* Init the builtin history */ 13684260Sobrien /* Remember 100 events */ 13784260Sobrien history(hist, &ev, H_SETSIZE, 100); 1381573Srgrimes 13984260Sobrien tok = tok_init(NULL); /* Initialize the tokenizer */ 1401573Srgrimes 14184260Sobrien /* Initialize editline */ 14284260Sobrien el = el_init(*argv, stdin, stdout, stderr); 1431573Srgrimes 14484260Sobrien el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */ 14584260Sobrien el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */ 146268502Spfg el_set(el, EL_PROMPT_ESC, prompt, '\1');/* Set the prompt function */ 1471573Srgrimes 14884260Sobrien /* Tell editline to use this history interface */ 14984260Sobrien el_set(el, EL_HIST, history, hist); 1501573Srgrimes 15184260Sobrien /* Add a user-defined function */ 15284260Sobrien el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete); 1531573Srgrimes 15484260Sobrien /* Bind tab to it */ 15584260Sobrien el_set(el, EL_BIND, "^I", "ed-complete", NULL); 1561573Srgrimes 15784260Sobrien /* 15884260Sobrien * Bind j, k in vi command mode to previous and next line, instead 15984260Sobrien * of previous and next history. 16084260Sobrien */ 16184260Sobrien el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL); 16284260Sobrien el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL); 1631573Srgrimes 16484260Sobrien /* 16584260Sobrien * Source the user's defaults file. 16684260Sobrien */ 16784260Sobrien el_source(el, NULL); 1681573Srgrimes 16984260Sobrien while ((buf = el_gets(el, &num)) != NULL && num != 0) { 170148834Sstefanf int ac, cc, co; 1711573Srgrimes#ifdef DEBUG 172148834Sstefanf int i; 1731573Srgrimes#endif 174148834Sstefanf const char **av; 175148834Sstefanf const LineInfo *li; 176148834Sstefanf li = el_line(el); 177148834Sstefanf#ifdef DEBUG 178148834Sstefanf (void) fprintf(stderr, "==> got %d %s", num, buf); 179148834Sstefanf (void) fprintf(stderr, " > li `%.*s_%.*s'\n", 180148834Sstefanf (li->cursor - li->buffer), li->buffer, 181148834Sstefanf (li->lastchar - 1 - li->cursor), 182148834Sstefanf (li->cursor >= li->lastchar) ? "" : li->cursor); 183148834Sstefanf 184148834Sstefanf#endif 185148834Sstefanf if (gotsig) { 186268502Spfg (void) fprintf(stderr, "Got signal %d.\n", (int)gotsig); 187148834Sstefanf gotsig = 0; 188148834Sstefanf el_reset(el); 189148834Sstefanf } 190148834Sstefanf 19184260Sobrien if (!continuation && num == 1) 19284260Sobrien continue; 1931573Srgrimes 194148834Sstefanf ac = cc = co = 0; 195148834Sstefanf ncontinuation = tok_line(tok, li, &ac, &av, &cc, &co); 196148834Sstefanf if (ncontinuation < 0) { 197148834Sstefanf (void) fprintf(stderr, "Internal error\n"); 198148834Sstefanf continuation = 0; 199148834Sstefanf continue; 200148834Sstefanf } 201148834Sstefanf#ifdef DEBUG 202148834Sstefanf (void) fprintf(stderr, " > nc %d ac %d cc %d co %d\n", 203148834Sstefanf ncontinuation, ac, cc, co); 204148834Sstefanf#endif 20584260Sobrien#if 0 20684260Sobrien if (continuation) { 20784260Sobrien /* 20884260Sobrien * Append to the right event in case the user 20984260Sobrien * moved around in history. 21084260Sobrien */ 21184260Sobrien if (history(hist, &ev, H_SET, lastevent) == -1) 212148834Sstefanf err(1, "%d: %s", lastevent, ev.str); 21384260Sobrien history(hist, &ev, H_ADD , buf); 21484260Sobrien } else { 21584260Sobrien history(hist, &ev, H_ENTER, buf); 21684260Sobrien lastevent = ev.num; 21784260Sobrien } 21884260Sobrien#else 21984260Sobrien /* Simpler */ 22084260Sobrien history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf); 22184260Sobrien#endif 2221573Srgrimes 22384260Sobrien continuation = ncontinuation; 22484260Sobrien ncontinuation = 0; 225148834Sstefanf if (continuation) 226148834Sstefanf continue; 227148834Sstefanf#ifdef DEBUG 228148834Sstefanf for (i = 0; i < ac; i++) { 229148834Sstefanf (void) fprintf(stderr, " > arg# %2d ", i); 230148834Sstefanf if (i != cc) 231148834Sstefanf (void) fprintf(stderr, "`%s'\n", av[i]); 232148834Sstefanf else 233148834Sstefanf (void) fprintf(stderr, "`%.*s_%s'\n", 234148834Sstefanf co, av[i], av[i] + co); 235148834Sstefanf } 236148834Sstefanf#endif 2371573Srgrimes 23884260Sobrien if (strcmp(av[0], "history") == 0) { 23984260Sobrien int rv; 24026927Smsmith 24184260Sobrien switch (ac) { 24284260Sobrien case 1: 24384260Sobrien for (rv = history(hist, &ev, H_LAST); rv != -1; 24484260Sobrien rv = history(hist, &ev, H_PREV)) 24584260Sobrien (void) fprintf(stdout, "%4d %s", 24684260Sobrien ev.num, ev.str); 24784260Sobrien break; 24826927Smsmith 24984260Sobrien case 2: 25084260Sobrien if (strcmp(av[1], "clear") == 0) 25184260Sobrien history(hist, &ev, H_CLEAR); 25284260Sobrien else 25384260Sobrien goto badhist; 25484260Sobrien break; 25526927Smsmith 25684260Sobrien case 3: 25784260Sobrien if (strcmp(av[1], "load") == 0) 25884260Sobrien history(hist, &ev, H_LOAD, av[2]); 25984260Sobrien else if (strcmp(av[1], "save") == 0) 26084260Sobrien history(hist, &ev, H_SAVE, av[2]); 26184260Sobrien break; 26226927Smsmith 26384260Sobrien badhist: 26484260Sobrien default: 26584260Sobrien (void) fprintf(stderr, 26684260Sobrien "Bad history arguments\n"); 26784260Sobrien break; 26884260Sobrien } 26984260Sobrien } else if (el_parse(el, ac, av) == -1) { 27084260Sobrien switch (fork()) { 27184260Sobrien case 0: 272269107Spfg execvp(av[0], __DECONST(char **, av)); 27384260Sobrien perror(av[0]); 27484260Sobrien _exit(1); 27584260Sobrien /*NOTREACHED*/ 27684260Sobrien break; 27784260Sobrien 27884260Sobrien case -1: 27984260Sobrien perror("fork"); 28084260Sobrien break; 28184260Sobrien 28284260Sobrien default: 28384260Sobrien if (wait(&num) == -1) 28484260Sobrien perror("wait"); 28584260Sobrien (void) fprintf(stderr, "Exit %x\n", num); 28684260Sobrien break; 28784260Sobrien } 28884260Sobrien } 28984260Sobrien 29084260Sobrien tok_reset(tok); 29126927Smsmith } 2921573Srgrimes 29384260Sobrien el_end(el); 29484260Sobrien tok_end(tok); 29584260Sobrien history_end(hist); 2961573Srgrimes 29784260Sobrien return (0); 2981573Srgrimes} 299