diff --git a/.drone.yml b/.drone.yml index 685e2bf..b566a29 100644 --- a/.drone.yml +++ b/.drone.yml @@ -17,6 +17,8 @@ steps: - env - go version - go env + - git status -v + - git log -1 - name: build commands: - make @@ -25,6 +27,7 @@ steps: CONF_GITEATOKEN: from_secret: gitea-token commands: + - make prepare-test - make test - name: store commands: diff --git a/.gitignore b/.gitignore index 4e4ba07..60874eb 100644 --- a/.gitignore +++ b/.gitignore @@ -123,3 +123,4 @@ $RECYCLE.BIN/ # Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) build/ +!examples/**/*.out diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..13637d8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,28 @@ +[submodule "examples/cpplint/sillycode"] + path = examples/cpplint/sillycode + url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git + branch = cpplint/sillycode +[submodule "examples/compile/success"] + path = examples/compile/success + url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git + branch = compile/success +[submodule "examples/compile/error"] + path = examples/compile/error + url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git + branch = compile/error +[submodule "examples/dummy/success"] + path = examples/dummy/success + url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git + branch = dummy/success +[submodule "examples/dummy/error"] + path = examples/dummy/error + url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git + branch = dummy/error +[submodule "examples/keyword/cpplint/sillycode"] + path = examples/keyword/cpplint/sillycode + url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git + branch = keyword/cpplint/sillycode +[submodule "examples/keyword/clang-tidy/sillycode"] + path = examples/keyword/clang-tidy/sillycode + url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git + branch = keyword/clang-tidy/sillycode diff --git a/Makefile b/Makefile index 3008575..5dace32 100644 --- a/Makefile +++ b/Makefile @@ -11,5 +11,8 @@ clean: rm -rf $(BUILD_DIR)/* rm -rf *.out +prepare-test: + git submodule update --init --remote + test: go test -coverprofile cover.out -v ./... diff --git a/README.md b/README.md index 8244647..5a27e7a 100644 --- a/README.md +++ b/README.md @@ -2,60 +2,97 @@ ## Quick Start -To register the sandbox executor, you need to run [`go-judge`](https://github.com/criyle/go-judge) before running this program. Install `go-judge` and start it with `go-judge -enable-grpc` +1. Make sure you are in a Unix-like OS (Linux, MacOS). For Windows, use [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/install). + +2. Install [Go](https://go.dev/doc/install). Also, make sure `make` and `git` are installed and all 3 programs are presented in `$PATH`. + +3. Enable cgroup v2 for your OS. Check [here](https://stackoverflow.com/a/73376219/13724598). So that you do not need root permission to run `go-judge`. + +4. Clone [go-judge](https://github.com/criyle/go-judge). +```bash +$ git clone https://github.com/criyle/go-judge && cd go-judge +$ go build -o ./tmp/go-judge ./cmd/go-judge +``` + +5. Run `go-judge`. +```bash +$ # make sure you are in go-judge directory +$ ./tmp/go-judge -enable-grpc -enable-debug -enable-metrics +``` + +6. Pull submodules. It might be slow, so only run it when necessary. + +```bash +$ # make sure you are in JOJ3 directory +$ make prepare-test +``` + +7. Build binaries in `/cmd`. + +```bash +$ make +``` + +8. Check the functions of `joj3` with the `make test`, which should pass all the test cases. The cases used here are in `/examples`. + +Note: you may fail the test if the checking tools are not installed. e.g. For the test case `cpplint/sillycode`, you need to install `cpplint` in `/usr/bin` or `/usr/local/bin`. ```bash $ make test -go test -v ./... -? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/cmd/dummy [no test files] +go test -coverprofile cover.out -v ./... + focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/cmd/dummy coverage: 0.0% of statements ? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/executors [no test files] -? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/executors/dummy [no test files] -? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/dummy [no test files] ? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers [no test files] -? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/diff [no test files] -? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/executors/sandbox [no test files] -? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/resultstatus [no test files] -? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage [no test files] -? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/pkg/dummy [no test files] ? focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/pkg/healthcheck [no test files] + focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/executors/dummy coverage: 0.0% of statements + focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/cpplint coverage: 0.0% of statements + focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/diff coverage: 0.0% of statements + focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage coverage: 0.0% of statements + focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/pkg/dummy coverage: 0.0% of statements + focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/keyword coverage: 0.0% of statements + focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/dummy coverage: 0.0% of statements + focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/executors/sandbox coverage: 0.0% of statements + focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/resultstatus coverage: 0.0% of statements === RUN TestMain -=== RUN TestMain/success - main_test.go:96: stageResults: [{Name:compile Results:[{Score:0 Comment:}]} {Name:run Results:[{Score:100 Comment:executor status: run time: 1910200 ns, memory: 13529088 bytes} {Score:100 Comment:executor status: run time: 1703000 ns, memory: 15536128 bytes}]}] -=== RUN TestMain/compile_error - main_test.go:96: stageResults: [{Name:compile Results:[{Score:0 Comment:Unexpected executor status: Nonzero Exit Status.}]}] -=== RUN TestMain/dummy - main_test.go:96: stageResults: [{Name:dummy Results:[{Score:110 Comment:dummy comment + comment from toml conf}]}] -=== RUN TestMain/dummy_error - main_test.go:96: stageResults: [{Name:dummy Results:[{Score:0 Comment:Unexpected executor status: Nonzero Exit Status. - Stderr: dummy negative score: -1}]}] ---- PASS: TestMain (0.29s) - --- PASS: TestMain/success (0.27s) - --- PASS: TestMain/compile_error (0.01s) - --- PASS: TestMain/dummy (0.01s) - --- PASS: TestMain/dummy_error (0.01s) +=== RUN TestMain/compile/error +=== RUN TestMain/compile/success +=== RUN TestMain/cpplint/sillycode +=== RUN TestMain/dummy/error +=== RUN TestMain/dummy/success +=== RUN TestMain/keyword/clang-tidy/sillycode +=== RUN TestMain/keyword/cpplint/sillycode +--- PASS: TestMain (2.28s) + --- PASS: TestMain/compile/error (0.03s) + --- PASS: TestMain/compile/success (0.42s) + --- PASS: TestMain/cpplint/sillycode (0.14s) + --- PASS: TestMain/dummy/error (0.01s) + --- PASS: TestMain/dummy/success (0.01s) + --- PASS: TestMain/keyword/clang-tidy/sillycode (1.57s) + --- PASS: TestMain/keyword/cpplint/sillycode (0.11s) PASS -ok focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/cmd/joj3 0.295s +coverage: 74.0% of statements +ok focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/cmd/joj3 2.290s coverage: 74.0% of statements ``` ### For developers -Install [`pre-commit`](https://pre-commit.com/), [`golangci-lint`](https://golangci-lint.run), [`goimports`](https://golang.org/x/tools/cmd/goimports), [`gofumpt`](https://github.com/mvdan/gofumpt). - -Then install the pre-commit hooks. It will run some checks before you commit. +1. Install [`pre-commit`](https://pre-commit.com/), [`golangci-lint`](https://golangci-lint.run), [`goimports`](https://golang.org/x/tools/cmd/goimports), [`gofumpt`](https://github.com/mvdan/gofumpt). +2. Install the pre-commit hooks. It will run some checks before you commit. ```bash $ pre-commit install pre-commit installed at .git/hooks/pre-commit ``` +3. You only need to run steps 5, 7, and 8 in the quick start during development. If the test cases need to be updated, step 6 is also needed. + ## Models -The program parses the TOML file to run multiple stages. -Each stage contains an executor and parser. +The program parses the configuration file to run multiple stages. It can create an issue on Gitea to report the result of each stage after all stages are done. -Executor takes a `Cmd` and returns an `ExecutorResult`. +Each stage contains an executor and parser. An executor just executes a command and returns the original result (stdout, stderr, output files). We can limit the time and memory used by each command in the executor. We run all kinds of commands in executors of different stages, including code formatting, static check, compilation, and execution. A parser takes the result and the configuration of the stage to parse the result and return the score and comment. e.g. If in the current stage, the executor runs a `clang-tidy` command, then we can use the clang-tidy parser in the configuration file to parse the stdout of the executor result and check whether some of the rules are followed. We can deduct the score and add some comments based on the result, and return the score and comment as the output of this stage. This stage ends here and the next stage starts. -Parser takes an `ExecutorResult` and its conf and returns a `ParserResult` and `bool` to indicate whether we should skip the rest stages. +In codes, an executor takes a `Cmd` and returns an `ExecutorResult`, while a parser takes an `ExecutorResult` and its conf and returns a `ParserResult` and `bool` to indicate whether we should skip the rest stages. ### `Cmd` diff --git a/cmd/joj3/conf.go b/cmd/joj3/conf.go index ec576ad..ef87bbf 100644 --- a/cmd/joj3/conf.go +++ b/cmd/joj3/conf.go @@ -89,7 +89,7 @@ func commitMsgToConf() (conf Conf, err error) { return } msg := commit.Message - slog.Info("commit msg to conf", "msg", msg) + slog.Debug("commit msg to conf", "msg", msg) // TODO: parse msg to conf name conf = parseConfFile("conf.toml") return diff --git a/cmd/joj3/main.go b/cmd/joj3/main.go index 154d8cf..4348b73 100644 --- a/cmd/joj3/main.go +++ b/cmd/joj3/main.go @@ -2,7 +2,6 @@ package main import ( "encoding/json" - "errors" "log/slog" "os" @@ -10,7 +9,6 @@ import ( _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers" "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" - "github.com/go-git/go-git/v5" "github.com/jinzhu/copier" ) @@ -75,13 +73,8 @@ func outputResult(conf Conf, results []stage.StageResult) error { func main() { conf, err := commitMsgToConf() if err != nil { - // FIXME: just for local testing purpose - if errors.Is(err, git.ErrRepositoryNotExists) { - conf = parseConfFile("conf.toml") - } else { - slog.Error("no conf found", "error", err) - os.Exit(1) - } + slog.Error("no conf found", "error", err) + os.Exit(1) } setupSlog(conf) stages := generateStages(conf) diff --git a/cmd/joj3/main_test.go b/cmd/joj3/main_test.go index 44b4821..2169197 100644 --- a/cmd/joj3/main_test.go +++ b/cmd/joj3/main_test.go @@ -4,86 +4,95 @@ import ( "encoding/json" "fmt" "os" + "path/filepath" "regexp" + "strings" "testing" "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" ) -func compareStageResults(t *testing.T, actual, want []stage.StageResult) { +func compareStageResults(t *testing.T, actual, expected []stage.StageResult, regex bool) { t.Helper() - if len(actual) != len(want) { - t.Fatalf("len(actual) = %d, want %d", len(actual), len(want)) + if len(actual) != len(expected) { + t.Fatalf("len(actual) = %d, expected %d", len(actual), len(expected)) } for i := range actual { - if actual[i].Name != want[i].Name { - t.Errorf("actual[%d].Name = %s, want = %s", i, actual[i].Name, - want[i].Name) + if actual[i].Name != expected[i].Name { + t.Errorf("actual[%d].Name = %s, expected = %s", i, actual[i].Name, + expected[i].Name) } - if len(actual[i].Results) != len(want[i].Results) { - t.Fatalf("len(actual[%d].Results) = %d, want = %d", i, - len(actual[i].Results), len(want[i].Results)) + if len(actual[i].Results) != len(expected[i].Results) { + t.Fatalf("len(actual[%d].Results) = %d, expected = %d", i, + len(actual[i].Results), len(expected[i].Results)) } for j := range actual[i].Results { - if actual[i].Results[j].Score != want[i].Results[j].Score { - t.Errorf("actual[%d].Results[%d].Score = %d, want = %d", i, j, - actual[i].Results[j].Score, want[i].Results[j].Score) + if actual[i].Results[j].Score != expected[i].Results[j].Score { + t.Errorf("actual[%d].Results[%d].Score = %d, expected = %d", i, j, + actual[i].Results[j].Score, expected[i].Results[j].Score) } - r := regexp.MustCompile(want[i].Results[j].Comment) - if !r.MatchString(actual[i].Results[j].Comment) { - t.Errorf("actual[%d].Results[%d].Comment = %s, want RegExp = %s", - i, j, actual[i].Results[j].Comment, - want[i].Results[j].Comment) + if regex { + r := regexp.MustCompile(expected[i].Results[j].Comment) + if !r.MatchString(actual[i].Results[j].Comment) { + t.Errorf("actual[%d].Results[%d].Comment = %s, expected RegExp = %s", + i, j, actual[i].Results[j].Comment, + expected[i].Results[j].Comment) + } + } else if actual[i].Results[j].Comment != expected[i].Results[j].Comment { + t.Errorf("actual[%d].Results[%d].Comment = %s, expected = %s", i, j, + actual[i].Results[j].Comment, expected[i].Results[j].Comment) } } } } +func readStageResults(t *testing.T, path string) []stage.StageResult { + t.Helper() + file, err := os.Open(path) + if err != nil { + t.Fatal(err) + } + defer file.Close() + var results []stage.StageResult + err = json.NewDecoder(file).Decode(&results) + if err != nil { + t.Fatal(err) + } + return results +} + func TestMain(t *testing.T) { - tests := []struct { - name string - want []stage.StageResult - }{ - {"success", []stage.StageResult{ - {Name: "compile", Results: []stage.ParserResult{ - {Score: 0, Comment: ""}, - }}, - {Name: "run", Results: []stage.ParserResult{ - {Score: 100, Comment: "executor status: run time: \\d+ ns, memory: \\d+ bytes"}, - {Score: 100, Comment: "executor status: run time: \\d+ ns, memory: \\d+ bytes"}, - }}, - }}, - {"clang-tidy", []stage.StageResult{ - {Name: "prepare", Results: []stage.ParserResult{ - {Score: 0, Comment: ""}, - }}, - {Name: "clang-tidy", Results: []stage.ParserResult{ - {Score: 10, Comment: ""}, - }}, - }}, - {"compile_error", []stage.StageResult{ - {Name: "compile", Results: []stage.ParserResult{ - {Score: 0, Comment: "Unexpected executor status: Nonzero Exit Status\\."}, - }}, - }}, - {"dummy", []stage.StageResult{ - {Name: "dummy", Results: []stage.ParserResult{ - {Score: 110, Comment: "dummy comment \\+ comment from toml conf"}, - }}, - }}, - {"dummy_error", []stage.StageResult{ - {Name: "dummy", Results: []stage.ParserResult{ - {Score: 0, Comment: "Unexpected executor status: Nonzero Exit Status\\.\\s*Stderr: dummy negative score: -1"}, - }}, - }}, + var tests []string + root := "../../examples/" + err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + if path == root { + return nil + } + path0 := filepath.Join(path, "expected_regex.json") + path1 := filepath.Join(path, "expected.json") + _, err0 := os.Stat(path0) + _, err1 := os.Stat(path1) + if err0 != nil && err1 != nil { + return nil + } + tests = append(tests, strings.TrimPrefix(path, root)) + } + return nil + }) + if err != nil { + t.Fatal(err) } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { + t.Run(tt, func(t *testing.T) { origDir, err := os.Getwd() if err != nil { t.Fatal(err) } - err = os.Chdir(fmt.Sprintf("../../examples/%s", tt.name)) + err = os.Chdir(fmt.Sprintf("%s%s", root, tt)) if err != nil { t.Fatal(err) } @@ -94,20 +103,18 @@ func TestMain(t *testing.T) { } }() os.Args = []string{"./joj3"} - main() outputFile := "joj3_result.json" - data, err := os.ReadFile(outputFile) - if err != nil { - t.Fatal(err) - } defer os.Remove(outputFile) - var stageResults []stage.StageResult - err = json.Unmarshal(data, &stageResults) - if err != nil { - t.Fatal(err) + main() + stageResults := readStageResults(t, outputFile) + regex := true + expectedFile := "expected_regex.json" + if _, err := os.Stat(expectedFile); os.IsNotExist(err) { + regex = false + expectedFile = "expected.json" } - t.Logf("stageResults: %+v", stageResults) - compareStageResults(t, stageResults, tt.want) + expectedStageResults := readStageResults(t, expectedFile) + compareStageResults(t, stageResults, expectedStageResults, regex) }) } } diff --git a/examples/clang_tidy/clangtidy_result.json b/examples/clang_tidy/clangtidy_result.json deleted file mode 100644 index 19acf18..0000000 --- a/examples/clang_tidy/clangtidy_result.json +++ /dev/null @@ -1,1996 +0,0 @@ -[ - { - "type": "issue", - "check_name": "clang-diagnostic-error", - "description": "'gtest/test.h' file not found", - "content": { - "body": "```\n#include \n\n ^\n\n```" - }, - "categories": [ - "Bug Risk" - ], - "location": { - "lines": { - "begin": 3 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "critical", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "modernize-use-trailing-return-type", - "description": "use a trailing return type for this function", - "content": { - "body": "```\n Month month() const; // do\n\n ^\n\n```" - }, - "categories": [ - "Compatibility" - ], - "location": { - "lines": { - "begin": 9 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "modernize-use-trailing-return-type", - "description": "use a trailing return type for this function", - "content": { - "body": "```\n int month(); // don't\n\n ~~~ ^\n\n auto -> int\n\n```" - }, - "categories": [ - "Compatibility" - ], - "location": { - "lines": { - "begin": 10 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "google-runtime-references", - "description": "non-const reference parameter 'v', make it const or use a pointer", - "content": { - "body": "```\nvoid do_something(vector& v)\n\n ^\n\n```" - }, - "categories": [ - "Bug Risk" - ], - "location": { - "lines": { - "begin": 14 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "misc-unused-parameters", - "description": "parameter 'v' is unused", - "content": { - "body": "```\nvoid do_something(vector& v)\n\n ^\n\n /*v*/\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 14 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-init-variables", - "description": "variable 'val' is not initialized", - "content": { - "body": "```\n string val;\n\n ^\n\n = 0\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 16 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-special-member-functions", - "description": "class 'X' defines a copy constructor and a copy assignment operator but does not define a destructor, a move constructor or a move assignment operator", - "content": { - "body": "```\nstruct X {\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 28 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-special-member-functions", - "description": "class 'X' defines a copy constructor and a copy assignment operator but does not define a destructor, a move constructor or a move assignment operator", - "content": { - "body": "```\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 28 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "misc-non-private-member-variables-in-classes", - "description": "member variable 'ch' has public visibility", - "content": { - "body": "```\n char ch;\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 29 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "misc-non-private-member-variables-in-classes", - "description": "member variable 'i' has public visibility", - "content": { - "body": "```\n int i;\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 30 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "misc-non-private-member-variables-in-classes", - "description": "member variable 's' has public visibility", - "content": { - "body": "```\n string s;\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 31 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "misc-non-private-member-variables-in-classes", - "description": "member variable 'ch2' has public visibility", - "content": { - "body": "```\n char ch2;\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 32 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "modernize-use-trailing-return-type", - "description": "use a trailing return type for this function", - "content": { - "body": "```\n X& operator=(const X& a); // NOLINT(clang-analyzer-valist.Uninitialized)\n\n ~~ ^\n\n auto -> X&\n\n```" - }, - "categories": [ - "Compatibility" - ], - "location": { - "lines": { - "begin": 34 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "modernize-use-trailing-return-type", - "description": "use a trailing return type for this function", - "content": { - "body": "```\nX waste(const char* p)\n\n~ ^\n\nauto -> X\n\n```" - }, - "categories": [ - "Compatibility" - ], - "location": { - "lines": { - "begin": 38 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-init-variables", - "description": "variable 'n' is not initialized", - "content": { - "body": "```\n int n = strlen(p);\n\n ^\n\n = 0\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 41 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-owning-memory", - "description": "initializing non-owner 'char *' with a newly created 'gsl::owner<>'", - "content": { - "body": "```\n auto buf = new char[n];\n\n ^\n\n../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp:42:5: type deduction did not result in an owner\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 42 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [ - { - "lines": { - "begin": 42 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - } - ] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "llvm-qualified-auto", - "description": "'auto buf' can be declared as 'auto *buf'", - "content": { - "body": "```\n auto buf = new char[n];\n\n ^\n\nnote: this fix will not be applied because it overlaps with another fix\n\n```" - }, - "categories": [ - "Bug Risk" - ], - "location": { - "lines": { - "begin": 42 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "readability-qualified-auto", - "description": "'auto buf' can be declared as 'auto *buf'", - "content": { - "body": "```\nnote: this fix will not be applied because it overlaps with another fix\n\n```" - }, - "categories": [ - "Clarity" - ], - "location": { - "lines": { - "begin": 42 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-braces-around-statements", - "description": "statement should be inside braces", - "content": { - "body": "```\n for (int i = 0; i < n; ++i) buf[i] = p[i];\n\n ^\n\n {\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 44 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "readability-braces-around-statements", - "description": "statement should be inside braces", - "content": { - "body": "```\n for (int i = 0; i < n; ++i) buf[i] = p[i];\n\n ^\n\n {\n\n```" - }, - "categories": [ - "Clarity" - ], - "location": { - "lines": { - "begin": 44 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-pro-bounds-pointer-arithmetic", - "description": "do not use pointer arithmetic", - "content": { - "body": "```\n for (int i = 0; i < n; ++i) buf[i] = p[i];\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 44 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-pro-bounds-pointer-arithmetic", - "description": "do not use pointer arithmetic", - "content": { - "body": "```\n for (int i = 0; i < n; ++i) buf[i] = p[i];\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 44 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-owning-memory", - "description": "deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead", - "content": { - "body": "```\n delete buf;\n\n ^\n\n../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp:42:5: variable declared here\n auto buf = new char[n];\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 50 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [ - { - "lines": { - "begin": 42 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - } - ] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-avoid-magic-numbers", - "description": "666 is a magic number; consider replacing it with a named constant", - "content": { - "body": "```\n int i {666};\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 71 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "readability-magic-numbers", - "description": "666 is a magic number; consider replacing it with a named constant", - "content": { - "body": "```\n```" - }, - "categories": [ - "Clarity" - ], - "location": { - "lines": { - "begin": 71 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "google-explicit-constructor", - "description": "single-argument constructors must be marked explicit to avoid unintentional implicit conversions", - "content": { - "body": "```\n X2(int ii) :i{ii} {} // s and j initialized to their defaults\n\n ^\n\n explicit \n\n```" - }, - "categories": [ - "Bug Risk" - ], - "location": { - "lines": { - "begin": 76 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-explicit-conversions", - "description": "single-argument constructors must be marked explicit to avoid unintentional implicit conversions", - "content": { - "body": "```\n X2(int ii) :i{ii} {} // s and j initialized to their defaults\n\n ^\n\n explicit \n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 76 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "modernize-use-default-member-init", - "description": "use default member initializer for 'i'", - "content": { - "body": "```\n int i;\n\n ^\n\n {ii}\n\n```" - }, - "categories": [ - "Compatibility" - ], - "location": { - "lines": { - "begin": 81 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "modernize-use-default-member-init", - "description": "use default member initializer for 'j'", - "content": { - "body": "```\n int j;\n\n ^\n\n {jj}\n\n```" - }, - "categories": [ - "Compatibility" - ], - "location": { - "lines": { - "begin": 83 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-pro-type-member-init", - "description": "constructor does not initialize these fields: s", - "content": { - "body": "```\n X3(int ii = 666, const string& ss = \"qqq\", int jj = 0)\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 85 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "google-explicit-constructor", - "description": "constructors that are callable with a single argument must be marked explicit to avoid unintentional implicit conversions", - "content": { - "body": "```\n X3(int ii = 666, const string& ss = \"qqq\", int jj = 0)\n\n ^\n\n explicit \n\n```" - }, - "categories": [ - "Bug Risk" - ], - "location": { - "lines": { - "begin": 85 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-explicit-conversions", - "description": "constructors that are callable with a single argument must be marked explicit to avoid unintentional implicit conversions", - "content": { - "body": "```\n X3(int ii = 666, const string& ss = \"qqq\", int jj = 0)\n\n ^\n\n explicit \n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 85 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-member-init", - "description": "constructor does not initialize these fields: s", - "content": { - "body": "```\n X3(int ii = 666, const string& ss = \"qqq\", int jj = 0)\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 85 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "fuchsia-default-arguments-declarations", - "description": "declaring a parameter with a default argument is disallowed", - "content": { - "body": "```\n X3(int ii = 666, const string& ss = \"qqq\", int jj = 0)\n\n ^ ~~~~~~\n\n```" - }, - "categories": [ - "Bug Risk" - ], - "location": { - "lines": { - "begin": 85 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-avoid-magic-numbers", - "description": "666 is a magic number; consider replacing it with a named constant", - "content": { - "body": "```\n X3(int ii = 666, const string& ss = \"qqq\", int jj = 0)\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 85 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "readability-magic-numbers", - "description": "666 is a magic number; consider replacing it with a named constant", - "content": { - "body": "```\n```" - }, - "categories": [ - "Clarity" - ], - "location": { - "lines": { - "begin": 85 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "misc-unused-parameters", - "description": "parameter 'ss' is unused", - "content": { - "body": "```\n X3(int ii = 666, const string& ss = \"qqq\", int jj = 0)\n\n ^~\n\n /*ss*/\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 85 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "fuchsia-default-arguments-declarations", - "description": "declaring a parameter with a default argument is disallowed", - "content": { - "body": "```\n X3(int ii = 666, const string& ss = \"qqq\", int jj = 0)\n\n ^ ~~~~\n\n```" - }, - "categories": [ - "Bug Risk" - ], - "location": { - "lines": { - "begin": 85 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-special-member-functions", - "description": "class 'Foo' defines a move assignment operator but does not define a destructor, a copy constructor, a copy assignment operator or a move constructor", - "content": { - "body": "```\nclass Foo {\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 91 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-special-member-functions", - "description": "class 'Foo' defines a move assignment operator but does not define a destructor, a copy constructor, a copy assignment operator or a move constructor", - "content": { - "body": "```\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 91 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-noexcept-move", - "description": "move assignment operators should be marked noexcept", - "content": { - "body": "```\n Foo& operator=(Foo&& a);\n\n ^\n\n noexcept \n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 95 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "modernize-use-trailing-return-type", - "description": "use a trailing return type for this function", - "content": { - "body": "```\n Foo& operator=(Foo&& a);\n\n ~~~~ ^\n\n auto -> Foo&\n\n```" - }, - "categories": [ - "Compatibility" - ], - "location": { - "lines": { - "begin": 95 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "performance-noexcept-move-constructor", - "description": "move assignment operators should be marked noexcept", - "content": { - "body": "```\n Foo& operator=(Foo&& a);\n\n ^\n\n noexcept \n\n```" - }, - "categories": [ - "Performance" - ], - "location": { - "lines": { - "begin": 95 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-noexcept-move", - "description": "move assignment operators should be marked noexcept", - "content": { - "body": "```\nFoo& Foo::operator=(Foo&& a) // OK, but there is a cost\n\n ^\n\n noexcept \n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 99 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "modernize-use-trailing-return-type", - "description": "use a trailing return type for this function", - "content": { - "body": "```\nFoo& Foo::operator=(Foo&& a) // OK, but there is a cost\n\n~~~~ ^\n\nauto -> Foo&\n\n```" - }, - "categories": [ - "Compatibility" - ], - "location": { - "lines": { - "begin": 99 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "performance-noexcept-move-constructor", - "description": "move assignment operators should be marked noexcept", - "content": { - "body": "```\nFoo& Foo::operator=(Foo&& a) // OK, but there is a cost\n\n ^\n\n noexcept \n\n```" - }, - "categories": [ - "Performance" - ], - "location": { - "lines": { - "begin": 99 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-braces-around-statements", - "description": "statement should be inside braces", - "content": { - "body": "```\n if (this == &a) return *this; // this line is redundant\n\n ^\n\n {\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 101 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "readability-braces-around-statements", - "description": "statement should be inside braces", - "content": { - "body": "```\n if (this == &a) return *this; // this line is redundant\n\n ^\n\n {\n\n```" - }, - "categories": [ - "Clarity" - ], - "location": { - "lines": { - "begin": 101 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-special-member-functions", - "description": "class 'Vector2' defines a move constructor and a move assignment operator but does not define a destructor, a copy constructor or a copy assignment operator", - "content": { - "body": "```\nclass Vector2 {\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 108 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-special-member-functions", - "description": "class 'Vector2' defines a move constructor and a move assignment operator but does not define a destructor, a copy constructor or a copy assignment operator", - "content": { - "body": "```\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 108 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-pro-type-member-init", - "description": "constructor does not initialize these fields: sz", - "content": { - "body": "```\n Vector2(Vector2&& a) { *this = a; } // just use the copy\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 110 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-member-init", - "description": "constructor does not initialize these fields: sz", - "content": { - "body": "```\n Vector2(Vector2&& a) { *this = a; } // just use the copy\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 110 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-noexcept-move", - "description": "move constructors should be marked noexcept", - "content": { - "body": "```\n Vector2(Vector2&& a) { *this = a; } // just use the copy\n\n ^\n\n noexcept \n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 110 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "performance-noexcept-move-constructor", - "description": "move constructors should be marked noexcept", - "content": { - "body": "```\n Vector2(Vector2&& a) { *this = a; } // just use the copy\n\n ^\n\n noexcept \n\n```" - }, - "categories": [ - "Performance" - ], - "location": { - "lines": { - "begin": 110 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-noexcept-move", - "description": "move assignment operators should be marked noexcept", - "content": { - "body": "```\n Vector2& operator=(Vector2&& a) { *this = a; } // just use the copy\n\n ^\n\n noexcept \n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 111 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "modernize-use-trailing-return-type", - "description": "use a trailing return type for this function", - "content": { - "body": "```\n Vector2& operator=(Vector2&& a) { *this = a; } // just use the copy\n\n ~~~~~~~~ ^\n\n auto -> Vector2&\n\n```" - }, - "categories": [ - "Compatibility" - ], - "location": { - "lines": { - "begin": 111 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "performance-noexcept-move-constructor", - "description": "move assignment operators should be marked noexcept", - "content": { - "body": "```\n Vector2& operator=(Vector2&& a) { *this = a; } // just use the copy\n\n ^\n\n noexcept \n\n```" - }, - "categories": [ - "Performance" - ], - "location": { - "lines": { - "begin": 111 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "misc-non-private-member-variables-in-classes", - "description": "member variable 'elem' has public visibility", - "content": { - "body": "```\n T* elem;\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 114 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "misc-non-private-member-variables-in-classes", - "description": "member variable 'sz' has public visibility", - "content": { - "body": "```\n int sz;\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 115 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "google-runtime-references", - "description": "non-const reference parameter 'a', make it const or use a pointer", - "content": { - "body": "```\nvoid f2(N::X& a, N::X& b)\n\n ^\n\n```" - }, - "categories": [ - "Bug Risk" - ], - "location": { - "lines": { - "begin": 118 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "google-runtime-references", - "description": "non-const reference parameter 'b', make it const or use a pointer", - "content": { - "body": "```\nvoid f2(N::X& a, N::X& b)\n\n ^\n\n```" - }, - "categories": [ - "Bug Risk" - ], - "location": { - "lines": { - "begin": 118 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "google-runtime-references", - "description": "non-const reference parameter 'a', make it const or use a pointer", - "content": { - "body": "```\nvoid f3(N::X& a, N::X& b)\n\n ^\n\n```" - }, - "categories": [ - "Bug Risk" - ], - "location": { - "lines": { - "begin": 123 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "misc-unused-parameters", - "description": "parameter 'a' is unused", - "content": { - "body": "```\nvoid f3(N::X& a, N::X& b)\n\n ^\n\n /*a*/\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 123 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "google-runtime-references", - "description": "non-const reference parameter 'b', make it const or use a pointer", - "content": { - "body": "```\nvoid f3(N::X& a, N::X& b)\n\n ^\n\n```" - }, - "categories": [ - "Bug Risk" - ], - "location": { - "lines": { - "begin": 123 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "misc-unused-parameters", - "description": "parameter 'b' is unused", - "content": { - "body": "```\nvoid f3(N::X& a, N::X& b)\n\n ^\n\n /*b*/\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 123 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-macro-usage", - "description": "macro 'RED' used to declare a constant; consider using a 'constexpr' constant", - "content": { - "body": "```\n#define RED 0xFF0000\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 131 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-macro-usage", - "description": "macro 'GREEN' used to declare a constant; consider using a 'constexpr' constant", - "content": { - "body": "```\n#define GREEN 0x00FF00\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 132 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-macro-usage", - "description": "macro 'BLUE' used to declare a constant; consider using a 'constexpr' constant", - "content": { - "body": "```\n#define BLUE 0x0000FF\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 133 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-macro-usage", - "description": "macro 'RED' used to declare a constant; consider using a 'constexpr' constant", - "content": { - "body": "```\n#define RED 0\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 137 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-macro-usage", - "description": "macro 'PURPLE' used to declare a constant; consider using a 'constexpr' constant", - "content": { - "body": "```\n#define PURPLE 1\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 138 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-macro-usage", - "description": "macro 'BLUE' used to declare a constant; consider using a 'constexpr' constant", - "content": { - "body": "```\n#define BLUE 2\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 139 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "google-runtime-references", - "description": "non-const reference parameter at index 0, make it const or use a pointer", - "content": { - "body": "```\nvoid reseat(unique_ptr&); // \"will\" or \"might\" reseat pointer\n\n ^\n\n```" - }, - "categories": [ - "Bug Risk" - ], - "location": { - "lines": { - "begin": 168 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-avoid-c-arrays", - "description": "do not declare C-style arrays, use std::array<> instead", - "content": { - "body": "```\nint buf[max]; // OK, but suspicious: uninitialized\n\n^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 171 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-avoid-c-arrays", - "description": "do not declare C-style arrays, use std::array<> instead", - "content": { - "body": "```\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 171 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "modernize-avoid-c-arrays", - "description": "do not declare C-style arrays, use std::array<> instead", - "content": { - "body": "```\n```" - }, - "categories": [ - "Compatibility" - ], - "location": { - "lines": { - "begin": 171 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-avoid-c-arrays", - "description": "do not declare C-style arrays, use std::array<> instead", - "content": { - "body": "```\nint buf[max] = {0}; // better in some situations\n\n^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 175 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-avoid-c-arrays", - "description": "do not declare C-style arrays, use std::array<> instead", - "content": { - "body": "```\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 175 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "modernize-avoid-c-arrays", - "description": "do not declare C-style arrays, use std::array<> instead", - "content": { - "body": "```\n```" - }, - "categories": [ - "Compatibility" - ], - "location": { - "lines": { - "begin": 175 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-multiway-paths-covered", - "description": "potential uncovered code path; add a default label", - "content": { - "body": "```\n switch (n) { // good\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 218 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-avoid-magic-numbers", - "description": "7 is a magic number; consider replacing it with a named constant", - "content": { - "body": "```\n case 7: // ...\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 220 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "readability-magic-numbers", - "description": "7 is a magic number; consider replacing it with a named constant", - "content": { - "body": "```\n```" - }, - "categories": [ - "Clarity" - ], - "location": { - "lines": { - "begin": 220 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-special-member-functions", - "description": "class 'base' defines a non-default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator", - "content": { - "body": "```\nclass base { public: virtual ~base() = 0; };\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 230 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "hicpp-special-member-functions", - "description": "class 'base' defines a non-default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator", - "content": { - "body": "```\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 230 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "modernize-use-trailing-return-type", - "description": "use a trailing return type for this function", - "content": { - "body": "```\n std::string get_s() { return s; }\n\n ^\n\n```" - }, - "categories": [ - "Compatibility" - ], - "location": { - "lines": { - "begin": 237 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "fuchsia-statically-constructed-objects", - "description": "static objects are disallowed; if possible, use a constexpr constructor instead", - "content": { - "body": "```\nderived1 d1;\n\n^\n\n```" - }, - "categories": [ - "Bug Risk" - ], - "location": { - "lines": { - "begin": 240 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-pro-type-cstyle-cast", - "description": "do not use C-style cast to convert between unrelated types", - "content": { - "body": "```\nderived2* p2 = (derived2*)(p); // BAD, tries to treat d1 as a derived2, which it is not\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 243 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "google-readability-casting", - "description": "C-style casts are discouraged; use reinterpret_cast", - "content": { - "body": "```\nderived2* p2 = (derived2*)(p); // BAD, tries to treat d1 as a derived2, which it is not\n\n ^~~~~~~~~~~\n\n reinterpret_cast\n\n```" - }, - "categories": [ - "Clarity" - ], - "location": { - "lines": { - "begin": 243 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "google-readability-casting", - "description": "C-style casts are discouraged; use const_cast", - "content": { - "body": "```\n (int&)(i) = 42; // BAD\n\n ^~~~~~\n\n const_cast\n\n```" - }, - "categories": [ - "Clarity" - ], - "location": { - "lines": { - "begin": 247 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "cppcoreguidelines-avoid-magic-numbers", - "description": "42 is a magic number; consider replacing it with a named constant", - "content": { - "body": "```\n (int&)(i) = 42; // BAD\n\n ^\n\n```" - }, - "categories": [ - "Style" - ], - "location": { - "lines": { - "begin": 247 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - }, - { - "type": "issue", - "check_name": "readability-magic-numbers", - "description": "42 is a magic number; consider replacing it with a named constant", - "content": { - "body": "```\n```" - }, - "categories": [ - "Clarity" - ], - "location": { - "lines": { - "begin": 247 - }, - "path": "../home/zjche/Desktop/JOJ3/examples/clang_tidy/sillycode.cpp" - }, - "trace": { - "locations": [] - }, - "severity": "major", - "fingerprint": "" - } -] diff --git a/examples/compile/error b/examples/compile/error new file mode 160000 index 0000000..dc7be30 --- /dev/null +++ b/examples/compile/error @@ -0,0 +1 @@ +Subproject commit dc7be30db1fbfd83ecb78f214cff3f42732a1365 diff --git a/examples/compile/success b/examples/compile/success new file mode 160000 index 0000000..21f6df7 --- /dev/null +++ b/examples/compile/success @@ -0,0 +1 @@ +Subproject commit 21f6df70d483f34a99b50335e0a1fbe50d3a82dd diff --git a/examples/compile_error/conf.toml b/examples/compile_error/conf.toml deleted file mode 100644 index a52ff88..0000000 --- a/examples/compile_error/conf.toml +++ /dev/null @@ -1,61 +0,0 @@ -skipGitea = true -logLevel = 0 -[[stages]] -name = "compile" -[stages.executor] -name = "sandbox" -[stages.executor.with.default] -args = ["g++", "b.cc", "-o", "a"] -env = ["PATH=/usr/bin:/bin"] -cpuLimit = 10_000_000_000 -memoryLimit = 104_857_600 -procLimit = 50 -copyInCwd = true -copyOut = ["stdout", "stderr"] -copyOutCached = ["a"] -[stages.executor.with.default.stdin] -content = "" -[stages.executor.with.default.stdout] -name = "stdout" -max = 4_096 -[stages.executor.with.default.stderr] -name = "stderr" -max = 4_096 -[stages.parser] -name = "result-status" -[stages.parser.with] -score = 100 -comment = "compile done" -[[stages]] -name = "run" -[stages.executor] -name = "sandbox" -[stages.executor.with.default] -args = ["./a"] -env = ["PATH=/usr/bin:/bin"] -cpuLimit = 1_000_000_000 -memoryLimit = 104_857_600 -procLimit = 50 -copyOut = ["stdout", "stderr"] -[stages.executor.with.default.stdout] -name = "stdout" -max = 4_096 -[stages.executor.with.default.stderr] -name = "stderr" -max = 4_096 -[stages.executor.with.default.copyInCached] -a = "a" -[[stages.executor.with.cases]] -[stages.executor.with.cases.stdin] -src = "./cases/1.in" -[[stages.executor.with.cases]] -[stages.executor.with.cases.stdin] -src = "./cases/2.in" -[stages.parser] -name = "diff" -[[stages.parser.with.cases]] -score = 100 -stdoutPath = "./cases/1.out" -[[stages.parser.with.cases]] -score = 100 -stdoutPath = "./cases/2.out" diff --git a/examples/cpplint/sillycode b/examples/cpplint/sillycode new file mode 160000 index 0000000..a700156 --- /dev/null +++ b/examples/cpplint/sillycode @@ -0,0 +1 @@ +Subproject commit a7001564a22f9807119efb7b8f4cf6f74d4c12fc diff --git a/examples/dummy/conf.toml b/examples/dummy/conf.toml deleted file mode 100644 index 80b2d72..0000000 --- a/examples/dummy/conf.toml +++ /dev/null @@ -1,28 +0,0 @@ -skipGitea = true -[[stages]] -name = "dummy" -[stages.executor] -name = "sandbox" -[stages.executor.with.default] -args = ["./dummy", "--score", "100"] -env = ["PATH=/usr/bin:/bin"] -cpuLimit = 10_000_000_000 -memoryLimit = 104_857_600 -procLimit = 50 -copyInCwd = true -[stages.executor.with.default.copyIn.dummy] -src = "./../../build/dummy" -copyOut = ["stdout", "stderr"] -[stages.executor.with.default.stdin] -content = "" -[stages.executor.with.default.stdout] -name = "stdout" -max = 4_096 -[stages.executor.with.default.stderr] -name = "stderr" -max = 4_096 -[stages.parser] -name = "dummy" -[stages.parser.with] -score = 10 -comment = " + comment from toml conf" diff --git a/examples/dummy/error b/examples/dummy/error new file mode 160000 index 0000000..3ebebbc --- /dev/null +++ b/examples/dummy/error @@ -0,0 +1 @@ +Subproject commit 3ebebbc913534fb4c4598d3ed313d1bb3ff29020 diff --git a/examples/dummy/success b/examples/dummy/success new file mode 160000 index 0000000..4bca6f0 --- /dev/null +++ b/examples/dummy/success @@ -0,0 +1 @@ +Subproject commit 4bca6f0e4b5e263532b8410afecca615e90524e9 diff --git a/examples/dummy_error/conf.toml b/examples/dummy_error/conf.toml deleted file mode 100644 index c6b8fa2..0000000 --- a/examples/dummy_error/conf.toml +++ /dev/null @@ -1,28 +0,0 @@ -skipGitea = true -[[stages]] -name = "dummy" -[stages.executor] -name = "sandbox" -[stages.executor.with.default] -args = ["./dummy", "--score", "-1"] -env = ["PATH=/usr/bin:/bin"] -cpuLimit = 10_000_000_000 -memoryLimit = 104_857_600 -procLimit = 50 -copyInCwd = true -[stages.executor.with.default.copyIn.dummy] -src = "./../../build/dummy" -copyOut = ["stdout", "stderr"] -[stages.executor.with.default.stdin] -content = "" -[stages.executor.with.default.stdout] -name = "stdout" -max = 4_096 -[stages.executor.with.default.stderr] -name = "stderr" -max = 4_096 -[stages.parser] -name = "dummy" -[stages.parser.with] -score = 10 -comment = " + comment from toml conf" diff --git a/examples/keyword/clang-tidy/sillycode b/examples/keyword/clang-tidy/sillycode new file mode 160000 index 0000000..51160e0 --- /dev/null +++ b/examples/keyword/clang-tidy/sillycode @@ -0,0 +1 @@ +Subproject commit 51160e0a0cb01159fa264435865185083d756b06 diff --git a/examples/keyword/cpplint/sillycode b/examples/keyword/cpplint/sillycode new file mode 160000 index 0000000..f43b0b3 --- /dev/null +++ b/examples/keyword/cpplint/sillycode @@ -0,0 +1 @@ +Subproject commit f43b0b3a7b873ee935b19e4e5f26a8ceda7d3d61 diff --git a/examples/success/.gitignore b/examples/success/.gitignore deleted file mode 100644 index 6aa6b80..0000000 --- a/examples/success/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!*.out diff --git a/examples/success/a.cc b/examples/success/a.cc deleted file mode 100644 index 2c7ca74..0000000 --- a/examples/success/a.cc +++ /dev/null @@ -1,6 +0,0 @@ -#include -int main() { - int a, b; - std::cin >> a >> b; - std::cout << a + b << '\n'; -} diff --git a/examples/success/cases/1.in b/examples/success/cases/1.in deleted file mode 100644 index 2fb73a0..0000000 --- a/examples/success/cases/1.in +++ /dev/null @@ -1 +0,0 @@ -1 1 diff --git a/examples/success/cases/1.out b/examples/success/cases/1.out deleted file mode 100644 index 0cfbf08..0000000 --- a/examples/success/cases/1.out +++ /dev/null @@ -1 +0,0 @@ -2 diff --git a/examples/success/cases/2.in b/examples/success/cases/2.in deleted file mode 100644 index b5f1e36..0000000 --- a/examples/success/cases/2.in +++ /dev/null @@ -1 +0,0 @@ -1024 2048 diff --git a/examples/success/cases/2.out b/examples/success/cases/2.out deleted file mode 100644 index 5fd86fd..0000000 --- a/examples/success/cases/2.out +++ /dev/null @@ -1 +0,0 @@ -3072 diff --git a/examples/success/conf.toml b/examples/success/conf.toml deleted file mode 100644 index e91739a..0000000 --- a/examples/success/conf.toml +++ /dev/null @@ -1,60 +0,0 @@ -skipGitea = true -[[stages]] -name = "compile" -[stages.executor] -name = "sandbox" -[stages.executor.with.default] -args = ["g++", "a.cc", "-o", "a"] -env = ["PATH=/usr/bin:/bin"] -cpuLimit = 10_000_000_000 -memoryLimit = 104_857_600 -procLimit = 50 -copyInCwd = true -copyOut = ["stdout", "stderr"] -copyOutCached = ["a"] -[stages.executor.with.default.stdin] -content = "" -[stages.executor.with.default.stdout] -name = "stdout" -max = 4_096 -[stages.executor.with.default.stderr] -name = "stderr" -max = 4_096 -[stages.parser] -name = "result-status" -[stages.parser.with] -score = 100 -comment = "compile done" -[[stages]] -name = "run" -[stages.executor] -name = "sandbox" -[stages.executor.with.default] -args = ["./a"] -env = ["PATH=/usr/bin:/bin"] -cpuLimit = 1_000_000_000 -memoryLimit = 104_857_600 -procLimit = 50 -copyOut = ["stdout", "stderr"] -[stages.executor.with.default.stdout] -name = "stdout" -max = 4_096 -[stages.executor.with.default.stderr] -name = "stderr" -max = 4_096 -[stages.executor.with.default.copyInCached] -a = "a" -[[stages.executor.with.cases]] -[stages.executor.with.cases.stdin] -src = "./cases/1.in" -[[stages.executor.with.cases]] -[stages.executor.with.cases.stdin] -src = "./cases/2.in" -[stages.parser] -name = "diff" -[[stages.parser.with.cases]] -score = 100 -stdoutPath = "./cases/1.out" -[[stages.parser.with.cases]] -score = 100 -stdoutPath = "./cases/2.out" diff --git a/internal/parsers/all.go b/internal/parsers/all.go index ba5106b..64dddd9 100644 --- a/internal/parsers/all.go +++ b/internal/parsers/all.go @@ -2,8 +2,10 @@ package parsers import ( _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/clang_tidy" + _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/cpplint" _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/diff" _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/dummy" + _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/keyword" _ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/resultstatus" ) diff --git a/internal/parsers/cpplint/meta.go b/internal/parsers/cpplint/meta.go new file mode 100644 index 0000000..33b5188 --- /dev/null +++ b/internal/parsers/cpplint/meta.go @@ -0,0 +1,9 @@ +package cpplint + +import "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" + +var name = "cpplint" + +func init() { + stage.RegisterParser(name, &Cpplint{}) +} diff --git a/internal/parsers/cpplint/parser.go b/internal/parsers/cpplint/parser.go new file mode 100644 index 0000000..55a7f60 --- /dev/null +++ b/internal/parsers/cpplint/parser.go @@ -0,0 +1,53 @@ +package cpplint + +import ( + "fmt" + "regexp" + "strconv" + + "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" +) + +type Conf struct { + Score int +} + +type Cpplint struct{} + +func Parse(executorResult stage.ExecutorResult, conf Conf) stage.ParserResult { + stderr := executorResult.Files["stderr"] + pattern := `(.+):(\d+): (.+) \[(.+)\] \[(\d)]\n` + re := regexp.MustCompile(pattern) + matches := re.FindAllStringSubmatch(stderr, -1) + score := 0 + comment := "" + for _, match := range matches { + fileName := match[1] + lineNum, _ := strconv.Atoi(match[2]) + message := match[3] + category := match[4] + confidence, _ := strconv.Atoi(match[5]) + score -= confidence + // TODO: add more detailed comment, just re-assemble for now + comment += fmt.Sprintf("%s:%d: %s [%s] [%d]\n", + fileName, lineNum, message, category, confidence) + } + return stage.ParserResult{ + Score: score, + Comment: comment, + } +} + +func (*Cpplint) Run(results []stage.ExecutorResult, confAny any) ( + []stage.ParserResult, bool, error, +) { + conf, err := stage.DecodeConf[Conf](confAny) + if err != nil { + return nil, true, err + } + var res []stage.ParserResult + for _, result := range results { + res = append(res, Parse(result, *conf)) + } + return res, false, nil +} diff --git a/internal/parsers/keyword/meta.go b/internal/parsers/keyword/meta.go new file mode 100644 index 0000000..fd2dccd --- /dev/null +++ b/internal/parsers/keyword/meta.go @@ -0,0 +1,9 @@ +package keyword + +import "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" + +var name = "keyword" + +func init() { + stage.RegisterParser(name, &Keyword{}) +} diff --git a/internal/parsers/keyword/parser.go b/internal/parsers/keyword/parser.go new file mode 100644 index 0000000..ccf0c0f --- /dev/null +++ b/internal/parsers/keyword/parser.go @@ -0,0 +1,67 @@ +package keyword + +import ( + "fmt" + "strings" + + "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" +) + +type Match struct { + Keyword string + Score int +} + +type Conf struct { + FullScore int + MinScore int + Files []string + EndOnMatch bool + Matches []Match +} + +type Keyword struct{} + +func Parse(executorResult stage.ExecutorResult, conf Conf) ( + stage.ParserResult, bool, +) { + score := conf.FullScore + comment := "" + matched := false + for _, file := range conf.Files { + content := executorResult.Files[file] + for _, match := range conf.Matches { + count := strings.Count(content, match.Keyword) + if count > 0 { + matched = true + score -= count * match.Score + comment += fmt.Sprintf( + "Matched keyword %d time(s): %s\n", + count, match.Keyword) + } + } + } + return stage.ParserResult{ + Score: max(score, conf.MinScore), + Comment: comment, + }, matched +} + +func (*Keyword) Run(results []stage.ExecutorResult, confAny any) ( + []stage.ParserResult, bool, error, +) { + conf, err := stage.DecodeConf[Conf](confAny) + if err != nil { + return nil, true, err + } + var res []stage.ParserResult + end := false + for _, result := range results { + tmp, matched := Parse(result, *conf) + if matched && conf.EndOnMatch { + end = true + } + res = append(res, tmp) + } + return res, end, nil +} diff --git a/internal/stage/model.go b/internal/stage/model.go index 848e4ec..1b052d8 100644 --- a/internal/stage/model.go +++ b/internal/stage/model.go @@ -159,11 +159,11 @@ type Stage struct { } type ParserResult struct { - Score int - Comment string + Score int `json:"score"` + Comment string `json:"comment"` } type StageResult struct { - Name string - Results []ParserResult + Name string `json:"name"` + Results []ParserResult `json:"results"` }