12efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 25a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// Redistribution and use in source and binary forms, with or without 35a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// modification, are permitted provided that the following conditions are 45a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// met: 55a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// 65a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// * Redistributions of source code must retain the above copyright 75a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// notice, this list of conditions and the following disclaimer. 85a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// * Redistributions in binary form must reproduce the above 95a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// copyright notice, this list of conditions and the following 105a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// disclaimer in the documentation and/or other materials provided 115a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// with the distribution. 125a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// * Neither the name of Google Inc. nor the names of its 135a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// contributors may be used to endorse or promote products derived 145a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// from this software without specific prior written permission. 155a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// 165a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 288bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org#include <cstdio> // NOLINT 2959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org#include <string.h> // NOLINT 305c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include <readline/readline.h> // NOLINT 315c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include <readline/history.h> // NOLINT 325a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 333847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com// The readline includes leaves RETURN defined which breaks V8 compilation. 343847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com#undef RETURN 355a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 365a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org#include "d8.h" 375a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 388bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org// There are incompatibilities between different versions and different 393291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// implementations of readline. This smooths out one known incompatibility. 408bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org#if RL_READLINE_VERSION >= 0x0500 418bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org#define completion_matches rl_completion_matches 428bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org#endif 438bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 448bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 455a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgnamespace v8 { 465a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 475a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 485a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgclass ReadLineEditor: public LineEditor { 495a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org public: 505a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org ReadLineEditor() : LineEditor(LineEditor::READLINE, "readline") { } 512efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org virtual Handle<String> Prompt(const char* prompt); 526e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org virtual bool Open(Isolate* isolate); 535a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org virtual bool Close(); 545a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org virtual void AddHistory(const char* str); 552efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 562efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org static const char* kHistoryFileName; 572efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org static const int kMaxHistoryEntries; 582efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 595a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org private: 6059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org#ifndef V8_SHARED 615a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org static char** AttemptedCompletion(const char* text, int start, int end); 625a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org static char* CompletionGenerator(const char* text, int state); 6359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org#endif // V8_SHARED 645a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org static char kWordBreakCharacters[]; 656e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 666e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Isolate* isolate_; 675a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org}; 685a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 695a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 705a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgstatic ReadLineEditor read_line_editor; 715a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgchar ReadLineEditor::kWordBreakCharacters[] = {' ', '\t', '\n', '"', 725a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org '\\', '\'', '`', '@', '.', '>', '<', '=', ';', '|', '&', '{', '(', 735a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org '\0'}; 745a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 755a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 762efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.orgconst char* ReadLineEditor::kHistoryFileName = ".d8_history"; 772efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.orgconst int ReadLineEditor::kMaxHistoryEntries = 1000; 782efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 792efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org 806e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgbool ReadLineEditor::Open(Isolate* isolate) { 816e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org isolate_ = isolate; 826e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 835a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org rl_initialize(); 8459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 8559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org#ifdef V8_SHARED 8659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // Don't do completion on shared library mode 8759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // http://cnswww.cns.cwru.edu/php/chet/readline/readline.html#SEC24 8859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org rl_bind_key('\t', rl_insert); 8959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org#else 905a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org rl_attempted_completion_function = AttemptedCompletion; 9159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org#endif // V8_SHARED 9259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 935a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org rl_completer_word_break_characters = kWordBreakCharacters; 945a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org rl_bind_key('\t', rl_complete); 955a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org using_history(); 962efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org stifle_history(kMaxHistoryEntries); 972efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org return read_history(kHistoryFileName) == 0; 985a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org} 995a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 1005a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 1015a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgbool ReadLineEditor::Close() { 1022efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org return write_history(kHistoryFileName) == 0; 1035a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org} 1045a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 1055a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 1062efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.orgHandle<String> ReadLineEditor::Prompt(const char* prompt) { 10705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org char* result = NULL; 10805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org { // Release lock for blocking input. 10905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org Unlocker unlock(Isolate::GetCurrent()); 11005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org result = readline(prompt); 11105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org } 1122efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (result != NULL) { 1132efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org AddHistory(result); 1142efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else { 1152efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org return Handle<String>(); 1162efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 1172efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org return String::New(result); 1185a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org} 1195a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 1205a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 1215a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgvoid ReadLineEditor::AddHistory(const char* str) { 12234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Do not record empty input. 12334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (strlen(str) == 0) return; 12434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Remove duplicate history entry. 12534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org history_set_pos(history_length-1); 12634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (current_history()) { 12734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org do { 12834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (strcmp(current_history()->line, str) == 0) { 12934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org remove_history(where_history()); 13034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org break; 13134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 13234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } while (previous_history()); 13334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 1345a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org add_history(str); 1355a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org} 1365a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 1375a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 13859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org#ifndef V8_SHARED 1395a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgchar** ReadLineEditor::AttemptedCompletion(const char* text, 1405a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org int start, 1415a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org int end) { 1428bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org char** result = completion_matches(text, CompletionGenerator); 1435a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org rl_attempted_completion_over = true; 1445a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org return result; 1455a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org} 1465a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 1475a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 1485a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.orgchar* ReadLineEditor::CompletionGenerator(const char* text, int state) { 1495a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org static unsigned current_index; 1505a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org static Persistent<Array> current_completions; 1516e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Isolate* isolate = read_line_editor.isolate_; 1526e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Locker lock(isolate); 153b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org HandleScope scope; 154b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<Array> completions; 1555a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org if (state == 0) { 1562efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org Local<String> full_text = String::New(rl_line_buffer, rl_point); 157b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org completions = Shell::GetCompletions(isolate, String::New(text), full_text); 158b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org current_completions.Reset(isolate, completions); 1595a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org current_index = 0; 160b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } else { 161b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org completions = Local<Array>::New(isolate, current_completions); 1625a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org } 163b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (current_index < completions->Length()) { 1645a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org Handle<Integer> index = Integer::New(current_index); 165b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<Value> str_obj = completions->Get(index); 1665a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org current_index++; 1675a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org String::Utf8Value str(str_obj); 1685a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org return strdup(*str); 1695a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org } else { 1706e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org current_completions.Dispose(isolate); 1715a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org current_completions.Clear(); 1725a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org return NULL; 1735a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org } 1745a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org} 17559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org#endif // V8_SHARED 1765a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 1775a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 1785a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org} // namespace v8 179