PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/libedit/TEST/tc1.c

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