diff options
Diffstat (limited to 'cmd/ethereum')
-rw-r--r-- | cmd/ethereum/cmd.go | 55 | ||||
-rw-r--r-- | cmd/ethereum/flags.go | 166 | ||||
-rw-r--r-- | cmd/ethereum/main.go | 159 | ||||
-rw-r--r-- | cmd/ethereum/repl/console_colors_windows.go | 97 | ||||
-rw-r--r-- | cmd/ethereum/repl/repl.go | 103 | ||||
-rw-r--r-- | cmd/ethereum/repl/repl_darwin.go | 144 | ||||
l--------- | cmd/ethereum/repl/repl_linux.go | 1 | ||||
-rw-r--r-- | cmd/ethereum/repl/repl_windows.go | 92 |
8 files changed, 817 insertions, 0 deletions
diff --git a/cmd/ethereum/cmd.go b/cmd/ethereum/cmd.go new file mode 100644 index 000000000..8ffd868ed --- /dev/null +++ b/cmd/ethereum/cmd.go @@ -0,0 +1,55 @@ +/* + This file is part of go-ethereum + + go-ethereum 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 3 of the License, or + (at your option) any later version. + + go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>. +*/ +/** + * @authors + * Jeffrey Wilcke <i@jev.io> + */ +package main + +import ( + "io/ioutil" + "os" + + "github.com/ethereum/go-ethereum/cmd/ethereum/repl" + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/javascript" +) + +func InitJsConsole(ethereum *eth.Ethereum) { + repl := ethrepl.NewJSRepl(ethereum) + go repl.Start() + utils.RegisterInterrupt(func(os.Signal) { + repl.Stop() + }) +} + +func ExecJsFile(ethereum *eth.Ethereum, InputFile string) { + file, err := os.Open(InputFile) + if err != nil { + clilogger.Fatalln(err) + } + content, err := ioutil.ReadAll(file) + if err != nil { + clilogger.Fatalln(err) + } + re := javascript.NewJSRE(ethereum) + utils.RegisterInterrupt(func(os.Signal) { + re.Stop() + }) + re.Run(string(content)) +} diff --git a/cmd/ethereum/flags.go b/cmd/ethereum/flags.go new file mode 100644 index 000000000..c42083160 --- /dev/null +++ b/cmd/ethereum/flags.go @@ -0,0 +1,166 @@ +/* + This file is part of go-ethereum + + go-ethereum 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 3 of the License, or + (at your option) any later version. + + go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>. +*/ +/** + * @authors + * Jeffrey Wilcke <i@jev.io> + */ +package main + +import ( + "crypto/ecdsa" + "flag" + "fmt" + "log" + "os" + "path" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/p2p/nat" + "github.com/ethereum/go-ethereum/vm" +) + +var ( + Identifier string + KeyRing string + DiffTool bool + DiffType string + KeyStore string + StartRpc bool + StartWebSockets bool + RpcPort int + WsPort int + OutboundPort string + ShowGenesis bool + AddPeer string + MaxPeer int + GenAddr bool + BootNodes string + NodeKey *ecdsa.PrivateKey + NAT nat.Interface + SecretFile string + ExportDir string + NonInteractive bool + Datadir string + LogFile string + ConfigFile string + DebugFile string + LogLevel int + LogFormat string + Dump bool + DumpHash string + DumpNumber int + VmType int + ImportChain string + SHH bool + Dial bool + PrintVersion bool +) + +// flags specific to cli client +var ( + StartMining bool + StartJsConsole bool + InputFile string +) + +var defaultConfigFile = path.Join(ethutil.DefaultDataDir(), "conf.ini") + +func Init() { + // TODO: move common flag processing to cmd/util + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "%s [options] [filename]:\noptions precedence: default < config file < environment variables < command line\n", os.Args[0]) + flag.PrintDefaults() + } + + flag.IntVar(&VmType, "vm", 0, "Virtual Machine type: 0-1: standard, debug") + flag.StringVar(&Identifier, "id", "", "Custom client identifier") + flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use") + flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)") + + flag.IntVar(&RpcPort, "rpcport", 8545, "port to start json-rpc server on") + flag.IntVar(&WsPort, "wsport", 40404, "port to start websocket rpc server on") + flag.BoolVar(&StartRpc, "rpc", false, "start rpc server") + flag.BoolVar(&StartWebSockets, "ws", false, "start websocket server") + flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)") + flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") + flag.StringVar(&SecretFile, "import", "", "imports the file given (hex or mnemonic formats)") + flag.StringVar(&ExportDir, "export", "", "exports the session keyring to files in the directory given") + flag.StringVar(&LogFile, "logfile", "", "log file (defaults to standard output)") + flag.StringVar(&Datadir, "datadir", ethutil.DefaultDataDir(), "specifies the datadir to use") + flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file") + flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)") + flag.IntVar(&LogLevel, "loglevel", int(logger.InfoLevel), "loglevel: 0-5: silent,error,warn,info,debug,debug detail)") + flag.StringVar(&LogFormat, "logformat", "std", "logformat: std,raw)") + flag.BoolVar(&DiffTool, "difftool", false, "creates output for diff'ing. Sets LogLevel=0") + flag.StringVar(&DiffType, "diff", "all", "sets the level of diff output [vm, all]. Has no effect if difftool=false") + flag.BoolVar(&ShowGenesis, "genesis", false, "Dump the genesis block") + flag.StringVar(&ImportChain, "chain", "", "Imports given chain") + + flag.BoolVar(&Dump, "dump", false, "output the ethereum state in JSON format. Sub args [number, hash]") + flag.StringVar(&DumpHash, "hash", "", "specify arg in hex") + flag.IntVar(&DumpNumber, "number", -1, "specify arg in number") + + flag.BoolVar(&StartMining, "mine", false, "start dagger mining") + flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console") + flag.BoolVar(&PrintVersion, "version", false, "prints version number") + + // Network stuff + var ( + nodeKeyFile = flag.String("nodekey", "", "network private key file") + nodeKeyHex = flag.String("nodekeyhex", "", "network private key (for testing)") + natstr = flag.String("nat", "any", "port mapping mechanism (any|none|upnp|pmp|extip:<IP>)") + ) + flag.BoolVar(&Dial, "dial", true, "dial out connections (default on)") + //flag.BoolVar(&SHH, "shh", true, "run whisper protocol (default on)") + flag.StringVar(&OutboundPort, "port", "30303", "listening port") + + flag.StringVar(&BootNodes, "bootnodes", "", "space-separated node URLs for discovery bootstrap") + flag.IntVar(&MaxPeer, "maxpeer", 30, "maximum desired peers") + + flag.Parse() + + // When the javascript console is started log to a file instead + // of stdout + if StartJsConsole { + LogFile = path.Join(Datadir, "ethereum.log") + } + + var err error + if NAT, err = nat.Parse(*natstr); err != nil { + log.Fatalf("-nat: %v", err) + } + switch { + case *nodeKeyFile != "" && *nodeKeyHex != "": + log.Fatal("Options -nodekey and -nodekeyhex are mutually exclusive") + case *nodeKeyFile != "": + if NodeKey, err = crypto.LoadECDSA(*nodeKeyFile); err != nil { + log.Fatalf("-nodekey: %v", err) + } + case *nodeKeyHex != "": + if NodeKey, err = crypto.HexToECDSA(*nodeKeyHex); err != nil { + log.Fatalf("-nodekeyhex: %v", err) + } + } + + if VmType >= int(vm.MaxVmTy) { + log.Fatal("Invalid VM type ", VmType) + } + + InputFile = flag.Arg(0) +} diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go new file mode 100644 index 000000000..f72b11e14 --- /dev/null +++ b/cmd/ethereum/main.go @@ -0,0 +1,159 @@ +/* + This file is part of go-ethereum + + go-ethereum 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 3 of the License, or + (at your option) any later version. + + go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>. +*/ +/** + * @authors + * Jeffrey Wilcke <i@jev.io> + */ +package main + +import ( + "fmt" + "os" + "runtime" + "time" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/state" +) + +const ( + ClientIdentifier = "Ethereum(G)" + Version = "0.8.6" +) + +var clilogger = logger.NewLogger("CLI") + +func main() { + runtime.GOMAXPROCS(runtime.NumCPU()) + + defer func() { + logger.Flush() + }() + + utils.HandleInterrupt() + + // precedence: code-internal flag default < config file < environment variables < command line + Init() // parsing command line + + if PrintVersion { + printVersion() + return + } + + utils.InitConfig(VmType, ConfigFile, Datadir, "ETH") + + ethereum, err := eth.New(ð.Config{ + Name: p2p.MakeName(ClientIdentifier, Version), + KeyStore: KeyStore, + DataDir: Datadir, + LogFile: LogFile, + LogLevel: LogLevel, + LogFormat: LogFormat, + MaxPeers: MaxPeer, + Port: OutboundPort, + NAT: NAT, + KeyRing: KeyRing, + Shh: true, + Dial: Dial, + BootNodes: BootNodes, + NodeKey: NodeKey, + }) + + if err != nil { + clilogger.Fatalln(err) + } + + utils.KeyTasks(ethereum.KeyManager(), KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive) + + if Dump { + var block *types.Block + + if len(DumpHash) == 0 && DumpNumber == -1 { + block = ethereum.ChainManager().CurrentBlock() + } else if len(DumpHash) > 0 { + block = ethereum.ChainManager().GetBlock(ethutil.Hex2Bytes(DumpHash)) + } else { + block = ethereum.ChainManager().GetBlockByNumber(uint64(DumpNumber)) + } + + if block == nil { + fmt.Fprintln(os.Stderr, "block not found") + + // We want to output valid JSON + fmt.Println("{}") + + os.Exit(1) + } + + // Leave the Println. This needs clean output for piping + statedb := state.New(block.Root(), ethereum.Db()) + fmt.Printf("%s\n", statedb.Dump()) + + fmt.Println(block) + + return + } + + if StartMining { + utils.StartMining(ethereum) + } + + if len(ImportChain) > 0 { + start := time.Now() + err := utils.ImportChain(ethereum, ImportChain) + if err != nil { + clilogger.Infoln(err) + } + clilogger.Infoln("import done in", time.Since(start)) + return + } + + if StartRpc { + utils.StartRpc(ethereum, RpcPort) + } + + if StartWebSockets { + utils.StartWebSockets(ethereum, WsPort) + } + + utils.StartEthereum(ethereum) + + fmt.Printf("Welcome to the FRONTIER\n") + + if StartJsConsole { + InitJsConsole(ethereum) + } else if len(InputFile) > 0 { + ExecJsFile(ethereum, InputFile) + } + // this blocks the thread + ethereum.WaitForShutdown() +} + +func printVersion() { + fmt.Printf(`%v %v +PV=%d +GOOS=%s +GO=%s +GOPATH=%s +GOROOT=%s +`, ClientIdentifier, Version, eth.ProtocolVersion, runtime.GOOS, runtime.Version(), os.Getenv("GOPATH"), runtime.GOROOT()) +} diff --git a/cmd/ethereum/repl/console_colors_windows.go b/cmd/ethereum/repl/console_colors_windows.go new file mode 100644 index 000000000..8062746fb --- /dev/null +++ b/cmd/ethereum/repl/console_colors_windows.go @@ -0,0 +1,97 @@ +// 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 new file mode 100644 index 000000000..11b812617 --- /dev/null +++ b/cmd/ethereum/repl/repl.go @@ -0,0 +1,103 @@ +// 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/eth" + "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/javascript" + "github.com/ethereum/go-ethereum/logger" +) + +var repllogger = logger.NewLogger("REPL") + +type Repl interface { + Start() + Stop() +} + +type JSRepl struct { + re *javascript.JSRE + + prompt string + + history *os.File + + running bool +} + +func NewJSRepl(ethereum *eth.Ethereum) *JSRepl { + hist, err := os.OpenFile(path.Join(ethutil.Config.ExecPath, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm) + if err != nil { + panic(err) + } + + return &JSRepl{re: javascript.NewJSRE(ethereum), prompt: "> ", history: hist} +} + +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 + self.re.Stop() + 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) +} diff --git a/cmd/ethereum/repl/repl_darwin.go b/cmd/ethereum/repl/repl_darwin.go new file mode 100644 index 000000000..3710150cc --- /dev/null +++ b/cmd/ethereum/repl/repl_darwin.go @@ -0,0 +1,144 @@ +// 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 new file mode 120000 index 000000000..276f135d7 --- /dev/null +++ b/cmd/ethereum/repl/repl_linux.go @@ -0,0 +1 @@ +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 new file mode 100644 index 000000000..d2c405ee9 --- /dev/null +++ b/cmd/ethereum/repl/repl_windows.go @@ -0,0 +1,92 @@ +// 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)) + } + } +} |