1 /*
2  * linehistory.c
3  *
4  * linehistory is forked from linenoise; the original version
5  * is available from https://github.com/antirez/linenoise
6  *
7  * ------------------------------------------------------------------------
8  *
9  * Copyright (c) 2010-2016, Salvatore Sanfilippo <antirez at gmail dot com>
10  * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
11  * Copyright (c) 2021 The DPS8M Development Team
12  *
13  * All rights reserved.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions are
17  * met:
18  *
19  *  *  Redistributions of source code must retain the above copyright
20  *     notice, this list of conditions and the following disclaimer.
21  *
22  *  *  Redistributions in binary form must reproduce the above copyright
23  *     notice, this list of conditions and the following disclaimer in the
24  *     documentation and/or other materials provided with the distribution.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #ifndef _POSIX_C_SOURCE
40 # define _POSIX_C_SOURCE 200809L
41 #endif /* ifndef _POSIX_C_SOURCE */
42 
43 #if !defined( __MINGW32__ )    \
44   && !defined( CROSS_MINGW32 ) \
45   && !defined( CROSS_MINGW64 ) \
46   && !defined( __MINGW64__ )   \
47   && !defined( _MSC_VER )      \
48   && !defined( _MSC_BUILD )
49 
50 # if defined( __sun ) && defined( __SVR4 )
51 #  ifndef __EXTENSIONS__
52 #   define __EXTENSIONS__ 1
53 #  endif /* ifndef __EXTENSIONS__ */
54 # endif /* if defined( __sun ) && defined( __SVR4 ) */
55 # include <termios.h>
56 # if defined( __sun ) && defined( __SVR4 )
57 #  include <sys/termiox.h>
58 # endif /* if defined( __sun ) && defined( __SVR4 ) */
59 # include "linehistory.h"
60 # include <ctype.h>
61 # include <errno.h>
62 # include <stdio.h>
63 # include <stdlib.h>
64 # include <string.h>
65 # include <strings.h>
66 # include <sys/ioctl.h>
67 # include <sys/stat.h>
68 # include <sys/types.h>
69 # include <unistd.h>
70 
71 # define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
72 # define LINENOISE_MAX_LINE 4096
73 
74 static char *unsupported_term[] = {
75   "dumb", "cons25", "emacs", NULL
76 };
77 
78 # ifdef LH_COMPLETION
79 static linenoiseCompletionCallback *completionCallback = NULL;
80 # endif /* ifdef LH_COMPLETION */
81 
82 # ifdef LH_HINTS
83 static linenoiseHintsCallback *hintsCallback = NULL;
84 static linenoiseFreeHintsCallback *freeHintsCallback = NULL;
85 # endif /* ifdef LH_HINTS */
86 
87 static struct termios orig_termios; /* In order to restore at exit.*/
88 
89 # ifdef LH_MASKMODE
90 static int maskmode = 0; /* Show "***" instead of input. For passwords. */
91 # endif /* ifdef LH_MASKMODE */
92 
93 static int rawmode = 0;
94 static int mlmode = 0; /* Multi line mode. Default is single line. */
95 static int atexit_registered = 0; /* Register atexit just 1 time. */
96 static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
97 static int history_len = 0;
98 static char **history = NULL;
99 
100 /*
101  * The linenoiseState structure represents the state during line editing.
102  * We pass this state to functions implementing specific editing
103  * functionalities.
104  */
105 
106 struct linenoiseState
107 {
108   int ifd;            /* Terminal stdin file descriptor. */
109   int ofd;            /* Terminal stdout file descriptor. */
110   char *buf;          /* Edited line buffer. */
111   size_t buflen;      /* Edited line buffer size. */
112   const char *prompt; /* Prompt to display. */
113   size_t plen;        /* Prompt length. */
114   size_t pos;         /* Current cursor position. */
115   size_t oldpos;      /* Previous refresh cursor position. */
116   size_t len;         /* Current edited line length. */
117   size_t cols;        /* Number of columns in terminal. */
118   size_t maxrows;     /* Maximum num of rows used so far (multiline mode) */
119   int history_index;  /* The history index we are currently editing. */
120 };
121 
122 enum KEY_ACTION
123 {
124   KEY_NULL  = 0,  /* NULL      */
125   CTRL_A    = 1,  /* Ctrl-A    */
126   CTRL_B    = 2,  /* Ctrl-B    */
127   CTRL_C    = 3,  /* Ctrl-C    */
128   CTRL_D    = 4,  /* Ctrl-D    */
129   CTRL_E    = 5,  /* Ctrl-E    */
130   CTRL_F    = 6,  /* Ctrl-F    */
131   CTRL_H    = 8,  /* Ctrl-H    */
132   TAB       = 9,  /* Tab       */
133   CTRL_K    = 11, /* Ctrl-K    */
134   CTRL_L    = 12, /* Ctrl-L    */
135   ENTER     = 13, /* Enter     */
136   CTRL_N    = 14, /* Ctrl-N    */
137   CTRL_P    = 16, /* Ctrl-P    */
138   CTRL_T    = 20, /* Ctrl-T    */
139   CTRL_U    = 21, /* Ctrl-U    */
140   CTRL_W    = 23, /* Ctrl-W    */
141   ESC       = 27, /* Escape    */
142   BACKSPACE = 127 /* Backspace */
143 };
144 
145 static void linenoiseAtExit(void);
146 static void refreshLine(struct linenoiseState *l);
147 size_t pstrlen(const char *s);
148 
149 # ifdef LH_MASKMODE
150 
151 /*
152  * Enable "mask mode". When it is enabled, instead of the input that
153  * the user is typing, the terminal will just display a corresponding
154  * number of asterisks, like "****". This is useful for passwords and other
155  * secrets that should not be displayed.
156  */
157 
158 void
linenoiseMaskModeEnable(void)159 linenoiseMaskModeEnable(void)
160 {
161   maskmode = 1;
162 }
163 
164 /* Disable mask mode. */
165 void
linenoiseMaskModeDisable(void)166 linenoiseMaskModeDisable(void)
167 {
168   maskmode = 0;
169 }
170 # endif /* ifdef LH_MASKMODE */
171 
172 /* Set if to use or not the multi line mode. */
173 void
linenoiseSetMultiLine(int ml)174 linenoiseSetMultiLine(int ml)
175 {
176   mlmode = ml;
177 }
178 
179 /*
180  * Return true if the terminal name is in the list of terminals we know are
181  * not able to understand basic escape sequences.
182  */
183 
184 static int
isUnsupportedTerm(void)185 isUnsupportedTerm(void)
186 {
187   char *term = getenv("TERM");
188   int j;
189 
190   if (term == NULL)
191   {
192     return ( 0 );
193   }
194 
195   for (j = 0; unsupported_term[j]; j++)
196   {
197     if (!strcasecmp(term, unsupported_term[j]))
198     {
199       return ( 1 );
200     }
201   }
202 
203   return ( 0 );
204 }
205 
206 /* Raw mode */
207 static int
enableRawMode(int fd)208 enableRawMode(int fd)
209 {
210   struct termios raw;
211 
212   if (!isatty(STDIN_FILENO))
213   {
214     goto fatal;
215   }
216 
217   if (!atexit_registered)
218   {
219     atexit(linenoiseAtExit);
220     atexit_registered = 1;
221   }
222 
223   if (tcgetattr(fd, &orig_termios) == -1)
224   {
225     goto fatal;
226   }
227 
228   raw = orig_termios; /* modify the original mode */
229   /* input modes: no break, no CR to NL, no parity check, no strip char,
230    * no start/stop output control. */
231   raw.c_iflag &= ~( BRKINT | ICRNL | INPCK | ISTRIP | IXON );
232   /* control modes - set 8 bit chars */
233   raw.c_cflag |= ( CS8 );
234   /* local modes - choing off, canonical off, no extended functions,
235    * no signal chars (^Z,^C) */
236   raw.c_lflag &= ~( ECHO | ICANON | IEXTEN | ISIG );
237   /* control chars - set return condition: min number of bytes and timer.
238    * We want read to return every single byte, without timeout. */
239   raw.c_cc[VMIN] = 1;
240   raw.c_cc[VTIME] = 0; /* 1 byte, no timer */
241 
242   /* put terminal in raw mode after flushing */
243   if (tcsetattr(fd, TCSAFLUSH, &raw) < 0)
244   {
245     goto fatal;
246   }
247 
248   rawmode = 1;
249   return ( 0 );
250 
251 fatal:
252   errno = ENOTTY;
253   return ( -1 );
254 }
255 
256 static void
disableRawMode(int fd)257 disableRawMode(int fd)
258 {
259   /* Don't even check the return value as it's too late. */
260   if (rawmode && tcsetattr(fd, TCSAFLUSH, &orig_termios) != -1)
261   {
262     rawmode = 0;
263   }
264 }
265 
266 /*
267  * Use the ESC [6n escape sequence to query the horizontal cursor position
268  * and return it. On error -1 is returned, on success the position of the
269  * cursor.
270  */
271 
272 static int
getCursorPosition(int ifd,int ofd)273 getCursorPosition(int ifd, int ofd)
274 {
275   char buf[32];
276   int cols, rows;
277   unsigned int i = 0;
278 
279   /* Report cursor location */
280   if (write(ofd, "\x1b[6n", 4) != 4)
281   {
282     return ( -1 );
283   }
284 
285   /* Read the response: ESC [ rows ; cols R */
286   while (i < sizeof ( buf ) - 1)
287   {
288     if (read(ifd, buf + i, 1) != 1)
289     {
290       break;
291     }
292 
293     if (buf[i] == 'R')
294     {
295       break;
296     }
297 
298     i++;
299   }
300   buf[i] = '\0';
301 
302   /* Parse it. */
303   if (buf[0] != ESC || buf[1] != '[')
304   {
305     return ( -1 );
306   }
307 
308   if (sscanf(buf + 2, "%d;%d", &rows, &cols) != 2)
309   {
310     return ( -1 );
311   }
312 
313   return ( cols );
314 }
315 
316 /* Try to get the number of columns in terminal, or assume 80 */
317 static int
getColumns(int ifd,int ofd)318 getColumns(int ifd, int ofd)
319 {
320   struct winsize ws;
321 
322   if (ioctl(1, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0)
323   {
324     /* ioctl() failed. Try to query the terminal itself. */
325     int start, cols;
326 
327     /* Get the initial position so we can restore it later. */
328     start = getCursorPosition(ifd, ofd);
329     if (start == -1)
330     {
331       goto failed;
332     }
333 
334     /* Go to right margin and get position. */
335     if (write(ofd, "\x1b[999C", 6) != 6)
336     {
337       goto failed;
338     }
339 
340     cols = getCursorPosition(ifd, ofd);
341     if (cols == -1)
342     {
343       goto failed;
344     }
345 
346     /* Restore position. */
347     if (cols > start)
348     {
349       char seq[32];
350       snprintf(seq, sizeof ( seq ), "\x1b[%dD", cols - start);
351       if (write(ofd, seq, strlen(seq)) == -1)
352       { /* Can't recover... */
353       }
354     }
355 
356     return ( cols );
357   }
358   else
359   {
360     return ( ws.ws_col );
361   }
362 
363 failed:
364   return ( 80 );
365 }
366 
367 /* Clear the screen. Used to handle ctrl+l */
368 void
linenoiseClearScreen(void)369 linenoiseClearScreen(void)
370 {
371   if (write(STDOUT_FILENO, "\x1b[H\x1b[2J", 7) <= 0)
372   { /* nothing to do, just to avoid warning. */
373   }
374 }
375 
376 # ifdef LH_COMPLETION
377 
378 /*
379  * Beep, used for completion when there is nothing to complete or when all
380  * the choices were already shown.
381  */
382 
383 static void
linenoiseBeep(void)384 linenoiseBeep(void)
385 {
386   fprintf(stderr, "\x7");
387   fflush(stderr);
388 }
389 
390 /* Free a list of completion option populated by linenoiseAddCompletion(). */
391 static void
freeCompletions(const linenoiseCompletions * lc)392 freeCompletions(const linenoiseCompletions *lc)
393 {
394   size_t i;
395 
396   for (i = 0; i < lc->len; i++)
397   {
398     free(lc->cvec[i]);
399   }
400 
401   if (lc->cvec != NULL)
402   {
403     free(lc->cvec);
404   }
405 }
406 
407 /*
408  * This is an helper function for linenoiseEdit() and is called when the
409  * user types the <tab> key in order to complete the string currently in the
410  * input.
411  *
412  * The state of the editing is encapsulated into the pointed linenoiseState
413  * structure as described in the structure definition.
414  */
415 
416 static int
completeLine(struct linenoiseState * ls)417 completeLine(struct linenoiseState *ls)
418 {
419   linenoiseCompletions lc = {
420     0, NULL
421   };
422   int nread, nwritten;
423   char c = 0;
424 
425   completionCallback(ls->buf, &lc);
426   if (lc.len == 0)
427   {
428     linenoiseBeep();
429   }
430   else
431   {
432     size_t stop = 0, i = 0;
433 
434     while (!stop)
435     {
436       /* Show completion or original buffer */
437       if (i < lc.len)
438       {
439         struct linenoiseState saved = *ls;
440 
441         ls->len = ls->pos = strlen(lc.cvec[i]);
442         ls->buf = lc.cvec[i];
443         refreshLine(ls);
444         ls->len = saved.len;
445         ls->pos = saved.pos;
446         ls->buf = saved.buf;
447       }
448       else
449       {
450         refreshLine(ls);
451       }
452 
453       nread = read(ls->ifd, &c, 1);
454       if (nread <= 0)
455       {
456         freeCompletions(&lc);
457         return ( -1 );
458       }
459 
460       switch (c)
461       {
462       case 9: /* Tab */
463         i = ( i + 1 ) % ( lc.len + 1 );
464         if (i == lc.len)
465         {
466           linenoiseBeep();
467         }
468 
469         stop = 1;
470         break;
471 
472       default:
473         /* Update buffer and return */
474         if (i < lc.len)
475         {
476           nwritten = snprintf(ls->buf, ls->buflen, "%s", lc.cvec[i]);
477           ls->len = ls->pos = nwritten;
478         }
479 
480         stop = 1;
481         break;
482       }
483     }
484   }
485 
486   freeCompletions(&lc);
487   return ( c ); /* Return last read character */
488 }
489 
490 /* Register a callback function to be called for tab-completion. */
491 void
linenoiseSetCompletionCallback(linenoiseCompletionCallback * fn)492 linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn)
493 {
494   completionCallback = fn;
495 }
496 
497 # endif /* ifdef LH_COMPLETION */
498 
499 # ifdef LH_HINTS
500 
501 /*
502  * Register a hits function to be called to show hits to the user at the
503  * right of the prompt.
504  */
505 
506 void
linenoiseSetHintsCallback(linenoiseHintsCallback * fn)507 linenoiseSetHintsCallback(linenoiseHintsCallback *fn)
508 {
509   hintsCallback = fn;
510 }
511 
512 /*
513  * Register a function to free the hints returned by the hints callback
514  * registered with linenoiseSetHintsCallback().
515  */
516 
517 void
linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback * fn)518 linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *fn)
519 {
520   freeHintsCallback = fn;
521 }
522 
523 # endif /* ifdef LH_HINTS */
524 
525 # ifdef LH_COMPLETION
526 
527 /*
528  * This function is used by the callback function registered by the user
529  * in order to add completion options given the input string when the
530  * user typed <tab>.
531  */
532 
533 void
linenoiseAddCompletion(linenoiseCompletions * lc,const char * str)534 linenoiseAddCompletion(linenoiseCompletions *lc, const char *str)
535 {
536   size_t len = strlen(str);
537   char *copy, **cvec;
538 
539   copy = malloc(len + 1);
540   if (copy == NULL)
541   {
542     return;
543   }
544 
545   memcpy(copy, str, len + 1);
546   cvec = realloc(lc->cvec, sizeof ( char * ) * ( lc->len + 1 ));
547   if (cvec == NULL)
548   {
549     free(copy);
550     return;
551   }
552 
553   lc->cvec = cvec;
554   lc->cvec[lc->len++] = copy;
555 }
556 
557 # endif /* ifdef LH_COMPLETION */
558 
559 /*
560  * We define a very simple "append buffer" structure, that is an heap
561  * allocated string where we can append to. This is useful in order to
562  * write all the escape sequences in a buffer and flush them to the standard
563  * output in a single call, to avoid flickering effects.
564  */
565 
566 struct abuf
567 {
568   char *b;
569   int len;
570 };
571 
572 static void
abInit(struct abuf * ab)573 abInit(struct abuf *ab)
574 {
575   ab->b = NULL;
576   ab->len = 0;
577 }
578 
579 static void
abAppend(struct abuf * ab,const char * s,int len)580 abAppend(struct abuf *ab, const char *s, int len)
581 {
582   if (len <= 0)
583   {
584     return;
585   }
586 
587   char *new = realloc(ab->b, ab->len + len);
588 
589   if (new == NULL)
590   {
591     return;
592   }
593 
594   memcpy(new + ab->len, s, len);
595   ab->b = new;
596   ab->len += len;
597 }
598 
599 static void
abFree(const struct abuf * ab)600 abFree(const struct abuf *ab)
601 {
602   free(ab->b);
603 }
604 
605 # ifdef LH_HINTS
606 
607 /*
608  * Helper of refreshSingleLine() and refreshMultiLine() to show hints
609  * to the right of the prompt.
610  */
611 
612 static void
refreshShowHints(struct abuf * ab,const struct linenoiseState * l,int plen)613 refreshShowHints(struct abuf *ab, const struct linenoiseState *l, int plen)
614 {
615   char seq[64];
616 
617   seq[0] = '\0';
618   if (hintsCallback && plen + l->len < l->cols)
619   {
620     int color = -1, bold = 0;
621     char *hint = hintsCallback(l->buf, &color, &bold);
622     if (hint)
623     {
624       int hintlen = strlen(hint);
625       int hintmaxlen = l->cols - ( plen + l->len );
626       if (hintlen > hintmaxlen)
627       {
628         hintlen = hintmaxlen;
629       }
630 
631       if (bold == 1 && color == -1)
632       {
633         color = 37;
634       }
635 
636       if (color != -1 || bold != 0)
637       {
638         snprintf(seq, sizeof ( seq ), "\033[%d;%d;49m", bold, color);
639       }
640       else
641       {
642         seq[0] = '\0';
643       }
644 
645       abAppend(ab, seq, strlen(seq));
646       abAppend(ab, hint, hintlen);
647       if (color != -1 || bold != 0)
648       {
649         abAppend(ab, "\033[0m", 4);
650       }
651 
652       /* Call the function to free the hint returned. */
653       if (freeHintsCallback)
654       {
655         freeHintsCallback(hint);
656       }
657     }
658   }
659 }
660 
661 # endif /* ifdef LH_HINTS */
662 
663 /*
664  * Single line low level line refresh.
665  *
666  * Rewrite the currently edited line accordingly to the buffer content,
667  * cursor position, and number of columns of the terminal.
668  */
669 
670 static void
refreshSingleLine(const struct linenoiseState * l)671 refreshSingleLine(const struct linenoiseState *l)
672 {
673   char seq[64];
674   size_t plen = pstrlen(l->prompt);
675   int fd = l->ofd;
676   char *buf = l->buf;
677   size_t len = l->len;
678   size_t pos = l->pos;
679   struct abuf ab;
680 
681   while (( plen + pos ) >= l->cols)
682   {
683     buf++;
684     len--;
685     pos--;
686   }
687   while (plen + len > l->cols)
688   {
689     len--;
690   }
691 
692   abInit(&ab);
693   /* Cursor to left edge */
694   snprintf(seq, sizeof ( seq ), "\r");
695   abAppend(&ab, seq, strlen(seq));
696   /* Write the prompt and the current buffer content */
697   abAppend(&ab, l->prompt, strlen(l->prompt));
698 # ifdef LH_MASKMODE
699   if (maskmode == 1)
700   {
701     while (len--)
702     {
703       abAppend(&ab, "*", 1);
704     }
705   }
706   else
707   {
708 # endif /* ifdef LH_MASKMODE */
709   abAppend(&ab, buf, len);
710 # ifdef LH_MASKMODE
711 }
712 # endif /* ifdef LH_MASKMODE */
713 # ifdef LH_HINTS
714   /* Show hits if any. */
715   refreshShowHints(&ab, l, plen);
716 # endif /* ifdef LH_HINTS */
717   /* Erase to right */
718   snprintf(seq, sizeof ( seq ), "\x1b[0K");
719   abAppend(&ab, seq, strlen(seq));
720   /* Move cursor to original position. */
721   snprintf(seq, sizeof ( seq ), "\r\x1b[%dC", (int)( pos + plen ));
722   abAppend(&ab, seq, strlen(seq));
723   if (write(fd, ab.b, ab.len) == -1)
724   { /* Can't recover from write error. */
725   }
726 
727   abFree(&ab);
728 }
729 
730 /*
731  * Multi line low level line refresh.
732  *
733  * Rewrite the currently edited line accordingly to the buffer content,
734  * cursor position, and number of columns of the terminal.
735  */
736 
737 static void
refreshMultiLine(struct linenoiseState * l)738 refreshMultiLine(struct linenoiseState *l)
739 {
740   char seq[64];
741   int plen = strlen(l->prompt);
742   int rows = ( plen + l->len + l->cols - 1 )
743              / l->cols; /* rows used by current buf. */
744   int rpos = ( plen + l->oldpos + l->cols ) / l->cols; /* cursor relative row. */
745   int rpos2; /* rpos after refresh. */
746   int col; /* colum position, zero-based. */
747   int old_rows = l->maxrows;
748   int fd = l->ofd, j;
749   struct abuf ab;
750 
751   /* Update maxrows if needed. */
752   if (rows > (int)l->maxrows)
753   {
754     l->maxrows = rows;
755   }
756 
757   /*
758    * First step: clear all the lines used before. To do so start by
759    * going to the last row.
760    */
761 
762   abInit(&ab);
763   if (old_rows - rpos > 0)
764   {
765     snprintf(seq, sizeof ( seq ), "\x1b[%dB", old_rows - rpos);
766     abAppend(&ab, seq, strlen(seq));
767   }
768 
769   /* Now for every row clear it, go up. */
770   for (j = 0; j < old_rows - 1; j++)
771   {
772     snprintf(seq, sizeof ( seq ), "\r\x1b[0K\x1b[1A");
773     abAppend(&ab, seq, strlen(seq));
774   }
775 
776   /* Clean the top line. */
777   snprintf(seq, sizeof ( seq ), "\r\x1b[0K");
778   abAppend(&ab, seq, strlen(seq));
779 
780   /* Write the prompt and the current buffer content */
781   abAppend(&ab, l->prompt, strlen(l->prompt));
782 # ifdef LH_MASKMODE
783   if (maskmode == 1)
784   {
785     unsigned int i;
786     for (i = 0; i < l->len; i++)
787     {
788       abAppend(&ab, "*", 1);
789     }
790   }
791   else
792   {
793 # endif /* ifdef LH_MASKMODE */
794   abAppend(&ab, l->buf, l->len);
795 # ifdef LH_MASKMODE
796 }
797 # endif /* ifdef LH_MASKMODE */
798 
799 # ifdef LH_HINTS
800   /* Show hits if any. */
801   refreshShowHints(&ab, l, plen);
802 # endif /* ifdef LH_HINTS */
803 
804   /*
805    * If we are at the very end of the screen with our prompt, we need to
806    * emit a newline and move the prompt to the first column.
807    */
808 
809   if (l->pos && l->pos == l->len && ( l->pos + plen ) % l->cols == 0)
810   {
811     abAppend(&ab, "\n", 1);
812     snprintf(seq, sizeof ( seq ), "\r");
813     abAppend(&ab, seq, strlen(seq));
814     rows++;
815     if (rows > (int)l->maxrows)
816     {
817       l->maxrows = rows;
818     }
819   }
820 
821   /* Move cursor to right position. */
822   rpos2 = ( plen + l->pos + l->cols ) / l->cols;
823 
824   /* Go up till we reach the expected positon. */
825   if (rows - rpos2 > 0)
826   {
827     snprintf(seq, sizeof ( seq ), "\x1b[%dA", rows - rpos2);
828     abAppend(&ab, seq, strlen(seq));
829   }
830 
831   /* Set column. */
832   col = ( plen + (int)l->pos ) % (int)l->cols;
833   if (col)
834   {
835     snprintf(seq, sizeof ( seq ), "\r\x1b[%dC", col);
836   }
837   else
838   {
839     snprintf(seq, sizeof ( seq ), "\r");
840   }
841 
842   abAppend(&ab, seq, strlen(seq));
843 
844   l->oldpos = l->pos;
845 
846   if (write(fd, ab.b, ab.len) == -1)
847   { /* Can't recover from write error. */
848   }
849 
850   abFree(&ab);
851 }
852 
853 /*
854  * Calls the two low level functions refreshSingleLine() or
855  * refreshMultiLine() according to the selected mode.
856  */
857 
858 static void
refreshLine(struct linenoiseState * l)859 refreshLine(struct linenoiseState *l)
860 {
861   l->cols = getColumns(STDIN_FILENO, STDOUT_FILENO);
862   if (mlmode)
863   {
864     refreshMultiLine(l);
865   }
866   else
867   {
868     refreshSingleLine(l);
869   }
870 }
871 
872 /*
873  * Insert the character 'c' at cursor current position.
874  * On error writing to the terminal -1 is returned, otherwise 0.
875  */
876 
877 int
linenoiseEditInsert(struct linenoiseState * l,char c)878 linenoiseEditInsert(struct linenoiseState *l, char c)
879 {
880   if (l->len < l->buflen)
881   {
882     if (l->len == l->pos)
883     {
884       l->buf[l->pos] = c;
885       l->pos++;
886       l->len++;
887       l->buf[l->len] = '\0';
888 # if defined( LH_MASKMODE ) && defined( LH_HINTS )
889       if (( !mlmode && l->plen + l->len < l->cols && !hintsCallback ))
890       {
891         /* Avoid a full update of the line in the trivial case. */
892         char d = ( maskmode == 1 ) ? '*' : (char)c;
893         if (write(l->ofd, &d, 1) == -1)
894         {
895           return ( -1 );
896         }
897       }
898       else
899       {
900 # endif /* if defined( LH_MASKMODE ) && defined( LH_HINTS ) */
901       refreshLine(l);
902 # if defined( LH_MASKMODE ) && defined( LH_HINTS )
903       }
904 # endif /* if defined( LH_MASKMODE ) && defined( LH_HINTS ) */
905     }
906     else
907     {
908       memmove(l->buf + l->pos + 1, l->buf + l->pos, l->len - l->pos);
909       l->buf[l->pos] = c;
910       l->len++;
911       l->pos++;
912       l->buf[l->len] = '\0';
913       refreshLine(l);
914     }
915   }
916 
917   return ( 0 );
918 }
919 
920 /* Move cursor on the left. */
921 void
linenoiseEditMoveLeft(struct linenoiseState * l)922 linenoiseEditMoveLeft(struct linenoiseState *l)
923 {
924   if (l->pos > 0)
925   {
926     l->pos--;
927     refreshLine(l);
928   }
929 }
930 
931 /* Move cursor on the right. */
932 void
linenoiseEditMoveRight(struct linenoiseState * l)933 linenoiseEditMoveRight(struct linenoiseState *l)
934 {
935   if (l->pos != l->len)
936   {
937     l->pos++;
938     refreshLine(l);
939   }
940 }
941 
942 /* Move cursor to the end of the current word. */
943 void
linenoiseEditMoveWordEnd(struct linenoiseState * l)944 linenoiseEditMoveWordEnd(struct linenoiseState *l)
945 {
946   if (l->len == 0 || l->pos >= l->len)
947   {
948     return;
949   }
950 
951   if (l->buf[l->pos] == ' ')
952   {
953     while (l->pos < l->len && l->buf[l->pos] == ' ')
954     {
955       ++l->pos;
956     }
957   }
958 
959   while (l->pos < l->len && l->buf[l->pos] != ' ')
960   {
961     ++l->pos;
962   }
963   refreshLine(l);
964 }
965 
966 /* Move cursor to the start of the current word. */
967 void
linenoiseEditMoveWordStart(struct linenoiseState * l)968 linenoiseEditMoveWordStart(struct linenoiseState *l)
969 {
970   if (l->len == 0)
971   {
972     return;
973   }
974 
975   if (l->buf[l->pos - 1] == ' ')
976   {
977     --l->pos;
978   }
979 
980   if (l->buf[l->pos] == ' ')
981   {
982     while (l->pos > 0 && l->buf[l->pos] == ' ')
983     {
984       --l->pos;
985     }
986   }
987 
988   while (l->pos > 0 && l->buf[l->pos - 1] != ' ')
989   {
990     --l->pos;
991   }
992   refreshLine(l);
993 }
994 
995 /* Move cursor to the start of the line. */
996 void
linenoiseEditMoveHome(struct linenoiseState * l)997 linenoiseEditMoveHome(struct linenoiseState *l)
998 {
999   if (l->pos != 0)
1000   {
1001     l->pos = 0;
1002     refreshLine(l);
1003   }
1004 }
1005 
1006 /* Move cursor to the end of the line. */
1007 void
linenoiseEditMoveEnd(struct linenoiseState * l)1008 linenoiseEditMoveEnd(struct linenoiseState *l)
1009 {
1010   if (l->pos != l->len)
1011   {
1012     l->pos = l->len;
1013     refreshLine(l);
1014   }
1015 }
1016 
1017 /*
1018  * Substitute the currently edited line with the next
1019  * or previous history entry as specified by 'dir'.
1020  */
1021 
1022 # define LINENOISE_HISTORY_NEXT 0
1023 # define LINENOISE_HISTORY_PREV 1
1024 void
linenoiseEditHistoryNext(struct linenoiseState * l,int dir)1025 linenoiseEditHistoryNext(struct linenoiseState *l, int dir)
1026 {
1027   if (history_len > 1)
1028   {
1029 
1030     /*
1031      * Update the current history entry before to
1032      * overwrite it with the next one.
1033      */
1034 
1035     free(history[history_len - 1 - l->history_index]);
1036     history[history_len - 1 - l->history_index] = strdup(l->buf);
1037     /* Show the new entry */
1038     l->history_index += ( dir == LINENOISE_HISTORY_PREV ) ? 1 : -1;
1039     if (l->history_index < 0)
1040     {
1041       l->history_index = 0;
1042       return;
1043     }
1044     else if (l->history_index >= history_len)
1045     {
1046       l->history_index = history_len - 1;
1047       return;
1048     }
1049 
1050     strncpy(l->buf, history[history_len - 1 - l->history_index], l->buflen);
1051     l->buf[l->buflen - 1] = '\0';
1052     l->len = l->pos = strlen(l->buf);
1053     refreshLine(l);
1054   }
1055 }
1056 
1057 /*
1058  * Search a line in history that start with the same characters as the
1059  * currently edited line. Substitue the current line with this history
1060  */
1061 
1062 # define LINENOISE_SEARCH_HISTORY_FORWARD 0
1063 # define LINENOISE_SEARCH_HISTROY_REVERSE 1
1064 void
linenoiseSearchInHistory(struct linenoiseState * l,int direction)1065 linenoiseSearchInHistory(struct linenoiseState *l, int direction)
1066 {
1067   if (history_len > 1)
1068   {
1069 
1070     /*
1071      * Update the current history entry before to
1072      * overwrite it with the next one.
1073      */
1074 
1075     free(history[history_len - 1 - l->history_index]);
1076     history[history_len - 1 - l->history_index] = strdup(l->buf);
1077 
1078     /* Search new entry */
1079     int cnt;
1080     if (direction == LINENOISE_SEARCH_HISTORY_FORWARD)
1081     {
1082       cnt = history_len - 2 - l->history_index;
1083       for (; cnt >= 0; cnt--)
1084       {
1085 
1086         /*
1087          * Search a history entry that start with same
1088          * as the current line until the curser position
1089          */
1090 
1091         if (strncmp(l->buf, history[cnt], l->pos) == 0)
1092         {
1093           strncpy(l->buf, history[cnt], l->buflen);
1094           l->buf[l->buflen - 1] = '\0';
1095           /* Don't change old curser postion */
1096           l->len = strlen(l->buf);
1097 
1098           /*
1099            * Set history index so that we can contiune
1100            * the search on this postiion
1101            */
1102 
1103           l->history_index = history_len - 1 - cnt;
1104           refreshLine(l);
1105           return;
1106         }
1107       }
1108     }
1109     else if (direction == LINENOISE_SEARCH_HISTROY_REVERSE)
1110     {
1111       cnt = history_len - l->history_index;
1112       for (; cnt < history_len; cnt++)
1113       {
1114 
1115         /*
1116          * Search a history entry that start with same
1117          * as the current line until the curser position
1118          */
1119 
1120         if (strncmp(l->buf, history[cnt], l->pos) == 0)
1121         {
1122           strncpy(l->buf, history[cnt], l->buflen);
1123           l->buf[l->buflen - 1] = '\0';
1124           /* Don't change old curser position */
1125           l->len = strlen(l->buf);
1126 
1127           /*
1128            * Set history index so that we can contiune
1129            * the search on this postiion
1130            */
1131 
1132           l->history_index = history_len - 1 - cnt;
1133           refreshLine(l);
1134           return;
1135         }
1136       }
1137     }
1138   }
1139 }
1140 
1141 /*
1142  * Delete the character at the right of the cursor without altering the cursor
1143  * position. Basically this is what happens with the "Delete" keyboard key.
1144  */
1145 
1146 void
linenoiseEditDelete(struct linenoiseState * l)1147 linenoiseEditDelete(struct linenoiseState *l)
1148 {
1149   if (l->len > 0 && l->pos < l->len)
1150   {
1151     memmove(l->buf + l->pos, l->buf + l->pos + 1, l->len - l->pos - 1);
1152     l->len--;
1153     l->buf[l->len] = '\0';
1154     refreshLine(l);
1155   }
1156 }
1157 
1158 /* Backspace implementation. */
1159 void
linenoiseEditBackspace(struct linenoiseState * l)1160 linenoiseEditBackspace(struct linenoiseState *l)
1161 {
1162   if (l->pos > 0 && l->len > 0)
1163   {
1164     memmove(l->buf + l->pos - 1, l->buf + l->pos, l->len - l->pos);
1165     l->pos--;
1166     l->len--;
1167     l->buf[l->len] = '\0';
1168     refreshLine(l);
1169   }
1170 }
1171 
1172 /*
1173  * Delete the previosu word, maintaining the
1174  * cursor at the start of the current word.
1175  */
1176 
1177 void
linenoiseEditDeletePrevWord(struct linenoiseState * l)1178 linenoiseEditDeletePrevWord(struct linenoiseState *l)
1179 {
1180   size_t old_pos = l->pos;
1181   size_t diff;
1182 
1183   while (l->pos > 0 && l->buf[l->pos - 1] == ' ')
1184   {
1185     l->pos--;
1186   }
1187   while (l->pos > 0 && l->buf[l->pos - 1] != ' ')
1188   {
1189     l->pos--;
1190   }
1191   diff = old_pos - l->pos;
1192   memmove(l->buf + l->pos, l->buf + old_pos, l->len - old_pos + 1);
1193   l->len -= diff;
1194   refreshLine(l);
1195 }
1196 
1197 /* Delete the next word, maintaining the cursor at the same position */
1198 void
linenoiseEditDeleteNextWord(struct linenoiseState * l)1199 linenoiseEditDeleteNextWord(struct linenoiseState *l)
1200 {
1201   size_t next_word_end = l->pos;
1202 
1203   while (next_word_end < l->len && l->buf[next_word_end] == ' ')
1204   {
1205     ++next_word_end;
1206   }
1207   while (next_word_end < l->len && l->buf[next_word_end] != ' ')
1208   {
1209     ++next_word_end;
1210   }
1211   memmove(l->buf + l->pos, l->buf + next_word_end, l->len - next_word_end);
1212   l->len -= next_word_end - l->pos;
1213   refreshLine(l);
1214 }
1215 
1216 /*
1217  * This function is the core of the line editing capability of linenoise.
1218  * It expects 'fd' to be already in "raw mode" so that every key pressed
1219  * will be returned ASAP to read().
1220  *
1221  * The resulting string is put into 'buf' when the user type enter, or
1222  * when ctrl+d is typed.
1223  *
1224  * The function returns the length of the current buffer.
1225  */
1226 
1227 static int
linenoiseEdit(int stdin_fd,int stdout_fd,char * buf,size_t buflen,const char * prompt)1228 linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen,
1229               const char *prompt)
1230 {
1231   struct linenoiseState l;
1232 
1233   /*
1234    * Populate the linenoise state that we pass to functions implementing
1235    * specific editing functionalities.
1236    */
1237 
1238   l.ifd = stdin_fd;
1239   l.ofd = stdout_fd;
1240   l.buf = buf;
1241   l.buflen = buflen;
1242   l.prompt = prompt;
1243   l.plen = pstrlen(prompt);
1244   l.oldpos = l.pos = 0;
1245   l.len = 0;
1246   l.cols = getColumns(stdin_fd, stdout_fd);
1247   l.maxrows = 0;
1248   l.history_index = 0;
1249 
1250   /* Buffer starts empty. */
1251   l.buf[0] = '\0';
1252   l.buflen--; /* Make sure there is always space for the nulterm */
1253 
1254   /*
1255    * The latest history entry is always our current
1256    * buffer, that initially is just an empty string.
1257    */
1258 
1259   (void)linenoiseHistoryAdd("");
1260 
1261   if (write(l.ofd, prompt, strlen(prompt)) == -1)
1262   {
1263     return ( -1 );
1264   }
1265 
1266   while (1)
1267   {
1268     signed char c;
1269     int nread;
1270     char seq[3];
1271 
1272     nread = read(l.ifd, &c, 1);
1273     if (nread <= 0)
1274     {
1275       return ( l.len );
1276     }
1277 
1278 # ifdef LH_COMPLETION
1279 
1280     /*
1281      * Only autocomplete when the callback is set. It returns < 0 when
1282      * there was an error reading from fd. Otherwise it will return the
1283      * character that should be handled next.
1284      */
1285 
1286     if (c == 9 && completionCallback != NULL)
1287     {
1288       int cint = completeLine(&l);
1289       /* Return on errors */
1290       if (cint < 0)
1291       {
1292         return ( l.len );
1293       }
1294 
1295       /* Read next character when 0 */
1296       if (cint == 0)
1297       {
1298         continue;
1299       }
1300 
1301       c = (char)cint;
1302     }
1303 
1304 # endif /* ifdef LH_COMPLETION */
1305 
1306     switch (c)
1307     {
1308     case 9:
1309       break;    /* johnsonjh - disable processing of tabs */
1310 
1311     case ENTER: /* Enter */
1312       history_len--;
1313       free(history[history_len]);
1314       if (mlmode)
1315       {
1316         linenoiseEditMoveEnd(&l);
1317       }
1318 
1319 # ifdef LH_HINTS
1320       if (hintsCallback)
1321       {
1322 
1323         /*
1324          * Force a refresh without hints to leave the previous
1325          * line as the user typed it after a newline.
1326          */
1327 
1328         linenoiseHintsCallback *hc = hintsCallback;
1329         hintsCallback = NULL;
1330         refreshLine(&l);
1331         hintsCallback = hc;
1332       }
1333 
1334 # endif /* ifdef LH_HINTS */
1335       return ((int)l.len );
1336 
1337     case CTRL_C: /* Ctrl-C */
1338       errno = EAGAIN;
1339       return ( -1 );
1340 
1341     case BACKSPACE: /* Backspace */
1342     case 8:         /* Ctrl-H */
1343       linenoiseEditBackspace(&l);
1344       break;
1345 
1346     case CTRL_D:     /* Ctrl-D, remove char at right of cursor, or */
1347       if (l.len > 0) /* if the line is empty, act as end-of-file.  */
1348       {
1349         linenoiseEditDelete(&l);
1350       }
1351       else
1352       {
1353         history_len--;
1354         free(history[history_len]);
1355         return ( -1 );
1356       }
1357 
1358       break;
1359 
1360     case CTRL_T: /* Ctrl-T */
1361       break;
1362 
1363     case CTRL_B: /* Ctrl-B */
1364       linenoiseEditMoveLeft(&l);
1365       break;
1366 
1367     case CTRL_F: /* Ctrl-F */
1368       linenoiseEditMoveRight(&l);
1369       break;
1370 
1371     case CTRL_P: /* Ctrl-P */
1372       linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV);
1373       break;
1374 
1375     case CTRL_N: /* Ctrl-N */
1376       linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT);
1377       break;
1378 
1379     case ESC: /* Escape Sequence */
1380 
1381       /*
1382        * Read the next two bytes representing the escape sequence.
1383        * Use two calls to handle slow terminals returning the two
1384        * chars at different times.
1385        */
1386 
1387       if (read(l.ifd, seq, 1) == -1)
1388       {
1389         break;
1390       }
1391 
1392       if (read(l.ifd, seq + 1, 1) == -1)
1393       {
1394         break;
1395       }
1396 
1397       /* ESC [ sequences. */
1398       if (seq[0] == '[')
1399       {
1400         if (seq[1] >= '0' && seq[1] <= '9')
1401         {
1402           /* Extended escape, read additional byte. */
1403           if (read(l.ifd, seq + 2, 1) == -1)
1404           {
1405             break;
1406           }
1407 
1408           if (seq[2] == '~')
1409           {
1410             switch (seq[1])
1411             {
1412             case '3': /* Delete */
1413               linenoiseEditDelete(&l);
1414               break;
1415 
1416             case '6': /* Page Down */
1417               linenoiseSearchInHistory(
1418                 &l,
1419                 LINENOISE_SEARCH_HISTROY_REVERSE);
1420               break;
1421 
1422             case '5': /* Page Up */
1423               linenoiseSearchInHistory(
1424                 &l,
1425                 LINENOISE_SEARCH_HISTORY_FORWARD);
1426               break;
1427             }
1428           }
1429         }
1430         else
1431         {
1432           switch (seq[1])
1433           {
1434           case 'A': /* Up */
1435             linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV);
1436             break;
1437 
1438           case 'B': /* Down */
1439             linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT);
1440             break;
1441 
1442           case 'C': /* Right */
1443             linenoiseEditMoveRight(&l);
1444             break;
1445 
1446           case 'D': /* Left */
1447             linenoiseEditMoveLeft(&l);
1448             break;
1449 
1450           case 'H': /* Home */
1451             linenoiseEditMoveHome(&l);
1452             break;
1453 
1454           case 'F': /* End */
1455             linenoiseEditMoveEnd(&l);
1456             break;
1457           }
1458         }
1459       }
1460 
1461       break;
1462 
1463     default:
1464       if (linenoiseEditInsert(&l, c))
1465       {
1466         return ( -1 );
1467       }
1468 
1469       break;
1470 
1471     case CTRL_U: /* Ctrl+U, delete the whole line. */
1472       buf[0] = '\0';
1473       l.pos = l.len = 0;
1474       refreshLine(&l);
1475       break;
1476 
1477     case CTRL_K: /* Ctrl+K, delete from current to end of line. */
1478       buf[l.pos] = '\0';
1479       l.len = l.pos;
1480       refreshLine(&l);
1481       break;
1482 
1483     case CTRL_A: /* Ctrl+A, go to the start of the line */
1484       linenoiseEditMoveHome(&l);
1485       break;
1486 
1487     case CTRL_E: /* Ctrl+E, go to the end of the line */
1488       linenoiseEditMoveEnd(&l);
1489       break;
1490 
1491     case CTRL_L: /* Ctrl+L, clear screen */
1492       linenoiseClearScreen();
1493       refreshLine(&l);
1494       break;
1495 
1496     case CTRL_W: /* Ctrl+W, delete previous word */
1497       linenoiseEditDeletePrevWord(&l);
1498       break;
1499     }
1500   }
1501 }
1502 
1503 /*
1504  * This function calls the line editing function linenoiseEdit() using
1505  * the STDIN file descriptor set in raw mode.
1506  */
1507 
1508 static int
linenoiseRaw(char * buf,size_t buflen,const char * prompt)1509 linenoiseRaw(char *buf, size_t buflen, const char *prompt)
1510 {
1511   int count;
1512 
1513   if (buflen == 0)
1514   {
1515     errno = EINVAL;
1516     return ( -1 );
1517   }
1518 
1519   if (enableRawMode(STDIN_FILENO) == -1)
1520   {
1521     return ( -1 );
1522   }
1523 
1524   count = linenoiseEdit(STDIN_FILENO, STDOUT_FILENO, buf, buflen, prompt);
1525   disableRawMode(STDIN_FILENO);
1526   printf("\n");
1527   return ( count );
1528 }
1529 
1530 /*
1531  * This function is called when linenoise() is called with the standard
1532  * input file descriptor not attached to a TTY. So for example when the
1533  * program using linenoise is called in pipe or with a file redirected
1534  * to its standard input. In this case, we want to be able to return the
1535  * line regardless of its length (by default we are limited to 4k).
1536  */
1537 
1538 static char *
linenoiseNoTTY(void)1539 linenoiseNoTTY(void)
1540 {
1541   char *line = NULL;
1542   size_t len = 0, maxlen = 0;
1543 
1544   while (1)
1545   {
1546     if (len == maxlen)
1547     {
1548       if (maxlen == 0)
1549       {
1550         maxlen = 16;
1551       }
1552 
1553       maxlen *= 2;
1554       char *oldval = line;
1555       line = realloc(line, maxlen);
1556       if (line == NULL)
1557       {
1558         if (oldval)
1559         {
1560           free(oldval);
1561         }
1562 
1563         return ( NULL );
1564       }
1565     }
1566 
1567     int c = fgetc(stdin);
1568     if (c == EOF || c == '\n')
1569     {
1570       if (c == EOF && len == 0)
1571       {
1572         free(line);
1573         return ( NULL );
1574       }
1575       else
1576       {
1577         line[len] = '\0';
1578         return ( line );
1579       }
1580     }
1581     else
1582     {
1583       line[len] = c;
1584       len++;
1585     }
1586   }
1587 }
1588 
1589 /*
1590  * The high level function that is the main API of the linenoise library.
1591  * This function checks if the terminal has basic capabilities, just checking
1592  * for a blacklist of stupid terminals, and later either calls the line
1593  * editing function or uses dummy fgets() so that you will be able to type
1594  * something even in the most desperate of the conditions.
1595  */
1596 
1597 char *
linenoise(const char * prompt)1598 linenoise(const char *prompt)
1599 {
1600   char buf[LINENOISE_MAX_LINE];
1601   int count;
1602 
1603   if (!isatty(STDIN_FILENO))
1604   {
1605 
1606     /*
1607      * Not a tty: read from file / pipe. In this mode we don't want any
1608      * limit to the line size, so we call a function to handle that.
1609      */
1610 
1611     return ( linenoiseNoTTY());
1612   }
1613   else if (isUnsupportedTerm())
1614   {
1615     size_t len;
1616 
1617     printf("%s", prompt);
1618     fflush(stdout);
1619     if (fgets(buf, LINENOISE_MAX_LINE, stdin) == NULL)
1620     {
1621       return ( NULL );
1622     }
1623 
1624     len = strlen(buf);
1625     while (len && ( buf[len - 1] == '\n' || buf[len - 1] == '\r' ))
1626     {
1627       len--;
1628       buf[len] = '\0';
1629     }
1630     return ( strdup(buf));
1631   }
1632   else
1633   {
1634     count = linenoiseRaw(buf, LINENOISE_MAX_LINE, prompt);
1635     if (count == -1)
1636     {
1637       return ( NULL );
1638     }
1639 
1640     return ( strdup(buf));
1641   }
1642 }
1643 
1644 /*
1645  * This is just a wrapper the user may want to call in order to make sure
1646  * the linenoise returned buffer is freed with the same allocator it was
1647  * created with. Useful when the main program is using an alternative
1648  * allocator.
1649  */
1650 
1651 void
linenoiseFree(void * ptr)1652 linenoiseFree(void *ptr)
1653 {
1654   free(ptr);
1655 }
1656 
1657 /*
1658  * Free the history, but does not reset it. Only used when we have to
1659  * exit() to avoid memory leaks are reported by valgrind & co.
1660  */
1661 
1662 static void
freeHistory(void)1663 freeHistory(void)
1664 {
1665   if (history)
1666   {
1667     int j;
1668 
1669     for (j = 0; j < history_len; j++)
1670     {
1671       free(history[j]);
1672     }
1673 
1674     free(history);
1675   }
1676 }
1677 
1678 /* At exit we'll try to fix the terminal to the initial conditions. */
1679 static void
linenoiseAtExit(void)1680 linenoiseAtExit(void)
1681 {
1682   disableRawMode(STDIN_FILENO);
1683   freeHistory();
1684 }
1685 
1686 /*
1687  * This is the API call to add a new entry in the linenoise history.
1688  * It uses a fixed array of char pointers that are shifted (memmoved)
1689  * when the history max length is reached in order to remove the older
1690  * entry and make room for the new one, so it is not exactly suitable for huge
1691  * histories, but will work well for a few hundred of entries.
1692  */
1693 
1694 int
linenoiseHistoryAdd(const char * line)1695 linenoiseHistoryAdd(const char *line)
1696 {
1697   char *linecopy;
1698 
1699   if (history_max_len == 0)
1700   {
1701     return ( 0 );
1702   }
1703 
1704   /* Initialization on first call. */
1705   if (history == NULL)
1706   {
1707     history = malloc(sizeof ( char * ) * history_max_len);
1708     if (history == NULL)
1709     {
1710       return ( 0 );
1711     }
1712 
1713     memset(history, 0, ( sizeof ( char * ) * history_max_len ));
1714   }
1715 
1716   /* Don't add duplicated lines. */
1717   if (( history_len > 0 ) && ( !strcmp(history[history_len - 1], line)))
1718   {
1719     return ( 0 );
1720   }
1721 
1722   /*
1723    * Add an heap allocated copy of the line in the history.
1724    * If we reached the max length, remove the older line.
1725    */
1726 
1727   linecopy = strdup(line);
1728   if (!linecopy)
1729   {
1730     return ( 0 );
1731   }
1732 
1733   if (history_len == history_max_len)
1734   {
1735     free(history[0]);
1736     memmove(
1737       history,
1738       history + 1,
1739       sizeof ( char * ) * ( history_max_len - 1 ));
1740     history_len--;
1741   }
1742 
1743   history[history_len] = linecopy;
1744   history_len++;
1745   return ( 1 );
1746 }
1747 
1748 /*
1749  * Set the maximum length for the history. This function can be called even
1750  * if there is already some history, the function will make sure to retain
1751  * just the latest 'len' elements if the new history length value is smaller
1752  * than the amount of items already inside the history.
1753  */
1754 
1755 int
linenoiseHistorySetMaxLen(int len)1756 linenoiseHistorySetMaxLen(int len)
1757 {
1758   char **new;
1759 
1760   if (len < 1)
1761   {
1762     return ( 0 );
1763   }
1764 
1765   if (history)
1766   {
1767     int tocopy = history_len;
1768 
1769     new = malloc(sizeof ( char * ) * len);
1770     if (new == NULL)
1771     {
1772       return ( 0 );
1773     }
1774 
1775     /* If we can't copy everything, free the elements we'll not use. */
1776     if (len < tocopy)
1777     {
1778       int j;
1779 
1780       for (j = 0; j < tocopy - len; j++)
1781       {
1782         free(history[j]);
1783       }
1784 
1785       tocopy = len;
1786     }
1787 
1788     memset(new, 0, sizeof ( char * ) * len);
1789     memcpy(
1790       new,
1791       history + ( history_len - tocopy ),
1792       sizeof ( char * ) * tocopy);
1793     free(history);
1794     history = new;
1795   }
1796 
1797   history_max_len = len;
1798   if (history_len > history_max_len)
1799   {
1800     history_len = history_max_len;
1801   }
1802 
1803   return ( 1 );
1804 }
1805 
1806 /* Calculate length of the prompt string as seen from a terminal. */
1807 size_t
pstrlen(const char * s)1808 pstrlen(const char *s)
1809 {
1810   size_t len = 0, i = 0;
1811 
1812   while (s[i] != '\0')
1813   {
1814     if (s[i] == '\033')
1815     {
1816       i = strpbrk(s + i, "m") - s + 1;
1817       continue;
1818     }
1819 
1820     len++;
1821     i++;
1822   }
1823   return ( len );
1824 }
1825 
1826 #endif /* if !defined( __MINGW32__ )
1827            && !defined( CROSS_MINGW32 )
1828            && !defined( CROSS_MINGW64 )
1829            && !defined( __MINGW64__ )
1830            && !defined( _MSC_VER )
1831            && !defined( _MSC_BUILD ) */
1832