freebsd-dev/contrib/ntp/libntp/ntp_lineedit.c
Xin LI 3311ff84ea MFV r293415:
ntp 4.2.8p5

Reviewed by:	cy, roberto
Relnotes:	yes
Differential Revision:	https://reviews.freebsd.org/D4828
2016-01-08 15:53:48 +00:00

247 lines
3.9 KiB
C

/*
* ntp_lineedit.c - generic interface to various line editing libs
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#if defined(HAVE_READLINE_HISTORY) && \
(!defined(HAVE_READLINE_HISTORY_H) || \
!defined(HAVE_READLINE_READLINE_H))
# undef HAVE_READLINE_HISTORY
#endif
#if defined(HAVE_READLINE_HISTORY)
# include <readline/readline.h>
# include <readline/history.h>
# define LE_READLINE
#elif defined(HAVE_HISTEDIT_H)
# include <histedit.h>
# define LE_EDITLINE
#else
# define LE_NONE
#endif
#include "ntp.h"
#include "ntp_stdlib.h"
#include "ntp_lineedit.h"
#include "safecast.h"
#define MAXEDITLINE 512
/*
* external references
*/
extern char const * progname;
/*
* globals, private prototypes
*/
static int ntp_readline_initted;
static char * lineedit_prompt;
#ifdef LE_EDITLINE
# ifndef H_SETSIZE
# define H_SETSIZE H_EVENT
# endif
static EditLine * ntp_el;
static History * ntp_hist;
static HistEvent hev;
char * ntp_prompt_callback(EditLine *);
#endif /* LE_EDITLINE */
/*
* ntp_readline_init - setup, set or reset prompt string
*/
int
ntp_readline_init(
const char * prompt
)
{
int success;
success = 1;
if (prompt) {
if (lineedit_prompt)
free(lineedit_prompt);
lineedit_prompt = estrdup(prompt);
}
#ifdef LE_EDITLINE
if (NULL == ntp_el) {
# if 4 == EL_INIT_ARGS
ntp_el = el_init(progname, stdin, stdout, stderr);
# else
ntp_el = el_init(progname, stdin, stdout);
# endif
if (ntp_el) {
el_set(ntp_el, EL_PROMPT, ntp_prompt_callback);
el_set(ntp_el, EL_EDITOR, "emacs");
ntp_hist = history_init();
if (NULL == ntp_hist) {
mfprintf(stderr, "history_init(): %m\n");
fflush(stderr);
el_end(ntp_el);
ntp_el = NULL;
success = 0;
} else {
ZERO(hev);
#ifdef H_SETSIZE
history(ntp_hist, &hev, H_SETSIZE, 128);
#endif
el_set(ntp_el, EL_HIST, history,
ntp_hist);
/* use any .editrc */
el_source(ntp_el, NULL);
}
} else
success = 0;
}
#endif /* LE_EDITLINE */
ntp_readline_initted = success;
return success;
}
/*
* ntp_readline_uninit - release resources
*/
void
ntp_readline_uninit(
void
)
{
#ifdef LE_EDITLINE
if (ntp_el) {
el_end(ntp_el);
ntp_el = NULL;
history_end(ntp_hist);
ntp_hist = NULL;
}
#endif /* LE_EDITLINE */
if (lineedit_prompt) {
free(lineedit_prompt);
lineedit_prompt = NULL;
}
ntp_readline_initted = 0;
}
/*
* ntp_readline - read a line with the line editor available
*
* The string returned must be released with free()
*/
char *
ntp_readline(
int * pcount
)
{
char * line;
#ifdef LE_NONE
char line_buf[MAXEDITLINE];
#endif
#ifdef LE_EDITLINE
const char * cline;
#endif
if (!ntp_readline_initted)
return NULL;
*pcount = 0;
#ifdef LE_READLINE
line = readline(lineedit_prompt ? lineedit_prompt : "");
if (NULL != line) {
if (*line) {
add_history(line);
}
*pcount = strlen(line);
}
#endif /* LE_READLINE */
#ifdef LE_EDITLINE
cline = el_gets(ntp_el, pcount);
if (NULL != cline) {
history(ntp_hist, &hev, H_ENTER, cline);
line = estrdup(cline);
} else if (*pcount == -1) {
line = NULL;
} else {
line = estrdup("");
}
#endif /* LE_EDITLINE */
#ifdef LE_NONE
/* stone hammers */
if (lineedit_prompt) {
# ifdef VMS
/*
* work around problem mixing
* stdout & stderr
*/
fputs("", stdout);
# endif /* VMS */
fputs(lineedit_prompt, stderr);
fflush(stderr);
}
line = fgets(line_buf, sizeof(line_buf), stdin);
if (NULL != line && *line) {
*pcount = (int)strlen(line); /* cannot overflow here */
line = estrdup(line);
} else
line = NULL;
#endif /* LE_NONE */
if (!line) /* EOF */
fputs("\n", stderr);
return line;
}
#ifdef LE_EDITLINE
/*
* ntp_prompt_callback - return prompt string to el_gets()
*/
char *
ntp_prompt_callback(
EditLine *el
)
{
UNUSED_ARG(el);
return lineedit_prompt;
}
#endif /* LE_EDITLINE */