forked from test34/can_wizard
Multiplexing: API refactoring.
from orig commit c9d36d0, partial changes only, didn't include NoTTY support
This commit is contained in:
parent
73645ef92d
commit
16bcf3d8ad
2 changed files with 34 additions and 43 deletions
|
@ -760,31 +760,33 @@ int linenoiseEditStart(struct linenoiseState *l, char *buf, size_t buflen, const
|
|||
return 0;
|
||||
}
|
||||
|
||||
char *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.";
|
||||
|
||||
/* This function is part of the multiplexed API of linenoise, see the top
|
||||
* comment on linenoiseEditStart() for more information. Call this function
|
||||
* each time there is some data to read from the standard input file
|
||||
* descriptor. In the case of blocking operations, this function can just be
|
||||
* called in a loop, and block.
|
||||
*
|
||||
* The function returns NULL to signal that line editing is still in progress,
|
||||
* that is, the user didn't yet pressed enter / CTRL-D. Otherwise the function
|
||||
* returns the pointer to the buffer and populates '*len' with the current
|
||||
* buffer length. If '*len' is set to -1, some special condition occurred, and
|
||||
* the caller may want to check 'errno':
|
||||
* The function returns linenoiseEditMore to signal that line editing is still
|
||||
* in progress, that is, the user didn't yet pressed enter / CTRL-D. Otherwise
|
||||
* the function returns the pointer to the heap-allocated buffer with the
|
||||
* edited line, that the user should free with linenoiseFree().
|
||||
*
|
||||
* On special conditions, NULL is returned and errno is populated:
|
||||
*
|
||||
* EAGAIN if the user pressed Ctrl-C
|
||||
* ENOENT if the user pressed Ctrl-D
|
||||
*
|
||||
* Some other errno: I/O error.
|
||||
*/
|
||||
char *linenoiseEditFeed(struct linenoiseState *l, int *len) {
|
||||
char *linenoiseEditFeed(struct linenoiseState *l) {
|
||||
char c;
|
||||
int nread;
|
||||
char seq[3];
|
||||
|
||||
nread = fread(&c, 1, 1, stdin);
|
||||
if (nread <= 0) {
|
||||
if (len) *len = l->len;
|
||||
return l->buf;
|
||||
}
|
||||
if (nread <= 0) return NULL;
|
||||
|
||||
/* Only autocomplete when the callback is set. It returns < 0 when
|
||||
* there was an error reading from fd. Otherwise it will return the
|
||||
|
@ -792,12 +794,9 @@ char *linenoiseEditFeed(struct linenoiseState *l, int *len) {
|
|||
if (c == 9 && completionCallback != NULL) {
|
||||
c = completeLine(l);
|
||||
/* Return on errors */
|
||||
if (c < 0) {
|
||||
if (len) *len = -1;
|
||||
return l->buf;
|
||||
}
|
||||
if (c < 0) return NULL;
|
||||
/* Read next character when 0 */
|
||||
if (c == 0) return NULL;
|
||||
if (c == 0) return linenoiseEditMore;
|
||||
}
|
||||
|
||||
switch(c) {
|
||||
|
@ -813,12 +812,10 @@ char *linenoiseEditFeed(struct linenoiseState *l, int *len) {
|
|||
refreshLine(l);
|
||||
hintsCallback = hc;
|
||||
}
|
||||
if (len) *len = l->len;
|
||||
return l->buf;
|
||||
return strdup(l->buf);
|
||||
case CTRL_C: /* ctrl-c */
|
||||
errno = EAGAIN;
|
||||
if (len) *len = -1;
|
||||
return l->buf;
|
||||
return NULL;
|
||||
case BACKSPACE: /* backspace */
|
||||
case 8: /* ctrl-h */
|
||||
linenoiseEditBackspace(l);
|
||||
|
@ -830,9 +827,8 @@ char *linenoiseEditFeed(struct linenoiseState *l, int *len) {
|
|||
} else {
|
||||
history_len--;
|
||||
free(history[history_len]);
|
||||
if (len) *len = -1;
|
||||
errno = ENOENT;
|
||||
return l->buf;
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case CTRL_T: /* ctrl-t, swaps current character with previous. */
|
||||
|
@ -912,10 +908,7 @@ char *linenoiseEditFeed(struct linenoiseState *l, int *len) {
|
|||
}
|
||||
break;
|
||||
default:
|
||||
if (linenoiseEditInsert(l,c)) {
|
||||
if (len) *len = -1;
|
||||
return l->buf;
|
||||
}
|
||||
if (linenoiseEditInsert(l,c)) return NULL;
|
||||
break;
|
||||
case CTRL_U: /* Ctrl+u, delete the whole line. */
|
||||
l->buf[0] = '\0';
|
||||
|
@ -941,7 +934,7 @@ char *linenoiseEditFeed(struct linenoiseState *l, int *len) {
|
|||
linenoiseEditDeletePrevWord(l);
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
return linenoiseEditMore;
|
||||
}
|
||||
|
||||
|
||||
|
@ -957,33 +950,28 @@ void linenoiseEditStop(struct linenoiseState *l) {
|
|||
* In many applications that are not event-drivern, we can just call
|
||||
* the blocking linenoise API, wait for the user to complete the editing
|
||||
* and return the buffer. */
|
||||
static int linenoiseBlockingEdit(struct linenoiseState *l, int stdin_fd, int stdout_fd, char *buf, size_t buflen, const char *prompt)
|
||||
static char *linenoiseBlockingEdit(char *buf, size_t buflen, const char *prompt)
|
||||
{
|
||||
struct linenoiseState l;
|
||||
/* Editing without a buffer is invalid. */
|
||||
if (buflen == 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
linenoiseEditStart(l,buf,buflen,prompt);
|
||||
int len;
|
||||
while(1) {
|
||||
char *res = linenoiseEditFeed(l,&len);
|
||||
if (res != NULL) break;
|
||||
}
|
||||
linenoiseEditStop(l);
|
||||
return len;
|
||||
linenoiseEditStart(&l,buf,buflen,prompt);
|
||||
char *res;
|
||||
while((res = linenoiseEditFeed(&l)) == linenoiseEditMore);
|
||||
linenoiseEditStop(&l);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* The high level function that is the main API of the linenoise library. */
|
||||
char *linenoise(const char *prompt) {
|
||||
char buf[LINENOISE_MAX_LINE];
|
||||
int count;
|
||||
|
||||
struct linenoiseState l;
|
||||
count = linenoiseBlockingEdit(&l,-1,-1,buf,LINENOISE_MAX_LINE,prompt);
|
||||
if (count == -1) return NULL;
|
||||
return strdup(buf);
|
||||
char *retval = linenoiseBlockingEdit(buf,LINENOISE_MAX_LINE,prompt);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* This is just a wrapper the user may want to call in order to make sure
|
||||
|
@ -991,6 +979,7 @@ char *linenoise(const char *prompt) {
|
|||
* created with. Useful when the main program is using an alternative
|
||||
* allocator. */
|
||||
void linenoiseFree(void *ptr) {
|
||||
if (ptr == linenoiseEditMore) return; // Protect from API misuse.
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@ extern "C" {
|
|||
|
||||
#include <stddef.h> /* For size_t. */
|
||||
|
||||
extern char *linenoiseEditMore;
|
||||
|
||||
/* The linenoiseState structure represents the state during line editing.
|
||||
* We pass this state to functions implementing specific editing
|
||||
* functionalities. */
|
||||
|
@ -71,7 +73,7 @@ typedef struct linenoiseCompletions {
|
|||
|
||||
/* Non blocking API. */
|
||||
int linenoiseEditStart(struct linenoiseState *l, char *buf, size_t buflen, const char *prompt);
|
||||
char *linenoiseEditFeed(struct linenoiseState *l, int *len);
|
||||
char *linenoiseEditFeed(struct linenoiseState *l);
|
||||
void linenoiseEditStop(struct linenoiseState *l);
|
||||
void linenoiseHide(struct linenoiseState *l);
|
||||
void linenoiseShow(struct linenoiseState *l);
|
||||
|
|
Loading…
Reference in a new issue