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