mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-24 20:47:16 +00:00
cmd/ethereum: fix JS REPL exit and add support for dumb terminals
It is now possible to exit the REPL using Ctrl-C, Ctrl-D or by typing "exit".
This commit is contained in:
parent
2393de5d6b
commit
de86403f33
@ -18,9 +18,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"os/signal"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -55,44 +57,38 @@ type repl struct {
|
|||||||
ethereum *eth.Ethereum
|
ethereum *eth.Ethereum
|
||||||
xeth *xeth.XEth
|
xeth *xeth.XEth
|
||||||
prompt string
|
prompt string
|
||||||
histfile *os.File
|
|
||||||
lr *liner.State
|
lr *liner.State
|
||||||
running bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newREPL(ethereum *eth.Ethereum) *repl {
|
func runREPL(ethereum *eth.Ethereum) {
|
||||||
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)
|
xeth := xeth.New(ethereum)
|
||||||
repl := &repl{
|
repl := &repl{
|
||||||
re: javascript.NewJSRE(xeth),
|
re: javascript.NewJSRE(xeth),
|
||||||
xeth: xeth,
|
xeth: xeth,
|
||||||
ethereum: ethereum,
|
ethereum: ethereum,
|
||||||
prompt: "> ",
|
prompt: "> ",
|
||||||
histfile: hist,
|
|
||||||
lr: liner.NewLiner(),
|
|
||||||
}
|
}
|
||||||
repl.initStdFuncs()
|
repl.initStdFuncs()
|
||||||
return repl
|
if !liner.TerminalSupported() {
|
||||||
}
|
repl.dumbRead()
|
||||||
|
} else {
|
||||||
func (self *repl) Start() {
|
lr := liner.NewLiner()
|
||||||
if !self.running {
|
defer lr.Close()
|
||||||
self.running = true
|
lr.SetCtrlCAborts(true)
|
||||||
self.lr.ReadHistory(self.histfile)
|
repl.withHistory(func(hist *os.File) { lr.ReadHistory(hist) })
|
||||||
go self.read()
|
repl.read(lr)
|
||||||
|
repl.withHistory(func(hist *os.File) { hist.Truncate(0); lr.WriteHistory(hist) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *repl) Stop() {
|
func (self *repl) withHistory(op func(*os.File)) {
|
||||||
if self.running {
|
hist, err := os.OpenFile(path.Join(self.ethereum.DataDir, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm)
|
||||||
self.running = false
|
if err != nil {
|
||||||
self.histfile.Truncate(0)
|
fmt.Printf("unable to open history file: %v\n", err)
|
||||||
self.lr.WriteHistory(self.histfile)
|
return
|
||||||
self.histfile.Close()
|
|
||||||
}
|
}
|
||||||
|
op(hist)
|
||||||
|
hist.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *repl) parseInput(code string) {
|
func (self *repl) parseInput(code string) {
|
||||||
@ -126,9 +122,9 @@ func (self *repl) setIndent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *repl) read() {
|
func (self *repl) read(lr *liner.State) {
|
||||||
for {
|
for {
|
||||||
input, err := self.lr.Prompt(self.prompt)
|
input, err := lr.Prompt(self.prompt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -139,17 +135,51 @@ func (self *repl) read() {
|
|||||||
self.setIndent()
|
self.setIndent()
|
||||||
if indentCount <= 0 {
|
if indentCount <= 0 {
|
||||||
if input == "exit" {
|
if input == "exit" {
|
||||||
self.Stop()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hist := str[:len(str)-1]
|
hist := str[:len(str)-1]
|
||||||
self.lr.AppendHistory(hist)
|
lr.AppendHistory(hist)
|
||||||
self.parseInput(str)
|
self.parseInput(str)
|
||||||
str = ""
|
str = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *repl) dumbRead() {
|
||||||
|
fmt.Println("Unsupported terminal, line editing will not work.")
|
||||||
|
|
||||||
|
// process lines
|
||||||
|
readDone := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
r := bufio.NewReader(os.Stdin)
|
||||||
|
loop:
|
||||||
|
for {
|
||||||
|
fmt.Print(self.prompt)
|
||||||
|
line, err := r.ReadString('\n')
|
||||||
|
switch {
|
||||||
|
case err != nil || line == "exit":
|
||||||
|
break loop
|
||||||
|
case line == "":
|
||||||
|
continue
|
||||||
|
default:
|
||||||
|
self.parseInput(line + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(readDone)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// wait for Ctrl-C
|
||||||
|
sigc := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigc, os.Interrupt, os.Kill)
|
||||||
|
defer signal.Stop(sigc)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-readDone:
|
||||||
|
case <-sigc:
|
||||||
|
os.Stdin.Close() // terminate read
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (self *repl) printValue(v interface{}) {
|
func (self *repl) printValue(v interface{}) {
|
||||||
method, _ := self.re.Vm.Get("prettyPrint")
|
method, _ := self.re.Vm.Get("prettyPrint")
|
||||||
v, err := self.re.Vm.ToValue(v)
|
v, err := self.re.Vm.ToValue(v)
|
||||||
|
@ -125,7 +125,6 @@ runtime will execute the file and exit.
|
|||||||
func main() {
|
func main() {
|
||||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||||
defer logger.Flush()
|
defer logger.Flush()
|
||||||
utils.HandleInterrupt()
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
if err := app.Run(os.Args); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -134,6 +133,7 @@ func main() {
|
|||||||
|
|
||||||
func run(ctx *cli.Context) {
|
func run(ctx *cli.Context) {
|
||||||
fmt.Printf("Welcome to the FRONTIER\n")
|
fmt.Printf("Welcome to the FRONTIER\n")
|
||||||
|
utils.HandleInterrupt()
|
||||||
eth := utils.GetEthereum(ClientIdentifier, Version, ctx)
|
eth := utils.GetEthereum(ClientIdentifier, Version, ctx)
|
||||||
startEth(ctx, eth)
|
startEth(ctx, eth)
|
||||||
// this blocks the thread
|
// this blocks the thread
|
||||||
@ -144,9 +144,8 @@ func runjs(ctx *cli.Context) {
|
|||||||
eth := utils.GetEthereum(ClientIdentifier, Version, ctx)
|
eth := utils.GetEthereum(ClientIdentifier, Version, ctx)
|
||||||
startEth(ctx, eth)
|
startEth(ctx, eth)
|
||||||
if len(ctx.Args()) == 0 {
|
if len(ctx.Args()) == 0 {
|
||||||
repl := newREPL(eth)
|
runREPL(eth)
|
||||||
utils.RegisterInterrupt(func(os.Signal) { repl.Stop() })
|
eth.Stop()
|
||||||
repl.Start()
|
|
||||||
eth.WaitForShutdown()
|
eth.WaitForShutdown()
|
||||||
} else if len(ctx.Args()) == 1 {
|
} else if len(ctx.Args()) == 1 {
|
||||||
execJsFile(eth, ctx.Args()[0])
|
execJsFile(eth, ctx.Args()[0])
|
||||||
|
Loading…
Reference in New Issue
Block a user