summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJefferson Delfes <jefferson.delfes@gmail.com>2013-10-21 10:32:16 -0400
committerJefferson Delfes <jefferson.delfes@gmail.com>2013-10-21 14:30:06 -0400
commit1cf6f20a6ed77e7677405d798a3c8b355664b9f7 (patch)
tree54aa74ad99821fca5c28acfbb65c739327f41616
parent2e9d705c155203af66c72dd70af3c363c88415a5 (diff)
rl_helper: implement a minimal line editing prompt
With this helper, we can replace fgets and printf, so we are able to do editing line and command history.
-rw-r--r--Android.mk2
-rw-r--r--rl_helper.c118
-rw-r--r--rl_helper.h13
3 files changed, 132 insertions, 1 deletions
diff --git a/Android.mk b/Android.mk
index c6aae80..7e5fe03 100644
--- a/Android.mk
+++ b/Android.mk
@@ -2,7 +2,7 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := btctl.c util.c
+LOCAL_SRC_FILES := btctl.c util.c rl_helper.c
LOCAL_SHARED_LIBRARIES := libhardware
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE := btctl
diff --git a/rl_helper.c b/rl_helper.c
new file mode 100644
index 0000000..1e7c2ae
--- /dev/null
+++ b/rl_helper.c
@@ -0,0 +1,118 @@
+/*
+ * Line editing helper
+ *
+ * Copyright (C) 2013 Jefferson Delfes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <termios.h>
+#include "rl_helper.h"
+
+#define MAX_LINE_BUFFER 512
+
+typedef enum {
+ K_ESC = 0x1b,
+ K_BACKSPACE = 0x7f,
+ /* user defined codes (used for escape sequences */
+ K_UP = 0x100,
+ K_DOWN = 0x101,
+ K_RIGHT = 0x102,
+ K_LEFT = 0x103,
+} keys_t;
+
+line_process_callback line_cb;
+char lnbuf[MAX_LINE_BUFFER]; /* buffer for our line editing */
+size_t pos = 0;
+
+void rl_clear() {
+
+ memset(lnbuf, 0, sizeof(lnbuf));
+ pos = 0;
+}
+
+/* clear current line and returns to line begin */
+void rl_clear_line() {
+
+ printf("\x1b[2K\r");
+}
+
+void rl_reprint_prompt() {
+
+ rl_clear_line();
+ printf("> %s", lnbuf);
+ fflush(stdout);
+}
+
+void rl_init(line_process_callback cb) {
+ struct termios settings;
+
+ /* disable echo */
+ tcgetattr(0, &settings); /* read settings from stdin (0) */
+ settings.c_lflag &= ~(ICANON | ECHO); /* disable canonical and echo flags */
+ tcsetattr(0, TCSANOW, &settings); /* store new settings */
+
+ rl_clear();
+ line_cb = cb;
+}
+
+void rl_quit() {
+
+ rl_clear();
+ rl_clear_line();
+}
+
+void rl_feed(int c) {
+
+ switch (c) {
+ case '\r':
+ case '\n':
+ putchar('\n');
+ line_cb(lnbuf);
+ rl_clear();
+ rl_reprint_prompt();
+ break;
+ case K_ESC:
+ break;
+ case K_BACKSPACE:
+ if (pos > 0) {
+ memmove(lnbuf + pos - 1, lnbuf + pos, sizeof(lnbuf) - pos);
+ rl_reprint_prompt();
+ pos--;
+ }
+ break;
+ case K_UP:
+ case K_DOWN:
+ /* history handle */
+ break;
+ case K_RIGHT:
+ case K_LEFT:
+ break;
+ default:
+ if (isprint(c)) {
+ if (pos < MAX_LINE_BUFFER) {
+ lnbuf[pos++] = c;
+ rl_reprint_prompt();
+ }
+ } else
+ printf(" %x ", c);
+ break;
+ }
+}
diff --git a/rl_helper.h b/rl_helper.h
new file mode 100644
index 0000000..3da3406
--- /dev/null
+++ b/rl_helper.h
@@ -0,0 +1,13 @@
+#ifndef __RL_HELPER_H__
+#define __RL_HELPER_H__
+
+typedef void (*line_process_callback)(char *line);
+
+/* initializes buffers and set line process callback */
+void rl_init(line_process_callback cb);
+/* close resources */
+void rl_quit();
+/* add char to line buffer */
+void rl_feed(int c);
+
+#endif // __RL_HELPER_H__