[En-Nut-Discussion] More tweaks to the edline line editor

Philipp Burch phip at hb9etc.ch
Sun Nov 16 21:20:14 CET 2014


Hello,

I made some more tweaks to the edline line editor to improve the
usability when accessing it over a Telnet connection. The changes are
split over three distinct commits (r5894 .. r5896) into the devnut_tiva
branch, whereas the below patch combines them all in one. The commit
messages are as follows:

devnut_tiva$ svn commit -m 'Extended the line editor edline by a flush
feature. If EDIT_MODE_AUTOFLUSH is passed to EdLineOpen(), a flush
function is called whenever the editor modifies the input line in
EdLineRead(). This allows the editor and especially the history feature
to be used with buffered streams, e.g. for Telnet connections.'
nut/gorp/edit/edline.c nut/include/gorp/edline.h
Sending        nut/gorp/edit/edline.c
Sending        nut/include/gorp/edline.h
Transmitting file data ..
Committed revision 5894.

devnut_tiva$ svn commit -m 'Updated edline to avoid sending bells when
there is not actually a buffer overflow.' nut/gorp/edit/edline.c
Sending        nut/gorp/edit/edline.c
Transmitting file data .
Committed revision 5895.

devnut_tiva$ svn commit -m 'Updated the edline VT100 keymap to treat
character code 0x7f (DEL) as backspace. Some terminals use this code
instead of 0x08 (BS) for the backspace key.'
Sending        nut/gorp/edit/vt100.c
Transmitting file data .
Committed revision 5896.

Please consider integrating these changes into trunk, as they may be
useful for other people as well.

Cheers,
Philipp


Index: nut/gorp/edit/edline.c
===================================================================
--- nut/gorp/edit/edline.c	(revision 5892)
+++ nut/gorp/edit/edline.c	(working copy)
@@ -81,6 +81,7 @@
  * Uses stdout and may be replaced by calling EdLineRegisterOutput().
  *
  * \param param Optional parameter, ignored here.
+ * \param ch    Character to print.
  *
  * \return Character written or EOF in case of an error.
  */
