aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/ethereum/repl
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2015-03-06 10:38:19 +0800
committerFelix Lange <fjl@twurst.com>2015-03-06 10:57:13 +0800
commit38f6d60e6e699db24b7a850b5999823b9e36d5bb (patch)
treee29709adf03982aeb8e5d61c40b1e37399a2fd4e /cmd/ethereum/repl
parentbae7e93a9c5af679682f89b0f475e98c1eee9e58 (diff)
downloaddexon-38f6d60e6e699db24b7a850b5999823b9e36d5bb.tar
dexon-38f6d60e6e699db24b7a850b5999823b9e36d5bb.tar.gz
dexon-38f6d60e6e699db24b7a850b5999823b9e36d5bb.tar.bz2
dexon-38f6d60e6e699db24b7a850b5999823b9e36d5bb.tar.lz
dexon-38f6d60e6e699db24b7a850b5999823b9e36d5bb.tar.xz
dexon-38f6d60e6e699db24b7a850b5999823b9e36d5bb.tar.zst
dexon-38f6d60e6e699db24b7a850b5999823b9e36d5bb.zip
cmd/ethereum: new JS repl with cross-platform line editing
Diffstat (limited to 'cmd/ethereum/repl')
-rw-r--r--cmd/ethereum/repl/console_colors_windows.go97
-rw-r--r--cmd/ethereum/repl/repl.go201
-rw-r--r--cmd/ethereum/repl/repl_darwin.go144
l---------cmd/ethereum/repl/repl_linux.go1
-rw-r--r--cmd/ethereum/repl/repl_windows.go92
5 files changed, 0 insertions, 535 deletions
diff --git a/cmd/ethereum/repl/console_colors_windows.go b/cmd/ethereum/repl/console_colors_windows.go
deleted file mode 100644
index 8062746fb..000000000
--- a/cmd/ethereum/repl/console_colors_windows.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
-//
-// This library 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.1 of the License, or (at your option) any later version.
-//
-// This library 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 library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-// MA 02110-1301 USA
-
-/* Inspired by https://github.com/xuyu/logging/blob/master/colorful_win.go */
-
-package ethrepl
-
-import (
- "syscall"
- "unsafe"
-)
-
-type color uint16
-
-const (
- green = color(0x0002)
- red = color(0x0004)
- yellow = color(0x000E)
-)
-
-const (
- mask = uint16(yellow | green | red)
-)
-
-var (
- kernel32 = syscall.NewLazyDLL("kernel32.dll")
- procGetStdHandle = kernel32.NewProc("GetStdHandle")
- procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
- procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
- hStdout uintptr
- initScreenInfo *consoleScreenBufferInfo
-)
-
-func setConsoleTextAttribute(hConsoleOutput uintptr, wAttributes uint16) bool {
- ret, _, _ := procSetConsoleTextAttribute.Call(hConsoleOutput, uintptr(wAttributes))
- return ret != 0
-}
-
-type coord struct {
- X, Y int16
-}
-
-type smallRect struct {
- Left, Top, Right, Bottom int16
-}
-
-type consoleScreenBufferInfo struct {
- DwSize coord
- DwCursorPosition coord
- WAttributes uint16
- SrWindow smallRect
- DwMaximumWindowSize coord
-}
-
-func getConsoleScreenBufferInfo(hConsoleOutput uintptr) *consoleScreenBufferInfo {
- var csbi consoleScreenBufferInfo
- ret, _, _ := procGetConsoleScreenBufferInfo.Call(hConsoleOutput, uintptr(unsafe.Pointer(&csbi)))
- if ret == 0 {
- return nil
- }
- return &csbi
-}
-
-const (
- stdOutputHandle = uint32(-11 & 0xFFFFFFFF)
-)
-
-func init() {
- hStdout, _, _ = procGetStdHandle.Call(uintptr(stdOutputHandle))
- initScreenInfo = getConsoleScreenBufferInfo(hStdout)
-}
-
-func resetColorful() {
- if initScreenInfo == nil {
- return
- }
- setConsoleTextAttribute(hStdout, initScreenInfo.WAttributes)
-}
-
-func changeColor(c color) {
- attr := uint16(0) & ^mask | uint16(c)
- setConsoleTextAttribute(hStdout, attr)
-}
diff --git a/cmd/ethereum/repl/repl.go b/cmd/ethereum/repl/repl.go
deleted file mode 100644
index 05ea71e79..000000000
--- a/cmd/ethereum/repl/repl.go
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
-//
-// This library 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.1 of the License, or (at your option) any later version.
-//
-// This library 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 library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-// MA 02110-1301 USA
-
-package ethrepl
-
-import (
- "bufio"
- "fmt"
- "io"
- "os"
- "path"
-
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/javascript"
- "github.com/ethereum/go-ethereum/logger"
- "github.com/ethereum/go-ethereum/state"
- "github.com/ethereum/go-ethereum/xeth"
- "github.com/obscuren/otto"
-)
-
-var repllogger = logger.NewLogger("REPL")
-
-type Repl interface {
- Start()
- Stop()
-}
-
-type JSRepl struct {
- re *javascript.JSRE
- ethereum *eth.Ethereum
- xeth *xeth.XEth
-
- prompt string
-
- history *os.File
-
- running bool
-}
-
-func NewJSRepl(ethereum *eth.Ethereum) *JSRepl {
- hist, err := os.OpenFile(path.Join(ethereum.DataDir, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm)
- if err != nil {
- panic(err)
- }
-
- xeth := xeth.New(ethereum)
- repl := &JSRepl{re: javascript.NewJSRE(xeth), xeth: xeth, ethereum: ethereum, prompt: "> ", history: hist}
- repl.initStdFuncs()
-
- return repl
-}
-
-func (self *JSRepl) Start() {
- if !self.running {
- self.running = true
- repllogger.Infoln("init JS Console")
-
- reader := bufio.NewReader(self.history)
- for {
- line, err := reader.ReadString('\n')
- if err != nil && err == io.EOF {
- break
- } else if err != nil {
- fmt.Println("error reading history", err)
- break
- }
-
- addHistory(line[:len(line)-1])
- }
- self.read()
- }
-}
-
-func (self *JSRepl) Stop() {
- if self.running {
- self.running = false
- repllogger.Infoln("exit JS Console")
- self.history.Close()
- }
-}
-
-func (self *JSRepl) parseInput(code string) {
- defer func() {
- if r := recover(); r != nil {
- fmt.Println("[native] error", r)
- }
- }()
-
- value, err := self.re.Run(code)
- if err != nil {
- fmt.Println(err)
- return
- }
-
- self.PrintValue(value)
-}
-
-func (self *JSRepl) initStdFuncs() {
- t, _ := self.re.Vm.Get("eth")
- eth := t.Object()
- eth.Set("connect", self.connect)
- eth.Set("stopMining", self.stopMining)
- eth.Set("startMining", self.startMining)
- eth.Set("dump", self.dump)
- eth.Set("export", self.export)
-}
-
-/*
- * The following methods are natively implemented javascript functions
- */
-
-func (self *JSRepl) dump(call otto.FunctionCall) otto.Value {
- var block *types.Block
-
- if len(call.ArgumentList) > 0 {
- if call.Argument(0).IsNumber() {
- num, _ := call.Argument(0).ToInteger()
- block = self.ethereum.ChainManager().GetBlockByNumber(uint64(num))
- } else if call.Argument(0).IsString() {
- hash, _ := call.Argument(0).ToString()
- block = self.ethereum.ChainManager().GetBlock(ethutil.Hex2Bytes(hash))
- } else {
- fmt.Println("invalid argument for dump. Either hex string or number")
- }
-
- if block == nil {
- fmt.Println("block not found")
-
- return otto.UndefinedValue()
- }
-
- } else {
- block = self.ethereum.ChainManager().CurrentBlock()
- }
-
- statedb := state.New(block.Root(), self.ethereum.Db())
-
- v, _ := self.re.Vm.ToValue(statedb.RawDump())
-
- return v
-}
-
-func (self *JSRepl) stopMining(call otto.FunctionCall) otto.Value {
- self.xeth.Miner().Stop()
-
- return otto.TrueValue()
-}
-
-func (self *JSRepl) startMining(call otto.FunctionCall) otto.Value {
- self.xeth.Miner().Start()
- return otto.TrueValue()
-}
-
-func (self *JSRepl) connect(call otto.FunctionCall) otto.Value {
- nodeURL, err := call.Argument(0).ToString()
- if err != nil {
- return otto.FalseValue()
- }
- if err := self.ethereum.SuggestPeer(nodeURL); err != nil {
- return otto.FalseValue()
- }
- return otto.TrueValue()
-}
-
-func (self *JSRepl) export(call otto.FunctionCall) otto.Value {
- if len(call.ArgumentList) == 0 {
- fmt.Println("err: require file name")
- return otto.FalseValue()
- }
-
- fn, err := call.Argument(0).ToString()
- if err != nil {
- fmt.Println(err)
- return otto.FalseValue()
- }
-
- data := self.ethereum.ChainManager().Export()
-
- if err := ethutil.WriteFile(fn, data); err != nil {
- fmt.Println(err)
- return otto.FalseValue()
- }
-
- return otto.TrueValue()
-}
diff --git a/cmd/ethereum/repl/repl_darwin.go b/cmd/ethereum/repl/repl_darwin.go
deleted file mode 100644
index 3710150cc..000000000
--- a/cmd/ethereum/repl/repl_darwin.go
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
-//
-// This library 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.1 of the License, or (at your option) any later version.
-//
-// This library 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 library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-// MA 02110-1301 USA
-
-package ethrepl
-
-// #cgo darwin CFLAGS: -I/usr/local/opt/readline/include
-// #cgo darwin LDFLAGS: -L/usr/local/opt/readline/lib
-// #cgo LDFLAGS: -lreadline
-// #include <stdio.h>
-// #include <stdlib.h>
-// #include <readline/readline.h>
-// #include <readline/history.h>
-import "C"
-import (
- "fmt"
- "os"
- "os/signal"
- "strings"
- "syscall"
- "unsafe"
-)
-
-func initReadLine() {
- C.rl_catch_sigwinch = 0
- C.rl_catch_signals = 0
- c := make(chan os.Signal, 1)
- signal.Notify(c, syscall.SIGWINCH)
- signal.Notify(c, os.Interrupt)
- go func() {
- for sig := range c {
- switch sig {
- case syscall.SIGWINCH:
- C.rl_resize_terminal()
-
- case os.Interrupt:
- C.rl_cleanup_after_signal()
- default:
-
- }
- }
- }()
-}
-
-func readLine(prompt *string) *string {
- var p *C.char
-
- //readline allows an empty prompt(NULL)
- if prompt != nil {
- p = C.CString(*prompt)
- }
-
- ret := C.readline(p)
-
- if p != nil {
- C.free(unsafe.Pointer(p))
- }
-
- if ret == nil {
- return nil
- } //EOF
-
- s := C.GoString(ret)
- C.free(unsafe.Pointer(ret))
- return &s
-}
-
-func addHistory(s string) {
- p := C.CString(s)
- C.add_history(p)
- C.free(unsafe.Pointer(p))
-}
-
-var indentCount = 0
-var str = ""
-
-func (self *JSRepl) setIndent() {
- open := strings.Count(str, "{")
- open += strings.Count(str, "(")
- closed := strings.Count(str, "}")
- closed += strings.Count(str, ")")
- indentCount = open - closed
- if indentCount <= 0 {
- self.prompt = "> "
- } else {
- self.prompt = strings.Join(make([]string, indentCount*2), "..")
- self.prompt += " "
- }
-}
-
-func (self *JSRepl) read() {
- initReadLine()
-L:
- for {
- switch result := readLine(&self.prompt); true {
- case result == nil:
- break L
-
- case *result != "":
- str += *result + "\n"
-
- self.setIndent()
-
- if indentCount <= 0 {
- if *result == "exit" {
- self.Stop()
- break L
- }
-
- hist := str[:len(str)-1]
- addHistory(hist) //allow user to recall this line
- self.history.WriteString(str)
-
- self.parseInput(str)
-
- str = ""
- }
- }
- }
-}
-
-func (self *JSRepl) PrintValue(v interface{}) {
- method, _ := self.re.Vm.Get("prettyPrint")
- v, err := self.re.Vm.ToValue(v)
- if err == nil {
- val, err := method.Call(method, v)
- if err == nil {
- fmt.Printf("%v", val)
- }
- }
-}
diff --git a/cmd/ethereum/repl/repl_linux.go b/cmd/ethereum/repl/repl_linux.go
deleted file mode 120000
index 276f135d7..000000000
--- a/cmd/ethereum/repl/repl_linux.go
+++ /dev/null
@@ -1 +0,0 @@
-repl_darwin.go \ No newline at end of file
diff --git a/cmd/ethereum/repl/repl_windows.go b/cmd/ethereum/repl/repl_windows.go
deleted file mode 100644
index d2c405ee9..000000000
--- a/cmd/ethereum/repl/repl_windows.go
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
-//
-// This library 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.1 of the License, or (at your option) any later version.
-//
-// This library 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 library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-// MA 02110-1301 USA
-
-package ethrepl
-
-import (
- "bufio"
- "fmt"
- "os"
- "strings"
-)
-
-func (self *JSRepl) read() {
- reader := bufio.NewReader(os.Stdin)
- for {
- fmt.Printf(self.prompt)
- str, _, err := reader.ReadLine()
- if err != nil {
- fmt.Println("Error reading input", err)
- } else {
- if string(str) == "exit" {
- self.Stop()
- break
- } else {
- self.parseInput(string(str))
- }
- }
- }
-}
-
-func addHistory(s string) {
-}
-
-func printColored(outputVal string) {
- for outputVal != "" {
- codePart := ""
- if strings.HasPrefix(outputVal, "\033[32m") {
- codePart = "\033[32m"
- changeColor(2)
- }
- if strings.HasPrefix(outputVal, "\033[1m\033[30m") {
- codePart = "\033[1m\033[30m"
- changeColor(8)
- }
- if strings.HasPrefix(outputVal, "\033[31m") {
- codePart = "\033[31m"
- changeColor(red)
- }
- if strings.HasPrefix(outputVal, "\033[35m") {
- codePart = "\033[35m"
- changeColor(5)
- }
- if strings.HasPrefix(outputVal, "\033[0m") {
- codePart = "\033[0m"
- resetColorful()
- }
- textPart := outputVal[len(codePart):len(outputVal)]
- index := strings.Index(textPart, "\033")
- if index == -1 {
- outputVal = ""
- } else {
- outputVal = textPart[index:len(textPart)]
- textPart = textPart[0:index]
- }
- fmt.Printf("%v", textPart)
- }
-}
-
-func (self *JSRepl) PrintValue(v interface{}) {
- method, _ := self.re.Vm.Get("prettyPrint")
- v, err := self.re.Vm.ToValue(v)
- if err == nil {
- val, err := method.Call(method, v)
- if err == nil {
- printColored(fmt.Sprintf("%v", val))
- }
- }
-}