test.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /* $NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $ */
  2. /*-
  3. * Copyright (c) 1992, 1993
  4. * The Regents of the University of California. All rights reserved.
  5. *
  6. * This code is derived from software contributed to Berkeley by
  7. * Christos Zoulas of Cornell University.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * 3. All advertising materials mentioning features or use of this software
  18. * must display the following acknowledgement:
  19. * This product includes software developed by the University of
  20. * California, Berkeley and its contributors.
  21. * 4. Neither the name of the University nor the names of its contributors
  22. * may be used to endorse or promote products derived from this software
  23. * without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35. * SUCH DAMAGE.
  36. */
  37. #include "config.h"
  38. #ifndef lint
  39. __COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
  40. The Regents of the University of California. All rights reserved.\n");
  41. #endif /* not lint */
  42. #if !defined(lint) && !defined(SCCSID)
  43. #if 0
  44. static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93";
  45. #else
  46. __RCSID("$NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $");
  47. #endif
  48. #endif /* not lint && not SCCSID */
  49. /*
  50. * test.c: A little test program
  51. */
  52. #include <stdio.h>
  53. #include <string.h>
  54. #include <signal.h>
  55. #include <sys/wait.h>
  56. #include <ctype.h>
  57. #include <stdlib.h>
  58. #include <unistd.h>
  59. #include <dirent.h>
  60. #include "histedit.h"
  61. #include "tokenizer.h"
  62. static int continuation = 0;
  63. static EditLine *el = NULL;
  64. static u_char complete(EditLine *, int);
  65. int main(int, char **);
  66. static char *prompt(EditLine *);
  67. static void sig(int);
  68. static char *
  69. prompt(EditLine *el)
  70. {
  71. static char a[] = "Edit$";
  72. static char b[] = "Edit>";
  73. return (continuation ? b : a);
  74. }
  75. static void
  76. sig(int i)
  77. {
  78. (void) fprintf(stderr, "Got signal %d.\n", i);
  79. el_reset(el);
  80. }
  81. static unsigned char
  82. complete(EditLine *el, int ch)
  83. {
  84. DIR *dd = opendir(".");
  85. struct dirent *dp;
  86. const char* ptr;
  87. const LineInfo *lf = el_line(el);
  88. int len;
  89. /*
  90. * Find the last word
  91. */
  92. for (ptr = lf->cursor - 1; !isspace(*ptr) && ptr > lf->buffer; ptr--)
  93. continue;
  94. len = lf->cursor - ++ptr;
  95. for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
  96. if (len > strlen(dp->d_name))
  97. continue;
  98. if (strncmp(dp->d_name, ptr, len) == 0) {
  99. closedir(dd);
  100. if (el_insertstr(el, &dp->d_name[len]) == -1)
  101. return (CC_ERROR);
  102. else
  103. return (CC_REFRESH);
  104. }
  105. }
  106. closedir(dd);
  107. return (CC_ERROR);
  108. }
  109. int
  110. main(int argc, char *argv[])
  111. {
  112. int num;
  113. const char *buf;
  114. Tokenizer *tok;
  115. #if 0
  116. int lastevent = 0;
  117. #endif
  118. int ncontinuation;
  119. History *hist;
  120. HistEvent ev;
  121. (void) signal(SIGINT, sig);
  122. (void) signal(SIGQUIT, sig);
  123. (void) signal(SIGHUP, sig);
  124. (void) signal(SIGTERM, sig);
  125. hist = history_init(); /* Init the builtin history */
  126. /* Remember 100 events */
  127. history(hist, &ev, H_SETSIZE, 100);
  128. tok = tok_init(NULL); /* Initialize the tokenizer */
  129. /* Initialize editline */
  130. el = el_init(*argv, stdin, stdout, stderr);
  131. el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */
  132. el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */
  133. el_set(el, EL_PROMPT, prompt); /* Set the prompt function */
  134. /* Tell editline to use this history interface */
  135. el_set(el, EL_HIST, history, hist);
  136. /* Add a user-defined function */
  137. el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete);
  138. /* Bind tab to it */
  139. el_set(el, EL_BIND, "^I", "ed-complete", NULL);
  140. /*
  141. * Bind j, k in vi command mode to previous and next line, instead
  142. * of previous and next history.
  143. */
  144. el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL);
  145. el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL);
  146. /*
  147. * Source the user's defaults file.
  148. */
  149. el_source(el, NULL);
  150. while ((buf = el_gets(el, &num)) != NULL && num != 0) {
  151. int ac;
  152. const char **av;
  153. #ifdef DEBUG
  154. (void) fprintf(stderr, "got %d %s", num, buf);
  155. #endif
  156. if (!continuation && num == 1)
  157. continue;
  158. ncontinuation = tok_line(tok, buf, &ac, &av) > 0;
  159. #if 0
  160. if (continuation) {
  161. /*
  162. * Append to the right event in case the user
  163. * moved around in history.
  164. */
  165. if (history(hist, &ev, H_SET, lastevent) == -1)
  166. err(1, "%d: %s\n", lastevent, ev.str);
  167. history(hist, &ev, H_ADD , buf);
  168. } else {
  169. history(hist, &ev, H_ENTER, buf);
  170. lastevent = ev.num;
  171. }
  172. #else
  173. /* Simpler */
  174. history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf);
  175. #endif
  176. continuation = ncontinuation;
  177. ncontinuation = 0;
  178. if (strcmp(av[0], "history") == 0) {
  179. int rv;
  180. switch (ac) {
  181. case 1:
  182. for (rv = history(hist, &ev, H_LAST); rv != -1;
  183. rv = history(hist, &ev, H_PREV))
  184. (void) fprintf(stdout, "%4d %s",
  185. ev.num, ev.str);
  186. break;
  187. case 2:
  188. if (strcmp(av[1], "clear") == 0)
  189. history(hist, &ev, H_CLEAR);
  190. else
  191. goto badhist;
  192. break;
  193. case 3:
  194. if (strcmp(av[1], "load") == 0)
  195. history(hist, &ev, H_LOAD, av[2]);
  196. else if (strcmp(av[1], "save") == 0)
  197. history(hist, &ev, H_SAVE, av[2]);
  198. break;
  199. badhist:
  200. default:
  201. (void) fprintf(stderr,
  202. "Bad history arguments\n");
  203. break;
  204. }
  205. } else if (el_parse(el, ac, av) == -1) {
  206. switch (fork()) {
  207. case 0:
  208. execvp(av[0], (char *const *)av);
  209. perror(av[0]);
  210. _exit(1);
  211. /*NOTREACHED*/
  212. break;
  213. case -1:
  214. perror("fork");
  215. break;
  216. default:
  217. if (wait(&num) == -1)
  218. perror("wait");
  219. (void) fprintf(stderr, "Exit %x\n", num);
  220. break;
  221. }
  222. }
  223. tok_reset(tok);
  224. }
  225. el_end(el);
  226. tok_end(tok);
  227. history_end(hist);
  228. return (0);
  229. }