]> git.lizzy.rs Git - linenoise.git/blob - linenoise.c
linenoiseHistorySetMaxLen() was broken and never tested. Fixed.
[linenoise.git] / linenoise.c
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/msteveb/linenoise
7  *   (forked from http://github.com/antirez/linenoise)
8  *
9  * Does a number of crazy assumptions that happen to be true in 99.9999% of
10  * the 2010 UNIX computers around.
11  *
12  * ------------------------------------------------------------------------
13  *
14  * Copyright (c) 2010, Salvatore Sanfilippo <antirez at gmail dot com>
15  * Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
16  * Copyright (c) 2011, Steve Bennett <steveb at workware dot net dot au>
17  *
18  * All rights reserved.
19  *
20  * Redistribution and use in source and binary forms, with or without
21  * modification, are permitted provided that the following conditions are
22  * met:
23  *
24  *  *  Redistributions of source code must retain the above copyright
25  *     notice, this list of conditions and the following disclaimer.
26  *
27  *  *  Redistributions in binary form must reproduce the above copyright
28  *     notice, this list of conditions and the following disclaimer in the
29  *     documentation and/or other materials provided with the distribution.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  *
43  * ------------------------------------------------------------------------
44  *
45  * References:
46  * - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
47  * - http://www.3waylabs.com/nw/WWW/products/wizcon/vt220.html
48  *
49  * Bloat:
50  * - Completion?
51  *
52  * Unix/termios
53  * ------------
54  * List of escape sequences used by this program, we do everything just
55  * a few 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 of n chars
68  *
69  * CR (Carriage Return)
70  *    Sequence: \r
71  *    Effect: moves cursor to column 1
72  *
73  * The following are used to clear the screen: ESC [ H ESC [ 2 J
74  * This is actually composed of two sequences:
75  *
76  * cursorhome
77  *    Sequence: ESC [ H
78  *    Effect: moves the cursor to upper left corner
79  *
80  * ED2 (Clear entire screen)
81  *    Sequence: ESC [ 2 J
82  *    Effect: clear the whole screen
83  *
84  * == For highlighting control characters, we also use the following two ==
85  * SO (enter StandOut)
86  *    Sequence: ESC [ 7 m
87  *    Effect: Uses some standout mode such as reverse video
88  *
89  * SE (Standout End)
90  *    Sequence: ESC [ 0 m
91  *    Effect: Exit standout mode
92  *
93  * == Only used if TIOCGWINSZ fails ==
94  * DSR/CPR (Report cursor position)
95  *    Sequence: ESC [ 6 n
96  *    Effect: reports current cursor position as ESC [ NNN ; MMM R
97  *
98  * win32/console
99  * -------------
100  * If __MINGW32__ is defined, the win32 console API is used.
101  * This could probably be made to work for the msvc compiler too.
102  * This support based in part on work by Jon Griffiths.
103  */
104
105 #ifdef _WIN32 /* Windows platform, either MinGW or Visual Studio (MSVC) */
106 #include <windows.h>
107 #include <fcntl.h>
108 #define USE_WINCONSOLE
109 #ifdef __MINGW32__
110 #define HAVE_UNISTD_H
111 #else
112 /* Microsoft headers don't like old POSIX names */
113 #define strdup _strdup
114 #define snprintf _snprintf
115 #endif
116 #else
117 #include <termios.h>
118 #include <sys/ioctl.h>
119 #include <sys/poll.h>
120 #define USE_TERMIOS
121 #define HAVE_UNISTD_H
122 #endif
123
124 #ifdef HAVE_UNISTD_H
125 #include <unistd.h>
126 #endif
127 #include <stdlib.h>
128 #include <stdarg.h>
129 #include <stdio.h>
130 #include <errno.h>
131 #include <string.h>
132 #include <stdlib.h>
133 #include <sys/types.h>
134
135 #include "linenoise.h"
136 #include "utf8.h"
137
138 #define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
139 #define LINENOISE_MAX_LINE 4096
140
141 #define ctrl(C) ((C) - '@')
142
143 /* Use -ve numbers here to co-exist with normal unicode chars */
144 enum {
145     SPECIAL_NONE,
146     SPECIAL_UP = -20,
147     SPECIAL_DOWN = -21,
148     SPECIAL_LEFT = -22,
149     SPECIAL_RIGHT = -23,
150     SPECIAL_DELETE = -24,
151     SPECIAL_HOME = -25,
152     SPECIAL_END = -26,
153     SPECIAL_INSERT = -27,
154     SPECIAL_PAGE_UP = -28,
155     SPECIAL_PAGE_DOWN = -29
156 };
157
158 static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
159 static int history_len = 0;
160 static char **history = NULL;
161
162 /* Structure to contain the status of the current (being edited) line */
163 struct current {
164     char *buf;  /* Current buffer. Always null terminated */
165     int bufmax; /* Size of the buffer, including space for the null termination */
166     int len;    /* Number of bytes in 'buf' */
167     int chars;  /* Number of chars in 'buf' (utf-8 chars) */
168     int pos;    /* Cursor position, measured in chars */
169     int cols;   /* Size of the window, in chars */
170     const char *prompt;
171     char *capture; /* Allocated capture buffer, or NULL for none. Always null terminated */
172 #if defined(USE_TERMIOS)
173     int fd;     /* Terminal fd */
174 #elif defined(USE_WINCONSOLE)
175     HANDLE outh; /* Console output handle */
176     HANDLE inh; /* Console input handle */
177     int rows;   /* Screen rows */
178     int x;      /* Current column during output */
179     int y;      /* Current row */
180 #endif
181 };
182
183 static int fd_read(struct current *current);
184 static int getWindowSize(struct current *current);
185
186 void linenoiseHistoryFree(void) {
187     if (history) {
188         int j;
189
190         for (j = 0; j < history_len; j++)
191             free(history[j]);
192         free(history);
193         history = NULL;
194         history_len = 0;
195     }
196 }
197
198 #if defined(USE_TERMIOS)
199 static void linenoiseAtExit(void);
200 static struct termios orig_termios; /* in order to restore at exit */
201 static int rawmode = 0; /* for atexit() function to check if restore is needed*/
202 static int atexit_registered = 0; /* register atexit just 1 time */
203
204 static const char *unsupported_term[] = {"dumb","cons25",NULL};
205
206 static int isUnsupportedTerm(void) {
207     char *term = getenv("TERM");
208
209     if (term) {
210         int j;
211         for (j = 0; unsupported_term[j]; j++) {
212             if (strcasecmp(term, unsupported_term[j]) == 0) {
213                 return 1;
214             }
215         }
216     }
217     return 0;
218 }
219
220 static int enableRawMode(struct current *current) {
221     struct termios raw;
222
223     current->fd = STDIN_FILENO;
224
225     if (!isatty(current->fd) || isUnsupportedTerm() ||
226         tcgetattr(current->fd, &orig_termios) == -1) {
227 fatal:
228         errno = ENOTTY;
229         return -1;
230     }
231
232     if (!atexit_registered) {
233         atexit(linenoiseAtExit);
234         atexit_registered = 1;
235     }
236
237     raw = orig_termios;  /* modify the original mode */
238     /* input modes: no break, no CR to NL, no parity check, no strip char,
239      * no start/stop output control. */
240     raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
241     /* output modes - disable post processing */
242     raw.c_oflag &= ~(OPOST);
243     /* control modes - set 8 bit chars */
244     raw.c_cflag |= (CS8);
245     /* local modes - choing off, canonical off, no extended functions,
246      * no signal chars (^Z,^C) */
247     raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
248     /* control chars - set return condition: min number of bytes and timer.
249      * We want read to return every single byte, without timeout. */
250     raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */
251
252     /* put terminal in raw mode after flushing */
253     if (tcsetattr(current->fd,TCSADRAIN,&raw) < 0) {
254         goto fatal;
255     }
256     rawmode = 1;
257
258     current->cols = 0;
259     return 0;
260 }
261
262 static void disableRawMode(struct current *current) {
263     /* Don't even check the return value as it's too late. */
264     if (rawmode && tcsetattr(current->fd,TCSADRAIN,&orig_termios) != -1)
265         rawmode = 0;
266 }
267
268 /* At exit we'll try to fix the terminal to the initial conditions. */
269 static void linenoiseAtExit(void) {
270     if (rawmode) {
271         tcsetattr(STDIN_FILENO, TCSADRAIN, &orig_termios);
272     }
273     linenoiseHistoryFree();
274 }
275
276 /* gcc/glibc insists that we care about the return code of write!
277  * Clarification: This means that a void-cast like "(void) (EXPR)"
278  * does not work.
279  */
280 #define IGNORE_RC(EXPR) if (EXPR) {}
281
282 /* This is fdprintf() on some systems, but use a different
283  * name to avoid conflicts
284  */
285 static void fd_printf(int fd, const char *format, ...)
286 {
287     va_list args;
288     char buf[64];
289     int n;
290
291     va_start(args, format);
292     n = vsnprintf(buf, sizeof(buf), format, args);
293     va_end(args);
294     IGNORE_RC(write(fd, buf, n));
295 }
296
297 static void clearScreen(struct current *current)
298 {
299     fd_printf(current->fd, "\x1b[H\x1b[2J");
300 }
301
302 static void cursorToLeft(struct current *current)
303 {
304     fd_printf(current->fd, "\r");
305 }
306
307 static int outputChars(struct current *current, const char *buf, int len)
308 {
309     return write(current->fd, buf, len);
310 }
311
312 static void outputControlChar(struct current *current, char ch)
313 {
314     fd_printf(current->fd, "\x1b[7m^%c\x1b[0m", ch);
315 }
316
317 static void eraseEol(struct current *current)
318 {
319     fd_printf(current->fd, "\x1b[0K");
320 }
321
322 static void setCursorPos(struct current *current, int x)
323 {
324     fd_printf(current->fd, "\r\x1b[%dC", x);
325 }
326
327 /**
328  * Reads a char from 'fd', waiting at most 'timeout' milliseconds.
329  *
330  * A timeout of -1 means to wait forever.
331  *
332  * Returns -1 if no char is received within the time or an error occurs.
333  */
334 static int fd_read_char(int fd, int timeout)
335 {
336     struct pollfd p;
337     unsigned char c;
338
339     p.fd = fd;
340     p.events = POLLIN;
341
342     if (poll(&p, 1, timeout) == 0) {
343         /* timeout */
344         return -1;
345     }
346     if (read(fd, &c, 1) != 1) {
347         return -1;
348     }
349     return c;
350 }
351
352 /**
353  * Reads a complete utf-8 character
354  * and returns the unicode value, or -1 on error.
355  */
356 static int fd_read(struct current *current)
357 {
358 #ifdef USE_UTF8
359     char buf[4];
360     int n;
361     int i;
362     int c;
363
364     if (read(current->fd, &buf[0], 1) != 1) {
365         return -1;
366     }
367     n = utf8_charlen(buf[0]);
368     if (n < 1 || n > 3) {
369         return -1;
370     }
371     for (i = 1; i < n; i++) {
372         if (read(current->fd, &buf[i], 1) != 1) {
373             return -1;
374         }
375     }
376     buf[n] = 0;
377     /* decode and return the character */
378     utf8_tounicode(buf, &c);
379     return c;
380 #else
381     return fd_read_char(current->fd, -1);
382 #endif
383 }
384
385 static int countColorControlChars(const char* prompt, int plen)
386 {
387     /* ANSI color control sequences have the form:
388      * "\x1b" "[" [0-9;]+ "m"
389      * We parse them with a simple state machine.
390      */
391
392     enum {
393         search_esc,
394         expect_bracket,
395         expect_inner,
396         expect_trail
397     } state = search_esc;
398     int len, found = 0;
399     char ch;
400
401     /* XXX: Strictly we should be checking utf8 chars rather than
402      *      bytes in case of the extremely unlikely scenario where
403      *      an ANSI sequence is part of a utf8 sequence.
404      */
405     for (; plen ; plen--, prompt++) {
406         ch = *prompt;
407
408         switch (state) {
409         case search_esc:
410             len = 0;
411             if (ch == '\x1b') {
412                 state = expect_bracket;
413                 len++;
414             }
415             break;
416         case expect_bracket:
417             if (ch == '[') {
418                 state = expect_inner;
419                 len++;
420             } else {
421                 state = search_esc;
422             }
423             break;
424         case expect_inner:
425             if (ch >= '0' && ch <= '9') {
426                 len++;
427                 state = expect_trail;
428             } else {
429                 state = search_esc;
430             }
431             break;
432         case expect_trail:
433             if (ch == 'm') {
434                 len++;
435                 found += len;
436                 state = search_esc;
437             } else if ((ch != ';') && ((ch < '0') || (ch > '9'))) {
438                 state = search_esc;
439             }
440             /* 0-9, or semicolon */
441             len++;
442             break;
443         }
444     }
445
446     return found;
447 }
448
449 static int getWindowSize(struct current *current)
450 {
451     struct winsize ws;
452
453     if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col != 0) {
454         current->cols = ws.ws_col;
455         return 0;
456     }
457
458     /* Failed to query the window size. Perhaps we are on a serial terminal.
459      * Try to query the width by sending the cursor as far to the right
460      * and reading back the cursor position.
461      * Note that this is only done once per call to linenoise rather than
462      * every time the line is refreshed for efficiency reasons.
463      */
464     if (current->cols == 0) {
465         current->cols = 80;
466
467         /* Move cursor far right and report cursor position, then back to the left */
468         fd_printf(current->fd, "\x1b[999C" "\x1b[6n");
469
470         /* Parse the response: ESC [ rows ; cols R */
471         if (fd_read_char(current->fd, 100) == 0x1b && fd_read_char(current->fd, 100) == '[') {
472             int n = 0;
473             while (1) {
474                 int ch = fd_read_char(current->fd, 100);
475                 if (ch == ';') {
476                     /* Ignore rows */
477                     n = 0;
478                 }
479                 else if (ch == 'R') {
480                     /* Got cols */
481                     if (n != 0 && n < 1000) {
482                         current->cols = n;
483                     }
484                     break;
485                 }
486                 else if (ch >= 0 && ch <= '9') {
487                     n = n * 10 + ch - '0';
488                 }
489                 else {
490                     break;
491                 }
492             }
493         }
494     }
495     return 0;
496 }
497
498 /**
499  * If escape (27) was received, reads subsequent
500  * chars to determine if this is a known special key.
501  *
502  * Returns SPECIAL_NONE if unrecognised, or -1 if EOF.
503  *
504  * If no additional char is received within a short time,
505  * 27 is returned.
506  */
507 static int check_special(int fd)
508 {
509     int c = fd_read_char(fd, 50);
510     int c2;
511
512     if (c < 0) {
513         return 27;
514     }
515
516     c2 = fd_read_char(fd, 50);
517     if (c2 < 0) {
518         return c2;
519     }
520     if (c == '[' || c == 'O') {
521         /* Potential arrow key */
522         switch (c2) {
523             case 'A':
524                 return SPECIAL_UP;
525             case 'B':
526                 return SPECIAL_DOWN;
527             case 'C':
528                 return SPECIAL_RIGHT;
529             case 'D':
530                 return SPECIAL_LEFT;
531             case 'F':
532                 return SPECIAL_END;
533             case 'H':
534                 return SPECIAL_HOME;
535         }
536     }
537     if (c == '[' && c2 >= '1' && c2 <= '8') {
538         /* extended escape */
539         c = fd_read_char(fd, 50);
540         if (c == '~') {
541             switch (c2) {
542                 case '2':
543                     return SPECIAL_INSERT;
544                 case '3':
545                     return SPECIAL_DELETE;
546                 case '5':
547                     return SPECIAL_PAGE_UP;
548                 case '6':
549                     return SPECIAL_PAGE_DOWN;
550                 case '7':
551                     return SPECIAL_HOME;
552                 case '8':
553                     return SPECIAL_END;
554             }
555         }
556         while (c != -1 && c != '~') {
557             /* .e.g \e[12~ or '\e[11;2~   discard the complete sequence */
558             c = fd_read_char(fd, 50);
559         }
560     }
561
562     return SPECIAL_NONE;
563 }
564 #elif defined(USE_WINCONSOLE)
565
566 static DWORD orig_consolemode = 0;
567
568 static int enableRawMode(struct current *current) {
569     DWORD n;
570     INPUT_RECORD irec;
571
572     current->outh = GetStdHandle(STD_OUTPUT_HANDLE);
573     current->inh = GetStdHandle(STD_INPUT_HANDLE);
574
575     if (!PeekConsoleInput(current->inh, &irec, 1, &n)) {
576         return -1;
577     }
578     if (getWindowSize(current) != 0) {
579         return -1;
580     }
581     if (GetConsoleMode(current->inh, &orig_consolemode)) {
582         SetConsoleMode(current->inh, ENABLE_PROCESSED_INPUT);
583     }
584     return 0;
585 }
586
587 static void disableRawMode(struct current *current)
588 {
589     SetConsoleMode(current->inh, orig_consolemode);
590 }
591
592 static void clearScreen(struct current *current)
593 {
594     COORD topleft = { 0, 0 };
595     DWORD n;
596
597     FillConsoleOutputCharacter(current->outh, ' ',
598         current->cols * current->rows, topleft, &n);
599     FillConsoleOutputAttribute(current->outh,
600         FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN,
601         current->cols * current->rows, topleft, &n);
602     SetConsoleCursorPosition(current->outh, topleft);
603 }
604
605 static void cursorToLeft(struct current *current)
606 {
607     COORD pos = { 0, (SHORT)current->y };
608     DWORD n;
609
610     FillConsoleOutputAttribute(current->outh,
611         FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, current->cols, pos, &n);
612     current->x = 0;
613 }
614
615 static int outputChars(struct current *current, const char *buf, int len)
616 {
617     COORD pos = { (SHORT)current->x, (SHORT)current->y };
618     DWORD n;
619
620     WriteConsoleOutputCharacter(current->outh, buf, len, pos, &n);
621     current->x += len;
622     return 0;
623 }
624
625 static void outputControlChar(struct current *current, char ch)
626 {
627     COORD pos = { (SHORT)current->x, (SHORT)current->y };
628     DWORD n;
629
630     FillConsoleOutputAttribute(current->outh, BACKGROUND_INTENSITY, 2, pos, &n);
631     outputChars(current, "^", 1);
632     outputChars(current, &ch, 1);
633 }
634
635 static void eraseEol(struct current *current)
636 {
637     COORD pos = { (SHORT)current->x, (SHORT)current->y };
638     DWORD n;
639
640     FillConsoleOutputCharacter(current->outh, ' ', current->cols - current->x, pos, &n);
641 }
642
643 static void setCursorPos(struct current *current, int x)
644 {
645     COORD pos = { (SHORT)x, (SHORT)current->y };
646
647     SetConsoleCursorPosition(current->outh, pos);
648     current->x = x;
649 }
650
651 static int fd_read(struct current *current)
652 {
653     while (1) {
654         INPUT_RECORD irec;
655         DWORD n;
656         if (WaitForSingleObject(current->inh, INFINITE) != WAIT_OBJECT_0) {
657             break;
658         }
659         if (!ReadConsoleInput (current->inh, &irec, 1, &n)) {
660             break;
661         }
662         if (irec.EventType == KEY_EVENT && irec.Event.KeyEvent.bKeyDown) {
663             KEY_EVENT_RECORD *k = &irec.Event.KeyEvent;
664             if (k->dwControlKeyState & ENHANCED_KEY) {
665                 switch (k->wVirtualKeyCode) {
666                  case VK_LEFT:
667                     return SPECIAL_LEFT;
668                  case VK_RIGHT:
669                     return SPECIAL_RIGHT;
670                  case VK_UP:
671                     return SPECIAL_UP;
672                  case VK_DOWN:
673                     return SPECIAL_DOWN;
674                  case VK_INSERT:
675                     return SPECIAL_INSERT;
676                  case VK_DELETE:
677                     return SPECIAL_DELETE;
678                  case VK_HOME:
679                     return SPECIAL_HOME;
680                  case VK_END:
681                     return SPECIAL_END;
682                  case VK_PRIOR:
683                     return SPECIAL_PAGE_UP;
684                  case VK_NEXT:
685                     return SPECIAL_PAGE_DOWN;
686                 }
687             }
688             /* Note that control characters are already translated in AsciiChar */
689             else {
690 #ifdef USE_UTF8
691                 return k->uChar.UnicodeChar;
692 #else
693                 return k->uChar.AsciiChar;
694 #endif
695             }
696         }
697     }
698     return -1;
699 }
700
701 static int countColorControlChars(char* prompt, int plen)
702 {
703     /* For windows we assume that there are no embedded ansi color
704      * control sequences.
705      */
706     return 0;
707 }
708
709 static int getWindowSize(struct current *current)
710 {
711     CONSOLE_SCREEN_BUFFER_INFO info;
712     if (!GetConsoleScreenBufferInfo(current->outh, &info)) {
713         return -1;
714     }
715     current->cols = info.dwSize.X;
716     current->rows = info.dwSize.Y;
717     if (current->cols <= 0 || current->rows <= 0) {
718         current->cols = 80;
719         return -1;
720     }
721     current->y = info.dwCursorPosition.Y;
722     current->x = info.dwCursorPosition.X;
723     return 0;
724 }
725 #endif
726
727 static int utf8_getchars(char *buf, int c)
728 {
729 #ifdef USE_UTF8
730     return utf8_fromunicode(buf, c);
731 #else
732     *buf = c;
733     return 1;
734 #endif
735 }
736
737 /**
738  * Returns the unicode character at the given offset,
739  * or -1 if none.
740  */
741 static int get_char(struct current *current, int pos)
742 {
743     if (pos >= 0 && pos < current->chars) {
744         int c;
745         int i = utf8_index(current->buf, pos);
746         (void)utf8_tounicode(current->buf + i, &c);
747         return c;
748     }
749     return -1;
750 }
751
752 static void refreshLine(const char *prompt, struct current *current)
753 {
754     int plen;
755     int pchars;
756     int backup = 0;
757     int i;
758     const char *buf = current->buf;
759     int chars = current->chars;
760     int pos = current->pos;
761     int b;
762     int ch;
763     int n;
764
765     /* Should intercept SIGWINCH. For now, just get the size every time */
766     getWindowSize(current);
767
768     plen = strlen(prompt);
769     pchars = utf8_strlen(prompt, plen);
770
771     /* Scan the prompt for embedded ansi color control sequences and
772      * discount them as characters/columns.
773      */
774     pchars -= countColorControlChars(prompt, plen);
775
776     /* Account for a line which is too long to fit in the window.
777      * Note that control chars require an extra column
778      */
779
780     /* How many cols are required to the left of 'pos'?
781      * The prompt, plus one extra for each control char
782      */
783     n = pchars + utf8_strlen(buf, current->len);
784     b = 0;
785     for (i = 0; i < pos; i++) {
786         b += utf8_tounicode(buf + b, &ch);
787         if (ch < ' ') {
788             n++;
789         }
790     }
791
792     /* If too many are needed, strip chars off the front of 'buf'
793      * until it fits. Note that if the current char is a control character,
794      * we need one extra col.
795      */
796     if (current->pos < current->chars && get_char(current, current->pos) < ' ') {
797         n++;
798     }
799
800     while (n >= current->cols && pos > 0) {
801         b = utf8_tounicode(buf, &ch);
802         if (ch < ' ') {
803             n--;
804         }
805         n--;
806         buf += b;
807         pos--;
808         chars--;
809     }
810
811     /* Cursor to left edge, then the prompt */
812     cursorToLeft(current);
813     outputChars(current, prompt, plen);
814
815     /* Now the current buffer content */
816
817     /* Need special handling for control characters.
818      * If we hit 'cols', stop.
819      */
820     b = 0; /* unwritted bytes */
821     n = 0; /* How many control chars were written */
822     for (i = 0; i < chars; i++) {
823         int ch;
824         int w = utf8_tounicode(buf + b, &ch);
825         if (ch < ' ') {
826             n++;
827         }
828         if (pchars + i + n >= current->cols) {
829             break;
830         }
831         if (ch < ' ') {
832             /* A control character, so write the buffer so far */
833             outputChars(current, buf, b);
834             buf += b + w;
835             b = 0;
836             outputControlChar(current, ch + '@');
837             if (i < pos) {
838                 backup++;
839             }
840         }
841         else {
842             b += w;
843         }
844     }
845     outputChars(current, buf, b);
846
847     /* Erase to right, move cursor to original position */
848     eraseEol(current);
849     setCursorPos(current, pos + pchars + backup);
850 }
851
852 static void set_current(struct current *current, const char *str)
853 {
854     strncpy(current->buf, str, current->bufmax);
855     current->buf[current->bufmax - 1] = 0;
856     current->len = strlen(current->buf);
857     current->pos = current->chars = utf8_strlen(current->buf, current->len);
858 }
859
860 static int has_room(struct current *current, int bytes)
861 {
862     return current->len + bytes < current->bufmax - 1;
863 }
864
865 /**
866  * Removes the char at 'pos'.
867  *
868  * Returns 1 if the line needs to be refreshed, 2 if not
869  * and 0 if nothing was removed
870  */
871 static int remove_char(struct current *current, int pos)
872 {
873     if (pos >= 0 && pos < current->chars) {
874         int p1, p2;
875         int ret = 1;
876         p1 = utf8_index(current->buf, pos);
877         p2 = p1 + utf8_index(current->buf + p1, 1);
878
879 #ifdef USE_TERMIOS
880         /* optimise remove char in the case of removing the last char */
881         if (current->pos == pos + 1 && current->pos == current->chars) {
882             if (current->buf[pos] >= ' ' && utf8_strlen(current->prompt, -1) + utf8_strlen(current->buf, current->len) < current->cols - 1) {
883                 ret = 2;
884                 fd_printf(current->fd, "\b \b");
885             }
886         }
887 #endif
888
889         /* Move the null char too */
890         memmove(current->buf + p1, current->buf + p2, current->len - p2 + 1);
891         current->len -= (p2 - p1);
892         current->chars--;
893
894         if (current->pos > pos) {
895             current->pos--;
896         }
897         return ret;
898     }
899     return 0;
900 }
901
902 /**
903  * Insert 'ch' at position 'pos'
904  *
905  * Returns 1 if the line needs to be refreshed, 2 if not
906  * and 0 if nothing was inserted (no room)
907  */
908 static int insert_char(struct current *current, int pos, int ch)
909 {
910     char buf[3];
911     int n = utf8_getchars(buf, ch);
912
913     if (has_room(current, n) && pos >= 0 && pos <= current->chars) {
914         int p1, p2;
915         int ret = 1;
916         p1 = utf8_index(current->buf, pos);
917         p2 = p1 + n;
918
919 #ifdef USE_TERMIOS
920         /* optimise the case where adding a single char to the end and no scrolling is needed */
921         if (current->pos == pos && current->chars == pos) {
922             if (ch >= ' ' && utf8_strlen(current->prompt, -1) + utf8_strlen(current->buf, current->len) < current->cols - 1) {
923                 IGNORE_RC(write(current->fd, buf, n));
924                 ret = 2;
925             }
926         }
927 #endif
928
929         memmove(current->buf + p2, current->buf + p1, current->len - p1);
930         memcpy(current->buf + p1, buf, n);
931         current->len += n;
932
933         current->chars++;
934         if (current->pos >= pos) {
935             current->pos++;
936         }
937         return ret;
938     }
939     return 0;
940 }
941
942 /**
943  * Captures up to 'n' characters starting at 'pos' for the cut buffer.
944  *
945  * This replaces any existing characters in the cut buffer.
946  */
947 static void capture_chars(struct current *current, int pos, int n)
948 {
949     if (pos >= 0 && (pos + n - 1) < current->chars) {
950         int p1 = utf8_index(current->buf, pos);
951         int nbytes = utf8_index(current->buf + p1, n);
952
953         if (nbytes) {
954             free(current->capture);
955             /* Include space for the null terminator */
956             current->capture = (char *)malloc(nbytes + 1);
957             memcpy(current->capture, current->buf + p1, nbytes);
958             current->capture[nbytes] = '\0';
959         }
960     }
961 }
962
963 /**
964  * Removes up to 'n' characters at cursor position 'pos'.
965  *
966  * Returns 0 if no chars were removed or non-zero otherwise.
967  */
968 static int remove_chars(struct current *current, int pos, int n)
969 {
970     int removed = 0;
971
972     /* First save any chars which will be removed */
973     capture_chars(current, pos, n);
974
975     while (n-- && remove_char(current, pos)) {
976         removed++;
977     }
978     return removed;
979 }
980 /**
981  * Inserts the characters (string) 'chars' at the cursor position 'pos'.
982  *
983  * Returns 0 if no chars were inserted or non-zero otherwise.
984  */
985 static int insert_chars(struct current *current, int pos, const char *chars)
986 {
987     int inserted = 0;
988
989     while (*chars) {
990         int ch;
991         int n = utf8_tounicode(chars, &ch);
992         if (insert_char(current, pos, ch) == 0) {
993             break;
994         }
995         inserted++;
996         pos++;
997         chars += n;
998     }
999     return inserted;
1000 }
1001
1002 #ifndef NO_COMPLETION
1003 static linenoiseCompletionCallback *completionCallback = NULL;
1004
1005 static void beep() {
1006 #ifdef USE_TERMIOS
1007     fprintf(stderr, "\x7");
1008     fflush(stderr);
1009 #endif
1010 }
1011
1012 static void freeCompletions(linenoiseCompletions *lc) {
1013     size_t i;
1014     for (i = 0; i < lc->len; i++)
1015         free(lc->cvec[i]);
1016     free(lc->cvec);
1017 }
1018
1019 static int completeLine(struct current *current) {
1020     linenoiseCompletions lc = { 0, NULL };
1021     int c = 0;
1022
1023     completionCallback(current->buf,&lc);
1024     if (lc.len == 0) {
1025         beep();
1026     } else {
1027         size_t stop = 0, i = 0;
1028
1029         while(!stop) {
1030             /* Show completion or original buffer */
1031             if (i < lc.len) {
1032                 struct current tmp = *current;
1033                 tmp.buf = lc.cvec[i];
1034                 tmp.pos = tmp.len = strlen(tmp.buf);
1035                 tmp.chars = utf8_strlen(tmp.buf, tmp.len);
1036                 refreshLine(current->prompt, &tmp);
1037             } else {
1038                 refreshLine(current->prompt, current);
1039             }
1040
1041             c = fd_read(current);
1042             if (c == -1) {
1043                 break;
1044             }
1045
1046             switch(c) {
1047                 case '\t': /* tab */
1048                     i = (i+1) % (lc.len+1);
1049                     if (i == lc.len) beep();
1050                     break;
1051                 case 27: /* escape */
1052                     /* Re-show original buffer */
1053                     if (i < lc.len) {
1054                         refreshLine(current->prompt, current);
1055                     }
1056                     stop = 1;
1057                     break;
1058                 default:
1059                     /* Update buffer and return */
1060                     if (i < lc.len) {
1061                         set_current(current,lc.cvec[i]);
1062                     }
1063                     stop = 1;
1064                     break;
1065             }
1066         }
1067     }
1068
1069     freeCompletions(&lc);
1070     return c; /* Return last read character */
1071 }
1072
1073 /* Register a callback function to be called for tab-completion. */
1074 void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) {
1075     completionCallback = fn;
1076 }
1077
1078 void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) {
1079     lc->cvec = (char **)realloc(lc->cvec,sizeof(char*)*(lc->len+1));
1080     lc->cvec[lc->len++] = strdup(str);
1081 }
1082
1083 #endif
1084
1085 static int linenoisePrompt(struct current *current) {
1086     int history_index = 0;
1087
1088     /* The latest history entry is always our current buffer, that
1089      * initially is just an empty string. */
1090     linenoiseHistoryAdd("");
1091
1092     set_current(current, "");
1093     refreshLine(current->prompt, current);
1094
1095     while(1) {
1096         int dir = -1;
1097         int c = fd_read(current);
1098
1099 #ifndef NO_COMPLETION
1100         /* Only autocomplete when the callback is set. It returns < 0 when
1101          * there was an error reading from fd. Otherwise it will return the
1102          * character that should be handled next. */
1103         if (c == '\t' && current->pos == current->chars && completionCallback != NULL) {
1104             c = completeLine(current);
1105             /* Return on errors */
1106             if (c < 0) return current->len;
1107             /* Read next character when 0 */
1108             if (c == 0) continue;
1109         }
1110 #endif
1111
1112 process_char:
1113         if (c == -1) return current->len;
1114 #ifdef USE_TERMIOS
1115         if (c == 27) {   /* escape sequence */
1116             c = check_special(current->fd);
1117         }
1118 #endif
1119         switch(c) {
1120         case '\r':    /* enter */
1121             history_len--;
1122             free(history[history_len]);
1123             return current->len;
1124         case ctrl('C'):     /* ctrl-c */
1125             errno = EAGAIN;
1126             return -1;
1127         case 127:   /* backspace */
1128         case ctrl('H'):
1129             if (remove_char(current, current->pos - 1) == 1) {
1130                 refreshLine(current->prompt, current);
1131             }
1132             break;
1133         case ctrl('D'):     /* ctrl-d */
1134             if (current->len == 0) {
1135                 /* Empty line, so EOF */
1136                 history_len--;
1137                 free(history[history_len]);
1138                 return -1;
1139             }
1140             /* Otherwise fall through to delete char to right of cursor */
1141         case SPECIAL_DELETE:
1142             if (remove_char(current, current->pos) == 1) {
1143                 refreshLine(current->prompt, current);
1144             }
1145             break;
1146         case SPECIAL_INSERT:
1147             /* Ignore. Expansion Hook.
1148              * Future possibility: Toggle Insert/Overwrite Modes
1149              */
1150             break;
1151         case ctrl('W'):    /* ctrl-w, delete word at left. save deleted chars */
1152             /* eat any spaces on the left */
1153             {
1154                 int pos = current->pos;
1155                 while (pos > 0 && get_char(current, pos - 1) == ' ') {
1156                     pos--;
1157                 }
1158
1159                 /* now eat any non-spaces on the left */
1160                 while (pos > 0 && get_char(current, pos - 1) != ' ') {
1161                     pos--;
1162                 }
1163
1164                 if (remove_chars(current, pos, current->pos - pos)) {
1165                     refreshLine(current->prompt, current);
1166                 }
1167             }
1168             break;
1169         case ctrl('R'):    /* ctrl-r */
1170             {
1171                 /* Display the reverse-i-search prompt and process chars */
1172                 char rbuf[50];
1173                 char rprompt[80];
1174                 int rchars = 0;
1175                 int rlen = 0;
1176                 int searchpos = history_len - 1;
1177
1178                 rbuf[0] = 0;
1179                 while (1) {
1180                     int n = 0;
1181                     const char *p = NULL;
1182                     int skipsame = 0;
1183                     int searchdir = -1;
1184
1185                     snprintf(rprompt, sizeof(rprompt), "(reverse-i-search)'%s': ", rbuf);
1186                     refreshLine(rprompt, current);
1187                     c = fd_read(current);
1188                     if (c == ctrl('H') || c == 127) {
1189                         if (rchars) {
1190                             int p = utf8_index(rbuf, --rchars);
1191                             rbuf[p] = 0;
1192                             rlen = strlen(rbuf);
1193                         }
1194                         continue;
1195                     }
1196 #ifdef USE_TERMIOS
1197                     if (c == 27) {
1198                         c = check_special(current->fd);
1199                     }
1200 #endif
1201                     if (c == ctrl('P') || c == SPECIAL_UP) {
1202                         /* Search for the previous (earlier) match */
1203                         if (searchpos > 0) {
1204                             searchpos--;
1205                         }
1206                         skipsame = 1;
1207                     }
1208                     else if (c == ctrl('N') || c == SPECIAL_DOWN) {
1209                         /* Search for the next (later) match */
1210                         if (searchpos < history_len) {
1211                             searchpos++;
1212                         }
1213                         searchdir = 1;
1214                         skipsame = 1;
1215                     }
1216                     else if (c >= ' ') {
1217                         if (rlen >= (int)sizeof(rbuf) + 3) {
1218                             continue;
1219                         }
1220
1221                         n = utf8_getchars(rbuf + rlen, c);
1222                         rlen += n;
1223                         rchars++;
1224                         rbuf[rlen] = 0;
1225
1226                         /* Adding a new char resets the search location */
1227                         searchpos = history_len - 1;
1228                     }
1229                     else {
1230                         /* Exit from incremental search mode */
1231                         break;
1232                     }
1233
1234                     /* Now search through the history for a match */
1235                     for (; searchpos >= 0 && searchpos < history_len; searchpos += searchdir) {
1236                         p = strstr(history[searchpos], rbuf);
1237                         if (p) {
1238                             /* Found a match */
1239                             if (skipsame && strcmp(history[searchpos], current->buf) == 0) {
1240                                 /* But it is identical, so skip it */
1241                                 continue;
1242                             }
1243                             /* Copy the matching line and set the cursor position */
1244                             set_current(current,history[searchpos]);
1245                             current->pos = utf8_strlen(history[searchpos], p - history[searchpos]);
1246                             break;
1247                         }
1248                     }
1249                     if (!p && n) {
1250                         /* No match, so don't add it */
1251                         rchars--;
1252                         rlen -= n;
1253                         rbuf[rlen] = 0;
1254                     }
1255                 }
1256                 if (c == ctrl('G') || c == ctrl('C')) {
1257                     /* ctrl-g terminates the search with no effect */
1258                     set_current(current, "");
1259                     c = 0;
1260                 }
1261                 else if (c == ctrl('J')) {
1262                     /* ctrl-j terminates the search leaving the buffer in place */
1263                     c = 0;
1264                 }
1265                 /* Go process the char normally */
1266                 refreshLine(current->prompt, current);
1267                 goto process_char;
1268             }
1269             break;
1270         case ctrl('T'):    /* ctrl-t */
1271             if (current->pos > 0 && current->pos <= current->chars) {
1272                 /* If cursor is at end, transpose the previous two chars */
1273                 int fixer = (current->pos == current->chars);
1274                 c = get_char(current, current->pos - fixer);
1275                 remove_char(current, current->pos - fixer);
1276                 insert_char(current, current->pos - 1, c);
1277                 refreshLine(current->prompt, current);
1278             }
1279             break;
1280         case ctrl('V'):    /* ctrl-v */
1281             if (has_room(current, 3)) {
1282                 /* Insert the ^V first */
1283                 if (insert_char(current, current->pos, c)) {
1284                     refreshLine(current->prompt, current);
1285                     /* Now wait for the next char. Can insert anything except \0 */
1286                     c = fd_read(current);
1287
1288                     /* Remove the ^V first */
1289                     remove_char(current, current->pos - 1);
1290                     if (c != -1) {
1291                         /* Insert the actual char */
1292                         insert_char(current, current->pos, c);
1293                     }
1294                     refreshLine(current->prompt, current);
1295                 }
1296             }
1297             break;
1298         case ctrl('B'):
1299         case SPECIAL_LEFT:
1300             if (current->pos > 0) {
1301                 current->pos--;
1302                 refreshLine(current->prompt, current);
1303             }
1304             break;
1305         case ctrl('F'):
1306         case SPECIAL_RIGHT:
1307             if (current->pos < current->chars) {
1308                 current->pos++;
1309                 refreshLine(current->prompt, current);
1310             }
1311             break;
1312         case SPECIAL_PAGE_UP:
1313           dir = history_len - history_index - 1; /* move to start of history */
1314           goto history_navigation;
1315         case SPECIAL_PAGE_DOWN:
1316           dir = -history_index; /* move to 0 == end of history, i.e. current */
1317           goto history_navigation;
1318         case ctrl('P'):
1319         case SPECIAL_UP:
1320             dir = 1;
1321           goto history_navigation;
1322         case ctrl('N'):
1323         case SPECIAL_DOWN:
1324 history_navigation:
1325             if (history_len > 1) {
1326                 /* Update the current history entry before to
1327                  * overwrite it with tne next one. */
1328                 free(history[history_len - 1 - history_index]);
1329                 history[history_len - 1 - history_index] = strdup(current->buf);
1330                 /* Show the new entry */
1331                 history_index += dir;
1332                 if (history_index < 0) {
1333                     history_index = 0;
1334                     break;
1335                 } else if (history_index >= history_len) {
1336                     history_index = history_len - 1;
1337                     break;
1338                 }
1339                 set_current(current, history[history_len - 1 - history_index]);
1340                 refreshLine(current->prompt, current);
1341             }
1342             break;
1343         case ctrl('A'): /* Ctrl+a, go to the start of the line */
1344         case SPECIAL_HOME:
1345             current->pos = 0;
1346             refreshLine(current->prompt, current);
1347             break;
1348         case ctrl('E'): /* ctrl+e, go to the end of the line */
1349         case SPECIAL_END:
1350             current->pos = current->chars;
1351             refreshLine(current->prompt, current);
1352             break;
1353         case ctrl('U'): /* Ctrl+u, delete to beginning of line, save deleted chars. */
1354             if (remove_chars(current, 0, current->pos)) {
1355                 refreshLine(current->prompt, current);
1356             }
1357             break;
1358         case ctrl('K'): /* Ctrl+k, delete from current to end of line, save deleted chars. */
1359             if (remove_chars(current, current->pos, current->chars - current->pos)) {
1360                 refreshLine(current->prompt, current);
1361             }
1362             break;
1363         case ctrl('Y'): /* Ctrl+y, insert saved chars at current position */
1364             if (current->capture && insert_chars(current, current->pos, current->capture)) {
1365                 refreshLine(current->prompt, current);
1366             }
1367             break;
1368         case ctrl('L'): /* Ctrl+L, clear screen */
1369             clearScreen(current);
1370             /* Force recalc of window size for serial terminals */
1371             current->cols = 0;
1372             refreshLine(current->prompt, current);
1373             break;
1374         default:
1375             /* Only tab is allowed without ^V */
1376             if (c == '\t' || c >= ' ') {
1377                 if (insert_char(current, current->pos, c) == 1) {
1378                     refreshLine(current->prompt, current);
1379                 }
1380             }
1381             break;
1382         }
1383     }
1384     return current->len;
1385 }
1386
1387 int linenoiseColumns(void)
1388 {
1389     struct current current;
1390     enableRawMode (&current);
1391     getWindowSize (&current);
1392     disableRawMode (&current);
1393     return current.cols;
1394 }
1395
1396 char *linenoise(const char *prompt)
1397 {
1398     int count;
1399     struct current current;
1400     char buf[LINENOISE_MAX_LINE];
1401
1402     if (enableRawMode(&current) == -1) {
1403         printf("%s", prompt);
1404         fflush(stdout);
1405         if (fgets(buf, sizeof(buf), stdin) == NULL) {
1406             return NULL;
1407         }
1408         count = strlen(buf);
1409         if (count && buf[count-1] == '\n') {
1410             count--;
1411             buf[count] = '\0';
1412         }
1413     }
1414     else
1415     {
1416         current.buf = buf;
1417         current.bufmax = sizeof(buf);
1418         current.len = 0;
1419         current.chars = 0;
1420         current.pos = 0;
1421         current.prompt = prompt;
1422         current.capture = NULL;
1423
1424         count = linenoisePrompt(&current);
1425
1426         disableRawMode(&current);
1427         printf("\n");
1428
1429         free(current.capture);
1430         if (count == -1) {
1431             return NULL;
1432         }
1433     }
1434     return strdup(buf);
1435 }
1436
1437 /* Using a circular buffer is smarter, but a bit more complex to handle. */
1438 int linenoiseHistoryAdd(const char *line) {
1439     char *linecopy;
1440
1441     if (history_max_len == 0) return 0;
1442     if (history == NULL) {
1443         history = (char **)malloc(sizeof(char*)*history_max_len);
1444         if (history == NULL) return 0;
1445         memset(history,0,(sizeof(char*)*history_max_len));
1446     }
1447
1448     /* do not insert duplicate lines into history */
1449     if (history_len > 0 && strcmp(line, history[history_len - 1]) == 0) {
1450         return 0;
1451     }
1452
1453     linecopy = strdup(line);
1454     if (!linecopy) return 0;
1455     if (history_len == history_max_len) {
1456         free(history[0]);
1457         memmove(history,history+1,sizeof(char*)*(history_max_len-1));
1458         history_len--;
1459     }
1460     history[history_len] = linecopy;
1461     history_len++;
1462     return 1;
1463 }
1464
1465 int linenoiseHistoryGetMaxLen(void) {
1466     return history_max_len;
1467 }
1468
1469 int linenoiseHistorySetMaxLen(int len) {
1470     char **newHistory;
1471
1472     if (len < 1) return 0;
1473     if (history) {
1474         int tocopy = history_len;
1475
1476         newHistory = (char **)malloc(sizeof(char*)*len);
1477         if (newHistory == NULL) return 0;
1478
1479         /* If we can't copy everything, free the elements we'll not use. */
1480         if (len < tocopy) {
1481             int j;
1482
1483             for (j = 0; j < tocopy-len; j++) free(history[j]);
1484             tocopy = len;
1485         }
1486         memset(newHistory,0,sizeof(char*)*len);
1487         memcpy(newHistory,history+(history_len-tocopy), sizeof(char*)*tocopy);
1488         free(history);
1489         history = newHistory;
1490     }
1491     history_max_len = len;
1492     if (history_len > history_max_len)
1493         history_len = history_max_len;
1494     return 1;
1495 }
1496
1497 /* Save the history in the specified file. On success 0 is returned
1498  * otherwise -1 is returned. */
1499 int linenoiseHistorySave(const char *filename) {
1500     FILE *fp = fopen(filename,"w");
1501     int j;
1502
1503     if (fp == NULL) return -1;
1504     for (j = 0; j < history_len; j++) {
1505         const char *str = history[j];
1506         /* Need to encode backslash, nl and cr */
1507         while (*str) {
1508             if (*str == '\\') {
1509                 fputs("\\\\", fp);
1510             }
1511             else if (*str == '\n') {
1512                 fputs("\\n", fp);
1513             }
1514             else if (*str == '\r') {
1515                 fputs("\\r", fp);
1516             }
1517             else {
1518                 fputc(*str, fp);
1519             }
1520             str++;
1521         }
1522         fputc('\n', fp);
1523     }
1524
1525     fclose(fp);
1526     return 0;
1527 }
1528
1529 /* Load the history from the specified file. If the file does not exist
1530  * zero is returned and no operation is performed.
1531  *
1532  * If the file exists and the operation succeeded 0 is returned, otherwise
1533  * on error -1 is returned. */
1534 int linenoiseHistoryLoad(const char *filename) {
1535     FILE *fp = fopen(filename,"r");
1536     char buf[LINENOISE_MAX_LINE];
1537
1538     if (fp == NULL) return -1;
1539
1540     while (fgets(buf,LINENOISE_MAX_LINE,fp) != NULL) {
1541         char *src, *dest;
1542
1543         /* Decode backslash escaped values */
1544         for (src = dest = buf; *src; src++) {
1545             char ch = *src;
1546
1547             if (ch == '\\') {
1548                 src++;
1549                 if (*src == 'n') {
1550                     ch = '\n';
1551                 }
1552                 else if (*src == 'r') {
1553                     ch = '\r';
1554                 } else {
1555                     ch = *src;
1556                 }
1557             }
1558             *dest++ = ch;
1559         }
1560         /* Remove trailing newline */
1561         if (dest != buf && (dest[-1] == '\n' || dest[-1] == '\r')) {
1562             dest--;
1563         }
1564         *dest = 0;
1565
1566         linenoiseHistoryAdd(buf);
1567     }
1568     fclose(fp);
1569     return 0;
1570 }
1571
1572 /* Provide access to the history buffer.
1573  *
1574  * If 'len' is not NULL, the length is stored in *len.
1575  */
1576 char **linenoiseHistory(int *len) {
1577     if (len) {
1578         *len = history_len;
1579     }
1580     return history;
1581 }