@@ -90,6 +91,18 @@
 }

 /*!
+ * \brief Default flush routine.
+ *
+ * Uses stdout and may be replaced by calling EdLineRegisterFlush().
+ *
+ * \param param Optional parameter, ignored here.
+ */
+static void EdLineFlush(void *param)
+{
+    fflush(stdout);
+}
+
+/*!
  * \brief Register an input routine.
  *
  * Applications may use this function to replace the default character
@@ -136,6 +149,28 @@
 }

 /*!
+ * \brief Register a flush routine.
+ *
+ * Applications may use this function to replace the default flush routine.
+ *
+ * \param el    Pointer to an \ref EDLINE structure, obtained by a
+ *              previous call to \ref EdLineOpen.
+ * \param flush Pointer to the new flush routine. If NULL, then the
+ *              default routine is restored.
+ * \param param Optional parameter, which is passed to the output
+ *              routine.
+ */
+void EdLineRegisterFlush(EDLINE *el, EDLINEFLUSH flush, void *param)
+{
+    if (flush) {
+        el->el_flush = flush;
+    } else {
+        el->el_flush = EdLineFlush;
+    }
+    el->el_fparm = param;
+}
+
+/*!
  * \brief Default key mapping routine.
  *
  * Replaces carriage returns and linefeeds by \ref EDIT_KEY_ENTER.
@@ -208,6 +243,7 @@
         el->el_mode = mode;
         EdLineRegisterInput(el, NULL, stdin);
         EdLineRegisterOutput(el, NULL, stdout);
+        EdLineRegisterFlush(el, NULL, stdout);
         EdLineRegisterKeymap(el, NULL);
 #ifndef EDIT_DISABLE_HISTORY
         if (mode & EDIT_MODE_HISTORY) {
@@ -410,19 +446,21 @@
             cpos = strlen(buf);
         }
         /* Normal character, insert at cursor position if buffer is not
full. */
-        else if (isprint(ch) && strlen(buf) < siz - 1) {
-            for (i = siz - 1; i > cpos; i--) {
-                buf[i] = buf[i - 1];
+        else if (isprint(ch)) {
+            if (strlen(buf) < siz - 1) {
+                for (i = siz - 1; i > cpos; i--) {
+                    buf[i] = buf[i - 1];
+                }
+                buf[cpos++] = ch;
+                if (el->el_mode & EDIT_MODE_ECHO) {
+                    (*el->el_put)(el->el_oparm, ch);
+                }
+                PrintString(el, &buf[cpos]);
+                PrintCharacter(el, EDIT_CHAR_BACKSPACE, strlen(buf) -
cpos);
+            } else {
+                /* Beep on buffer overflow. */
+                (*el->el_put)(el->el_oparm, EDIT_CHAR_ALARM);
             }
-            buf[cpos++] = ch;
-            if (el->el_mode & EDIT_MODE_ECHO) {
-                (*el->el_put)(el->el_oparm, ch);
-            }
-            PrintString(el, &buf[cpos]);
-            PrintCharacter(el, EDIT_CHAR_BACKSPACE, strlen(buf) - cpos);
-        } else {
-            /* Beep on buffer overflow. */
-            (*el->el_put)(el->el_oparm, EDIT_CHAR_ALARM);
         }
 #ifndef EDIT_DISABLE_HISTORY
         if (refresh && (el->el_mode & EDIT_MODE_HISTORY) != 0) {
@@ -435,6 +473,9 @@
             ClearLineEnd(el, ipos - cpos);
         }
 #endif
+        if (el->el_mode & EDIT_MODE_AUTOFLUSH) {
+            el->el_flush(el->el_fparm);
+        }
     }
     PrintString(el, EDIT_STR_EOL);
 #ifndef EDIT_DISABLE_HISTORY
Index: nut/gorp/edit/vt100.c
===================================================================
--- nut/gorp/edit/vt100.c	(revision 5892)
+++ nut/gorp/edit/vt100.c	(working copy)
@@ -111,6 +111,10 @@
         (*seq) = 1;
         key = EDIT_KEY_IGNORE;
     }
+    else if (key == 0x7f) {
+        (*seq) = 0;
+        key = EDIT_KEY_REMOVE;
+    }
     else {
         key = EdLineKeyMap(key, seq);
     }
Index: nut/include/gorp/edline.h
===================================================================
--- nut/include/gorp/edline.h	(revision 5892)
+++ nut/include/gorp/edline.h	(working copy)
@@ -65,6 +65,9 @@
 #define EDIT_MODE_BINARY    0x0002
 /*! \brief Enables input line history. */
 #define EDIT_MODE_HISTORY   0x0004
+/*! \brief Enables calls to the flush function when the editor modifies
+ *  the input line during a read. */
+#define EDIT_MODE_AUTOFLUSH 0x0008
 /*@}*/

 /*!
@@ -155,6 +158,8 @@
 typedef int (*EDLINEGET) (void *);
 /*! \brief Output routine type. */
 typedef int (*EDLINEPUT) (void *, int);
+/*! \brief Flush routine type. */
+typedef void (*EDLINEFLUSH) (void *);
 /*! \brief Character mapping routine type. */
 typedef int (*EDLINEMAP) (int, int *);

@@ -168,6 +173,10 @@
     EDLINEPUT el_put;
     /*! \brief Output routine parameter. */
     void *el_oparm;
+    /*! \brief Flush routine. */
+    EDLINEFLUSH el_flush;
+    /*! \brief Flush routine parameter. */
+    void *el_fparm;
     /*! \brief Character mapping routine. */
     EDLINEMAP el_map;
     /*! \brief Editor mode flags. */
@@ -200,5 +209,6 @@

 extern void EdLineRegisterInput(EDLINE *el, EDLINEGET get, void *iparm);
 extern void EdLineRegisterOutput(EDLINE *el, EDLINEPUT put, void *oparm);
+extern void EdLineRegisterFlush(EDLINE *el, EDLINEFLUSH flush, void
*oparm);

 #endif


More information about the En-Nut-Discussion mailing list