Example #1
0
int
main(int argc, char *argv[])
{
	EditLine *el = NULL;
	int numc, ncontinuation;
	const wchar_t *line;
	TokenizerW *tok;
	HistoryW *hist;
	HistEventW ev;
#ifdef DEBUG
	int i;
#endif

	setlocale(LC_ALL, "");

	(void)signal(SIGINT,  sig);
	(void)signal(SIGQUIT, sig);
	(void)signal(SIGHUP,  sig);
	(void)signal(SIGTERM, sig);

	hist = history_winit();		/* Init built-in history     */
	history_w(hist, &ev, H_SETSIZE, 100);	/* Remember 100 events	     */
	history_w(hist, &ev, H_LOAD, hfile);

	tok = tok_winit(NULL);			/* Init the tokenizer	     */

	el = el_init(argv[0], stdin, stdout, stderr);

	el_wset(el, EL_EDITOR, L"vi");		/* Default editor is vi	     */
	el_wset(el, EL_SIGNAL, 1);		/* Handle signals gracefully */
	el_wset(el, EL_PROMPT_ESC, prompt, '\1'); /* Set the prompt function */

	el_wset(el, EL_HIST, history_w, hist);	/* FIXME - history_w? */

					/* Add a user-defined function	*/
	el_wset(el, EL_ADDFN, L"ed-complete", L"Complete argument", complete);

					/* Bind <tab> to it */
	el_wset(el, EL_BIND, L"^I", L"ed-complete", NULL);

	/*
	* Bind j, k in vi command mode to previous and next line, instead
	* of previous and next history.
	*/
	el_wset(el, EL_BIND, L"-a", L"k", L"ed-prev-line", NULL);
	el_wset(el, EL_BIND, L"-a", L"j", L"ed-next-line", NULL);

	/* Source the user's defaults file. */
	el_source(el, NULL);

	while((line = el_wgets(el, &numc)) != NULL && numc != 0) {
		int ac, cc, co, rc;
		const wchar_t **av;

		const LineInfoW *li;
		li = el_wline(el);

#ifdef DEBUG
		(void)fwprintf(stderr, L"==> got %d %ls", numc, line);
		(void)fwprintf(stderr, L"  > li `%.*ls_%.*ls'\n",
		    (li->cursor - li->buffer), li->buffer,
		    (li->lastchar - 1 - li->cursor),
		    (li->cursor >= li->lastchar) ? L"" : li->cursor);
#endif

		if (gotsig) {
			(void)fprintf(stderr, "Got signal %d.\n", gotsig);
			gotsig = 0;
			el_reset(el);
		}

		if(!continuation && numc == 1)
			continue;	/* Only got a linefeed */

		ac = cc = co = 0;
		ncontinuation = tok_wline(tok, li, &ac, &av, &cc, &co);
		if (ncontinuation < 0) {
			(void) fprintf(stderr, "Internal error\n");
			continuation = 0;
			continue;
		}

#ifdef DEBUG
		(void)fprintf(stderr, "  > nc %d ac %d cc %d co %d\n",
			ncontinuation, ac, cc, co);
#endif
		history_w(hist, &ev, continuation ? H_APPEND : H_ENTER, line);

		continuation = ncontinuation;
		ncontinuation = 0;
		if(continuation)
			continue;

#ifdef DEBUG
		for (i = 0; i < ac; ++i) {
			(void)fwprintf(stderr, L"  > arg# %2d ", i);
			if (i != cc)
				(void)fwprintf(stderr, L"`%ls'\n", av[i]);
			else
				(void)fwprintf(stderr, L"`%.*ls_%ls'\n",
				    co, av[i], av[i] + co);
		}
#endif

		if (wcscmp (av[0], L"history") == 0) {
			switch(ac) {
			case 1:
				for(rc = history_w(hist, &ev, H_LAST);
				     rc != -1;
				     rc = history_w(hist, &ev, H_PREV))
					(void)fwprintf(stdout, L"%4d %ls",
					     ev.num, ev.str);
				break;
			case 2:
				if (wcscmp(av[1], L"clear") == 0)
					history_w(hist, &ev, H_CLEAR);
				else
					goto badhist;
				break;
			case 3:
				if (wcscmp(av[1], L"load") == 0)
					history_w(hist, &ev, H_LOAD,
					    my_wcstombs(av[2]));
				else if (wcscmp(av[1], L"save") == 0)
					history_w(hist, &ev, H_SAVE,
					    my_wcstombs(av[2]));
				else
					goto badhist;
				break;
			badhist:
			default:
				(void)fprintf(stderr,
				    "Bad history arguments\n");
				break;
			}
		} else if (el_wparse(el, ac, av) == -1) {
			switch (fork()) {
			case 0: {
				Tokenizer *ntok = tok_init(NULL);
				int nargc;
				const char **nav;
				tok_str(ntok, my_wcstombs(line), &nargc, &nav);
				execvp(nav[0],(char **)nav);
				perror(nav[0]);
				_exit(1);
				/* NOTREACHED */
				break;
			}
			case -1:
				perror("fork");
				break;
			default:
				if (wait(&rc) == -1)
					perror("wait");
				(void)fprintf(stderr, "Exit %x\n", rc);
				break;
			}
		}

		tok_wreset(tok);
	}

	el_end(el);
	tok_wend(tok);
	history_w(hist, &ev, H_SAVE, hfile);
	history_wend(hist);

	fprintf(stdout, "\n");
	return 0;
}
Example #2
0
char *lg_readline(const char *mb_prompt)
{
	static int is_init = FALSE;
	static HistoryW *hist = NULL;
	static HistEventW ev;
	static EditLine *el = NULL;

	int numc;
	size_t byte_len;
	const wchar_t *wc_line;
	char *mb_line;
	char *nl;

	if (!is_init)
	{
		size_t sz;
#define HFILE ".lg_history"
		is_init = TRUE;

		sz = mbstowcs(NULL, mb_prompt, 0) + 4;
		wc_prompt = malloc (sz*sizeof(wchar_t));
		mbstowcs(wc_prompt, mb_prompt, sz);

		hist = history_winit();    /* Init built-in history */
		history_w(hist, &ev, H_SETSIZE, 20);  /* Remember 20 events */
		history_w(hist, &ev, H_LOAD, HFILE);
		el = el_init("link-parser", stdin, stdout, stderr);

		/* By default, it comes up in vi mode, with the editor not in
		 * insert mode; and even when in insert mode, it drops back to
		 * command mode at the drop of a hat. Totally confusing/lame. */
		el_wset(el, EL_EDITOR, L"emacs");
		el_wset(el, EL_HIST, history_w, hist);
		el_wset(el, EL_PROMPT_ESC, prompt, '\1'); /* Set the prompt function */
		el_source(el, NULL); /* Source the user's defaults file. */
	}

	wc_line = el_wgets(el, &numc);

	/* Received end-of-file */
	if (numc <= 0)
	{
		el_end(el);
		history_wend(hist);
		free(wc_prompt);
		wc_prompt = NULL;
		hist = NULL;
		el = NULL;
		is_init = FALSE;
		return NULL;
	}

	if (1 < numc)
	{
		history_w(hist, &ev, H_ENTER, wc_line);
		history_w(hist, &ev, H_SAVE, HFILE);
	}
	/* fwprintf(stderr, L"==> got %d %ls", numc, wc_line); */

	byte_len = wcstombs(NULL, wc_line, 0) + 4;
	mb_line = malloc(byte_len);
	wcstombs(mb_line, wc_line, byte_len);

	/* In order to be compatible with regular libedit, we have to
	 * strip away the trailing newline, if any. */
	nl = strchr(mb_line, '\n');
	if (nl) *nl = 0x0;
	
	return mb_line;
}