ntp_lineedit.c revision 258945
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 39extern char * progname; 40 41/* 42 * globals, private prototypes 43 */ 44 45static int ntp_readline_initted; 46static char * lineedit_prompt; 47 48 49#ifdef LE_EDITLINE 50# ifndef H_SETSIZE 51# define H_SETSIZE H_EVENT 52# endif 53static EditLine * ntp_el; 54static History * ntp_hist; 55static HistEvent hev; 56 57char * ntp_prompt_callback(EditLine *); 58#endif /* LE_EDITLINE */ 59 60 61/* 62 * ntp_readline_init - setup, set or reset prompt string 63 */ 64int 65ntp_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 */ 129void 130ntp_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 159char * 160ntp_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 */ 237char * 238ntp_prompt_callback( 239 EditLine *el 240 ) 241{ 242 UNUSED_ARG(el); 243 244 return lineedit_prompt; 245} 246#endif /* LE_EDITLINE */ 247 248