1 /*- 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Christos Zoulas of Cornell University. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #if !defined(lint) && !defined(SCCSID) 12 static char sccsid[] = "@(#)el.c 8.1 (Berkeley) 06/04/93"; 13 #endif /* not lint && not SCCSID */ 14 15 /* 16 * el.c: EditLine interface functions 17 */ 18 #include "sys.h" 19 20 #include <sys/types.h> 21 #include <sys/param.h> 22 #include <string.h> 23 #include <stdlib.h> 24 #if __STDC__ 25 # include <stdarg.h> 26 #else 27 # include <varargs.h> 28 #endif 29 #include "el.h" 30 31 /* el_init(): 32 * Initialize editline and set default parameters. 33 */ 34 public EditLine * 35 el_init(prog, fin, fout) 36 const char *prog; 37 FILE *fin, *fout; 38 { 39 EditLine *el = (EditLine *) el_malloc(sizeof(EditLine)); 40 #ifdef DEBUG 41 char *tty; 42 #endif 43 44 if (el == NULL) 45 return NULL; 46 47 memset(el, 0, sizeof(EditLine)); 48 49 el->el_infd = fileno(fin); 50 el->el_outfile = fout; 51 el->el_prog = strdup(prog); 52 53 #ifdef DEBUG 54 if ((tty = getenv("DEBUGTTY")) != NULL) { 55 el->el_errfile = fopen(tty, "w"); 56 if (el->el_errfile == NULL) { 57 extern errno; 58 (void) fprintf(stderr, "Cannot open %s (%s).\n", 59 tty, strerror(errno)); 60 return NULL; 61 } 62 } 63 else 64 #endif 65 el->el_errfile = stderr; 66 67 /* 68 * Initialize all the modules. Order is important!!! 69 */ 70 (void) term_init(el); 71 (void) tty_init(el); 72 (void) key_init(el); 73 (void) map_init(el); 74 (void) ch_init(el); 75 (void) search_init(el); 76 (void) hist_init(el); 77 (void) prompt_init(el); 78 (void) sig_init(el); 79 el->el_flags = 0; 80 81 return el; 82 } /* end el_init */ 83 84 85 /* el_end(): 86 * Clean up. 87 */ 88 public void 89 el_end(el) 90 EditLine *el; 91 { 92 if (el == NULL) 93 return; 94 95 el_reset(el); 96 97 term_end(el); 98 tty_end(el); 99 key_end(el); 100 map_end(el); 101 ch_end(el); 102 search_end(el); 103 hist_end(el); 104 prompt_end(el); 105 sig_end(el); 106 107 el_free((ptr_t) el->el_prog); 108 el_free((ptr_t) el); 109 } /* end el_end */ 110 111 112 /* el_reset(): 113 * Reset the tty and the parser 114 */ 115 public void 116 el_reset(el) 117 EditLine *el; 118 { 119 tty_cookedmode(el); 120 ch_reset(el); /* XXX: Do we want that? */ 121 } 122 123 124 /* el_set(): 125 * set the editline parameters 126 */ 127 public int 128 #if __STDC__ 129 el_set(EditLine *el, int op, ...) 130 #else 131 el_set(va_alist) 132 va_dcl 133 #endif 134 { 135 va_list va; 136 int rv; 137 #if __STDC__ 138 va_start(va, op); 139 #else 140 EditLine *el; 141 int op; 142 143 va_start(va); 144 el = va_arg(va, EditLine *); 145 op = va_arg(va, int); 146 #endif 147 148 switch (op) { 149 case EL_PROMPT: 150 rv = prompt_set(el, va_arg(va, el_pfunc_t)); 151 break; 152 153 case EL_TERMINAL: 154 rv = term_set(el, va_arg(va, char *)); 155 break; 156 157 case EL_EDITOR: 158 rv = map_set_editor(el, va_arg(va, char *)); 159 break; 160 161 case EL_SIGNAL: 162 if (va_arg(va, int)) 163 el->el_flags |= HANDLE_SIGNALS; 164 else 165 el->el_flags &= ~HANDLE_SIGNALS; 166 rv = 0; 167 break; 168 169 case EL_BIND: 170 case EL_TELLTC: 171 case EL_SETTC: 172 case EL_ECHOTC: 173 case EL_SETTY: 174 { 175 char *argv[20]; 176 int i; 177 for (i = 1; i < 20; i++) 178 if ((argv[i] = va_arg(va, char *)) == NULL) 179 break; 180 181 switch (op) { 182 case EL_BIND: 183 argv[0] = "bind"; 184 rv = map_bind(el, i, argv); 185 break; 186 187 case EL_TELLTC: 188 argv[0] = "telltc"; 189 rv = term_telltc(el, i, argv); 190 break; 191 192 case EL_SETTC: 193 argv[0] = "settc"; 194 rv = term_settc(el, i, argv); 195 break; 196 197 case EL_ECHOTC: 198 argv[0] = "echotc"; 199 rv = term_echotc(el, i, argv); 200 break; 201 202 case EL_SETTY: 203 argv[0] = "setty"; 204 rv = tty_stty(el, i, argv); 205 break; 206 207 default: 208 rv = -1; 209 abort(); 210 break; 211 } 212 } 213 break; 214 215 case EL_ADDFN: 216 { 217 char *name = va_arg(va, char *); 218 char *help = va_arg(va, char *); 219 el_func_t func = va_arg(va, el_func_t); 220 rv = map_addfunc(el, name, help, func); 221 } 222 break; 223 224 case EL_HIST: 225 { 226 hist_fun_t func = va_arg(va, hist_fun_t); 227 ptr_t ptr = va_arg(va, char *); 228 rv = hist_set(el, func, ptr); 229 } 230 break; 231 232 default: 233 rv = -1; 234 } 235 236 va_end(va); 237 return rv; 238 } /* end el_set */ 239 240 241 /* el_line(): 242 * Return editing info 243 */ 244 public const LineInfo * 245 el_line(el) 246 EditLine *el; 247 { 248 return (const LineInfo *) &el->el_line; 249 } 250 251 static const char elpath[] = "/.editrc"; 252 253 /* el_source(): 254 * Source a file 255 */ 256 public int 257 el_source(el, fname) 258 EditLine *el; 259 const char *fname; 260 { 261 FILE *fp; 262 size_t len; 263 char *ptr, path[MAXPATHLEN]; 264 265 if (fname == NULL) { 266 fname = &elpath[1]; 267 if ((fp = fopen(fname, "r")) == NULL) { 268 if ((ptr = getenv("HOME")) == NULL) 269 return -1; 270 fname = strncpy(path, ptr, MAXPATHLEN); 271 (void) strncat(path, elpath, MAXPATHLEN); 272 path[MAXPATHLEN-1] = '\0'; 273 } 274 } 275 276 if ((fp = fopen(fname, "r")) == NULL) 277 return -1; 278 279 while ((ptr = fgetline(fp, &len)) != NULL) 280 ptr[len - 1] = '\0'; 281 if (parse_line(el, ptr) == -1) { 282 (void) fclose(fp); 283 return -1; 284 } 285 286 (void) fclose(fp); 287 return 0; 288 } 289 290 291 /* el_resize(): 292 * Called from program when terminal is resized 293 */ 294 public void 295 el_resize(el) 296 EditLine *el; 297 { 298 int lins, cols; 299 sigset_t oset, nset; 300 (void) sigemptyset(&nset); 301 (void) sigaddset(&nset, SIGWINCH); 302 (void) sigprocmask(SIG_BLOCK, &nset, &oset); 303 304 /* get the correct window size */ 305 if (term_get_size(el, &lins, &cols)) 306 term_change_size(el, lins, cols); 307 308 (void) sigprocmask(SIG_SETMASK, &oset, NULL); 309 } 310