Reviewers: Jakob,

Message:
Here's the second attempt. It turned out to be a NULL pointer access.
Additionally, I implemented a history entries limit and removal of duplicate
entries.

Description:
Fixing d8's broken readline history.


Please review this at http://codereview.chromium.org/7885026/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/d8-readline.cc
  M src/d8.h
  M src/d8.cc


Index: src/d8-readline.cc
diff --git a/src/d8-readline.cc b/src/d8-readline.cc
index 8422783407f94fb56933da0794081f20bcdbe251..be527b2d107ddc2a0fc81560a81da69cf30a7ca9 100644
--- a/src/d8-readline.cc
+++ b/src/d8-readline.cc
@@ -72,6 +72,7 @@ bool ReadLineEditor::Open() {
   rl_completer_word_break_characters = kWordBreakCharacters;
   rl_bind_key('\t', rl_complete);
   using_history();
+  stifle_history(Shell::kMaxHistoryEntries);
   return read_history(Shell::kHistoryFileName) == 0;
 }

@@ -88,6 +89,18 @@ i::SmartArrayPointer<char> ReadLineEditor::Prompt(const char* prompt) {


 void ReadLineEditor::AddHistory(const char* str) {
+  // Do not record empty input.
+  if (strlen(str) == 0) return;
+  // Remove duplicate history entry.
+  history_set_pos(0);
+  if (current_history()) {
+    do {
+      if (strcmp(current_history()->line, str) == 0) {
+        remove_history(where_history());
+        break;
+      }
+    } while(next_history());
+  }
   add_history(str);
 }

Index: src/d8.cc
diff --git a/src/d8.cc b/src/d8.cc
index a02529999aaa95864923ae9f5bedb186ac39319b..55f0d4c2ab57cf74b0027a7c12c81f6df8573f20 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -70,6 +70,7 @@ namespace v8 {
 #ifndef V8_SHARED
 LineEditor *LineEditor::first_ = NULL;
 const char* Shell::kHistoryFileName = ".d8_history";
+const int Shell::kMaxHistoryEntries = 1000;


 LineEditor::LineEditor(Type type, const char* name)
@@ -117,6 +118,7 @@ CounterCollection Shell::local_counters_;
 CounterCollection* Shell::counters_ = &local_counters_;
 i::Mutex* Shell::context_mutex_(i::OS::CreateMutex());
 Persistent<Context> Shell::utility_context_;
+LineEditor* Shell::console = NULL;
 #endif  // V8_SHARED

 Persistent<Context> Shell::evaluation_context_;
@@ -791,6 +793,7 @@ void Shell::Exit(int exit_code) {

 #ifndef V8_SHARED
 void Shell::OnExit() {
+  if (console != NULL) console->Close();
   if (i::FLAG_dump_counters) {
     printf("+----------------------------------------+-------------+\n");
     printf("| Name                                   | Value       |\n");
@@ -895,20 +898,19 @@ void Shell::RunShell() {
   HandleScope outer_scope;
   Handle<String> name = String::New("(d8)");
 #ifndef V8_SHARED
-  LineEditor* editor = LineEditor::Get();
- printf("V8 version %s [console: %s]\n", V8::GetVersion(), editor->name());
+  console = LineEditor::Get();
+ printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name());
   if (i::FLAG_debugger) {
     printf("JavaScript debugger enabled\n");
   }
-  editor->Open();
+  console->Open();
   while (true) {
-    i::SmartArrayPointer<char> input = editor->Prompt(Shell::kPrompt);
+    i::SmartArrayPointer<char> input = console->Prompt(Shell::kPrompt);
     if (input.is_empty()) break;
-    editor->AddHistory(*input);
+    console->AddHistory(*input);
     HandleScope inner_scope;
     ExecuteString(String::New(*input), name, true, true);
   }
-  editor->Close();
 #else
printf("V8 version %s [D8 light using shared library]\n", V8::GetVersion());
   static const int kBufferSize = 256;
Index: src/d8.h
diff --git a/src/d8.h b/src/d8.h
index e193f105a0d1cc601efc0d81b09d2b9494133a83..15d8d5d50fc96214df64ce7925487bdd360c068a 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -116,6 +116,29 @@ class CounterMap {
 #endif  // V8_SHARED


+#ifndef V8_SHARED
+class LineEditor {
+ public:
+  enum Type { DUMB = 0, READLINE = 1 };
+  LineEditor(Type type, const char* name);
+  virtual ~LineEditor() { }
+
+  virtual i::SmartArrayPointer<char> Prompt(const char* prompt) = 0;
+  virtual bool Open() { return true; }
+  virtual bool Close() { return true; }
+  virtual void AddHistory(const char* str) { }
+
+  const char* name() { return name_; }
+  static LineEditor* Get();
+ private:
+  Type type_;
+  const char* name_;
+  LineEditor* next_;
+  static LineEditor* first_;
+};
+#endif  // V8_SHARED
+
+
 class SourceGroup {
  public:
   SourceGroup() :
@@ -313,6 +336,8 @@ class Shell : public i::AllStatic {
   static void AddOSMethods(Handle<ObjectTemplate> os_template);
 #ifndef V8_SHARED
   static const char* kHistoryFileName;
+  static const int kMaxHistoryEntries;
+  static LineEditor* console;
 #endif  // V8_SHARED
   static const char* kPrompt;
   static ShellOptions options;
@@ -343,29 +368,6 @@ class Shell : public i::AllStatic {
 };


-#ifndef V8_SHARED
-class LineEditor {
- public:
-  enum Type { DUMB = 0, READLINE = 1 };
-  LineEditor(Type type, const char* name);
-  virtual ~LineEditor() { }
-
-  virtual i::SmartArrayPointer<char> Prompt(const char* prompt) = 0;
-  virtual bool Open() { return true; }
-  virtual bool Close() { return true; }
-  virtual void AddHistory(const char* str) { }
-
-  const char* name() { return name_; }
-  static LineEditor* Get();
- private:
-  Type type_;
-  const char* name_;
-  LineEditor* next_;
-  static LineEditor* first_;
-};
-#endif  // V8_SHARED
-
-
 }  // namespace v8




--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to