veyron/tools/naming/simulator: add support for printing out json dicts.

Change-Id: Ib9b6852151d31911b9adcf74135c5de90f2b1087
diff --git a/tools/naming/simulator/commands.go b/tools/naming/simulator/commands.go
index 3efbd5b..cf82ed2 100644
--- a/tools/naming/simulator/commands.go
+++ b/tools/naming/simulator/commands.go
@@ -2,6 +2,7 @@
 
 import (
 	"bytes"
+	"encoding/json"
 	"fmt"
 	"io"
 	"os"
@@ -21,18 +22,20 @@
 	needsHandle bool
 	fn          builtinCmd
 }{
-	"print":   {-1, "print <args>...", false, print},
-	"help":    {-1, "help", false, nil},
-	"set":     {-1, "set <var>=<val>...", false, set},
-	"splitEP": {-1, "splitEP", false, splitEP},
-	"assert":  {2, "val1 val2", false, assert},
-	"read":    {-1, "read <handle> [var]", true, read},
-	"eval":    {1, "eval <handle>", true, eval},
-	"wait":    {1, "wait <handle>", true, wait},
-	"stop":    {1, "stop <handle>", true, stop},
-	"stderr":  {1, "stderr <handle>", true, stderr},
-	"list":    {0, "list", false, list},
-	"quit":    {0, "quit", false, quit},
+	"print":      {-1, "print <args>...", false, print},
+	"help":       {-1, "help", false, nil},
+	"set":        {-1, "set <var>=<val>...", false, set},
+	"json_set":   {-1, "<var>...", false, json_set},
+	"json_print": {0, "", false, json_print},
+	"splitEP":    {-1, "splitEP", false, splitEP},
+	"assert":     {2, "val1 val2", false, assert},
+	"read":       {-1, "read <handle> [var]", true, read},
+	"eval":       {1, "eval <handle>", true, eval},
+	"wait":       {1, "wait <handle>", true, wait},
+	"stop":       {1, "stop <handle>", true, stop},
+	"stderr":     {1, "stderr <handle>", true, stderr},
+	"list":       {0, "list", false, list},
+	"quit":       {0, "quit", false, quit},
 }
 
 func init() {
@@ -222,3 +225,22 @@
 	l := handle.Session.ReadLine()
 	return l, handle.Session.Error()
 }
+
+func json_set(sh *modules.Shell, _ *cmdState, args ...string) (string, error) {
+	for _, k := range args {
+		if v, present := sh.GetVar(k); present {
+			jsonDict[k] = v
+		} else {
+			return "", fmt.Errorf("unrecognised variable: %q", k)
+		}
+	}
+	return "", nil
+}
+
+func json_print(sh *modules.Shell, _ *cmdState, args ...string) (string, error) {
+	bytes, err := json.Marshal(jsonDict)
+	if err != nil {
+		return "", err
+	}
+	return string(bytes), nil
+}
diff --git a/tools/naming/simulator/driver.go b/tools/naming/simulator/driver.go
index 31e6038..c6abba2 100644
--- a/tools/naming/simulator/driver.go
+++ b/tools/naming/simulator/driver.go
@@ -33,11 +33,13 @@
 var (
 	interactive bool
 	handles     map[string]*cmdState
+	jsonDict    map[string]string
 )
 
 func init() {
 	flag.BoolVar(&interactive, "interactive", true, "set interactive/batch mode")
 	handles = make(map[string]*cmdState)
+	jsonDict = make(map[string]string)
 	flag.Usage = usage
 }
 
@@ -126,7 +128,9 @@
 			}
 			if err := process(shell, line, lineno); err != nil {
 				fmt.Printf("ERROR: %d> %q: %v\n", lineno, line, err)
-				os.Exit(1)
+				if !interactive {
+					os.Exit(1)
+				}
 			}
 		}
 		shell.SetVar("_", strconv.Itoa(lineno))
@@ -194,11 +198,8 @@
 			expect.NewSession(nil, handle.Stdout(), time.Minute),
 			line,
 		}
-		if !interactive {
-			fmt.Printf("%d> %s\n", lineno, line)
-		}
+		output(lineno, line)
 	}
-
 	return nil
 }
 
diff --git a/tools/naming/simulator/json_example.scr b/tools/naming/simulator/json_example.scr
new file mode 100644
index 0000000..1fe1e3e
--- /dev/null
+++ b/tools/naming/simulator/json_example.scr
@@ -0,0 +1,29 @@
+
+cache off
+
+set localaddr=--veyron.tcp.address=127.0.0.1:0
+
+root -- $localaddr
+set root=$_
+eval $root
+set ROOT_NAME=$MT_NAME
+read $root
+eval $root
+set ROOT_PID=$PID
+json_set ROOT_NAME ROOT_PID
+
+set PROXY_MOUNTPOINT=$ROOT_NAME/proxy/mp
+proxyd -- $localaddr $PROXY_MOUNTPOINT
+set proxyd=$_
+read $proxyd
+eval $proxyd
+set PROXYD_NAME=$PROXY_NAME
+splitEP $PROXY_NAME
+set PROXY_HOST_ADDR=$P2
+json_set PROXY_MOUNTPOINT PROXY_NAME PROXY_HOST_ADDR
+
+
+json_print
+
+# uncomment wait $root to have the script leave all of the processes running
+#wait $root