linenoise.c (44296B)
1 /* linenoise.c -- guerrilla line editing library against the idea that a 2 * line editing lib needs to be 20,000 lines of C code. 3 * 4 * You can find the latest source code at: 5 * 6 * http://github.com/antirez/linenoise 7 * 8 * Does a number of crazy assumptions that happen to be true in 99.9999% of 9 * the 2010 UNIX computers around. 10 * 11 * ------------------------------------------------------------------------ 12 * 13 * Copyright (c) 2010-2023, Salvatore Sanfilippo <antirez at gmail dot com> 14 * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com> 15 * 16 * All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions are 20 * met: 21 * 22 * * Redistributions of source code must retain the above copyright 23 * notice, this list of conditions and the following disclaimer. 24 * 25 * * Redistributions in binary form must reproduce the above copyright 26 * notice, this list of conditions and the following disclaimer in the 27 * documentation and/or other materials provided with the distribution. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * ------------------------------------------------------------------------ 42 * 43 * References: 44 * - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html 45 * - http://www.3waylabs.com/nw/WWW/products/wizcon/vt220.html 46 * 47 * Todo list: 48 * - Filter bogus Ctrl+<char> combinations. 49 * - Win32 support 50 * 51 * Bloat: 52 * - History search like Ctrl+r in readline? 53 * 54 * List of escape sequences used by this program, we do everything just 55 * with three sequences. In order to be so cheap we may have some 56 * flickering effect with some slow terminal, but the lesser sequences 57 * the more compatible. 58 * 59 * EL (Erase Line) 60 * Sequence: ESC [ n K 61 * Effect: if n is 0 or missing, clear from cursor to end of line 62 * Effect: if n is 1, clear from beginning of line to cursor 63 * Effect: if n is 2, clear entire line 64 * 65 * CUF (CUrsor Forward) 66 * Sequence: ESC [ n C 67 * Effect: moves cursor forward n chars 68 * 69 * CUB (CUrsor Backward) 70 * Sequence: ESC [ n D 71 * Effect: moves cursor backward n chars 72 * 73 * The following is used to get the terminal width if getting 74 * the width with the TIOCGWINSZ ioctl fails 75 * 76 * DSR (Device Status Report) 77 * Sequence: ESC [ 6 n 78 * Effect: reports the current cusor position as ESC [ n ; m R 79 * where n is the row and m is the column 80 * 81 * When multi line mode is enabled, we also use an additional escape 82 * sequence. However multi line editing is disabled by default. 83 * 84 * CUU (Cursor Up) 85 * Sequence: ESC [ n A 86 * Effect: moves cursor up of n chars. 87 * 88 * CUD (Cursor Down) 89 * Sequence: ESC [ n B 90 * Effect: moves cursor down of n chars. 91 * 92 * When linenoiseClearScreen() is called, two additional escape sequences 93 * are used in order to clear the screen and position the cursor at home 94 * position. 95 * 96 * CUP (Cursor position) 97 * Sequence: ESC [ H 98 * Effect: moves the cursor to upper left corner 99 * 100 * ED (Erase display) 101 * Sequence: ESC [ 2 J 102 * Effect: clear the whole screen 103 * 104 */ 105 106 #include <termios.h> 107 #include <unistd.h> 108 #include <stdlib.h> 109 #include <stdio.h> 110 #include <errno.h> 111 #include <string.h> 112 #include <stdlib.h> 113 #include <ctype.h> 114 #include <sys/stat.h> 115 #include <sys/types.h> 116 #include <sys/ioctl.h> 117 #include <unistd.h> 118 #include "linenoise.h" 119 120 #define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100 121 #define LINENOISE_MAX_LINE 4096 122 static char *unsupported_term[] = {"dumb","cons25","emacs",NULL}; 123 static linenoiseCompletionCallback *completionCallback = NULL; 124 static linenoiseHintsCallback *hintsCallback = NULL; 125 static linenoiseFreeHintsCallback *freeHintsCallback = NULL; 126 static char *linenoiseNoTTY(void); 127 static void refreshLineWithCompletion(struct linenoiseState *ls, linenoiseCompletions *lc, int flags); 128 static void refreshLineWithFlags(struct linenoiseState *l, int flags); 129 130 static struct termios orig_termios; /* In order to restore at exit.*/ 131 static int maskmode = 0; /* Show "***" instead of input. For passwords. */ 132 static int rawmode = 0; /* For atexit() function to check if restore is needed*/ 133 static int mlmode = 0; /* Multi line mode. Default is single line. */ 134 static int atexit_registered = 0; /* Register atexit just 1 time. */ 135 static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN; 136 static int history_len = 0; 137 static char **history = NULL; 138 139 enum KEY_ACTION{ 140 KEY_NULL = 0, /* NULL */ 141 CTRL_A = 1, /* Ctrl+a */ 142 CTRL_B = 2, /* Ctrl-b */ 143 CTRL_C = 3, /* Ctrl-c */ 144 CTRL_D = 4, /* Ctrl-d */ 145 CTRL_E = 5, /* Ctrl-e */ 146 CTRL_F = 6, /* Ctrl-f */ 147 CTRL_H = 8, /* Ctrl-h */ 148 TAB = 9, /* Tab */ 149 CTRL_K = 11, /* Ctrl+k */ 150 CTRL_L = 12, /* Ctrl+l */ 151 ENTER = 13, /* Enter */ 152 CTRL_N = 14, /* Ctrl-n */ 153 CTRL_P = 16, /* Ctrl-p */ 154 CTRL_T = 20, /* Ctrl-t */ 155 CTRL_U = 21, /* Ctrl+u */ 156 CTRL_W = 23, /* Ctrl+w */ 157 ESC = 27, /* Escape */ 158 BACKSPACE = 127 /* Backspace */ 159 }; 160 161 static void linenoiseAtExit(void); 162 int linenoiseHistoryAdd(const char *line); 163 #define REFRESH_CLEAN (1<<0) // Clean the old prompt from the screen 164 #define REFRESH_WRITE (1<<1) // Rewrite the prompt on the screen. 165 #define REFRESH_ALL (REFRESH_CLEAN|REFRESH_WRITE) // Do both. 166 static void refreshLine(struct linenoiseState *l); 167 168 169 /* ======================= Low level terminal handling ====================== */ 170 171 /* Enable "mask mode". When it is enabled, instead of the input that 172 * the user is typing, the terminal will just display a corresponding 173 * number of asterisks, like "****". This is useful for passwords and other 174 * secrets that should not be displayed. */ 175 void linenoiseMaskModeEnable(void) { 176 maskmode = 1; 177 } 178 179 /* Disable mask mode. */ 180 void linenoiseMaskModeDisable(void) { 181 maskmode = 0; 182 } 183 184 /* Set if to use or not the multi line mode. */ 185 void linenoiseSetMultiLine(int ml) { 186 mlmode = ml; 187 } 188 189 /* Return true if the terminal name is in the list of terminals we know are 190 * not able to understand basic escape sequences. */ 191 static int isUnsupportedTerm(void) { 192 char *term = getenv("TERM"); 193 int j; 194 195 if (term == NULL) return 0; 196 for (j = 0; unsupported_term[j]; j++) 197 if (!strcasecmp(term,unsupported_term[j])) return 1; 198 return 0; 199 } 200 201 /* Raw mode: 1960 magic shit. */ 202 static int enableRawMode(int fd) { 203 struct termios raw; 204 205 if (!isatty(STDIN_FILENO)) goto fatal; 206 if (!atexit_registered) { 207 atexit(linenoiseAtExit); 208 atexit_registered = 1; 209 } 210 if (tcgetattr(fd,&orig_termios) == -1) goto fatal; 211 212 raw = orig_termios; /* modify the original mode */ 213 /* input modes: no break, no CR to NL, no parity check, no strip char, 214 * no start/stop output control. */ 215 raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); 216 /* output modes - disable post processing */ 217 raw.c_oflag &= ~(OPOST); 218 /* control modes - set 8 bit chars */ 219 raw.c_cflag |= (CS8); 220 /* local modes - choing off, canonical off, no extended functions, 221 * no signal chars (^Z,^C) */ 222 raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); 223 /* control chars - set return condition: min number of bytes and timer. 224 * We want read to return every single byte, without timeout. */ 225 raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */ 226 227 /* put terminal in raw mode after flushing */ 228 if (tcsetattr(fd,TCSAFLUSH,&raw) < 0) goto fatal; 229 rawmode = 1; 230 return 0; 231 232 fatal: 233 errno = ENOTTY; 234 return -1; 235 } 236 237 static void disableRawMode(int fd) { 238 /* Don't even check the return value as it's too late. */ 239 if (rawmode && tcsetattr(fd,TCSAFLUSH,&orig_termios) != -1) 240 rawmode = 0; 241 } 242 243 /* Use the ESC [6n escape sequence to query the horizontal cursor position 244 * and return it. On error -1 is returned, on success the position of the 245 * cursor. */ 246 static int getCursorPosition(int ifd, int ofd) { 247 char buf[32]; 248 int cols, rows; 249 unsigned int i = 0; 250 251 /* Report cursor location */ 252 if (write(ofd, "\x1b[6n", 4) != 4) return -1; 253 254 /* Read the response: ESC [ rows ; cols R */ 255 while (i < sizeof(buf)-1) { 256 if (read(ifd,buf+i,1) != 1) break; 257 if (buf[i] == 'R') break; 258 i++; 259 } 260 buf[i] = '\0'; 261 262 /* Parse it. */ 263 if (buf[0] != ESC || buf[1] != '[') return -1; 264 if (sscanf(buf+2,"%d;%d",&rows,&cols) != 2) return -1; 265 return cols; 266 } 267 268 /* Try to get the number of columns in the current terminal, or assume 80 269 * if it fails. */ 270 static int getColumns(int ifd, int ofd) { 271 struct winsize ws; 272 273 if (ioctl(1, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) { 274 /* ioctl() failed. Try to query the terminal itself. */ 275 int start, cols; 276 277 /* Get the initial position so we can restore it later. */ 278 start = getCursorPosition(ifd,ofd); 279 if (start == -1) goto failed; 280 281 /* Go to right margin and get position. */ 282 if (write(ofd,"\x1b[999C",6) != 6) goto failed; 283 cols = getCursorPosition(ifd,ofd); 284 if (cols == -1) goto failed; 285 286 /* Restore position. */ 287 if (cols > start) { 288 char seq[32]; 289 snprintf(seq,32,"\x1b[%dD",cols-start); 290 if (write(ofd,seq,strlen(seq)) == -1) { 291 /* Can't recover... */ 292 } 293 } 294 return cols; 295 } else { 296 return ws.ws_col; 297 } 298 299 failed: 300 return 80; 301 } 302 303 /* Clear the screen. Used to handle ctrl+l */ 304 void linenoiseClearScreen(void) { 305 if (write(STDOUT_FILENO,"\x1b[H\x1b[2J",7) <= 0) { 306 /* nothing to do, just to avoid warning. */ 307 } 308 } 309 310 /* Beep, used for completion when there is nothing to complete or when all 311 * the choices were already shown. */ 312 static void linenoiseBeep(void) { 313 fprintf(stderr, "\x7"); 314 fflush(stderr); 315 } 316 317 /* ============================== Completion ================================ */ 318 319 /* Free a list of completion option populated by linenoiseAddCompletion(). */ 320 static void freeCompletions(linenoiseCompletions *lc) { 321 size_t i; 322 for (i = 0; i < lc->len; i++) 323 free(lc->cvec[i]); 324 if (lc->cvec != NULL) 325 free(lc->cvec); 326 } 327 328 /* Called by completeLine() and linenoiseShow() to render the current 329 * edited line with the proposed completion. If the current completion table 330 * is already available, it is passed as second argument, otherwise the 331 * function will use the callback to obtain it. 332 * 333 * Flags are the same as refreshLine*(), that is REFRESH_* macros. */ 334 static void refreshLineWithCompletion(struct linenoiseState *ls, linenoiseCompletions *lc, int flags) { 335 /* Obtain the table of completions if the caller didn't provide one. */ 336 linenoiseCompletions ctable = { 0, NULL }; 337 if (lc == NULL) { 338 completionCallback(ls->buf,&ctable); 339 lc = &ctable; 340 } 341 342 /* Show the edited line with completion if possible, or just refresh. */ 343 if (ls->completion_idx < lc->len) { 344 struct linenoiseState saved = *ls; 345 ls->len = ls->pos = strlen(lc->cvec[ls->completion_idx]); 346 ls->buf = lc->cvec[ls->completion_idx]; 347 refreshLineWithFlags(ls,flags); 348 ls->len = saved.len; 349 ls->pos = saved.pos; 350 ls->buf = saved.buf; 351 } else { 352 refreshLineWithFlags(ls,flags); 353 } 354 355 /* Free the completions table if needed. */ 356 if (lc != &ctable) freeCompletions(&ctable); 357 } 358 359 /* This is an helper function for linenoiseEdit*() and is called when the 360 * user types the <tab> key in order to complete the string currently in the 361 * input. 362 * 363 * The state of the editing is encapsulated into the pointed linenoiseState 364 * structure as described in the structure definition. 365 * 366 * If the function returns non-zero, the caller should handle the 367 * returned value as a byte read from the standard input, and process 368 * it as usually: this basically means that the function may return a byte 369 * read from the termianl but not processed. Otherwise, if zero is returned, 370 * the input was consumed by the completeLine() function to navigate the 371 * possible completions, and the caller should read for the next characters 372 * from stdin. */ 373 static int completeLine(struct linenoiseState *ls, int keypressed) { 374 linenoiseCompletions lc = { 0, NULL }; 375 int nwritten; 376 char c = keypressed; 377 378 completionCallback(ls->buf,&lc); 379 if (lc.len == 0) { 380 linenoiseBeep(); 381 ls->in_completion = 0; 382 } else { 383 switch(c) { 384 case 9: /* tab */ 385 if (ls->in_completion == 0) { 386 ls->in_completion = 1; 387 ls->completion_idx = 0; 388 } else { 389 ls->completion_idx = (ls->completion_idx+1) % (lc.len+1); 390 if (ls->completion_idx == lc.len) linenoiseBeep(); 391 } 392 c = 0; 393 break; 394 case 27: /* escape */ 395 /* Re-show original buffer */ 396 if (ls->completion_idx < lc.len) refreshLine(ls); 397 ls->in_completion = 0; 398 c = 0; 399 break; 400 default: 401 /* Update buffer and return */ 402 if (ls->completion_idx < lc.len) { 403 nwritten = snprintf(ls->buf,ls->buflen,"%s", 404 lc.cvec[ls->completion_idx]); 405 ls->len = ls->pos = nwritten; 406 } 407 ls->in_completion = 0; 408 break; 409 } 410 411 /* Show completion or original buffer */ 412 if (ls->in_completion && ls->completion_idx < lc.len) { 413 refreshLineWithCompletion(ls,&lc,REFRESH_ALL); 414 } else { 415 refreshLine(ls); 416 } 417 } 418 419 freeCompletions(&lc); 420 return c; /* Return last read character */ 421 } 422 423 /* Register a callback function to be called for tab-completion. */ 424 void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) { 425 completionCallback = fn; 426 } 427 428 /* Register a hits function to be called to show hits to the user at the 429 * right of the prompt. */ 430 void linenoiseSetHintsCallback(linenoiseHintsCallback *fn) { 431 hintsCallback = fn; 432 } 433 434 /* Register a function to free the hints returned by the hints callback 435 * registered with linenoiseSetHintsCallback(). */ 436 void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *fn) { 437 freeHintsCallback = fn; 438 } 439 440 /* This function is used by the callback function registered by the user 441 * in order to add completion options given the input string when the 442 * user typed <tab>. See the example.c source code for a very easy to 443 * understand example. */ 444 void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) { 445 size_t len = strlen(str); 446 char *copy, **cvec; 447 448 copy = malloc(len+1); 449 if (copy == NULL) return; 450 memcpy(copy,str,len+1); 451 cvec = realloc(lc->cvec,sizeof(char*)*(lc->len+1)); 452 if (cvec == NULL) { 453 free(copy); 454 return; 455 } 456 lc->cvec = cvec; 457 lc->cvec[lc->len++] = copy; 458 } 459 460 /* =========================== Line editing ================================= */ 461 462 /* We define a very simple "append buffer" structure, that is an heap 463 * allocated string where we can append to. This is useful in order to 464 * write all the escape sequences in a buffer and flush them to the standard 465 * output in a single call, to avoid flickering effects. */ 466 struct abuf { 467 char *b; 468 int len; 469 }; 470 471 static void abInit(struct abuf *ab) { 472 ab->b = NULL; 473 ab->len = 0; 474 } 475 476 static void abAppend(struct abuf *ab, const char *s, int len) { 477 char *new = realloc(ab->b,ab->len+len); 478 479 if (new == NULL) return; 480 memcpy(new+ab->len,s,len); 481 ab->b = new; 482 ab->len += len; 483 } 484 485 static void abFree(struct abuf *ab) { 486 free(ab->b); 487 } 488 489 /* Helper of refreshSingleLine() and refreshMultiLine() to show hints 490 * to the right of the prompt. */ 491 void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) { 492 char seq[64]; 493 if (hintsCallback && plen+l->len < l->cols) { 494 int color = -1, bold = 0; 495 char *hint = hintsCallback(l->buf,&color,&bold); 496 if (hint) { 497 int hintlen = strlen(hint); 498 int hintmaxlen = l->cols-(plen+l->len); 499 if (hintlen > hintmaxlen) hintlen = hintmaxlen; 500 if (bold == 1 && color == -1) color = 37; 501 if (color != -1 || bold != 0) 502 snprintf(seq,64,"\033[%d;%d;49m",bold,color); 503 else 504 seq[0] = '\0'; 505 abAppend(ab,seq,strlen(seq)); 506 abAppend(ab,hint,hintlen); 507 if (color != -1 || bold != 0) 508 abAppend(ab,"\033[0m",4); 509 /* Call the function to free the hint returned. */ 510 if (freeHintsCallback) freeHintsCallback(hint); 511 } 512 } 513 } 514 515 /* Single line low level line refresh. 516 * 517 * Rewrite the currently edited line accordingly to the buffer content, 518 * cursor position, and number of columns of the terminal. 519 * 520 * Flags is REFRESH_* macros. The function can just remove the old 521 * prompt, just write it, or both. */ 522 static void refreshSingleLine(struct linenoiseState *l, int flags) { 523 char seq[64]; 524 size_t plen = strlen(l->prompt); 525 int fd = l->ofd; 526 char *buf = l->buf; 527 size_t len = l->len; 528 size_t pos = l->pos; 529 struct abuf ab; 530 531 while((plen+pos) >= l->cols) { 532 buf++; 533 len--; 534 pos--; 535 } 536 while (plen+len > l->cols) { 537 len--; 538 } 539 540 abInit(&ab); 541 /* Cursor to left edge */ 542 snprintf(seq,sizeof(seq),"\r"); 543 abAppend(&ab,seq,strlen(seq)); 544 545 if (flags & REFRESH_WRITE) { 546 /* Write the prompt and the current buffer content */ 547 abAppend(&ab,l->prompt,strlen(l->prompt)); 548 if (maskmode == 1) { 549 while (len--) abAppend(&ab,"*",1); 550 } else { 551 abAppend(&ab,buf,len); 552 } 553 /* Show hits if any. */ 554 refreshShowHints(&ab,l,plen); 555 } 556 557 /* Erase to right */ 558 snprintf(seq,sizeof(seq),"\x1b[0K"); 559 abAppend(&ab,seq,strlen(seq)); 560 561 if (flags & REFRESH_WRITE) { 562 /* Move cursor to original position. */ 563 snprintf(seq,sizeof(seq),"\r\x1b[%dC", (int)(pos+plen)); 564 abAppend(&ab,seq,strlen(seq)); 565 } 566 567 if (write(fd,ab.b,ab.len) == -1) {} /* Can't recover from write error. */ 568 abFree(&ab); 569 } 570 571 /* Multi line low level line refresh. 572 * 573 * Rewrite the currently edited line accordingly to the buffer content, 574 * cursor position, and number of columns of the terminal. 575 * 576 * Flags is REFRESH_* macros. The function can just remove the old 577 * prompt, just write it, or both. */ 578 static void refreshMultiLine(struct linenoiseState *l, int flags) { 579 char seq[64]; 580 int plen = strlen(l->prompt); 581 int rows = (plen+l->len+l->cols-1)/l->cols; /* rows used by current buf. */ 582 int rpos = (plen+l->oldpos+l->cols)/l->cols; /* cursor relative row. */ 583 int rpos2; /* rpos after refresh. */ 584 int col; /* colum position, zero-based. */ 585 int old_rows = l->oldrows; 586 int fd = l->ofd, j; 587 struct abuf ab; 588 589 l->oldrows = rows; 590 591 /* First step: clear all the lines used before. To do so start by 592 * going to the last row. */ 593 abInit(&ab); 594 595 if (flags & REFRESH_CLEAN) { 596 if (old_rows-rpos > 0) { 597 snprintf(seq,64,"\x1b[%dB", old_rows-rpos); 598 abAppend(&ab,seq,strlen(seq)); 599 } 600 601 /* Now for every row clear it, go up. */ 602 for (j = 0; j < old_rows-1; j++) { 603 snprintf(seq,64,"\r\x1b[0K\x1b[1A"); 604 abAppend(&ab,seq,strlen(seq)); 605 } 606 } 607 608 if (flags & REFRESH_ALL) { 609 /* Clean the top line. */ 610 snprintf(seq,64,"\r\x1b[0K"); 611 abAppend(&ab,seq,strlen(seq)); 612 } 613 614 if (flags & REFRESH_WRITE) { 615 /* Write the prompt and the current buffer content */ 616 abAppend(&ab,l->prompt,strlen(l->prompt)); 617 if (maskmode == 1) { 618 unsigned int i; 619 for (i = 0; i < l->len; i++) abAppend(&ab,"*",1); 620 } else { 621 abAppend(&ab,l->buf,l->len); 622 } 623 624 /* Show hits if any. */ 625 refreshShowHints(&ab,l,plen); 626 627 /* If we are at the very end of the screen with our prompt, we need to 628 * emit a newline and move the prompt to the first column. */ 629 if (l->pos && 630 l->pos == l->len && 631 (l->pos+plen) % l->cols == 0) 632 { 633 abAppend(&ab,"\n",1); 634 snprintf(seq,64,"\r"); 635 abAppend(&ab,seq,strlen(seq)); 636 rows++; 637 if (rows > (int)l->oldrows) l->oldrows = rows; 638 } 639 640 /* Move cursor to right position. */ 641 rpos2 = (plen+l->pos+l->cols)/l->cols; /* Current cursor relative row */ 642 643 /* Go up till we reach the expected positon. */ 644 if (rows-rpos2 > 0) { 645 snprintf(seq,64,"\x1b[%dA", rows-rpos2); 646 abAppend(&ab,seq,strlen(seq)); 647 } 648 649 /* Set column. */ 650 col = (plen+(int)l->pos) % (int)l->cols; 651 if (col) 652 snprintf(seq,64,"\r\x1b[%dC", col); 653 else 654 snprintf(seq,64,"\r"); 655 abAppend(&ab,seq,strlen(seq)); 656 } 657 658 l->oldpos = l->pos; 659 660 if (write(fd,ab.b,ab.len) == -1) {} /* Can't recover from write error. */ 661 abFree(&ab); 662 } 663 664 /* Calls the two low level functions refreshSingleLine() or 665 * refreshMultiLine() according to the selected mode. */ 666 static void refreshLineWithFlags(struct linenoiseState *l, int flags) { 667 if (mlmode) 668 refreshMultiLine(l,flags); 669 else 670 refreshSingleLine(l,flags); 671 } 672 673 /* Utility function to avoid specifying REFRESH_ALL all the times. */ 674 static void refreshLine(struct linenoiseState *l) { 675 refreshLineWithFlags(l,REFRESH_ALL); 676 } 677 678 /* Hide the current line, when using the multiplexing API. */ 679 void linenoiseHide(struct linenoiseState *l) { 680 if (mlmode) 681 refreshMultiLine(l,REFRESH_CLEAN); 682 else 683 refreshSingleLine(l,REFRESH_CLEAN); 684 } 685 686 /* Show the current line, when using the multiplexing API. */ 687 void linenoiseShow(struct linenoiseState *l) { 688 if (l->in_completion) { 689 refreshLineWithCompletion(l,NULL,REFRESH_WRITE); 690 } else { 691 refreshLineWithFlags(l,REFRESH_WRITE); 692 } 693 } 694 695 /* Insert the character 'c' at cursor current position. 696 * 697 * On error writing to the terminal -1 is returned, otherwise 0. */ 698 int linenoiseEditInsert(struct linenoiseState *l, char c) { 699 if (l->len < l->buflen) { 700 if (l->len == l->pos) { 701 l->buf[l->pos] = c; 702 l->pos++; 703 l->len++; 704 l->buf[l->len] = '\0'; 705 if ((!mlmode && l->plen+l->len < l->cols && !hintsCallback)) { 706 /* Avoid a full update of the line in the 707 * trivial case. */ 708 char d = (maskmode==1) ? '*' : c; 709 if (write(l->ofd,&d,1) == -1) return -1; 710 } else { 711 refreshLine(l); 712 } 713 } else { 714 memmove(l->buf+l->pos+1,l->buf+l->pos,l->len-l->pos); 715 l->buf[l->pos] = c; 716 l->len++; 717 l->pos++; 718 l->buf[l->len] = '\0'; 719 refreshLine(l); 720 } 721 } 722 return 0; 723 } 724 725 /* Move cursor on the left. */ 726 void linenoiseEditMoveLeft(struct linenoiseState *l) { 727 if (l->pos > 0) { 728 l->pos--; 729 refreshLine(l); 730 } 731 } 732 733 /* Move cursor on the right. */ 734 void linenoiseEditMoveRight(struct linenoiseState *l) { 735 if (l->pos != l->len) { 736 l->pos++; 737 refreshLine(l); 738 } 739 } 740 741 /* Move cursor to the start of the line. */ 742 void linenoiseEditMoveHome(struct linenoiseState *l) { 743 if (l->pos != 0) { 744 l->pos = 0; 745 refreshLine(l); 746 } 747 } 748 749 /* Move cursor to the end of the line. */ 750 void linenoiseEditMoveEnd(struct linenoiseState *l) { 751 if (l->pos != l->len) { 752 l->pos = l->len; 753 refreshLine(l); 754 } 755 } 756 757 /* Substitute the currently edited line with the next or previous history 758 * entry as specified by 'dir'. */ 759 #define LINENOISE_HISTORY_NEXT 0 760 #define LINENOISE_HISTORY_PREV 1 761 void linenoiseEditHistoryNext(struct linenoiseState *l, int dir) { 762 if (history_len > 1) { 763 /* Update the current history entry before to 764 * overwrite it with the next one. */ 765 free(history[history_len - 1 - l->history_index]); 766 history[history_len - 1 - l->history_index] = strdup(l->buf); 767 /* Show the new entry */ 768 l->history_index += (dir == LINENOISE_HISTORY_PREV) ? 1 : -1; 769 if (l->history_index < 0) { 770 l->history_index = 0; 771 return; 772 } else if (l->history_index >= history_len) { 773 l->history_index = history_len-1; 774 return; 775 } 776 strncpy(l->buf,history[history_len - 1 - l->history_index],l->buflen); 777 l->buf[l->buflen-1] = '\0'; 778 l->len = l->pos = strlen(l->buf); 779 refreshLine(l); 780 } 781 } 782 783 /* Delete the character at the right of the cursor without altering the cursor 784 * position. Basically this is what happens with the "Delete" keyboard key. */ 785 void linenoiseEditDelete(struct linenoiseState *l) { 786 if (l->len > 0 && l->pos < l->len) { 787 memmove(l->buf+l->pos,l->buf+l->pos+1,l->len-l->pos-1); 788 l->len--; 789 l->buf[l->len] = '\0'; 790 refreshLine(l); 791 } 792 } 793 794 /* Backspace implementation. */ 795 void linenoiseEditBackspace(struct linenoiseState *l) { 796 if (l->pos > 0 && l->len > 0) { 797 memmove(l->buf+l->pos-1,l->buf+l->pos,l->len-l->pos); 798 l->pos--; 799 l->len--; 800 l->buf[l->len] = '\0'; 801 refreshLine(l); 802 } 803 } 804 805 /* Delete the previosu word, maintaining the cursor at the start of the 806 * current word. */ 807 void linenoiseEditDeletePrevWord(struct linenoiseState *l) { 808 size_t old_pos = l->pos; 809 size_t diff; 810 811 while (l->pos > 0 && l->buf[l->pos-1] == ' ') 812 l->pos--; 813 while (l->pos > 0 && l->buf[l->pos-1] != ' ') 814 l->pos--; 815 diff = old_pos - l->pos; 816 memmove(l->buf+l->pos,l->buf+old_pos,l->len-old_pos+1); 817 l->len -= diff; 818 refreshLine(l); 819 } 820 821 /* This function is part of the multiplexed API of Linenoise, that is used 822 * in order to implement the blocking variant of the API but can also be 823 * called by the user directly in an event driven program. It will: 824 * 825 * 1. Initialize the linenoise state passed by the user. 826 * 2. Put the terminal in RAW mode. 827 * 3. Show the prompt. 828 * 4. Return control to the user, that will have to call linenoiseEditFeed() 829 * each time there is some data arriving in the standard input. 830 * 831 * The user can also call linenoiseEditHide() and linenoiseEditShow() if it 832 * is required to show some input arriving asyncronously, without mixing 833 * it with the currently edited line. 834 * 835 * When linenoiseEditFeed() returns non-NULL, the user finished with the 836 * line editing session (pressed enter CTRL-D/C): in this case the caller 837 * needs to call linenoiseEditStop() to put back the terminal in normal 838 * mode. This will not destroy the buffer, as long as the linenoiseState 839 * is still valid in the context of the caller. 840 * 841 * The function returns 0 on success, or -1 if writing to standard output 842 * fails. If stdin_fd or stdout_fd are set to -1, the default is to use 843 * STDIN_FILENO and STDOUT_FILENO. 844 */ 845 int linenoiseEditStart(struct linenoiseState *l, int stdin_fd, int stdout_fd, char *buf, size_t buflen, const char *prompt) { 846 /* Populate the linenoise state that we pass to functions implementing 847 * specific editing functionalities. */ 848 l->in_completion = 0; 849 l->ifd = stdin_fd != -1 ? stdin_fd : STDIN_FILENO; 850 l->ofd = stdout_fd != -1 ? stdout_fd : STDOUT_FILENO; 851 l->buf = buf; 852 l->buflen = buflen; 853 l->prompt = prompt; 854 l->plen = strlen(prompt); 855 l->oldpos = l->pos = 0; 856 l->len = 0; 857 858 /* Enter raw mode. */ 859 if (enableRawMode(l->ifd) == -1) return -1; 860 861 l->cols = getColumns(stdin_fd, stdout_fd); 862 l->oldrows = 0; 863 l->history_index = 0; 864 865 /* Buffer starts empty. */ 866 l->buf[0] = '\0'; 867 l->buflen--; /* Make sure there is always space for the nulterm */ 868 869 /* If stdin is not a tty, stop here with the initialization. We 870 * will actually just read a line from standard input in blocking 871 * mode later, in linenoiseEditFeed(). */ 872 if (!isatty(l->ifd)) return 0; 873 874 /* The latest history entry is always our current buffer, that 875 * initially is just an empty string. */ 876 linenoiseHistoryAdd(""); 877 878 if (write(l->ofd,prompt,l->plen) == -1) return -1; 879 return 0; 880 } 881 882 char *linenoiseEditMore = "If you see this, you are misusing the API: when linenoiseEditFeed() is called, if it returns linenoiseEditMore the user is yet editing the line. See the README file for more information."; 883 884 /* This function is part of the multiplexed API of linenoise, see the top 885 * comment on linenoiseEditStart() for more information. Call this function 886 * each time there is some data to read from the standard input file 887 * descriptor. In the case of blocking operations, this function can just be 888 * called in a loop, and block. 889 * 890 * The function returns linenoiseEditMore to signal that line editing is still 891 * in progress, that is, the user didn't yet pressed enter / CTRL-D. Otherwise 892 * the function returns the pointer to the heap-allocated buffer with the 893 * edited line, that the user should free with linenoiseFree(). 894 * 895 * On special conditions, NULL is returned and errno is populated: 896 * 897 * EAGAIN if the user pressed Ctrl-C 898 * ENOENT if the user pressed Ctrl-D 899 * 900 * Some other errno: I/O error. 901 */ 902 char *linenoiseEditFeed(struct linenoiseState *l) { 903 /* Not a TTY, pass control to line reading without character 904 * count limits. */ 905 if (!isatty(l->ifd)) return linenoiseNoTTY(); 906 907 char c; 908 int nread; 909 char seq[3]; 910 911 nread = read(l->ifd,&c,1); 912 if (nread <= 0) return NULL; 913 914 /* Only autocomplete when the callback is set. It returns < 0 when 915 * there was an error reading from fd. Otherwise it will return the 916 * character that should be handled next. */ 917 if ((l->in_completion || c == 9) && completionCallback != NULL) { 918 c = completeLine(l,c); 919 /* Return on errors */ 920 if (c < 0) return NULL; 921 /* Read next character when 0 */ 922 if (c == 0) return linenoiseEditMore; 923 } 924 925 switch(c) { 926 case ENTER: /* enter */ 927 history_len--; 928 free(history[history_len]); 929 if (mlmode) linenoiseEditMoveEnd(l); 930 if (hintsCallback) { 931 /* Force a refresh without hints to leave the previous 932 * line as the user typed it after a newline. */ 933 linenoiseHintsCallback *hc = hintsCallback; 934 hintsCallback = NULL; 935 refreshLine(l); 936 hintsCallback = hc; 937 } 938 return strdup(l->buf); 939 case CTRL_C: /* ctrl-c */ 940 errno = EAGAIN; 941 return NULL; 942 case BACKSPACE: /* backspace */ 943 case 8: /* ctrl-h */ 944 linenoiseEditBackspace(l); 945 break; 946 case CTRL_D: /* ctrl-d, remove char at right of cursor, or if the 947 line is empty, act as end-of-file. */ 948 if (l->len > 0) { 949 linenoiseEditDelete(l); 950 } else { 951 history_len--; 952 free(history[history_len]); 953 errno = ENOENT; 954 return NULL; 955 } 956 break; 957 case CTRL_T: /* ctrl-t, swaps current character with previous. */ 958 if (l->pos > 0 && l->pos < l->len) { 959 int aux = l->buf[l->pos-1]; 960 l->buf[l->pos-1] = l->buf[l->pos]; 961 l->buf[l->pos] = aux; 962 if (l->pos != l->len-1) l->pos++; 963 refreshLine(l); 964 } 965 break; 966 case CTRL_B: /* ctrl-b */ 967 linenoiseEditMoveLeft(l); 968 break; 969 case CTRL_F: /* ctrl-f */ 970 linenoiseEditMoveRight(l); 971 break; 972 case CTRL_P: /* ctrl-p */ 973 linenoiseEditHistoryNext(l, LINENOISE_HISTORY_PREV); 974 break; 975 case CTRL_N: /* ctrl-n */ 976 linenoiseEditHistoryNext(l, LINENOISE_HISTORY_NEXT); 977 break; 978 case ESC: /* escape sequence */ 979 /* Read the next two bytes representing the escape sequence. 980 * Use two calls to handle slow terminals returning the two 981 * chars at different times. */ 982 if (read(l->ifd,seq,1) == -1) break; 983 if (read(l->ifd,seq+1,1) == -1) break; 984 985 /* ESC [ sequences. */ 986 if (seq[0] == '[') { 987 if (seq[1] >= '0' && seq[1] <= '9') { 988 /* Extended escape, read additional byte. */ 989 if (read(l->ifd,seq+2,1) == -1) break; 990 if (seq[2] == '~') { 991 switch(seq[1]) { 992 case '3': /* Delete key. */ 993 linenoiseEditDelete(l); 994 break; 995 } 996 } 997 } else { 998 switch(seq[1]) { 999 case 'A': /* Up */ 1000 linenoiseEditHistoryNext(l, LINENOISE_HISTORY_PREV); 1001 break; 1002 case 'B': /* Down */ 1003 linenoiseEditHistoryNext(l, LINENOISE_HISTORY_NEXT); 1004 break; 1005 case 'C': /* Right */ 1006 linenoiseEditMoveRight(l); 1007 break; 1008 case 'D': /* Left */ 1009 linenoiseEditMoveLeft(l); 1010 break; 1011 case 'H': /* Home */ 1012 linenoiseEditMoveHome(l); 1013 break; 1014 case 'F': /* End*/ 1015 linenoiseEditMoveEnd(l); 1016 break; 1017 } 1018 } 1019 } 1020 1021 /* ESC O sequences. */ 1022 else if (seq[0] == 'O') { 1023 switch(seq[1]) { 1024 case 'H': /* Home */ 1025 linenoiseEditMoveHome(l); 1026 break; 1027 case 'F': /* End*/ 1028 linenoiseEditMoveEnd(l); 1029 break; 1030 } 1031 } 1032 break; 1033 default: 1034 if (linenoiseEditInsert(l,c)) return NULL; 1035 break; 1036 case CTRL_U: /* Ctrl+u, delete the whole line. */ 1037 l->buf[0] = '\0'; 1038 l->pos = l->len = 0; 1039 refreshLine(l); 1040 break; 1041 case CTRL_K: /* Ctrl+k, delete from current to end of line. */ 1042 l->buf[l->pos] = '\0'; 1043 l->len = l->pos; 1044 refreshLine(l); 1045 break; 1046 case CTRL_A: /* Ctrl+a, go to the start of the line */ 1047 linenoiseEditMoveHome(l); 1048 break; 1049 case CTRL_E: /* ctrl+e, go to the end of the line */ 1050 linenoiseEditMoveEnd(l); 1051 break; 1052 case CTRL_L: /* ctrl+l, clear screen */ 1053 linenoiseClearScreen(); 1054 refreshLine(l); 1055 break; 1056 case CTRL_W: /* ctrl+w, delete previous word */ 1057 linenoiseEditDeletePrevWord(l); 1058 break; 1059 } 1060 return linenoiseEditMore; 1061 } 1062 1063 /* This is part of the multiplexed linenoise API. See linenoiseEditStart() 1064 * for more information. This function is called when linenoiseEditFeed() 1065 * returns something different than NULL. At this point the user input 1066 * is in the buffer, and we can restore the terminal in normal mode. */ 1067 void linenoiseEditStop(struct linenoiseState *l) { 1068 if (!isatty(l->ifd)) return; 1069 disableRawMode(l->ifd); 1070 printf("\n"); 1071 } 1072 1073 /* This just implements a blocking loop for the multiplexed API. 1074 * In many applications that are not event-drivern, we can just call 1075 * the blocking linenoise API, wait for the user to complete the editing 1076 * and return the buffer. */ 1077 static char *linenoiseBlockingEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen, const char *prompt) 1078 { 1079 struct linenoiseState l; 1080 1081 /* Editing without a buffer is invalid. */ 1082 if (buflen == 0) { 1083 errno = EINVAL; 1084 return NULL; 1085 } 1086 1087 linenoiseEditStart(&l,stdin_fd,stdout_fd,buf,buflen,prompt); 1088 char *res; 1089 while((res = linenoiseEditFeed(&l)) == linenoiseEditMore); 1090 linenoiseEditStop(&l); 1091 return res; 1092 } 1093 1094 /* This special mode is used by linenoise in order to print scan codes 1095 * on screen for debugging / development purposes. It is implemented 1096 * by the linenoise_example program using the --keycodes option. */ 1097 void linenoisePrintKeyCodes(void) { 1098 char quit[4]; 1099 1100 printf("Linenoise key codes debugging mode.\n" 1101 "Press keys to see scan codes. Type 'quit' at any time to exit.\n"); 1102 if (enableRawMode(STDIN_FILENO) == -1) return; 1103 memset(quit,' ',4); 1104 while(1) { 1105 char c; 1106 int nread; 1107 1108 nread = read(STDIN_FILENO,&c,1); 1109 if (nread <= 0) continue; 1110 memmove(quit,quit+1,sizeof(quit)-1); /* shift string to left. */ 1111 quit[sizeof(quit)-1] = c; /* Insert current char on the right. */ 1112 if (memcmp(quit,"quit",sizeof(quit)) == 0) break; 1113 1114 printf("'%c' %02x (%d) (type quit to exit)\n", 1115 isprint(c) ? c : '?', (int)c, (int)c); 1116 printf("\r"); /* Go left edge manually, we are in raw mode. */ 1117 fflush(stdout); 1118 } 1119 disableRawMode(STDIN_FILENO); 1120 } 1121 1122 /* This function is called when linenoise() is called with the standard 1123 * input file descriptor not attached to a TTY. So for example when the 1124 * program using linenoise is called in pipe or with a file redirected 1125 * to its standard input. In this case, we want to be able to return the 1126 * line regardless of its length (by default we are limited to 4k). */ 1127 static char *linenoiseNoTTY(void) { 1128 char *line = NULL; 1129 size_t len = 0, maxlen = 0; 1130 1131 while(1) { 1132 if (len == maxlen) { 1133 if (maxlen == 0) maxlen = 16; 1134 maxlen *= 2; 1135 char *oldval = line; 1136 line = realloc(line,maxlen); 1137 if (line == NULL) { 1138 if (oldval) free(oldval); 1139 return NULL; 1140 } 1141 } 1142 int c = fgetc(stdin); 1143 if (c == EOF || c == '\n') { 1144 if (c == EOF && len == 0) { 1145 free(line); 1146 return NULL; 1147 } else { 1148 line[len] = '\0'; 1149 return line; 1150 } 1151 } else { 1152 line[len] = c; 1153 len++; 1154 } 1155 } 1156 } 1157 1158 /* The high level function that is the main API of the linenoise library. 1159 * This function checks if the terminal has basic capabilities, just checking 1160 * for a blacklist of stupid terminals, and later either calls the line 1161 * editing function or uses dummy fgets() so that you will be able to type 1162 * something even in the most desperate of the conditions. */ 1163 char *linenoise(const char *prompt) { 1164 char buf[LINENOISE_MAX_LINE]; 1165 1166 if (!isatty(STDIN_FILENO)) { 1167 /* Not a tty: read from file / pipe. In this mode we don't want any 1168 * limit to the line size, so we call a function to handle that. */ 1169 return linenoiseNoTTY(); 1170 } else if (isUnsupportedTerm()) { 1171 size_t len; 1172 1173 printf("%s",prompt); 1174 fflush(stdout); 1175 if (fgets(buf,LINENOISE_MAX_LINE,stdin) == NULL) return NULL; 1176 len = strlen(buf); 1177 while(len && (buf[len-1] == '\n' || buf[len-1] == '\r')) { 1178 len--; 1179 buf[len] = '\0'; 1180 } 1181 return strdup(buf); 1182 } else { 1183 char *retval = linenoiseBlockingEdit(STDIN_FILENO,STDOUT_FILENO,buf,LINENOISE_MAX_LINE,prompt); 1184 return retval; 1185 } 1186 } 1187 1188 /* This is just a wrapper the user may want to call in order to make sure 1189 * the linenoise returned buffer is freed with the same allocator it was 1190 * created with. Useful when the main program is using an alternative 1191 * allocator. */ 1192 void linenoiseFree(void *ptr) { 1193 if (ptr == linenoiseEditMore) return; // Protect from API misuse. 1194 free(ptr); 1195 } 1196 1197 /* ================================ History ================================= */ 1198 1199 /* Free the history, but does not reset it. Only used when we have to 1200 * exit() to avoid memory leaks are reported by valgrind & co. */ 1201 static void freeHistory(void) { 1202 if (history) { 1203 int j; 1204 1205 for (j = 0; j < history_len; j++) 1206 free(history[j]); 1207 free(history); 1208 } 1209 } 1210 1211 /* At exit we'll try to fix the terminal to the initial conditions. */ 1212 static void linenoiseAtExit(void) { 1213 disableRawMode(STDIN_FILENO); 1214 freeHistory(); 1215 } 1216 1217 /* This is the API call to add a new entry in the linenoise history. 1218 * It uses a fixed array of char pointers that are shifted (memmoved) 1219 * when the history max length is reached in order to remove the older 1220 * entry and make room for the new one, so it is not exactly suitable for huge 1221 * histories, but will work well for a few hundred of entries. 1222 * 1223 * Using a circular buffer is smarter, but a bit more complex to handle. */ 1224 int linenoiseHistoryAdd(const char *line) { 1225 char *linecopy; 1226 1227 if (history_max_len == 0) return 0; 1228 1229 /* Initialization on first call. */ 1230 if (history == NULL) { 1231 history = malloc(sizeof(char*)*history_max_len); 1232 if (history == NULL) return 0; 1233 memset(history,0,(sizeof(char*)*history_max_len)); 1234 } 1235 1236 /* Don't add duplicated lines. */ 1237 if (history_len && !strcmp(history[history_len-1], line)) return 0; 1238 1239 /* Add an heap allocated copy of the line in the history. 1240 * If we reached the max length, remove the older line. */ 1241 linecopy = strdup(line); 1242 if (!linecopy) return 0; 1243 if (history_len == history_max_len) { 1244 free(history[0]); 1245 memmove(history,history+1,sizeof(char*)*(history_max_len-1)); 1246 history_len--; 1247 } 1248 history[history_len] = linecopy; 1249 history_len++; 1250 return 1; 1251 } 1252 1253 /* Set the maximum length for the history. This function can be called even 1254 * if there is already some history, the function will make sure to retain 1255 * just the latest 'len' elements if the new history length value is smaller 1256 * than the amount of items already inside the history. */ 1257 int linenoiseHistorySetMaxLen(int len) { 1258 char **new; 1259 1260 if (len < 1) return 0; 1261 if (history) { 1262 int tocopy = history_len; 1263 1264 new = malloc(sizeof(char*)*len); 1265 if (new == NULL) return 0; 1266 1267 /* If we can't copy everything, free the elements we'll not use. */ 1268 if (len < tocopy) { 1269 int j; 1270 1271 for (j = 0; j < tocopy-len; j++) free(history[j]); 1272 tocopy = len; 1273 } 1274 memset(new,0,sizeof(char*)*len); 1275 memcpy(new,history+(history_len-tocopy), sizeof(char*)*tocopy); 1276 free(history); 1277 history = new; 1278 } 1279 history_max_len = len; 1280 if (history_len > history_max_len) 1281 history_len = history_max_len; 1282 return 1; 1283 } 1284 1285 /* Save the history in the specified file. On success 0 is returned 1286 * otherwise -1 is returned. */ 1287 int linenoiseHistorySave(const char *filename) { 1288 mode_t old_umask = umask(S_IXUSR|S_IRWXG|S_IRWXO); 1289 FILE *fp; 1290 int j; 1291 1292 fp = fopen(filename,"w"); 1293 umask(old_umask); 1294 if (fp == NULL) return -1; 1295 fchmod(fileno(fp),S_IRUSR|S_IWUSR); 1296 for (j = 0; j < history_len; j++) 1297 fprintf(fp,"%s\n",history[j]); 1298 fclose(fp); 1299 return 0; 1300 } 1301 1302 /* Load the history from the specified file. If the file does not exist 1303 * zero is returned and no operation is performed. 1304 * 1305 * If the file exists and the operation succeeded 0 is returned, otherwise 1306 * on error -1 is returned. */ 1307 int linenoiseHistoryLoad(const char *filename) { 1308 FILE *fp = fopen(filename,"r"); 1309 char buf[LINENOISE_MAX_LINE]; 1310 1311 if (fp == NULL) return -1; 1312 1313 while (fgets(buf,LINENOISE_MAX_LINE,fp) != NULL) { 1314 char *p; 1315 1316 p = strchr(buf,'\r'); 1317 if (!p) p = strchr(buf,'\n'); 1318 if (p) *p = '\0'; 1319 linenoiseHistoryAdd(buf); 1320 } 1321 fclose(fp); 1322 return 0; 1323 }