some linenoise refactoring

This commit is contained in:
Данила Горнушко 2023-12-16 13:08:17 +03:00
parent c76a9669d8
commit 98b406b571
3 changed files with 57 additions and 83 deletions

View file

@ -53,7 +53,7 @@ void list_insert(List** head, void* data) {
*head = node; *head = node;
} }
unsigned int list_sizeof(List* head) { unsigned int list_sizeof(const List* head) {
if (head == NULL) { if (head == NULL) {
return 0; return 0;
} }

View file

@ -16,7 +16,7 @@ void* list_pop(List** head);
void list_insert(List** head, void* data); void list_insert(List** head, void* data);
// Get the size of the list. // Get the size of the list.
unsigned int list_sizeof(List* head); unsigned int list_sizeof(const List* head);
// Get the data of the node at the given ordinal number in the list. // Get the data of the node at the given ordinal number in the list.
List* list_get(List* head, unsigned int index); List* list_get(List* head, unsigned int index);

View file

@ -104,19 +104,15 @@
* *
*/ */
// ReSharper disable CppDefaultCaseNotHandledInSwitchStatement
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdio_ext.h> #include <stdio_ext.h>
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/stat.h>
#include <assert.h>
#include <sys/fcntl.h> #include <sys/fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h>
#include "linenoise.h" #include "linenoise.h"
#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100 #define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
@ -128,7 +124,7 @@
static linenoiseCompletionCallback *completionCallback = NULL; static linenoiseCompletionCallback *completionCallback = NULL;
static linenoiseHintsCallback *hintsCallback = NULL; static linenoiseHintsCallback *hintsCallback = NULL;
static linenoiseFreeHintsCallback *freeHintsCallback = NULL; static linenoiseFreeHintsCallback *freeHintsCallback = NULL;
static void refreshLineWithCompletion(struct linenoiseState *ls, linenoiseCompletions *lc, int flags); static void refreshLineWithCompletion(struct linenoiseState *ls, const linenoiseCompletions *lc, int flags);
static void refreshLineWithFlags(struct linenoiseState *l, int flags); static void refreshLineWithFlags(struct linenoiseState *l, int flags);
static int maskmode = 0; /* Show "***" instead of input. For passwords. */ static int maskmode = 0; /* Show "***" instead of input. For passwords. */
@ -265,9 +261,6 @@ static int getCursorPosition(void) {
/* Try to get the number of columns in the current terminal, or assume 80 /* Try to get the number of columns in the current terminal, or assume 80
* if it fails. */ * if it fails. */
static int getColumns(void) { static int getColumns(void) {
int start = 0;
int cols = 0;
int written = 0;
char seq[LINENOISE_COMMAND_MAX_LEN] = { 0 }; char seq[LINENOISE_COMMAND_MAX_LEN] = { 0 };
const int fd = fileno(stdout); const int fd = fileno(stdout);
@ -280,7 +273,7 @@ static int getColumns(void) {
const char set_cursor_pos[] = "\x1b[%dD"; const char set_cursor_pos[] = "\x1b[%dD";
/* Get the initial position so we can restore it later. */ /* Get the initial position so we can restore it later. */
start = getCursorPosition(); const int start = getCursorPosition();
if (start == -1) { if (start == -1) {
goto failed; goto failed;
} }
@ -294,7 +287,7 @@ static int getColumns(void) {
/* After sending this command, we can get the new position of the cursor, /* After sending this command, we can get the new position of the cursor,
* we'd get the size, in columns, of the opened TTY. */ * we'd get the size, in columns, of the opened TTY. */
cols = getCursorPosition(); const int cols = getCursorPosition();
if (cols == -1) { if (cols == -1) {
goto failed; goto failed;
} }
@ -302,7 +295,7 @@ static int getColumns(void) {
/* Restore the position of the cursor back. */ /* Restore the position of the cursor back. */
if (cols > start) { if (cols > start) {
/* Generate the move cursor command. */ /* Generate the move cursor command. */
written = snprintf(seq, LINENOISE_COMMAND_MAX_LEN, set_cursor_pos, cols-start); const int written = snprintf(seq, LINENOISE_COMMAND_MAX_LEN, set_cursor_pos, cols - start);
/* If `written` is equal or bigger than LINENOISE_COMMAND_MAX_LEN, it /* If `written` is equal or bigger than LINENOISE_COMMAND_MAX_LEN, it
* means that the output has been truncated because the size provided * means that the output has been truncated because the size provided
@ -337,12 +330,10 @@ static void linenoiseBeep(void) {
/* ============================== Completion ================================ */ /* ============================== Completion ================================ */
/* Free a list of completion option populated by linenoiseAddCompletion(). */ /* Free a list of completion option populated by linenoiseAddCompletion(). */
static void freeCompletions(linenoiseCompletions *lc) { static void freeCompletions(const linenoiseCompletions *lc) {
size_t i; for (size_t i = 0; i < lc->len; i++)
for (i = 0; i < lc->len; i++) // ReSharper disable once CppDFANullDereference
free(lc->cvec[i]); free(lc->cvec[i]);
if (lc->cvec != NULL)
free(lc->cvec);
} }
/* Called by completeLine() and linenoiseShow() to render the current /* Called by completeLine() and linenoiseShow() to render the current
@ -351,7 +342,7 @@ static void freeCompletions(linenoiseCompletions *lc) {
* function will use the callback to obtain it. * function will use the callback to obtain it.
* *
* Flags are the same as refreshLine*(), that is REFRESH_* macros. */ * Flags are the same as refreshLine*(), that is REFRESH_* macros. */
static void refreshLineWithCompletion(struct linenoiseState *ls, linenoiseCompletions *lc, int flags) { static void refreshLineWithCompletion(struct linenoiseState *ls, const linenoiseCompletions *lc, int flags) {
/* Obtain the table of completions if the caller didn't provide one. */ /* Obtain the table of completions if the caller didn't provide one. */
linenoiseCompletions ctable = { 0, NULL }; linenoiseCompletions ctable = { 0, NULL };
if (lc == NULL) { if (lc == NULL) {
@ -361,7 +352,7 @@ static void refreshLineWithCompletion(struct linenoiseState *ls, linenoiseComple
/* Show the edited line with completion if possible, or just refresh. */ /* Show the edited line with completion if possible, or just refresh. */
if (ls->completion_idx < lc->len) { if (ls->completion_idx < lc->len) {
struct linenoiseState saved = *ls; const struct linenoiseState saved = *ls;
ls->len = ls->pos = strlen(lc->cvec[ls->completion_idx]); ls->len = ls->pos = strlen(lc->cvec[ls->completion_idx]);
ls->buf = lc->cvec[ls->completion_idx]; ls->buf = lc->cvec[ls->completion_idx];
refreshLineWithFlags(ls,flags); refreshLineWithFlags(ls,flags);
@ -392,7 +383,6 @@ static void refreshLineWithCompletion(struct linenoiseState *ls, linenoiseComple
* from stdin. */ * from stdin. */
static int completeLine(struct linenoiseState *ls, int keypressed) { static int completeLine(struct linenoiseState *ls, int keypressed) {
linenoiseCompletions lc = { 0, NULL }; linenoiseCompletions lc = { 0, NULL };
int nwritten;
char c = keypressed; char c = keypressed;
completionCallback(ls->buf,&lc); completionCallback(ls->buf,&lc);
@ -421,8 +411,7 @@ static int completeLine(struct linenoiseState *ls, int keypressed) {
default: default:
/* Update buffer and return */ /* Update buffer and return */
if (ls->completion_idx < lc.len) { if (ls->completion_idx < lc.len) {
nwritten = snprintf(ls->buf,ls->buflen,"%s", const int nwritten = snprintf(ls->buf, ls->buflen, "%s", lc.cvec[ls->completion_idx]);
lc.cvec[ls->completion_idx]);
ls->len = ls->pos = nwritten; ls->len = ls->pos = nwritten;
} }
ls->in_completion = 0; ls->in_completion = 0;
@ -463,13 +452,12 @@ void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *fn) {
* user typed <tab>. See the example.c source code for a very easy to * user typed <tab>. See the example.c source code for a very easy to
* understand example. */ * understand example. */
void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) { void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) {
size_t len = strlen(str); const size_t len = strlen(str);
char *copy, **cvec;
copy = malloc(len+1); char* copy = malloc(len + 1);
if (copy == NULL) return; if (copy == NULL) return;
memcpy(copy,str,len+1); 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) { if (cvec == NULL) {
free(copy); free(copy);
return; return;
@ -503,20 +491,20 @@ static void abAppend(struct abuf *ab, const char *s, int len) {
ab->len += len; ab->len += len;
} }
static void abFree(struct abuf *ab) { static void abFree(const struct abuf *ab) {
free(ab->b); free(ab->b);
} }
/* Helper of refreshSingleLine() and refreshMultiLine() to show hints /* Helper of refreshSingleLine() and refreshMultiLine() to show hints
* to the right of the prompt. */ * to the right of the prompt. */
void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) { void refreshShowHints(struct abuf *ab, const struct linenoiseState *l, int plen) {
char seq[64];
if (hintsCallback && plen+l->len < l->cols) { if (hintsCallback && plen+l->len < l->cols) {
int color = -1, bold = 0; int color = -1, bold = 0;
char *hint = hintsCallback(l->buf,&color,&bold); char *hint = hintsCallback(l->buf,&color,&bold);
if (hint) { if (hint) {
char seq[64];
int hintlen = strlen(hint); int hintlen = strlen(hint);
int hintmaxlen = l->cols-(plen+l->len); const int hintmaxlen = l->cols-(plen+l->len);
if (hintlen > hintmaxlen) hintlen = hintmaxlen; if (hintlen > hintmaxlen) hintlen = hintmaxlen;
if (bold == 1 && color == -1) color = 37; if (bold == 1 && color == -1) color = 37;
if (color != -1 || bold != 0) if (color != -1 || bold != 0)
@ -540,10 +528,10 @@ void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) {
* *
* Flags is REFRESH_* macros. The function can just remove the old * Flags is REFRESH_* macros. The function can just remove the old
* prompt, just write it, or both. */ * prompt, just write it, or both. */
static void refreshSingleLine(struct linenoiseState *l, int flags) { static void refreshSingleLine(const struct linenoiseState *l, int flags) {
char seq[64]; char seq[64];
size_t plen = l->plen; const size_t plen = l->plen;
char *buf = l->buf; const char *buf = l->buf;
size_t len = l->len; size_t len = l->len;
size_t pos = l->pos; size_t pos = l->pos;
struct abuf ab; struct abuf ab;
@ -597,13 +585,10 @@ static void refreshSingleLine(struct linenoiseState *l, int flags) {
* prompt, just write it, or both. */ * prompt, just write it, or both. */
static void refreshMultiLine(struct linenoiseState *l, int flags) { static void refreshMultiLine(struct linenoiseState *l, int flags) {
char seq[64]; char seq[64];
int plen = l->plen; const int plen = l->plen;
int rows = (plen+l->len+l->cols-1)/l->cols; /* rows used by current buf. */ int rows = (plen+l->len+l->cols-1)/l->cols; /* rows used by current buf. */
int rpos = (plen+l->oldpos+l->cols)/l->cols; /* cursor relative row. */ const int rpos = (plen+l->oldpos+l->cols)/l->cols; /* cursor relative row. */
int rpos2; /* rpos after refresh. */ const int old_rows = l->oldrows;
int col; /* colum position, zero-based. */
int old_rows = l->oldrows;
int j;
struct abuf ab; struct abuf ab;
l->oldrows = rows; l->oldrows = rows;
@ -619,7 +604,7 @@ static void refreshMultiLine(struct linenoiseState *l, int flags) {
} }
/* Now for every row clear it, go up. */ /* 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++) {
snprintf(seq,64,"\r\x1b[0K\x1b[1A"); snprintf(seq,64,"\r\x1b[0K\x1b[1A");
abAppend(&ab,seq,strlen(seq)); abAppend(&ab,seq,strlen(seq));
} }
@ -635,8 +620,7 @@ static void refreshMultiLine(struct linenoiseState *l, int flags) {
/* Write the prompt and the current buffer content */ /* Write the prompt and the current buffer content */
abAppend(&ab,l->prompt,strlen(l->prompt)); abAppend(&ab,l->prompt,strlen(l->prompt));
if (maskmode == 1) { if (maskmode == 1) {
unsigned int i; for (unsigned int i = 0; i < l->len; i++) abAppend(&ab,"*",1);
for (i = 0; i < l->len; i++) abAppend(&ab,"*",1);
} else { } else {
abAppend(&ab,l->buf,l->len); abAppend(&ab,l->buf,l->len);
} }
@ -658,7 +642,7 @@ static void refreshMultiLine(struct linenoiseState *l, int flags) {
} }
/* Move cursor to right position. */ /* Move cursor to right position. */
rpos2 = (plen+l->pos+l->cols)/l->cols; /* Current cursor relative row */ const int rpos2 = (plen + l->pos + l->cols) / l->cols; /* Current cursor relative row */
/* Go up till we reach the expected positon. */ /* Go up till we reach the expected positon. */
if (rows-rpos2 > 0) { if (rows-rpos2 > 0) {
@ -667,7 +651,7 @@ static void refreshMultiLine(struct linenoiseState *l, int flags) {
} }
/* Set column. */ /* Set column. */
col = (plen+(int)l->pos) % (int)l->cols; const int col = (plen + (int) l->pos) % (int) l->cols;
if (col) if (col)
snprintf(seq,64,"\r\x1b[%dC", col); snprintf(seq,64,"\r\x1b[%dC", col);
else else
@ -726,7 +710,7 @@ int linenoiseEditInsert(struct linenoiseState *l, char c) {
if ((!mlmode && l->plen+l->len < l->cols && !hintsCallback)) { if ((!mlmode && l->plen+l->len < l->cols && !hintsCallback)) {
/* Avoid a full update of the line in the /* Avoid a full update of the line in the
* trivial case. */ * trivial case. */
char d = (maskmode==1) ? '*' : c; const char d = (maskmode==1) ? '*' : c;
if (fwrite(&d,1,1,stdout) == -1) return -1; if (fwrite(&d,1,1,stdout) == -1) return -1;
flushWrite(); flushWrite();
} else { } else {
@ -745,7 +729,7 @@ int linenoiseEditInsert(struct linenoiseState *l, char c) {
} }
int linenoiseInsertPastedChar(struct linenoiseState *l, char c) { int linenoiseInsertPastedChar(struct linenoiseState *l, char c) {
int fd = fileno(stdout); const int fd = fileno(stdout);
if (l->len < l->buflen && l->len == l->pos) { if (l->len < l->buflen && l->len == l->pos) {
l->buf[l->pos] = c; l->buf[l->pos] = c;
l->pos++; l->pos++;
@ -842,14 +826,13 @@ void linenoiseEditBackspace(struct linenoiseState *l) {
/* Delete the previosu word, maintaining the cursor at the start of the /* Delete the previosu word, maintaining the cursor at the start of the
* current word. */ * current word. */
void linenoiseEditDeletePrevWord(struct linenoiseState *l) { void linenoiseEditDeletePrevWord(struct linenoiseState *l) {
size_t old_pos = l->pos; const size_t old_pos = l->pos;
size_t diff;
while (l->pos > 0 && l->buf[l->pos-1] == ' ') while (l->pos > 0 && l->buf[l->pos-1] == ' ')
l->pos--; l->pos--;
while (l->pos > 0 && l->buf[l->pos - 1] != ' ') while (l->pos > 0 && l->buf[l->pos - 1] != ' ')
l->pos--; l->pos--;
diff = old_pos - l->pos; const size_t diff = old_pos - l->pos;
memmove(l->buf+l->pos,l->buf+old_pos,l->len-old_pos+1); memmove(l->buf+l->pos,l->buf+old_pos,l->len-old_pos+1);
l->len -= diff; l->len -= diff;
refreshLine(l); refreshLine(l);
@ -863,7 +846,7 @@ static char *linenoiseDumb(struct linenoiseState *l) {
// flushWrite(); // flushWrite();
l->len = 0; //needed? l->len = 0; //needed?
while (l->len < l->buflen) { while (l->len < l->buflen) {
int c = fgetc(stdin); const int c = fgetc(stdin);
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY); xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
if (c == '\n') { if (c == '\n') {
xSemaphoreGive(stdout_taken_sem); xSemaphoreGive(stdout_taken_sem);
@ -987,10 +970,7 @@ char *linenoiseEditMore = "If you see this, you are misusing the API: when linen
*/ */
char *linenoiseEditFeed(struct linenoiseState *l) { char *linenoiseEditFeed(struct linenoiseState *l) {
if (dumbmode) return linenoiseDumb(l); if (dumbmode) return linenoiseDumb(l);
uint32_t t1 = 0;
uint32_t t2;
char c; char c;
int nread;
char seq[3]; char seq[3];
/* /*
@ -1002,10 +982,10 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
* NOTE: pressing a key down without releasing it will also spend * NOTE: pressing a key down without releasing it will also spend
* about 40ms (or even more) * about 40ms (or even more)
*/ */
t1 = getMillis(); const uint32_t t1 = getMillis();
nread = fread(&c, 1, 1, stdin); const int nread = fread(&c, 1, 1, stdin);
if (nread <= 0) return linenoiseEditMore; if (nread <= 0) return linenoiseEditMore;
t2 = getMillis(); const uint32_t t2 = getMillis();
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY); xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
// FIXME: line printed twice after pasting something that takes more than 1 line // FIXME: line printed twice after pasting something that takes more than 1 line
if ( (t2 - t1) < LINENOISE_PASTE_KEY_DELAY && c != ENTER) { if ( (t2 - t1) < LINENOISE_PASTE_KEY_DELAY && c != ENTER) {
@ -1073,7 +1053,7 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
break; break;
case CTRL_T: /* ctrl-t, swaps current character with previous. */ case CTRL_T: /* ctrl-t, swaps current character with previous. */
if (l->pos > 0 && l->pos < l->len) { if (l->pos > 0 && l->pos < l->len) {
int aux = l->buf[l->pos-1]; const int aux = l->buf[l->pos-1];
l->buf[l->pos-1] = l->buf[l->pos]; l->buf[l->pos-1] = l->buf[l->pos];
l->buf[l->pos] = aux; l->buf[l->pos] = aux;
if (l->pos != l->len-1) l->pos++; if (l->pos != l->len-1) l->pos++;
@ -1208,6 +1188,7 @@ static char *linenoiseBlockingEdit(struct linenoiseState *l)
char *res; char *res;
l->buflen = max_cmdline_length; l->buflen = max_cmdline_length;
linenoiseEditStart(l); linenoiseEditStart(l);
// ReSharper disable once CppPossiblyErroneousEmptyStatements
while ((res = linenoiseEditFeed(l)) == linenoiseEditMore); while ((res = linenoiseEditFeed(l)) == linenoiseEditMore);
linenoiseEditStop(l); linenoiseEditStop(l);
return res; return res;
@ -1216,7 +1197,7 @@ static char *linenoiseBlockingEdit(struct linenoiseState *l)
int linenoiseProbe() { int linenoiseProbe() {
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY); xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
/* Switch to non-blocking mode */ /* Switch to non-blocking mode */
int stdin_fileno = fileno(stdin); const int stdin_fileno = fileno(stdin);
int flags = fcntl(stdin_fileno, F_GETFL); int flags = fcntl(stdin_fileno, F_GETFL);
flags |= O_NONBLOCK; flags |= O_NONBLOCK;
int res = fcntl(stdin_fileno, F_SETFL, flags); int res = fcntl(stdin_fileno, F_SETFL, flags);
@ -1230,13 +1211,14 @@ int linenoiseProbe() {
/* Try to read response */ /* Try to read response */
int timeout_ms = 500; int timeout_ms = 500;
const int retry_ms = 10;
size_t read_bytes = 0; size_t read_bytes = 0;
while (timeout_ms > 0 && read_bytes < 4) { // response is ESC[0n or ESC[3n while (timeout_ms > 0 && read_bytes < 4) {
const int retry_ms = 10;
// response is ESC[0n or ESC[3n
usleep(retry_ms * 1000); usleep(retry_ms * 1000);
timeout_ms -= retry_ms; timeout_ms -= retry_ms;
char c; char c;
int cb = read(stdin_fileno, &c, 1); const int cb = read(stdin_fileno, &c, 1);
if (cb < 0) { if (cb < 0) {
continue; continue;
} }
@ -1262,14 +1244,12 @@ int linenoiseProbe() {
} }
/* The high level function that is the main API of the linenoise library. */ /* The high level function that is the main API of the linenoise library. */
// passing ls_to_pass is optional, you can just provide NULL
char *linenoise(const char *prompt, struct linenoiseState **ls_to_pass) { char *linenoise(const char *prompt, struct linenoiseState **ls_to_pass) {
struct linenoiseState l; struct linenoiseState *l = *ls_to_pass;
if (ls_to_pass != NULL) *ls_to_pass = &l;
char *buf = calloc(1, max_cmdline_length); char *buf = calloc(1, max_cmdline_length);
l.prompt = prompt; l->prompt = prompt;
l.buf = buf; l->buf = buf;
char *retval = linenoiseBlockingEdit(&l); char *retval = linenoiseBlockingEdit(l);
free(buf); free(buf);
return retval; return retval;
} }
@ -1303,7 +1283,6 @@ void linenoiseHistoryFree() {
* *
* Using a circular buffer is smarter, but a bit more complex to handle. */ * Using a circular buffer is smarter, but a bit more complex to handle. */
int linenoiseHistoryAdd(const char *line) { int linenoiseHistoryAdd(const char *line) {
char *linecopy;
if (history_max_len == 0) return 0; if (history_max_len == 0) return 0;
@ -1319,7 +1298,7 @@ int linenoiseHistoryAdd(const char *line) {
/* Add an heap allocated copy of the line in the history. /* Add an heap allocated copy of the line in the history.
* If we reached the max length, remove the older line. */ * If we reached the max length, remove the older line. */
linecopy = strdup(line); char* linecopy = strdup(line);
if (!linecopy) return 0; if (!linecopy) return 0;
if (history_len == history_max_len) { if (history_len == history_max_len) {
free(history[0]); free(history[0]);
@ -1336,20 +1315,18 @@ int linenoiseHistoryAdd(const char *line) {
* just the latest 'len' elements if the new history length value is smaller * just the latest 'len' elements if the new history length value is smaller
* than the amount of items already inside the history. */ * than the amount of items already inside the history. */
int linenoiseHistorySetMaxLen(int len) { int linenoiseHistorySetMaxLen(int len) {
char **new;
if (len < 1) return 0; if (len < 1) return 0;
if (history) { if (history) {
int tocopy = history_len; int tocopy = history_len;
new = malloc(sizeof(char*)*len); char** new = malloc(sizeof(char*) * len);
if (new == NULL) return 0; if (new == NULL) return 0;
/* If we can't copy everything, free the elements we'll not use. */ /* If we can't copy everything, free the elements we'll not use. */
if (len < tocopy) { if (len < tocopy) {
int j;
for (j = 0; j < tocopy-len; j++) free(history[j]); for (int j = 0; j < tocopy-len; j++) free(history[j]);
tocopy = len; tocopy = len;
} }
memset(new,0,sizeof(char*)*len); memset(new,0,sizeof(char*)*len);
@ -1366,12 +1343,10 @@ int linenoiseHistorySetMaxLen(int len) {
/* Save the history in the specified file. On success 0 is returned /* Save the history in the specified file. On success 0 is returned
* otherwise -1 is returned. */ * otherwise -1 is returned. */
int linenoiseHistorySave(const char *filename) { int linenoiseHistorySave(const char *filename) {
FILE *fp;
int j;
fp = fopen(filename,"w"); FILE* fp = fopen(filename, "w");
if (fp == NULL) return -1; if (fp == NULL) return -1;
for (j = 0; j < history_len; j++) for (int j = 0; j < history_len; j++)
fprintf(fp,"%s\n",history[j]); fprintf(fp,"%s\n",history[j]);
fclose(fp); fclose(fp);
return 0; return 0;
@ -1393,8 +1368,7 @@ int linenoiseHistoryLoad(const char *filename) {
return -1; return -1;
} }
while (fgets(buf, max_cmdline_length, fp) != NULL) { while (fgets(buf, max_cmdline_length, fp) != NULL) {
char *p; char* p = strchr(buf, '\r');
p = strchr(buf,'\r');
if (!p) p = strchr(buf,'\n'); if (!p) p = strchr(buf,'\n');
if (p) *p = '\0'; if (p) *p = '\0';
linenoiseHistoryAdd(buf); linenoiseHistoryAdd(buf);