func handleMsg(msg msgType) { c := msg.c if c == nil { log.Println("c shouldn't be nil") return } switch msg.Type { case "format": resp := &msgType{ Type: "format", } func() { defer func() { if r := recover(); r != nil { value := fmt.Sprintln(r) stack := make([]byte, 99999) runtime.Stack(stack, false) value += string(stack) resp.Value = value } }() formatted, err := format.Source([]byte(msg.Value.(string))) if err == nil { resp.Value = string(formatted) } }() c.WriteJSON(resp) case "translate": resp := &msgType{ Type: "translate", } func() { defer func() { if r := recover(); r != nil { value := fmt.Sprintln(r) stack := make([]byte, 99999) runtime.Stack(stack, false) value += string(stack) resp.Value = value } }() w := &bytes.Buffer{} errs := sgo.TranslateFile(func() (io.Writer, error) { return w, nil }, strings.NewReader(msg.Value.(string)), "name") if errs != nil { var errMsgs []string for _, err := range errs { if errs, ok := err.(scanner.ErrorList); ok { for _, err := range errs { errMsgs = append(errMsgs, err.Error()) } } else { errMsgs = append(errMsgs, err.Error()) } } resp.Value = strings.Join(errMsgs, "\n") } else { resp.Value = w.String() } }() c.WriteJSON(resp) case "execute": resp := &msgType{ Type: "execute", } body := url.Values{} body.Add("version", "2") var errs []error w := &bytes.Buffer{} func() { defer func() { if r := recover(); r != nil { value := fmt.Sprintln(r) stack := make([]byte, 99999) runtime.Stack(stack, false) value += string(stack) errs = append(errs, errors.New(value)) } }() errs = sgo.TranslateFile(func() (io.Writer, error) { return w, nil }, strings.NewReader(msg.Value.(string)), "name") }() if errs != nil { var errMsgs []string for _, err := range errs { if errs, ok := err.(scanner.ErrorList); ok { for _, err := range errs { errMsgs = append(errMsgs, err.Error()) } } else { errMsgs = append(errMsgs, err.Error()) } } resp.Value = strings.Join(errMsgs, "\n") } else { body.Add("body", w.String()) postResp, err := http.PostForm("https://play.golang.org/compile", body) if err != nil { resp.Value = err.Error() } else { var v interface{} err := json.NewDecoder(postResp.Body).Decode(&v) postResp.Body.Close() if err != nil { resp.Value = err.Error() } else { resp.Value = v } } } c.WriteJSON(resp) } }
func main() { if len(os.Args) == 1 { fmt.Print(helpMsg) return } var buildFlags []string var extraArgs []string for i, arg := range os.Args[2:] { if arg[0] == '-' { buildFlags = append(buildFlags, arg) } else { extraArgs = os.Args[i+2:] break } } switch os.Args[1] { case "version": fmt.Println("sgo version 0.7 (compatible with go1.7)") return case "run": if len(extraArgs) == 0 { fmt.Fprintln(os.Stderr, "sgo run: no files listed") os.Exit(1) } created, errs := sgo.TranslateFilePaths(extraArgs...) reportErrs(errs...) if len(errs) > 0 { os.Exit(1) } runGoCommand("run", buildFlags, created...) return case "help": if len(extraArgs) == 0 { fmt.Print(helpMsg) } else { switch extraArgs[0] { case "translate": fmt.Print(translateHelpMsg) return case "version": fmt.Print(versionHelpMsg) return } runGoCommand("help", buildFlags, extraArgs...) } return case "translate": errs := sgo.TranslateFile(func() (io.Writer, error) { return os.Stdout, nil }, os.Stdin, "stdin.sgo") if len(errs) > 0 { reportErrs(errs...) os.Exit(1) } return } if len(extraArgs) == 0 { extraArgs = append(extraArgs, ".") } _, warnings, errs := sgo.TranslatePaths(extraArgs) reportErrs(warnings...) reportErrs(errs...) if len(errs) > 0 { os.Exit(1) } runGoCommand(os.Args[1], buildFlags, extraArgs...) }