From 7227552f429e6ad035b22167d667712e61fcebbb Mon Sep 17 00:00:00 2001
From: Erez Wanderman <erez.wanderman@outlook.com>
Date: Wed, 15 Oct 2014 02:41:26 +0300
Subject: Fix ethereum compilation and functioning on Windows. repl console
 output is now colored. repl "exit" command now works.

---
 ethereum/repl/console_colors_windows.go | 80 +++++++++++++++++++++++++++++++++
 ethereum/repl/repl_darwin.go            |  5 ++-
 ethereum/repl/repl_windows.go           | 57 +++++++++++++++++++++--
 javascript/js_lib.go                    |  4 +-
 4 files changed, 141 insertions(+), 5 deletions(-)
 create mode 100644 ethereum/repl/console_colors_windows.go

diff --git a/ethereum/repl/console_colors_windows.go b/ethereum/repl/console_colors_windows.go
new file mode 100644
index 000000000..1f517bd8c
--- /dev/null
+++ b/ethereum/repl/console_colors_windows.go
@@ -0,0 +1,80 @@
+/* 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/ethereum/repl/repl_darwin.go b/ethereum/repl/repl_darwin.go
index 4c07280f7..2a53e5fc6 100644
--- a/ethereum/repl/repl_darwin.go
+++ b/ethereum/repl/repl_darwin.go
@@ -118,6 +118,9 @@ func (self *JSRepl) PrintValue(v interface{}) {
 	method, _ := self.re.Vm.Get("prettyPrint")
 	v, err := self.re.Vm.ToValue(v)
 	if err == nil {
-		method.Call(method, v)
+		val, err := method.Call(method, v)
+		if err == nil {
+			fmt.Printf("%v", val)
+		}
 	}
 }
diff --git a/ethereum/repl/repl_windows.go b/ethereum/repl/repl_windows.go
index 4106c89bc..bfae57088 100644
--- a/ethereum/repl/repl_windows.go
+++ b/ethereum/repl/repl_windows.go
@@ -4,6 +4,7 @@ import (
 	"bufio"
 	"fmt"
 	"os"
+	"strings"
 )
 
 func (self *JSRepl) read() {
@@ -14,11 +15,61 @@ func (self *JSRepl) read() {
 		if err != nil {
 			fmt.Println("Error reading input", err)
 		} else {
-			self.parseInput(string(str))
+			if (string(str) == "exit") {
+				self.Stop()
+				break
+			} else {
+				self.parseInput(string(str))
+			}
 		}
 	}
 }
 
-func (self *JSRepl) PrintValue(value otto.Value) {
-	fmt.Println(value)
+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))
+		}
+	}
 }
diff --git a/javascript/js_lib.go b/javascript/js_lib.go
index a3e9b8a5b..dd1fe5f4d 100644
--- a/javascript/js_lib.go
+++ b/javascript/js_lib.go
@@ -44,9 +44,11 @@ function pp(object) {
 
 function prettyPrint(/* */) {
     var args = arguments;
+    var ret = "";
     for(var i = 0, l = args.length; i < l; i++) {
-	    console.log(pp(args[i]))
+	    ret += pp(args[i]) + "\n";
     }
+    return ret;
 }
 
 var print = prettyPrint;
-- 
cgit v1.2.3