Chromium Code Reviews| Index: experimental/webtry/webtry.go |
| diff --git a/experimental/webtry/webtry.go b/experimental/webtry/webtry.go |
| index e644d138a71a26c3409e825d8706538e9fc8ffcc..e09e611264feb5b43b36c0f9fa59410f3ee3ee95 100644 |
| --- a/experimental/webtry/webtry.go |
| +++ b/experimental/webtry/webtry.go |
| @@ -23,6 +23,7 @@ import ( |
| "os/exec" |
| "path/filepath" |
| "regexp" |
| + "strconv" |
| "strings" |
| "text/template" |
| "time" |
| @@ -404,10 +405,10 @@ func expandGyp(hash string) error { |
| // response is serialized to JSON as a response to POSTs. |
| type response struct { |
| - Message string `json:"message"` |
| - StdOut string `json:"stdout"` |
| - Img string `json:"img"` |
| - Hash string `json:"hash"` |
| + Message string `json:"message"` |
| + CompileErrors []compileError `json:"compileErrors"` |
| + Img string `json:"img"` |
| + Hash string `json:"hash"` |
| } |
| // doCmd executes the given command line string; the command being |
| @@ -446,6 +447,23 @@ func reportTryError(w http.ResponseWriter, r *http.Request, err error, message, |
| } |
| log.Printf("Error: %s\n%s", message, err.Error()) |
| resp, err := json.Marshal(m) |
| + |
| + if err != nil { |
| + http.Error(w, "Failed to serialize a response", 500) |
| + return |
| + } |
| + w.Header().Set("Content-Type", "text/plain") |
| + w.Write(resp) |
| +} |
| + |
| +func reportCompileError(w http.ResponseWriter, r *http.Request, compileErrors []compileError, hash string) { |
| + m := response{ |
| + CompileErrors: compileErrors, |
| + Hash: hash, |
| + } |
| + |
| + resp, err := json.Marshal(m) |
| + |
| if err != nil { |
| http.Error(w, "Failed to serialize a response", 500) |
| return |
| @@ -792,6 +810,12 @@ func cleanCompileOutput(s, hash string) string { |
| return strings.Replace(s, old, "usercode.cpp:", -1) |
| } |
| +type compileError struct { |
| + Line int `json:"line"` |
| + Column int `json:"column"` |
| + Error string `json:"error"` |
| +} |
| + |
| // mainHandler handles the GET and POST of the main page. |
| func mainHandler(w http.ResponseWriter, r *http.Request) { |
| log.Printf("Main Handler: %q\n", r.URL.Path) |
| @@ -867,10 +891,41 @@ func mainHandler(w http.ResponseWriter, r *http.Request) { |
| } |
| message, err := doCmd(cmd) |
| + |
| + outputLines := strings.Split(message, "\n") |
| + errorLines := []compileError{} |
| + errorRE := regexp.MustCompile(fmt.Sprintf("^.*%s.cpp:(\\d+):(\\d+):\\s*(.*)", hash)) |
|
jcgregorio
2014/10/15 19:59:50
Move to top of file so it's only compiled once.
humper
2014/10/15 21:03:59
Done.
|
| + for _, line := range outputLines { |
| + match := errorRE.FindStringSubmatch(line) |
| + if len(match) > 0 { |
| + lineNumber, parseError := strconv.Atoi(match[1]) |
| + if parseError != nil { |
| + log.Printf("ERROR: Couldn't parse line number from %s\n", match[1]) |
|
jcgregorio
2014/10/15 19:59:50
Add a TODO to switch from log to glog (http://godo
tfarina
2014/10/15 20:05:21
I will do that. I have a bug filed for that: https
|
| + continue |
| + } |
| + columnNumber, parseError := strconv.Atoi(match[2]) |
| + if parseError != nil { |
| + log.Printf("ERROR: Couldn't parse column number from %s\n", match[2]) |
| + continue |
| + } |
| + errorLines = append(errorLines, |
| + compileError{ |
| + Line: lineNumber, |
| + Column: columnNumber, |
| + Error: match[3], |
| + }) |
| + } |
| + } |
| + |
| if err != nil { |
| - reportTryError(w, r, err, "Failed to run the code:\n"+message, hash) |
| + if len(errorLines) > 0 { |
| + reportCompileError(w, r, errorLines, hash) |
| + } else { |
| + reportTryError(w, r, err, "Failed to run the code:\n"+message, hash) |
| + } |
| return |
| } |
| + |
| png, err := ioutil.ReadFile("../../../inout/" + hash + ".png") |
| if err != nil { |
| reportTryError(w, r, err, "Failed to open the generated PNG.", hash) |