Fix bugs in EMACS command line editor, primarily errors in the VT100 commands

This commit is contained in:
Gregory Nutt 2014-02-02 12:24:45 -06:00
parent 82d71bb439
commit 9d49d3969f

View File

@ -91,7 +91,7 @@
#undef CTRL #undef CTRL
#define CTRL(a) ((a) & 0x1f) #define CTRL(a) ((a) & 0x1f)
#define CLE_BEL(cle) cle_putch(cle,CTRL('G')) #define CLE_BEL(priv) cle_putch(priv,CTRL('G'))
/* Sizes of things */ /* Sizes of things */
@ -101,40 +101,35 @@
/* Debug */ /* Debug */
#ifndef CONFIG_SYSEM_CLE_DEBUGLEVEL #ifndef CONFIG_SYSTEM_CLE_DEBUGLEVEL
# define CONFIG_SYSEM_CLE_DEBUGLEVEL 0 # define CONFIG_SYSTEM_CLE_DEBUGLEVEL 0
#endif #endif
#ifdef CONFIG_CPP_HAVE_VARARGS #ifdef CONFIG_CPP_HAVE_VARARGS
# if CONFIG_SYSEM_CLE_DEBUGLEVEL > 0 # if CONFIG_SYSTEM_CLE_DEBUGLEVEL > 0
# define vidbg(format, arg...) \ # define cledbg(format, arg...) \
syslog(EXTRA_FMT format EXTRA_ARG, ##arg) syslog(EXTRA_FMT format EXTRA_ARG, ##arg)
# define vvidbg(format, ap) \
vsyslog(format, ap)
# else # else
# define vidbg(x...) # define cledbg(x...)
# define vvidbg(x...)
# endif # endif
# if CONFIG_SYSEM_CLE_DEBUGLEVEL > 1 # if CONFIG_SYSTEM_CLE_DEBUGLEVEL > 1
# define vivdbg(format, arg...) \ # define clevdbg(format, arg...) \
syslog(EXTRA_FMT format EXTRA_ARG, ##arg) syslog(EXTRA_FMT format EXTRA_ARG, ##arg)
# else # else
# define vivdbg(x...) # define clevdbg(x...)
# endif # endif
#else #else
# if CONFIG_SYSEM_CLE_DEBUGLEVEL > 0 # if CONFIG_SYSTEM_CLE_DEBUGLEVEL > 0
# define vidbg syslog # define cledbg syslog
# define vvidbg vsyslog
# else # else
# define vidbg (void) # define cledbg (void)
# define vvidbg (void)
# endif # endif
# if CONFIG_SYSEM_CLE_DEBUGLEVEL > 1 # if CONFIG_SYSTEM_CLE_DEBUGLEVEL > 1
# define vivdbg syslog # define clevdbg syslog
# else # else
# define vivdbg (void) # define clevdbg (void)
# endif # endif
#endif #endif
@ -162,7 +157,7 @@ struct cle_s
{ {
uint16_t curpos; /* Current cursor position */ uint16_t curpos; /* Current cursor position */
uint16_t cursave; /* Saved cursor position */ uint16_t cursave; /* Saved cursor position */
uint16_t row; /* This is the row that we are editing iun */ uint16_t row; /* This is the row that we are editing in */
uint16_t coloffs; /* Left cursor offset */ uint16_t coloffs; /* Left cursor offset */
uint16_t linelen; /* Size of the line buffer */ uint16_t linelen; /* Size of the line buffer */
uint16_t nchars; /* Size of data in the line buffer */ uint16_t nchars; /* Size of data in the line buffer */
@ -177,25 +172,25 @@ struct cle_s
/* Low-level display and data entry functions */ /* Low-level display and data entry functions */
static void cle_write(FAR struct cle_s *cle, FAR const char *buffer, static void cle_write(FAR struct cle_s *priv, FAR const char *buffer,
uint16_t buflen); uint16_t buflen);
static void cle_putch(FAR struct cle_s *cle, char ch); static void cle_putch(FAR struct cle_s *priv, char ch);
static int cle_getch(FAR struct cle_s *cle); static int cle_getch(FAR struct cle_s *priv);
static void cle_cursoron(FAR struct cle_s *cle); static void cle_cursoron(FAR struct cle_s *priv);
static void cle_cursoroff(FAR struct cle_s *cle); static void cle_cursoroff(FAR struct cle_s *priv);
static void cle_setcursor(FAR struct cle_s *cle, uint16_t column); static void cle_setcursor(FAR struct cle_s *priv, uint16_t column);
static int cle_getcursor(FAR struct cle_s *cle, uint16_t *prow, static int cle_getcursor(FAR struct cle_s *priv, uint16_t *prow,
uint16_t *pcolumn); uint16_t *pcolumn);
static void cle_clrtoeol(FAR struct cle_s *cle); static void cle_clrtoeol(FAR struct cle_s *priv);
/* Editor function */ /* Editor function */
static bool cle_opentext(FAR struct cle_s *cle, uint16_t pos, static bool cle_opentext(FAR struct cle_s *priv, uint16_t pos,
uint16_t increment); uint16_t increment);
static void cle_closetext(FAR struct cle_s *cle, uint16_t pos, uint16_t size); static void cle_closetext(FAR struct cle_s *priv, uint16_t pos, uint16_t size);
static void cle_showtext(FAR struct cle_s *cle); static void cle_showtext(FAR struct cle_s *priv);
static void cle_insertch(FAR struct cle_s *cle, char ch); static void cle_insertch(FAR struct cle_s *priv, char ch);
static int cle_editloop(FAR struct cle_s *cle); static int cle_editloop(FAR struct cle_s *priv);
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
@ -218,10 +213,6 @@ static const char g_fmtnotvalid[] = "Command not valid";
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
/****************************************************************************
* Low-level display and data entry functions
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: cle_write * Name: cle_write
* *
@ -230,13 +221,13 @@ static const char g_fmtnotvalid[] = "Command not valid";
* *
****************************************************************************/ ****************************************************************************/
static void cle_write(FAR struct cle_s *cle, FAR const char *buffer, static void cle_write(FAR struct cle_s *priv, FAR const char *buffer,
uint16_t buflen) uint16_t buflen)
{ {
ssize_t nwritten; ssize_t nwritten;
uint16_t nremaining = buflen; uint16_t nremaining = buflen;
//vivdbg("buffer=%p buflen=%d\n", buffer, (int)buflen); //clevdbg("buffer=%p buflen=%d\n", buffer, (int)buflen);
/* Loop until all bytes have been successuflly written (or until a /* Loop until all bytes have been successuflly written (or until a
* un-recoverable error is encountered) * un-recoverable error is encountered)
@ -246,7 +237,7 @@ static void cle_write(FAR struct cle_s *cle, FAR const char *buffer,
{ {
/* Take the next gulp */ /* Take the next gulp */
nwritten = write(cle->outfd, buffer, buflen); nwritten = write(priv->outfd, buffer, buflen);
/* Handle write errors. write() should neve return 0. */ /* Handle write errors. write() should neve return 0. */
@ -259,7 +250,7 @@ static void cle_write(FAR struct cle_s *cle, FAR const char *buffer,
int errcode = errno; int errcode = errno;
if (nwritten == 0 || errcode != EINTR) if (nwritten == 0 || errcode != EINTR)
{ {
vidbg("ERROR: write to stdout failed: %d\n", errcode); cledbg("ERROR: write to stdout failed: %d\n", errcode);
return; return;
} }
} }
@ -284,9 +275,9 @@ static void cle_write(FAR struct cle_s *cle, FAR const char *buffer,
* *
****************************************************************************/ ****************************************************************************/
static void cle_putch(FAR struct cle_s *cle, char ch) static void cle_putch(FAR struct cle_s *priv, char ch)
{ {
cle_write(cle, &ch, 1); cle_write(priv, &ch, 1);
} }
/**************************************************************************** /****************************************************************************
@ -297,7 +288,7 @@ static void cle_putch(FAR struct cle_s *cle, char ch)
* *
****************************************************************************/ ****************************************************************************/
static int cle_getch(FAR struct cle_s *cle) static int cle_getch(FAR struct cle_s *priv)
{ {
char buffer; char buffer;
ssize_t nread; ssize_t nread;
@ -310,7 +301,7 @@ static int cle_getch(FAR struct cle_s *cle)
{ {
/* Read one character from the incoming stream */ /* Read one character from the incoming stream */
nread = read(cle->infd, &buffer, 1); nread = read(priv->infd, &buffer, 1);
/* Check for error or end-of-file. */ /* Check for error or end-of-file. */
@ -323,7 +314,7 @@ static int cle_getch(FAR struct cle_s *cle)
int errcode = errno; int errcode = errno;
if (nread == 0 || errcode != EINTR) if (nread == 0 || errcode != EINTR)
{ {
vidbg("ERROR: read from stdin failed: %d\n", errcode); cledbg("ERROR: read from stdin failed: %d\n", errcode);
return -EIO; return -EIO;
} }
} }
@ -332,7 +323,7 @@ static int cle_getch(FAR struct cle_s *cle)
/* On success, return the character that was read */ /* On success, return the character that was read */
vivdbg("Returning: %c[%02x]\n", isprint(buffer) ? buffer : '.', buffer); clevdbg("Returning: %c[%02x]\n", isprint(buffer) ? buffer : '.', buffer);
return buffer; return buffer;
} }
@ -344,11 +335,11 @@ static int cle_getch(FAR struct cle_s *cle)
* *
****************************************************************************/ ****************************************************************************/
static void cle_cursoron(FAR struct cle_s *cle) static void cle_cursoron(FAR struct cle_s *priv)
{ {
/* Send the VT100 CURSORON command */ /* Send the VT100 CURSORON command */
cle_write(cle, g_cursoron, sizeof(g_cursoron)); cle_write(priv, g_cursoron, sizeof(g_cursoron));
} }
/**************************************************************************** /****************************************************************************
@ -359,11 +350,11 @@ static void cle_cursoron(FAR struct cle_s *cle)
* *
****************************************************************************/ ****************************************************************************/
static void cle_cursoroff(FAR struct cle_s *cle) static void cle_cursoroff(FAR struct cle_s *priv)
{ {
/* Send the VT100 CURSOROFF command */ /* Send the VT100 CURSOROFF command */
cle_write(cle, g_cursoroff, sizeof(g_cursoroff)); cle_write(priv, g_cursoroff, sizeof(g_cursoroff));
} }
/**************************************************************************** /****************************************************************************
@ -374,20 +365,20 @@ static void cle_cursoroff(FAR struct cle_s *cle)
* *
****************************************************************************/ ****************************************************************************/
static void cle_setcursor(FAR struct cle_s *cle, uint16_t column) static void cle_setcursor(FAR struct cle_s *priv, uint16_t column)
{ {
char buffer[16]; char buffer[16];
int len; int len;
vivdbg("row=%d column=%d\n", row, column); clevdbg("row=%d column=%d offset=%d\n", priv->row, column, priv->coloffs);
/* Format the cursor position command. The origin is (1,1). */ /* Format the cursor position command. The origin is (1,1). */
len = snprintf(buffer, 16, g_fmtcursorpos, cle->row, column + cle->coloffs); len = snprintf(buffer, 16, g_fmtcursorpos, priv->row, column + priv->coloffs);
/* Send the VT100 CURSORPOS command */ /* Send the VT100 CURSORPOS command */
cle_write(cle, buffer, len); cle_write(priv, buffer, len);
} }
/**************************************************************************** /****************************************************************************
@ -398,7 +389,7 @@ static void cle_setcursor(FAR struct cle_s *cle, uint16_t column)
* *
****************************************************************************/ ****************************************************************************/
static int cle_getcursor(FAR struct cle_s *cle, FAR uint16_t *prow, static int cle_getcursor(FAR struct cle_s *priv, FAR uint16_t *prow,
FAR uint16_t *pcolumn) FAR uint16_t *pcolumn)
{ {
uint32_t row; uint32_t row;
@ -408,16 +399,16 @@ static int cle_getcursor(FAR struct cle_s *cle, FAR uint16_t *prow,
/* Send the VT100 GETCURSOR command */ /* Send the VT100 GETCURSOR command */
cle_write(cle, g_getcursor, sizeof(g_getcursor)); cle_write(priv, g_getcursor, sizeof(g_getcursor));
/* We expect to get ESCv;hR where v is the row and h is the column */ /* We expect to get ESC[v;hR where v is the row and h is the column */
nbad = 0; nbad = 0;
for (;;) for (;;)
{ {
/* Get the next character from the input */ /* Get the next character from the input */
ch = cle_getch(cle); ch = cle_getch(priv);
if (ch == ASCII_ESC) if (ch == ASCII_ESC)
{ {
break; break;
@ -434,14 +425,38 @@ static int cle_getcursor(FAR struct cle_s *cle, FAR uint16_t *prow,
} }
} }
/* Now we expect to see a numeric value terminated with ';' */ /* Have ESC, now we expect '[' */
nbad = 0;
for (;;)
{
/* Get the next character from the input */
ch = cle_getch(priv);
if (ch == '[')
{
break;
}
else if (ch < 0)
{
return -EIO;
}
else
{
/* We are probably talking to a non-VT100 terminal! */
return -EINVAL;
}
}
/* Have ESC'['. Now we expect to see a numeric value terminated with ';' */
row = 0; row = 0;
for (;;) for (;;)
{ {
/* Get the next character from the input */ /* Get the next character from the input */
ch = cle_getch(cle); ch = cle_getch(priv);
if (isdigit(ch)) if (isdigit(ch))
{ {
row = 10*row + (ch - '0'); row = 10*row + (ch - '0');
@ -460,14 +475,14 @@ static int cle_getcursor(FAR struct cle_s *cle, FAR uint16_t *prow,
} }
} }
/* Now we expect to see another numeric value terminated with 'R' */ /* Have ESC'['v';'. Now we expect to see another numeric value terminated with 'R' */
column = 0; column = 0;
for (;;) for (;;)
{ {
/* Get the next character from the input */ /* Get the next character from the input */
ch = cle_getch(cle); ch = cle_getch(priv);
if (isdigit(ch)) if (isdigit(ch))
{ {
column = 10*column + (ch - '0'); column = 10*column + (ch - '0');
@ -486,7 +501,7 @@ static int cle_getcursor(FAR struct cle_s *cle, FAR uint16_t *prow,
} }
} }
vivdbg("row=%ld column=%ld\n", row, column); clevdbg("row=%ld column=%ld\n", row, column);
/* Make sure that the values are within range */ /* Make sure that the values are within range */
@ -509,11 +524,11 @@ static int cle_getcursor(FAR struct cle_s *cle, FAR uint16_t *prow,
* *
****************************************************************************/ ****************************************************************************/
static void cle_clrtoeol(FAR struct cle_s *cle) static void cle_clrtoeol(FAR struct cle_s *priv)
{ {
/* Send the VT100 ERASETOEOL command */ /* Send the VT100 ERASETOEOL command */
cle_write(cle, g_erasetoeol, sizeof(g_erasetoeol)); cle_write(priv, g_erasetoeol, sizeof(g_erasetoeol));
} }
/**************************************************************************** /****************************************************************************
@ -525,17 +540,17 @@ static void cle_clrtoeol(FAR struct cle_s *cle)
* *
****************************************************************************/ ****************************************************************************/
static bool cle_opentext(FAR struct cle_s *cle, uint16_t pos, uint16_t increment) static bool cle_opentext(FAR struct cle_s *priv, uint16_t pos, uint16_t increment)
{ {
int i; int i;
vivdbg("pos=%ld increment=%ld\n", (long)pos, (long)increment); clevdbg("pos=%ld increment=%ld\n", (long)pos, (long)increment);
/* Check if there is space in the line buffer to open up a region the size /* Check if there is space in the line buffer to open up a region the size
* of 'increment' * of 'increment'
*/ */
if (cle->nchars + increment > cle->linelen) if (priv->nchars + increment > priv->linelen)
{ {
return false; return false;
} }
@ -544,14 +559,14 @@ static bool cle_opentext(FAR struct cle_s *cle, uint16_t pos, uint16_t increment
* cursor position * cursor position
*/ */
for (i = cle->nchars - 1; i >= pos; i--) for (i = priv->nchars - 1; i >= pos; i--)
{ {
cle->line[i + increment] = cle->line[i]; priv->line[i + increment] = priv->line[i];
} }
/* Adjust end of file position */ /* Adjust end of file position */
cle->nchars += increment; priv->nchars += increment;
return true; return true;
} }
@ -564,39 +579,39 @@ static bool cle_opentext(FAR struct cle_s *cle, uint16_t pos, uint16_t increment
* *
****************************************************************************/ ****************************************************************************/
static void cle_closetext(FAR struct cle_s *cle, uint16_t pos, uint16_t size) static void cle_closetext(FAR struct cle_s *priv, uint16_t pos, uint16_t size)
{ {
int i; int i;
vivdbg("pos=%ld size=%ld\n", (long)pos, (long)size); clevdbg("pos=%ld size=%ld\n", (long)pos, (long)size);
/* Close up the gap to remove 'size' characters at 'pos' */ /* Close up the gap to remove 'size' characters at 'pos' */
for (i = pos + size; i < cle->nchars; i++) for (i = pos + size; i < priv->nchars; i++)
{ {
cle->line[i - size] = cle->line[i]; priv->line[i - size] = priv->line[i];
} }
/* Adjust sizes and positions */ /* Adjust sizes and positions */
cle->nchars -= size; priv->nchars -= size;
/* Check if the cursor position is beyond the deleted region */ /* Check if the cursor position is beyond the deleted region */
if (cle->curpos > pos + size) if (priv->curpos > pos + size)
{ {
/* Yes... just subtract the size of the deleted region */ /* Yes... just subtract the size of the deleted region */
cle->curpos -= size; priv->curpos -= size;
} }
/* What if the position is within the deleted region? Set it to the /* What if the position is within the deleted region? Set it to the
* beginning of the deleted region. * beginning of the deleted region.
*/ */
else if (cle->curpos > pos) else if (priv->curpos > pos)
{ {
cle->curpos = pos; priv->curpos = pos;
} }
} }
@ -610,34 +625,34 @@ static void cle_closetext(FAR struct cle_s *cle, uint16_t pos, uint16_t size)
* *
****************************************************************************/ ****************************************************************************/
static void cle_showtext(FAR struct cle_s *cle) static void cle_showtext(FAR struct cle_s *priv)
{ {
uint16_t column; uint16_t column;
uint16_t tabcol; uint16_t tabcol;
/* Turn off the cursor during the update. */ /* Turn off the cursor during the update. */
cle_cursoroff(cle); cle_cursoroff(priv);
/* Set the cursor position to the beginning of this row */ /* Set the cursor position to the beginning of this row */
cle_setcursor(cle, 0); cle_setcursor(priv, 0);
cle_clrtoeol(cle); cle_clrtoeol(priv);
/* Loop for each column */ /* Loop for each column */
for (column = 0; column < cle->nchars && column < cle->linelen; column++) for (column = 0; column < priv->nchars && column < priv->linelen; )
{ {
/* Perform TAB expansion */ /* Perform TAB expansion */
if (cle->line[column] == '\t') if (priv->line[column] == '\t')
{ {
tabcol = NEXT_TAB(column); tabcol = NEXT_TAB(column);
if (tabcol < cle->linelen) if (tabcol < priv->linelen)
{ {
for (; column < tabcol; column++) for (; column < tabcol; column++)
{ {
cle_putch(cle, ' '); cle_putch(priv, ' ');
} }
} }
else else
@ -654,14 +669,14 @@ static void cle_showtext(FAR struct cle_s *cle)
else else
{ {
cle_putch(cle, cle->line[column]); cle_putch(priv, priv->line[column]);
column++; column++;
} }
} }
/* Turn the cursor back on */ /* Turn the cursor back on */
cle_cursoron(cle); cle_cursoron(priv);
} }
/**************************************************************************** /****************************************************************************
@ -672,17 +687,17 @@ static void cle_showtext(FAR struct cle_s *cle)
* *
****************************************************************************/ ****************************************************************************/
static void cle_insertch(FAR struct cle_s *cle, char ch) static void cle_insertch(FAR struct cle_s *priv, char ch)
{ {
vivdbg("curpos=%ld ch=%c[%02x]\n", cle->curpos, isprint(ch) ? ch : '.', ch); clevdbg("curpos=%ld ch=%c[%02x]\n", priv->curpos, isprint(ch) ? ch : '.', ch);
/* Make space in the buffer for the new character */ /* Make space in the buffer for the new character */
if (cle_opentext(cle, cle->curpos, 1)) if (cle_opentext(priv, priv->curpos, 1))
{ {
/* Add the new character to the buffer */ /* Add the new character to the buffer */
cle->line[cle->curpos++] = ch; priv->line[priv->curpos++] = ch;
} }
} }
@ -694,7 +709,7 @@ static void cle_insertch(FAR struct cle_s *cle, char ch)
* *
****************************************************************************/ ****************************************************************************/
static int cle_editloop(FAR struct cle_s *cle) static int cle_editloop(FAR struct cle_s *priv)
{ {
/* Loop while we are in command mode */ /* Loop while we are in command mode */
@ -704,12 +719,12 @@ static int cle_editloop(FAR struct cle_s *cle)
/* Make sure that the display reflects the current state */ /* Make sure that the display reflects the current state */
cle_showtext(cle); cle_showtext(priv);
cle_setcursor(cle, cle->curpos); cle_setcursor(priv, priv->curpos);
/* Get the next character from the input */ /* Get the next character from the input */
ch = cle_getch(cle); ch = cle_getch(priv);
if (ch < 0) if (ch < 0)
{ {
return -EIO; return -EIO;
@ -721,19 +736,19 @@ static int cle_editloop(FAR struct cle_s *cle)
{ {
case KEY_BEGINLINE: /* Move cursor to start of current line */ case KEY_BEGINLINE: /* Move cursor to start of current line */
{ {
cle->curpos = 0; priv->curpos = 0;
} }
break; break;
case KEY_LEFT: /* Move the cursor left 1 character */ case KEY_LEFT: /* Move the cursor left 1 character */
{ {
if (cle->curpos > 0) if (priv->curpos > 0)
{ {
cle->curpos--; priv->curpos--;
} }
else else
{ {
CLE_BEL(cle); CLE_BEL(priv);
} }
} }
break; break;
@ -741,39 +756,32 @@ static int cle_editloop(FAR struct cle_s *cle)
case KEY_DEL: /* Delete 1 character at the cursor */ case KEY_DEL: /* Delete 1 character at the cursor */
case ASCII_DEL: case ASCII_DEL:
{ {
if (cle->curpos < cle->nchars) if (priv->curpos < priv->nchars)
{ {
cle_closetext(cle, cle->curpos, 1); cle_closetext(priv, priv->curpos, 1);
} }
else else
{ {
CLE_BEL(cle); CLE_BEL(priv);
} }
} }
break; break;
case KEY_ENDLINE: /* Move cursor to end of current line */ case KEY_ENDLINE: /* Move cursor to end of current line */
{ {
if (cle->nchars > 0) priv->curpos = priv->nchars;
{
cle->curpos = cle->nchars - 1;
}
else
{
CLE_BEL(cle);
}
} }
break; break;
case KEY_RIGHT: /* Move the cursor right one character */ case KEY_RIGHT: /* Move the cursor right one character */
{ {
if (cle->curpos < cle->nchars) if (priv->curpos < priv->nchars)
{ {
cle->curpos++; priv->curpos++;
} }
else else
{ {
CLE_BEL(cle); CLE_BEL(priv);
} }
} }
break; break;
@ -781,33 +789,33 @@ static int cle_editloop(FAR struct cle_s *cle)
case KEY_DELLEFT: /* Delete 1 character before the cursor */ case KEY_DELLEFT: /* Delete 1 character before the cursor */
//case ASCII_BS: //case ASCII_BS:
{ {
if (cle->curpos > 0) if (priv->curpos > 0)
{ {
cle_closetext(cle, --cle->curpos, 1); cle_closetext(priv, --priv->curpos, 1);
} }
else else
{ {
CLE_BEL(cle); CLE_BEL(priv);
} }
} }
break; break;
case KEY_DELEOL: /* Delete to the end of the line */ case KEY_DELEOL: /* Delete to the end of the line */
{ {
cle->nchars = (cle->nchars > 0 ? cle->curpos + 1 : 0); priv->nchars = (priv->nchars > 0 ? priv->curpos + 1 : 0);
} }
break; break;
case KEY_DELLINE: /* Delete to the end of the line */ case KEY_DELLINE: /* Delete to the end of the line */
{ {
cle->nchars = 0; priv->nchars = 0;
cle->curpos = 0; priv->curpos = 0;
} }
break; break;
case KEY_QUOTE: /* Quoted character follows */ case KEY_QUOTE: /* Quoted character follows */
{ {
ch = cle_getch(cle); ch = cle_getch(priv);
if (ch < 0) if (ch < 0)
{ {
return -EIO; return -EIO;
@ -815,7 +823,7 @@ static int cle_editloop(FAR struct cle_s *cle)
/* Insert the next character unconditionally */ /* Insert the next character unconditionally */
cle_insertch(cle, ch); cle_insertch(priv, ch);
} }
break; break;
@ -859,11 +867,11 @@ static int cle_editloop(FAR struct cle_s *cle)
{ {
/* Insert the filtered character into the buffer */ /* Insert the filtered character into the buffer */
cle_insertch(cle, ch); cle_insertch(priv, ch);
} }
else else
{ {
CLE_BEL(cle); CLE_BEL(priv);
} }
} }
break; break;
@ -892,23 +900,25 @@ static int cle_editloop(FAR struct cle_s *cle)
int cle(FAR char *line, uint16_t linelen, FILE *instream, FILE *outstream) int cle(FAR char *line, uint16_t linelen, FILE *instream, FILE *outstream)
{ {
FAR struct cle_s cle; FAR struct cle_s priv;
uint16_t column; uint16_t column;
int ret; int ret;
/* Initialize the cle state structure */ /* Initialize the CLE state structure */
cle.linelen = linelen; memset(&priv, 0, sizeof(struct cle_s));
cle.line = line;
priv.linelen = linelen;
priv.line = line;
/* REVISIT: Non-standard, non-portable */ /* REVISIT: Non-standard, non-portable */
cle.infd = instream->fs_fd; priv.infd = instream->fs_fd;
cle.outfd = outstream->fs_fd; priv.outfd = outstream->fs_fd;
/* Get the current cursor position */ /* Get the current cursor position */
ret = cle_getcursor(&cle, &cle.row, &column); ret = cle_getcursor(&priv, &priv.row, &column);
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
@ -921,9 +931,11 @@ int cle(FAR char *line, uint16_t linelen, FILE *instream, FILE *outstream)
return -EINVAL; return -EINVAL;
} }
cle.coloffs = column - 1; priv.coloffs = column - 1;
clevdbg("row=%d column=%d\n", priv.row, column);
/* The editor loop */ /* The editor loop */
return cle_editloop(&cle); return cle_editloop(&priv);
} }