1: /*
2: * ntp_lineedit.c - generic interface to various line editing libs
3: */
4: #ifdef HAVE_CONFIG_H
5: # include <config.h>
6: #endif
7:
8: #include <errno.h>
9: #include <string.h>
10: #include <stdlib.h>
11: #include <stdio.h>
12:
13: #if defined(HAVE_READLINE_HISTORY) && \
14: (!defined(HAVE_READLINE_HISTORY_H) || \
15: !defined(HAVE_READLINE_READLINE_H))
16: # undef HAVE_READLINE_HISTORY
17: #endif
18: #if defined(HAVE_READLINE_HISTORY)
19: # include <readline/readline.h>
20: # include <readline/history.h>
21: # define LE_READLINE
22: #elif defined(HAVE_HISTEDIT_H)
23: # include <histedit.h>
24: # define LE_EDITLINE
25: #else
26: # define LE_NONE
27: #endif
28:
29: #include "ntp.h"
30: #include "ntp_stdlib.h"
31: #include "ntp_lineedit.h"
32:
33: #define MAXEDITLINE 512
34:
35: /*
36: * external references
37: */
38:
39: extern char * progname;
40:
41: /*
42: * globals, private prototypes
43: */
44:
45: static int ntp_readline_initted;
46: static char * lineedit_prompt;
47:
48:
49: #ifdef LE_EDITLINE
50: # ifndef H_SETSIZE
51: # define H_SETSIZE H_EVENT
52: # endif
53: static EditLine * ntp_el;
54: static History * ntp_hist;
55: static HistEvent hev;
56:
57: char * ntp_prompt_callback(EditLine *);
58: #endif /* LE_EDITLINE */
59:
60:
61: /*
62: * ntp_readline_init - setup, set or reset prompt string
63: */
64: int
65: ntp_readline_init(
66: const char * prompt
67: )
68: {
69: int success;
70:
71: success = 1;
72:
73: if (prompt) {
74: if (lineedit_prompt)
75: free(lineedit_prompt);
76: lineedit_prompt = estrdup(prompt);
77: }
78:
79: #ifdef LE_EDITLINE
80: if (NULL == ntp_el) {
81:
82: # if 4 == EL_INIT_ARGS
83: ntp_el = el_init(progname, stdin, stdout, stderr);
84: # else
85: ntp_el = el_init(progname, stdin, stdout);
86: # endif
87: if (ntp_el) {
88:
89: el_set(ntp_el, EL_PROMPT, ntp_prompt_callback);
90: el_set(ntp_el, EL_EDITOR, "emacs");
91:
92: ntp_hist = history_init();
93:
94: if (NULL == ntp_hist) {
95:
96: fprintf(stderr, "history_init(): %s\n",
97: strerror(errno));
98: fflush(stderr);
99:
100: el_end(ntp_el);
101: ntp_el = NULL;
102:
103: success = 0;
104:
105: } else {
106: memset(&hev, 0, sizeof(hev));
107: #ifdef H_SETSIZE
108: history(ntp_hist, &hev, H_SETSIZE, 128);
109: #endif
110: el_set(ntp_el, EL_HIST, history,
111: ntp_hist);
112: /* use any .editrc */
113: el_source(ntp_el, NULL);
114: }
115: } else
116: success = 0;
117: }
118: #endif /* LE_EDITLINE */
119:
120: ntp_readline_initted = success;
121:
122: return success;
123: }
124:
125:
126: /*
127: * ntp_readline_uninit - release resources
128: */
129: void
130: ntp_readline_uninit(
131: void
132: )
133: {
134: #ifdef LE_EDITLINE
135: if (ntp_el) {
136: el_end(ntp_el);
137: ntp_el = NULL;
138:
139: history_end(ntp_hist);
140: ntp_hist = NULL;
141: }
142: #endif /* LE_EDITLINE */
143:
144: if (lineedit_prompt) {
145: free(lineedit_prompt);
146: lineedit_prompt = NULL;
147: }
148:
149: ntp_readline_initted = 0;
150: }
151:
152:
153: /*
154: * ntp_readline - read a line with the line editor available
155: *
156: * The string returned must be released with free()
157: */
158:
159: char *
160: ntp_readline(
161: int * pcount
162: )
163: {
164: char * line;
165: #ifdef LE_NONE
166: char line_buf[MAXEDITLINE];
167: #endif
168: #ifdef LE_EDITLINE
169: const char * cline;
170: #endif
171:
172: if (!ntp_readline_initted)
173: return NULL;
174:
175: *pcount = 0;
176:
177: #ifdef LE_READLINE
178: line = readline(lineedit_prompt ? lineedit_prompt : "");
179: if (NULL != line) {
180: if (*line) {
181: add_history(line);
182: *pcount = strlen(line);
183: } else {
184: free(line);
185: line = NULL;
186: }
187: }
188: #endif /* LE_READLINE */
189:
190: #ifdef LE_EDITLINE
191: cline = el_gets(ntp_el, pcount);
192:
193: if (NULL != cline && *cline) {
194: history(ntp_hist, &hev, H_ENTER, cline);
195: *pcount = strlen(cline);
196: line = estrdup(cline);
197: } else
198: line = NULL;
199: #endif /* LE_EDITLINE */
200:
201: #ifdef LE_NONE
202: /* stone hammers */
203: if (lineedit_prompt) {
204: # ifdef VMS
205: /*
206: * work around problem mixing
207: * stdout & stderr
208: */
209: fputs("", stdout);
210: # endif /* VMS */
211:
212: fputs(lineedit_prompt, stderr);
213: fflush(stderr);
214: }
215:
216: line = fgets(line_buf, sizeof(line_buf), stdin);
217: if (NULL != line && *line) {
218: *pcount = strlen(line);
219: line = estrdup(line);
220: } else
221: line = NULL;
222:
223: #endif /* LE_NONE */
224:
225:
226: if (!line) /* EOF */
227: fputs("\n", stderr);
228:
229: return line;
230: }
231:
232:
233: #ifdef LE_EDITLINE
234: /*
235: * ntp_prompt_callback - return prompt string to el_gets()
236: */
237: char *
238: ntp_prompt_callback(
239: EditLine *el
240: )
241: {
242: UNUSED_ARG(el);
243:
244: return lineedit_prompt;
245: }
246: #endif /* LE_EDITLINE */
247:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>