The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / d8-readline.cc @ f230a1cf

History | View | Annotate | Download (5.53 KB)

1
// Copyright 2012 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
#include <cstdio>  // NOLINT
29
#include <string.h> // NOLINT
30
#include <readline/readline.h> // NOLINT
31
#include <readline/history.h> // NOLINT
32

    
33
// The readline includes leaves RETURN defined which breaks V8 compilation.
34
#undef RETURN
35

    
36
#include "d8.h"
37

    
38
// There are incompatibilities between different versions and different
39
// implementations of readline.  This smooths out one known incompatibility.
40
#if RL_READLINE_VERSION >= 0x0500
41
#define completion_matches rl_completion_matches
42
#endif
43

    
44

    
45
namespace v8 {
46

    
47

    
48
class ReadLineEditor: public LineEditor {
49
 public:
50
  ReadLineEditor() : LineEditor(LineEditor::READLINE, "readline") { }
51
  virtual Handle<String> Prompt(const char* prompt);
52
  virtual bool Open(Isolate* isolate);
53
  virtual bool Close();
54
  virtual void AddHistory(const char* str);
55

    
56
  static const char* kHistoryFileName;
57
  static const int kMaxHistoryEntries;
58

    
59
 private:
60
#ifndef V8_SHARED
61
  static char** AttemptedCompletion(const char* text, int start, int end);
62
  static char* CompletionGenerator(const char* text, int state);
63
#endif  // V8_SHARED
64
  static char kWordBreakCharacters[];
65

    
66
  Isolate* isolate_;
67
};
68

    
69

    
70
static ReadLineEditor read_line_editor;
71
char ReadLineEditor::kWordBreakCharacters[] = {' ', '\t', '\n', '"',
72
    '\\', '\'', '`', '@', '.', '>', '<', '=', ';', '|', '&', '{', '(',
73
    '\0'};
74

    
75

    
76
const char* ReadLineEditor::kHistoryFileName = ".d8_history";
77
const int ReadLineEditor::kMaxHistoryEntries = 1000;
78

    
79

    
80
bool ReadLineEditor::Open(Isolate* isolate) {
81
  isolate_ = isolate;
82

    
83
  rl_initialize();
84

    
85
#ifdef V8_SHARED
86
  // Don't do completion on shared library mode
87
  // http://cnswww.cns.cwru.edu/php/chet/readline/readline.html#SEC24
88
  rl_bind_key('\t', rl_insert);
89
#else
90
  rl_attempted_completion_function = AttemptedCompletion;
91
#endif  // V8_SHARED
92

    
93
  rl_completer_word_break_characters = kWordBreakCharacters;
94
  rl_bind_key('\t', rl_complete);
95
  using_history();
96
  stifle_history(kMaxHistoryEntries);
97
  return read_history(kHistoryFileName) == 0;
98
}
99

    
100

    
101
bool ReadLineEditor::Close() {
102
  return write_history(kHistoryFileName) == 0;
103
}
104

    
105

    
106
Handle<String> ReadLineEditor::Prompt(const char* prompt) {
107
  char* result = NULL;
108
  {  // Release lock for blocking input.
109
    Unlocker unlock(Isolate::GetCurrent());
110
    result = readline(prompt);
111
  }
112
  if (result != NULL) {
113
    AddHistory(result);
114
  } else {
115
    return Handle<String>();
116
  }
117
  return String::New(result);
118
}
119

    
120

    
121
void ReadLineEditor::AddHistory(const char* str) {
122
  // Do not record empty input.
123
  if (strlen(str) == 0) return;
124
  // Remove duplicate history entry.
125
  history_set_pos(history_length-1);
126
  if (current_history()) {
127
    do {
128
      if (strcmp(current_history()->line, str) == 0) {
129
        remove_history(where_history());
130
        break;
131
      }
132
    } while (previous_history());
133
  }
134
  add_history(str);
135
}
136

    
137

    
138
#ifndef V8_SHARED
139
char** ReadLineEditor::AttemptedCompletion(const char* text,
140
                                           int start,
141
                                           int end) {
142
  char** result = completion_matches(text, CompletionGenerator);
143
  rl_attempted_completion_over = true;
144
  return result;
145
}
146

    
147

    
148
char* ReadLineEditor::CompletionGenerator(const char* text, int state) {
149
  static unsigned current_index;
150
  static Persistent<Array> current_completions;
151
  Isolate* isolate = read_line_editor.isolate_;
152
  Locker lock(isolate);
153
  HandleScope scope(isolate);
154
  Handle<Array> completions;
155
  if (state == 0) {
156
    Local<String> full_text = String::New(rl_line_buffer, rl_point);
157
    completions = Shell::GetCompletions(isolate, String::New(text), full_text);
158
    current_completions.Reset(isolate, completions);
159
    current_index = 0;
160
  } else {
161
    completions = Local<Array>::New(isolate, current_completions);
162
  }
163
  if (current_index < completions->Length()) {
164
    Handle<Integer> index = Integer::New(current_index);
165
    Handle<Value> str_obj = completions->Get(index);
166
    current_index++;
167
    String::Utf8Value str(str_obj);
168
    return strdup(*str);
169
  } else {
170
    current_completions.Reset();
171
    return NULL;
172
  }
173
}
174
#endif  // V8_SHARED
175

    
176

    
177
}  // namespace v8