good morning!!!!

Skip to content
Snippets Groups Projects
repl_darwin.go 2.92 KiB
Newer Older
  • Learn to ignore specific revisions
  • Felix Lange's avatar
    Felix Lange committed
    // 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
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    // #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"
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    import (
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    	"fmt"
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    	"os"
    	"os/signal"
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    	"strings"
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    	"syscall"
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    	"unsafe"
    )
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    func initReadLine() {
    	C.rl_catch_sigwinch = 0
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    	C.rl_catch_signals = 0
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    	c := make(chan os.Signal, 1)
    	signal.Notify(c, syscall.SIGWINCH)
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    	signal.Notify(c, os.Interrupt)
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    	go func() {
    		for sig := range c {
    			switch sig {
    			case syscall.SIGWINCH:
    				C.rl_resize_terminal()
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    
    			case os.Interrupt:
    				C.rl_cleanup_after_signal()
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    			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))
    }
    
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    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 += " "
    	}
    }
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    func (self *JSRepl) read() {
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    	initReadLine()
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    		switch result := readLine(&self.prompt); true {
    
    		case result == nil:
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    			break L
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    		case *result != "":
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    			str += *result + "\n"
    
    			self.setIndent()
    
    			if indentCount <= 0 {
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    				if *result == "exit" {
    					self.Stop()
    					break L
    				}
    
    
    				hist := str[:len(str)-1]
    				addHistory(hist) //allow user to recall this line
    				self.history.WriteString(str)
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    				self.parseInput(str)
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    
    				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)
    		}
    
    Jeffrey Wilcke's avatar
    Jeffrey Wilcke committed
    }