diff --git a/console.c b/console.c index 74029e235..fb0808829 100644 --- a/console.c +++ b/console.c @@ -645,7 +645,7 @@ static bool cmd_maybe(const char *target, const char *src) return true; } -void completion(const char *buf, linenoiseCompletions *lc) +void completion(const char *buf, line_completions_t *lc) { if (strncmp("option ", buf, 7) == 0) { param_element_t *plist = param_list; @@ -659,7 +659,7 @@ void completion(const char *buf, linenoiseCompletions *lc) strcat(str, "option "); strcat(str, plist->name); if (cmd_maybe(str, buf)) - linenoiseAddCompletion(lc, str); + line_add_completion(lc, str); plist = plist->next; } @@ -669,7 +669,7 @@ void completion(const char *buf, linenoiseCompletions *lc) cmd_element_t *clist = cmd_list; while (clist) { if (cmd_maybe(clist->name, buf)) - linenoiseAddCompletion(lc, clist->name); + line_add_completion(lc, clist->name); clist = clist->next; } @@ -686,9 +686,9 @@ bool run_console(char *infile_name) char *cmdline; while (use_linenoise && (cmdline = linenoise(prompt))) { interpret_cmd(cmdline); - linenoiseHistoryAdd(cmdline); /* Add to the history. */ - linenoiseHistorySave(HISTORY_FILE); /* Save the history on disk. */ - linenoiseFree(cmdline); + line_history_add(cmdline); /* Add to the history. */ + line_history_save(HISTORY_FILE); /* Save the history on disk. */ + line_free(cmdline); while (buf_stack && buf_stack->fd != STDIN_FILENO) cmd_select(0, NULL, NULL, NULL, NULL); has_infile = false; diff --git a/console.h b/console.h index 67d286ba8..4bcb74de1 100644 --- a/console.h +++ b/console.h @@ -69,6 +69,6 @@ bool finish_cmd(); bool run_console(char *infile_name); /* Callback function to complete command by linenoise */ -void completion(const char *buf, linenoiseCompletions *lc); +void completion(const char *buf, line_completions_t *lc); #endif /* LAB0_CONSOLE_H */ diff --git a/linenoise.c b/linenoise.c index 13f3e4126..158f10448 100644 --- a/linenoise.c +++ b/linenoise.c @@ -89,7 +89,7 @@ * Sequence: ESC [ n B * Effect: moves cursor down of n chars. * - * When linenoiseClearScreen() is called, two additional escape sequences + * When line_clear_screen() is called, two additional escape sequences * are used in order to clear the screen and position the cursor at home * position. * @@ -105,6 +105,7 @@ #include #include +#include #include #include #include @@ -120,23 +121,25 @@ #define LINENOISE_MAX_LINE 4096 static char *unsupported_term[] = {"dumb", "cons25", "emacs", NULL}; -static linenoiseCompletionCallback *completionCallback = NULL; -static linenoiseHintsCallback *hintsCallback = NULL; -static linenoiseFreeHintsCallback *freeHintsCallback = NULL; +static line_completion_callback_t *completion_callback = NULL; +static line_hints_callback_t *hints_callback = NULL; +static line_free_hints_callback_t *free_hints_callback = NULL; static struct termios orig_termios; /* In order to restore at exit.*/ -static int maskmode = 0; /* Show "***" instead of input. For passwords. */ -static int rawmode = 0; /* For atexit() function to check if restore is needed*/ -static int mlmode = 0; /* Multi line mode. Default is single line. */ -static int atexit_registered = 0; /* Register atexit just 1 time. */ +static bool maskmode = false; /* Show "***" instead of input. For passwords. */ +static bool rawmode = + false; /* For atexit() function to check if restore is needed*/ +static bool mlmode = false; /* Multi line mode. Default is single line. */ +static bool atexit_registered = false; /* Register atexit just 1 time. */ static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN; static int history_len = 0; static char **history = NULL; -/* The linenoiseState structure represents the state during line editing. +/* The line_state structure represents the state during line editing. * We pass this state to functions implementing specific editing - * functionalities. */ -struct linenoiseState { + * functionalities. + */ +struct line_state { int ifd; /* Terminal stdin file descriptor. */ int ofd; /* Terminal stdout file descriptor. */ char *buf; /* Edited line buffer. */ @@ -173,9 +176,9 @@ enum KEY_ACTION { BACKSPACE = 127 /* Backspace */ }; -static void linenoiseAtExit(void); -int linenoiseHistoryAdd(const char *line); -static void refreshLine(struct linenoiseState *l); +static void line_atexit(void); +int line_history_add(const char *line); +static void refresh_line(struct line_state *l); /* Debugging macro. */ #if 0 @@ -202,73 +205,75 @@ FILE *lndebug_fp = NULL; /* Enable "mask mode". When it is enabled, instead of the input that * the user is typing, the terminal will just display a corresponding * number of asterisks, like "****". This is useful for passwords and other - * secrets that should not be displayed. */ -void linenoiseMaskModeEnable(void) + * secrets that should not be displayed. + */ +void line_mask_mode_enable(void) { - maskmode = 1; + maskmode = true; } /* Disable mask mode. */ -void linenoiseMaskModeDisable(void) +void line_mask_mode_disable(void) { - maskmode = 0; + maskmode = false; } /* Set if to use or not the multi line mode. */ -void linenoiseSetMultiLine(int ml) +void line_set_multi_line(int ml) { - mlmode = ml; + mlmode = (bool) ml; } /* Return true if the terminal name is in the list of terminals we know are * not able to understand basic escape sequences. */ -static int isUnsupportedTerm(void) +static bool is_unsupported_term(void) { char *term = getenv("TERM"); - int j; + if (!term) + return false; - if (term == NULL) - return 0; - for (j = 0; unsupported_term[j]; j++) + for (int j = 0; unsupported_term[j]; j++) if (!strcasecmp(term, unsupported_term[j])) - return 1; - return 0; + return true; + return false; } /* Raw mode: 1960 magic shit. */ -static int enableRawMode(int fd) +static int enable_raw_mode(int fd) { - struct termios raw; - if (!isatty(STDIN_FILENO)) goto fatal; if (!atexit_registered) { - atexit(linenoiseAtExit); - atexit_registered = 1; + atexit(line_atexit); + atexit_registered = true; } if (tcgetattr(fd, &orig_termios) == -1) goto fatal; + struct termios raw; raw = orig_termios; /* modify the original mode */ /* input modes: no break, no CR to NL, no parity check, no strip char, - * no start/stop output control. */ + * no start/stop output control. + */ raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); /* output modes - disable post processing */ raw.c_oflag &= ~(OPOST); /* control modes - set 8 bit chars */ raw.c_cflag |= (CS8); /* local modes - choing off, canonical off, no extended functions, - * no signal chars (^Z,^C) */ + * no signal chars (^Z,^C) + */ raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); /* control chars - set return condition: min number of bytes and timer. - * We want read to return every single byte, without timeout. */ + * We want read to return every single byte, without timeout. + */ raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */ /* put terminal in raw mode after flushing */ if (tcsetattr(fd, TCSAFLUSH, &raw) < 0) goto fatal; - rawmode = 1; + rawmode = true; return 0; fatal: @@ -276,26 +281,27 @@ static int enableRawMode(int fd) return -1; } -static void disableRawMode(int fd) +static void disable_raw_mode(int fd) { /* Don't even check the return value as it's too late. */ if (rawmode && tcsetattr(fd, TCSAFLUSH, &orig_termios) != -1) - rawmode = 0; + rawmode = false; } /* Use the ESC [6n escape sequence to query the horizontal cursor position * and return it. On error -1 is returned, on success the position of the - * cursor. */ -static int getCursorPosition(int ifd, int ofd) + * cursor. + */ +static int get_cursor_position(int ifd, int ofd) { char buf[32]; int cols, rows; - unsigned int i = 0; /* Report cursor location */ if (write(ofd, "\x1b[6n", 4) != 4) return -1; + unsigned int i = 0; /* Read the response: ESC [ rows ; cols R */ while (i < sizeof(buf) - 1) { if (read(ifd, buf + i, 1) != 1) @@ -315,8 +321,9 @@ static int getCursorPosition(int ifd, int ofd) } /* Try to get the number of columns in the current terminal, or assume 80 - * if it fails. */ -static int getColumns(int ifd, int ofd) + * if it fails. + */ +static int get_columns(int ifd, int ofd) { struct winsize ws; @@ -325,14 +332,14 @@ static int getColumns(int ifd, int ofd) int start, cols; /* Get the initial position so we can restore it later. */ - start = getCursorPosition(ifd, ofd); + start = get_cursor_position(ifd, ofd); if (start == -1) goto failed; /* Go to right margin and get position. */ if (write(ofd, "\x1b[999C", 6) != 6) goto failed; - cols = getCursorPosition(ifd, ofd); + cols = get_cursor_position(ifd, ofd); if (cols == -1) goto failed; @@ -345,16 +352,15 @@ static int getColumns(int ifd, int ofd) } } return cols; - } else { - return ws.ws_col; } + return ws.ws_col; failed: return 80; } /* Clear the screen. Used to handle ctrl+l */ -void linenoiseClearScreen(void) +void line_clear_screen(void) { if (write(STDOUT_FILENO, "\x1b[H\x1b[2J", 7) <= 0) { /* nothing to do, just to avoid warning. */ @@ -362,8 +368,9 @@ void linenoiseClearScreen(void) } /* Beep, used for completion when there is nothing to complete or when all - * the choices were already shown. */ -static void linenoiseBeep(void) + * the choices were already shown. + */ +static void line_beep(void) { fprintf(stderr, "\x7"); fflush(stderr); @@ -371,52 +378,51 @@ static void linenoiseBeep(void) /* ============================== Completion ================================ */ -/* Free a list of completion option populated by linenoiseAddCompletion(). */ -static void freeCompletions(linenoiseCompletions *lc) +/* Free a list of completion option populated by line_add_completion(). */ +static void free_completions(line_completions_t *lc) { - size_t i; - for (i = 0; i < lc->len; i++) + for (size_t i = 0; i < lc->len; i++) free(lc->cvec[i]); - if (lc->cvec != NULL) - free(lc->cvec); + free(lc->cvec); } -/* This is an helper function for linenoiseEdit() and is called when the +/* This is an helper function for line_edit() and is called when the * user types the key in order to complete the string currently in the * input. * - * The state of the editing is encapsulated into the pointed linenoiseState - * structure as described in the structure definition. */ -static int completeLine(struct linenoiseState *ls) + * The state of the editing is encapsulated into the pointed line_state + * structure as described in the structure definition. + */ +static int complete_line(struct line_state *ls) { - linenoiseCompletions lc = {0, NULL}; - int nread, nwritten; + line_completions_t lc = {0, NULL}; char c = 0; - completionCallback(ls->buf, &lc); + completion_callback(ls->buf, &lc); if (lc.len == 0) { - linenoiseBeep(); + line_beep(); } else { - size_t stop = 0, i = 0; + bool stop = false; + size_t i = 0; while (!stop) { /* Show completion or original buffer */ if (i < lc.len) { - struct linenoiseState saved = *ls; + struct line_state saved = *ls; ls->len = ls->pos = strlen(lc.cvec[i]); ls->buf = lc.cvec[i]; - refreshLine(ls); + refresh_line(ls); ls->len = saved.len; ls->pos = saved.pos; ls->buf = saved.buf; } else { - refreshLine(ls); + refresh_line(ls); } - nread = read(ls->ifd, &c, 1); + int nread = read(ls->ifd, &c, 1); if (nread <= 0) { - freeCompletions(&lc); + free_completions(&lc); return -1; } @@ -424,64 +430,65 @@ static int completeLine(struct linenoiseState *ls) case 9: /* tab */ i = (i + 1) % (lc.len + 1); if (i == lc.len) - linenoiseBeep(); + line_beep(); break; case 27: /* escape */ /* Re-show original buffer */ if (i < lc.len) - refreshLine(ls); - stop = 1; + refresh_line(ls); + stop = true; break; default: /* Update buffer and return */ if (i < lc.len) { - nwritten = snprintf(ls->buf, ls->buflen, "%s", lc.cvec[i]); + int nwritten = + snprintf(ls->buf, ls->buflen, "%s", lc.cvec[i]); ls->len = ls->pos = nwritten; } - stop = 1; + stop = true; break; } } } - freeCompletions(&lc); + free_completions(&lc); return c; /* Return last read character */ } /* Register a callback function to be called for tab-completion. */ -void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) +void line_set_completion_callback(line_completion_callback_t *fn) { - completionCallback = fn; + completion_callback = fn; } /* Register a hits function to be called to show hits to the user at the * right of the prompt. */ -void linenoiseSetHintsCallback(linenoiseHintsCallback *fn) +void line_set_hints_callback(line_hints_callback_t *fn) { - hintsCallback = fn; + hints_callback = fn; } /* Register a function to free the hints returned by the hints callback - * registered with linenoiseSetHintsCallback(). */ -void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *fn) + * registered with line_set_hints_callback(). + */ +void line_set_free_hints_callback(line_free_hints_callback_t *fn) { - freeHintsCallback = fn; + free_hints_callback = fn; } /* This function is used by the callback function registered by the user * in order to add completion options given the input string when the - * user typed . See the example.c source code for a very easy to - * understand example. */ -void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) + * user typed . + */ +void line_add_completion(line_completions_t *lc, const char *str) { size_t len = strlen(str); - char *copy, **cvec; - copy = malloc(len + 1); - if (copy == NULL) + char *copy = malloc(len + 1); + if (!copy) return; memcpy(copy, str, len + 1); - cvec = realloc(lc->cvec, sizeof(char *) * (lc->len + 1)); + char **cvec = realloc(lc->cvec, sizeof(char *) * (lc->len + 1)); if (cvec == NULL) { free(copy); return; @@ -495,43 +502,45 @@ void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) /* We define a very simple "append buffer" structure, that is an heap * allocated string where we can append to. This is useful in order to * write all the escape sequences in a buffer and flush them to the standard - * output in a single call, to avoid flickering effects. */ + * output in a single call, to avoid flickering effects. + */ struct abuf { char *b; int len; }; -static void abInit(struct abuf *ab) +static void ab_init(struct abuf *ab) { ab->b = NULL; ab->len = 0; } -static void abAppend(struct abuf *ab, const char *s, int len) +static void ab_append(struct abuf *ab, const char *s, int len) { char *new = realloc(ab->b, ab->len + len); - - if (new == NULL) + if (!new) return; + memcpy(new + ab->len, s, len); ab->b = new; ab->len += len; } -static void abFree(struct abuf *ab) +static inline void ab_free(struct abuf *ab) { free(ab->b); } -/* Helper of refreshSingleLine() and refreshMultiLine() to show hints - * to the right of the prompt. */ -void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) +/* Helper of refresh_single_line() and refresh_multi_Line() to show hints + * to the right of the prompt. + */ +void refresh_show_hints(struct abuf *ab, struct line_state *l, int plen) { - char seq[64]; - if (hintsCallback && plen + l->len < l->cols) { + if (hints_callback && plen + l->len < l->cols) { int color = -1, bold = 0; - char *hint = hintsCallback(l->buf, &color, &bold); + char *hint = hints_callback(l->buf, &color, &bold); if (hint) { + char seq[64]; int hintlen = strlen(hint); int hintmaxlen = l->cols - (plen + l->len); if (hintlen > hintmaxlen) @@ -542,13 +551,13 @@ void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) snprintf(seq, 64, "\033[%d;%d;49m", bold, color); else seq[0] = '\0'; - abAppend(ab, seq, strlen(seq)); - abAppend(ab, hint, hintlen); + ab_append(ab, seq, strlen(seq)); + ab_append(ab, hint, hintlen); if (color != -1 || bold != 0) - abAppend(ab, "\033[0m", 4); + ab_append(ab, "\033[0m", 4); /* Call the function to free the hint returned. */ - if (freeHintsCallback) - freeHintsCallback(hint); + if (free_hints_callback) + free_hints_callback(hint); } } } @@ -556,8 +565,9 @@ void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) /* Single line low level line refresh. * * Rewrite the currently edited line accordingly to the buffer content, - * cursor position, and number of columns of the terminal. */ -static void refreshSingleLine(struct linenoiseState *l) + * cursor position, and number of columns of the terminal. + */ +static void refresh_single_line(struct line_state *l) { char seq[64]; size_t plen = strlen(l->prompt); @@ -572,40 +582,40 @@ static void refreshSingleLine(struct linenoiseState *l) len--; pos--; } - while (plen + len > l->cols) { + while (plen + len > l->cols) len--; - } - abInit(&ab); + ab_init(&ab); /* Cursor to left edge */ snprintf(seq, 64, "\r"); - abAppend(&ab, seq, strlen(seq)); + ab_append(&ab, seq, strlen(seq)); /* Write the prompt and the current buffer content */ - abAppend(&ab, l->prompt, strlen(l->prompt)); - if (maskmode == 1) { + ab_append(&ab, l->prompt, strlen(l->prompt)); + if (maskmode) { while (len--) - abAppend(&ab, "*", 1); + ab_append(&ab, "*", 1); } else { - abAppend(&ab, buf, len); + ab_append(&ab, buf, len); } /* Show hits if any. */ - refreshShowHints(&ab, l, plen); + refresh_show_hints(&ab, l, plen); /* Erase to right */ snprintf(seq, 64, "\x1b[0K"); - abAppend(&ab, seq, strlen(seq)); + ab_append(&ab, seq, strlen(seq)); /* Move cursor to original position. */ snprintf(seq, 64, "\r\x1b[%dC", (int) (pos + plen)); - abAppend(&ab, seq, strlen(seq)); + ab_append(&ab, seq, strlen(seq)); if (write(fd, ab.b, ab.len) == -1) { } /* Can't recover from write error. */ - abFree(&ab); + ab_free(&ab); } /* Multi line low level line refresh. * * Rewrite the currently edited line accordingly to the buffer content, - * cursor position, and number of columns of the terminal. */ -static void refreshMultiLine(struct linenoiseState *l) + * cursor position, and number of columns of the terminal. + */ +static void refresh_multi_Line(struct line_state *l) { char seq[64]; int plen = strlen(l->prompt); @@ -616,7 +626,7 @@ static void refreshMultiLine(struct linenoiseState *l) int rpos2; /* rpos after refresh. */ int col; /* colum position, zero-based. */ int old_rows = l->maxrows; - int fd = l->ofd, j; + int fd = l->ofd; struct abuf ab; /* Update maxrows if needed. */ @@ -625,45 +635,45 @@ static void refreshMultiLine(struct linenoiseState *l) /* First step: clear all the lines used before. To do so start by * going to the last row. */ - abInit(&ab); + ab_init(&ab); if (old_rows - rpos > 0) { lndebug("go down %d", old_rows - rpos); snprintf(seq, 64, "\x1b[%dB", old_rows - rpos); - abAppend(&ab, seq, strlen(seq)); + ab_append(&ab, seq, strlen(seq)); } /* Now for every row clear it, go up. */ - for (j = 0; j < old_rows - 1; j++) { + for (int j = 0; j < old_rows - 1; j++) { lndebug("clear+up"); snprintf(seq, 64, "\r\x1b[0K\x1b[1A"); - abAppend(&ab, seq, strlen(seq)); + ab_append(&ab, seq, strlen(seq)); } /* Clean the top line. */ lndebug("clear"); snprintf(seq, 64, "\r\x1b[0K"); - abAppend(&ab, seq, strlen(seq)); + ab_append(&ab, seq, strlen(seq)); /* Write the prompt and the current buffer content */ - abAppend(&ab, l->prompt, strlen(l->prompt)); - if (maskmode == 1) { - unsigned int i; - for (i = 0; i < l->len; i++) - abAppend(&ab, "*", 1); + ab_append(&ab, l->prompt, strlen(l->prompt)); + if (maskmode) { + for (unsigned int i = 0; i < l->len; i++) + ab_append(&ab, "*", 1); } else { - abAppend(&ab, l->buf, l->len); + ab_append(&ab, l->buf, l->len); } /* Show hits if any. */ - refreshShowHints(&ab, l, plen); + refresh_show_hints(&ab, l, plen); /* If we are at the very end of the screen with our prompt, we need to - * emit a newline and move the prompt to the first column. */ + * emit a newline and move the prompt to the first column. + */ if (l->pos && l->pos == l->len && (l->pos + plen) % l->cols == 0) { lndebug(""); - abAppend(&ab, "\n", 1); + ab_append(&ab, "\n", 1); snprintf(seq, 64, "\r"); - abAppend(&ab, seq, strlen(seq)); + ab_append(&ab, seq, strlen(seq)); rows++; if (rows > (int) l->maxrows) l->maxrows = rows; @@ -678,7 +688,7 @@ static void refreshMultiLine(struct linenoiseState *l) if (rows - rpos2 > 0) { lndebug("go-up %d", rows - rpos2); snprintf(seq, 64, "\x1b[%dA", rows - rpos2); - abAppend(&ab, seq, strlen(seq)); + ab_append(&ab, seq, strlen(seq)); } /* Set column. */ @@ -688,30 +698,32 @@ static void refreshMultiLine(struct linenoiseState *l) snprintf(seq, 64, "\r\x1b[%dC", col); else snprintf(seq, 64, "\r"); - abAppend(&ab, seq, strlen(seq)); + ab_append(&ab, seq, strlen(seq)); lndebug("\n"); l->oldpos = l->pos; if (write(fd, ab.b, ab.len) == -1) { } /* Can't recover from write error. */ - abFree(&ab); + ab_free(&ab); } -/* Calls the two low level functions refreshSingleLine() or - * refreshMultiLine() according to the selected mode. */ -static void refreshLine(struct linenoiseState *l) +/* Calls the two low level functions refresh_single_line() or + * refresh_multi_Line() according to the selected mode. + */ +static void refresh_line(struct line_state *l) { if (mlmode) - refreshMultiLine(l); + refresh_multi_Line(l); else - refreshSingleLine(l); + refresh_single_line(l); } /* Insert the character 'c' at cursor current position. * - * On error writing to the terminal -1 is returned, otherwise 0. */ -int linenoiseEditInsert(struct linenoiseState *l, char c) + * On error writing to the terminal -1 is returned, otherwise 0. + */ +int line_edit_insert(struct line_state *l, char c) { if (l->len < l->buflen) { if (l->len == l->pos) { @@ -719,14 +731,14 @@ int linenoiseEditInsert(struct linenoiseState *l, char c) l->pos++; l->len++; l->buf[l->len] = '\0'; - if ((!mlmode && l->plen + l->len < l->cols && !hintsCallback)) { + if ((!mlmode && l->plen + l->len < l->cols && !hints_callback)) { /* Avoid a full update of the line in the * trivial case. */ - char d = (maskmode == 1) ? '*' : c; + char d = maskmode ? '*' : c; if (write(l->ofd, &d, 1) == -1) return -1; } else { - refreshLine(l); + refresh_line(l); } } else { memmove(l->buf + l->pos + 1, l->buf + l->pos, l->len - l->pos); @@ -734,53 +746,53 @@ int linenoiseEditInsert(struct linenoiseState *l, char c) l->len++; l->pos++; l->buf[l->len] = '\0'; - refreshLine(l); + refresh_line(l); } } return 0; } /* Move cursor on the left. */ -void linenoiseEditMoveLeft(struct linenoiseState *l) +void line_edit_move_left(struct line_state *l) { if (l->pos > 0) { l->pos--; - refreshLine(l); + refresh_line(l); } } /* Move cursor on the right. */ -void linenoiseEditMoveRight(struct linenoiseState *l) +void line_edit_move_right(struct line_state *l) { if (l->pos != l->len) { l->pos++; - refreshLine(l); + refresh_line(l); } } /* Move cursor to the start of the line. */ -void linenoiseEditMoveHome(struct linenoiseState *l) +void line_edit_move_home(struct line_state *l) { if (l->pos != 0) { l->pos = 0; - refreshLine(l); + refresh_line(l); } } /* Move cursor to the end of the line. */ -void linenoiseEditMoveEnd(struct linenoiseState *l) +void line_edit_move_end(struct line_state *l) { if (l->pos != l->len) { l->pos = l->len; - refreshLine(l); + refresh_line(l); } } /* Substitute the currently edited line with the next or previous history - * entry as specified by 'dir'. */ -#define LINENOISE_HISTORY_NEXT 0 -#define LINENOISE_HISTORY_PREV 1 -void linenoiseEditHistoryNext(struct linenoiseState *l, int dir) + * entry as specified by 'dir'. + */ +enum { LINENOISE_HISTORY_NEXT = 0, LINENOISE_HISTORY_PREV = 1 }; +void line_edit_history_next(struct line_state *l, int dir) { if (history_len > 1) { /* Update the current history entry before to @@ -799,63 +811,64 @@ void linenoiseEditHistoryNext(struct linenoiseState *l, int dir) strncpy(l->buf, history[history_len - 1 - l->history_index], l->buflen); l->buf[l->buflen - 1] = '\0'; l->len = l->pos = strlen(l->buf); - refreshLine(l); + refresh_line(l); } } /* Delete the character at the right of the cursor without altering the cursor - * position. Basically this is what happens with the "Delete" keyboard key. */ -void linenoiseEditDelete(struct linenoiseState *l) + * position. Basically this is what happens with the "Delete" keyboard key. + */ +void line_edit_delete(struct line_state *l) { if (l->len > 0 && l->pos < l->len) { memmove(l->buf + l->pos, l->buf + l->pos + 1, l->len - l->pos - 1); l->len--; l->buf[l->len] = '\0'; - refreshLine(l); + refresh_line(l); } } /* Backspace implementation. */ -void linenoiseEditBackspace(struct linenoiseState *l) +void line_edit_backspace(struct line_state *l) { if (l->pos > 0 && l->len > 0) { memmove(l->buf + l->pos - 1, l->buf + l->pos, l->len - l->pos); l->pos--; l->len--; l->buf[l->len] = '\0'; - refreshLine(l); + refresh_line(l); } } /* Delete the previous word, maintaining the cursor at the start of the - * current word. */ -void linenoiseEditDeletePrevWord(struct linenoiseState *l) + * current word. + */ +void line_edit_delete_prev_word(struct line_state *l) { size_t old_pos = l->pos; - size_t diff; while (l->pos > 0 && l->buf[l->pos - 1] == ' ') l->pos--; while (l->pos > 0 && l->buf[l->pos - 1] != ' ') l->pos--; - diff = old_pos - l->pos; + size_t diff = old_pos - l->pos; memmove(l->buf + l->pos, l->buf + old_pos, l->len - old_pos + 1); l->len -= diff; - refreshLine(l); + refresh_line(l); } /* Jump to the begining of the previous word */ -static void linenoiseEditPrevWord(struct linenoiseState *l) +static void line_edit_prev_word(struct line_state *l) { while (l->pos > 0 && l->buf[l->pos - 1] == ' ') l->pos--; while (l->pos > 0 && l->buf[l->pos - 1] != ' ') l->pos--; - refreshLine(l); + refresh_line(l); } /* Jump to the space after the current word */ -static void linenoiseEditNextWord(struct linenoiseState *l) +static void line_edit_next_word(struct line_state *l) { while (l->pos < l->len) { if (l->buf[l->pos] != ' ') @@ -872,7 +885,7 @@ static void linenoiseEditNextWord(struct linenoiseState *l) l->pos++; } - refreshLine(l); + refresh_line(l); } /* This function is the core of the line editing capability of linenoise. @@ -882,17 +895,19 @@ static void linenoiseEditNextWord(struct linenoiseState *l) * The resulting string is put into 'buf' when the user type enter, or * when ctrl+d is typed. * - * The function returns the length of the current buffer. */ -static int linenoiseEdit(int stdin_fd, - int stdout_fd, - char *buf, - size_t buflen, - const char *prompt) + * The function returns the length of the current buffer. + */ +static int line_edit(int stdin_fd, + int stdout_fd, + char *buf, + size_t buflen, + const char *prompt) { - struct linenoiseState l; + struct line_state l; /* Populate the linenoise state that we pass to functions implementing - * specific editing functionalities. */ + * specific editing functionalities. + */ l.ifd = stdin_fd; l.ofd = stdout_fd; l.buf = buf; @@ -901,7 +916,7 @@ static int linenoiseEdit(int stdin_fd, l.plen = strlen(prompt); l.oldpos = l.pos = 0; l.len = 0; - l.cols = getColumns(stdin_fd, stdout_fd); + l.cols = get_columns(stdin_fd, stdout_fd); l.maxrows = 0; l.history_index = 0; @@ -910,8 +925,9 @@ static int linenoiseEdit(int stdin_fd, l.buflen--; /* Make sure there is always space for the nulterm */ /* The latest history entry is always our current buffer, that - * initially is just an empty string. */ - linenoiseHistoryAdd(""); + * initially is just an empty string. + */ + line_history_add(""); if (write(l.ofd, prompt, l.plen) == -1) return -1; @@ -926,9 +942,10 @@ static int linenoiseEdit(int stdin_fd, /* Only autocomplete when the callback is set. It returns < 0 when * there was an error reading from fd. Otherwise it will return the - * character that should be handled next. */ - if (c == 9 && completionCallback != NULL) { - c = completeLine(&l); + * character that should be handled next. + */ + if (c == 9 && completion_callback != NULL) { + c = complete_line(&l); /* Return on errors */ if (c < 0) return l.len; @@ -942,14 +959,15 @@ static int linenoiseEdit(int stdin_fd, history_len--; free(history[history_len]); if (mlmode) - linenoiseEditMoveEnd(&l); - if (hintsCallback) { + line_edit_move_end(&l); + if (hints_callback) { /* Force a refresh without hints to leave the previous - * line as the user typed it after a newline. */ - linenoiseHintsCallback *hc = hintsCallback; - hintsCallback = NULL; - refreshLine(&l); - hintsCallback = hc; + * line as the user typed it after a newline. + */ + line_hints_callback_t *hc = hints_callback; + hints_callback = NULL; + refresh_line(&l); + hints_callback = hc; } return (int) l.len; case CTRL_C: /* ctrl-c */ @@ -957,12 +975,13 @@ static int linenoiseEdit(int stdin_fd, return -1; case BACKSPACE: /* backspace */ case 8: /* ctrl-h */ - linenoiseEditBackspace(&l); + line_edit_backspace(&l); break; - case CTRL_D: /* ctrl-d, remove char at right of cursor, or if the - line is empty, act as end-of-file. */ + case CTRL_D: /* ctrl-d, remove char at right of cursor, or if the line + * is empty, act as end-of-file. + */ if (l.len > 0) { - linenoiseEditDelete(&l); + line_edit_delete(&l); } else { history_len--; free(history[history_len]); @@ -976,25 +995,26 @@ static int linenoiseEdit(int stdin_fd, buf[l.pos] = aux; if (l.pos != l.len - 1) l.pos++; - refreshLine(&l); + refresh_line(&l); } break; case CTRL_B: /* ctrl-b */ - linenoiseEditMoveLeft(&l); + line_edit_move_left(&l); break; case CTRL_F: /* ctrl-f */ - linenoiseEditMoveRight(&l); + line_edit_move_right(&l); break; case CTRL_P: /* ctrl-p */ - linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV); + line_edit_history_next(&l, LINENOISE_HISTORY_PREV); break; case CTRL_N: /* ctrl-n */ - linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT); + line_edit_history_next(&l, LINENOISE_HISTORY_NEXT); break; case ESC: /* escape sequence */ /* Read the next two bytes representing the escape sequence. * Use two calls to handle slow terminals returning the two - * chars at different times. */ + * chars at different times. + */ if (read(l.ifd, seq, 1) == -1) break; if (read(l.ifd, seq + 1, 1) == -1) @@ -1010,7 +1030,7 @@ static int linenoiseEdit(int stdin_fd, case '~': switch (seq[1]) { case '3': /* Delete key. */ - linenoiseEditDelete(&l); + line_edit_delete(&l); break; } break; @@ -1024,10 +1044,10 @@ static int linenoiseEdit(int stdin_fd, if (seq[3] == '5') { switch (seq[4]) { case 'D': /* Ctrl Left */ - linenoiseEditPrevWord(&l); + line_edit_prev_word(&l); break; case 'C': /* Ctrl Right */ - linenoiseEditNextWord(&l); + line_edit_next_word(&l); break; } } @@ -1036,22 +1056,22 @@ static int linenoiseEdit(int stdin_fd, } else { switch (seq[1]) { case 'A': /* Up */ - linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV); + line_edit_history_next(&l, LINENOISE_HISTORY_PREV); break; case 'B': /* Down */ - linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT); + line_edit_history_next(&l, LINENOISE_HISTORY_NEXT); break; case 'C': /* Right */ - linenoiseEditMoveRight(&l); + line_edit_move_right(&l); break; case 'D': /* Left */ - linenoiseEditMoveLeft(&l); + line_edit_move_left(&l); break; case 'H': /* Home */ - linenoiseEditMoveHome(&l); + line_edit_move_home(&l); break; case 'F': /* End*/ - linenoiseEditMoveEnd(&l); + line_edit_move_end(&l); break; } } @@ -1061,94 +1081,60 @@ static int linenoiseEdit(int stdin_fd, else if (seq[0] == 'O') { switch (seq[1]) { case 'H': /* Home */ - linenoiseEditMoveHome(&l); + line_edit_move_home(&l); break; case 'F': /* End*/ - linenoiseEditMoveEnd(&l); + line_edit_move_end(&l); break; } } break; default: - if (linenoiseEditInsert(&l, c)) + if (line_edit_insert(&l, c)) return -1; break; case CTRL_U: /* Ctrl+u, delete the whole line. */ buf[0] = '\0'; l.pos = l.len = 0; - refreshLine(&l); + refresh_line(&l); break; case CTRL_K: /* Ctrl+k, delete from current to end of line. */ buf[l.pos] = '\0'; l.len = l.pos; - refreshLine(&l); + refresh_line(&l); break; case CTRL_A: /* Ctrl+a, go to the start of the line */ - linenoiseEditMoveHome(&l); + line_edit_move_home(&l); break; case CTRL_E: /* ctrl+e, go to the end of the line */ - linenoiseEditMoveEnd(&l); + line_edit_move_end(&l); break; case CTRL_L: /* ctrl+l, clear screen */ - linenoiseClearScreen(); - refreshLine(&l); + line_clear_screen(); + refresh_line(&l); break; case CTRL_W: /* ctrl+w, delete previous word */ - linenoiseEditDeletePrevWord(&l); + line_edit_delete_prev_word(&l); break; } } return l.len; } -/* This special mode is used by linenoise in order to print scan codes - * on screen for debugging / development purposes. It is implemented - * by the linenoise_example program using the --keycodes option. */ -void linenoisePrintKeyCodes(void) -{ - char quit[4]; - - printf( - "Linenoise key codes debugging mode.\n" - "Press keys to see scan codes. Type 'quit' at any time to exit.\n"); - if (enableRawMode(STDIN_FILENO) == -1) - return; - memset(quit, ' ', 4); - while (1) { - char c; - int nread; - - nread = read(STDIN_FILENO, &c, 1); - if (nread <= 0) - continue; - memmove(quit, quit + 1, sizeof(quit) - 1); /* shift string to left. */ - quit[sizeof(quit) - 1] = c; /* Insert current char on the right. */ - if (memcmp(quit, "quit", sizeof(quit)) == 0) - break; - - printf("'%c' %02x (%d) (type quit to exit)\n", isprint(c) ? c : '?', - (int) c, (int) c); - printf("\r"); /* Go left edge manually, we are in raw mode. */ - fflush(stdout); - } - disableRawMode(STDIN_FILENO); -} - -/* This function calls the line editing function linenoiseEdit() using - * the STDIN file descriptor set in raw mode. */ -static int linenoiseRaw(char *buf, size_t buflen, const char *prompt) +/* This function calls the line editing function line_edit() using + * the STDIN file descriptor set in raw mode. + */ +static int line_raw(char *buf, size_t buflen, const char *prompt) { - int count; - if (buflen == 0) { errno = EINVAL; return -1; } - if (enableRawMode(STDIN_FILENO) == -1) + if (enable_raw_mode(STDIN_FILENO) == -1) return -1; - count = linenoiseEdit(STDIN_FILENO, STDOUT_FILENO, buf, buflen, prompt); - disableRawMode(STDIN_FILENO); + int count = line_edit(STDIN_FILENO, STDOUT_FILENO, buf, buflen, prompt); + disable_raw_mode(STDIN_FILENO); printf("\n"); return count; } @@ -1157,8 +1143,9 @@ static int linenoiseRaw(char *buf, size_t buflen, const char *prompt) * input file descriptor not attached to a TTY. So for example when the * program using linenoise is called in pipe or with a file redirected * to its standard input. In this case, we want to be able to return the - * line regardless of its length (by default we are limited to 4k). */ -static char *linenoiseNoTTY(void) + * line regardless of its length (by default we are limited to 4k). + */ +static char *line_no_tty(void) { char *line = NULL; size_t len = 0, maxlen = 0; @@ -1196,22 +1183,22 @@ static char *linenoiseNoTTY(void) * This function checks if the terminal has basic capabilities, just checking * for a blacklist of stupid terminals, and later either calls the line * editing function or uses dummy fgets() so that you will be able to type - * something even in the most desperate of the conditions. */ + * something even in the most desperate of the conditions. + */ char *linenoise(const char *prompt) { char buf[LINENOISE_MAX_LINE]; - int count; if (!isatty(STDIN_FILENO)) { /* Not a tty: read from file / pipe. In this mode we don't want any * limit to the line size, so we call a function to handle that. */ - return linenoiseNoTTY(); - } else if (isUnsupportedTerm()) { + return line_no_tty(); + } else if (is_unsupported_term()) { size_t len; printf("%s", prompt); fflush(stdout); - if (fgets(buf, LINENOISE_MAX_LINE, stdin) == NULL) + if (!fgets(buf, LINENOISE_MAX_LINE, stdin)) return NULL; len = strlen(buf); while (len && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) { @@ -1219,19 +1206,20 @@ char *linenoise(const char *prompt) buf[len] = '\0'; } return strdup(buf); - } else { - count = linenoiseRaw(buf, LINENOISE_MAX_LINE, prompt); - if (count == -1) - return NULL; - return strdup(buf); } + + int count = line_raw(buf, LINENOISE_MAX_LINE, prompt); + if (count == -1) + return NULL; + return strdup(buf); } /* This is just a wrapper the user may want to call in order to make sure * the linenoise returned buffer is freed with the same allocator it was * created with. Useful when the main program is using an alternative - * allocator. */ -void linenoiseFree(void *ptr) + * allocator. + */ +void line_free(void *ptr) { free(ptr); } @@ -1239,23 +1227,22 @@ void linenoiseFree(void *ptr) /* ================================ History ================================= */ /* Free the history, but does not reset it. Only used when we have to - * exit() to avoid memory leaks are reported by valgrind & co. */ -static void freeHistory(void) + * exit() to avoid memory leaks are reported by valgrind & co. + */ +static void free_history(void) { if (history) { - int j; - - for (j = 0; j < history_len; j++) + for (int j = 0; j < history_len; j++) free(history[j]); free(history); } } /* At exit we'll try to fix the terminal to the initial conditions. */ -static void linenoiseAtExit(void) +static void line_atexit(void) { - disableRawMode(STDIN_FILENO); - freeHistory(); + disable_raw_mode(STDIN_FILENO); + free_history(); } /* This is the API call to add a new entry in the linenoise history. @@ -1264,18 +1251,17 @@ static void linenoiseAtExit(void) * entry and make room for the new one, so it is not exactly suitable for huge * histories, but will work well for a few hundred of entries. * - * Using a circular buffer is smarter, but a bit more complex to handle. */ -int linenoiseHistoryAdd(const char *line) + * Using a circular buffer is smarter, but a bit more complex to handle. + */ +int line_history_add(const char *line) { - char *linecopy; - if (history_max_len == 0) return 0; /* Initialization on first call. */ - if (history == NULL) { + if (!history) { history = malloc(sizeof(char *) * history_max_len); - if (history == NULL) + if (!history) return 0; memset(history, 0, (sizeof(char *) * history_max_len)); } @@ -1286,7 +1272,7 @@ int linenoiseHistoryAdd(const char *line) /* Add an heap allocated copy of the line in the history. * If we reached the max length, remove the older line. */ - linecopy = strdup(line); + char *linecopy = strdup(line); if (!linecopy) return 0; if (history_len == history_max_len) { @@ -1302,25 +1288,23 @@ int linenoiseHistoryAdd(const char *line) /* Set the maximum length for the history. This function can be called even * if there is already some history, the function will make sure to retain * just the latest 'len' elements if the new history length value is smaller - * than the amount of items already inside the history. */ -int linenoiseHistorySetMaxLen(int len) + * than the amount of items already inside the history. + */ +int line_history_set_max_len(int len) { - char **new; - if (len < 1) return 0; + if (history) { int tocopy = history_len; - new = malloc(sizeof(char *) * len); - if (new == NULL) + char **new = malloc(sizeof(char *) * len); + if (!new) return 0; /* If we can't copy everything, free the elements we'll not use. */ if (len < tocopy) { - int j; - - for (j = 0; j < tocopy - len; j++) + for (int j = 0; j < tocopy - len; j++) free(history[j]); tocopy = len; } @@ -1336,19 +1320,19 @@ int linenoiseHistorySetMaxLen(int len) } /* Save the history in the specified file. On success 0 is returned - * otherwise -1 is returned. */ -int linenoiseHistorySave(const char *filename) + * otherwise -1 is returned. + */ +int line_history_save(const char *filename) { mode_t old_umask = umask(S_IXUSR | S_IRWXG | S_IRWXO); - FILE *fp; - int j; - fp = fopen(filename, "w"); + FILE *fp = fopen(filename, "w"); umask(old_umask); - if (fp == NULL) + if (!fp) return -1; + chmod(filename, S_IRUSR | S_IWUSR); - for (j = 0; j < history_len; j++) + for (int j = 0; j < history_len; j++) fprintf(fp, "%s\n", history[j]); fclose(fp); return 0; @@ -1358,24 +1342,22 @@ int linenoiseHistorySave(const char *filename) * zero is returned and no operation is performed. * * If the file exists and the operation succeeded 0 is returned, otherwise - * on error -1 is returned. */ -int linenoiseHistoryLoad(const char *filename) + * on error -1 is returned. + */ +int line_hostory_load(const char *filename) { FILE *fp = fopen(filename, "r"); - char buf[LINENOISE_MAX_LINE]; - - if (fp == NULL) + if (!fp) return -1; + char buf[LINENOISE_MAX_LINE]; while (fgets(buf, LINENOISE_MAX_LINE, fp) != NULL) { - char *p; - - p = strchr(buf, '\r'); + char *p = strchr(buf, '\r'); if (!p) p = strchr(buf, '\n'); if (p) *p = '\0'; - linenoiseHistoryAdd(buf); + line_history_add(buf); } fclose(fp); return 0; diff --git a/linenoise.h b/linenoise.h index 174887333..f4c3292d5 100644 --- a/linenoise.h +++ b/linenoise.h @@ -36,7 +36,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #ifndef __LINENOISE_H #define __LINENOISE_H @@ -44,32 +43,33 @@ extern "C" { #endif -typedef struct linenoiseCompletions { +#include + +typedef struct { size_t len; char **cvec; -} linenoiseCompletions; +} line_completions_t; /* clang-format off */ -typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *); -typedef char *(linenoiseHintsCallback)(const char *, int *color, int *bold); -typedef void(linenoiseFreeHintsCallback)(void *); -void linenoiseSetCompletionCallback(linenoiseCompletionCallback *); -void linenoiseSetHintsCallback(linenoiseHintsCallback *); -void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *); -void linenoiseAddCompletion(linenoiseCompletions *, const char *); +typedef void(line_completion_callback_t)(const char *, line_completions_t *); +typedef char *(line_hints_callback_t)(const char *, int *color, int *bold); +typedef void(line_free_hints_callback_t)(void *); +void line_set_completion_callback(line_completion_callback_t *); +void line_set_hints_callback(line_hints_callback_t *); +void line_set_free_hints_callback(line_free_hints_callback_t *); +void line_add_completion(line_completions_t *, const char *); /* clang-format on */ char *linenoise(const char *prompt); -void linenoiseFree(void *ptr); -int linenoiseHistoryAdd(const char *line); -int linenoiseHistorySetMaxLen(int len); -int linenoiseHistorySave(const char *filename); -int linenoiseHistoryLoad(const char *filename); -void linenoiseClearScreen(void); -void linenoiseSetMultiLine(int ml); -void linenoisePrintKeyCodes(void); -void linenoiseMaskModeEnable(void); -void linenoiseMaskModeDisable(void); +void line_free(void *ptr); +int line_history_add(const char *line); +int line_history_set_max_len(int len); +int line_history_save(const char *filename); +int line_hostory_load(const char *filename); +void line_clear_screen(void); +void line_set_multi_line(int ml); +void line_mask_mode_enable(void); +void line_mask_mode_disable(void); #ifdef __cplusplus } #endif diff --git a/qtest.c b/qtest.c index 248185ae6..b8c7ef9d8 100644 --- a/qtest.c +++ b/qtest.c @@ -1069,10 +1069,10 @@ int main(int argc, char *argv[]) /* Initialize linenoise only when infile_name not exist */ if (!infile_name) { /* Trigger call back function(auto completion) */ - linenoiseSetCompletionCallback(completion); + line_set_completion_callback(completion); - linenoiseHistorySetMaxLen(HISTORY_LEN); - linenoiseHistoryLoad(HISTORY_FILE); /* Load the history at startup */ + line_history_set_max_len(HISTORY_LEN); + line_hostory_load(HISTORY_FILE); /* Load the history at startup */ } set_verblevel(level); diff --git a/scripts/pre-commit.hook b/scripts/pre-commit.hook index 4c24b0701..194632f7f 100755 --- a/scripts/pre-commit.hook +++ b/scripts/pre-commit.hook @@ -1,7 +1,7 @@ #!/usr/bin/env bash CPPCHECK_suppresses="--inline-suppr harness.c --suppress=unmatchedSuppression:harness.c --suppress=missingIncludeSystem \ ---suppress=unusedFunction:linenoise.c --suppress=variableScope:linenoise.c \ +--suppress=unusedFunction:linenoise.c \ --suppress=nullPointerRedundantCheck:report.c \ --suppress=nullPointerRedundantCheck:harness.c \ --suppress=nullPointer:qtest.c \