summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/BReadline.h23
-rw-r--r--src/Readline.cc51
2 files changed, 73 insertions, 1 deletions
diff --git a/includes/BReadline.h b/includes/BReadline.h
index 6f70f09..73756c4 100644
--- a/includes/BReadline.h
+++ b/includes/BReadline.h
@@ -1 +1,24 @@
#pragma once
+
+#include <histedit.h>
+#include <BString.h>
+#include <Handle.h>
+
+class Readline {
+ public:
+ Readline(const Balau::String & program, Balau::IO<Balau::Handle>);
+ ~Readline();
+ Balau::String gets();
+ bool gotEOF() { return m_eof; }
+ void setPrompt(const Balau::String & prompt);
+ private:
+ EditLine * m_el = NULL;
+ Balau::IO<Balau::Handle> m_in;
+ bool m_eof = false;
+ Balau::String m_prompt = "> ";
+
+ static const char * elPrompt(EditLine *);
+ const char * elPrompt() { return m_prompt.to_charp(); }
+ static int elGetCFN(EditLine *, char * c);
+ int elGetCFN(char * c);
+};
diff --git a/src/Readline.cc b/src/Readline.cc
index 5b47901..a58719d 100644
--- a/src/Readline.cc
+++ b/src/Readline.cc
@@ -1 +1,50 @@
-#include "BReadline.h" \ No newline at end of file
+#include <stdio.h>
+#include "BReadline.h"
+
+using namespace Balau;
+
+Readline::Readline(const String & program, IO<Handle> in)
+ : m_in(in)
+{
+ m_el = el_init(program.to_charp(), stdin, stdout, stderr);
+ el_set(m_el, EL_CLIENTDATA, this);
+ el_set(m_el, EL_PROMPT, (const char * (*)(EditLine *)) &Readline::elPrompt);
+ el_set(m_el, EL_SIGNAL, 1);
+ el_set(m_el, EL_GETCFN, (int (*)(EditLine *, char *)) &Readline::elGetCFN);
+}
+
+Readline::~Readline() {
+ el_end(m_el);
+}
+
+void Readline::setPrompt(const String & prompt) {
+ m_prompt = prompt;
+}
+
+String Readline::gets() {
+ int count;
+ const char * line = el_gets(m_el, &count);
+
+ if (!line) {
+ m_eof = true;
+ return "";
+ }
+
+ return line;
+}
+
+const char * Readline::elPrompt(EditLine * el) {
+ Readline * rl;
+ el_get(el, EL_CLIENTDATA, &rl);
+ return rl->elPrompt();
+}
+
+int Readline::elGetCFN(EditLine * el, char * c) {
+ Readline * rl;
+ el_get(el, EL_CLIENTDATA, &rl);
+ return rl->elGetCFN(c);
+}
+
+int Readline::elGetCFN(char * c) {
+ return m_in->read(c, 1);
+}