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