func (self *ProblemArchiveReader) LoadSolutions(problem *model.Problem, rePattern string) error { re, err := regexp.Compile(rePattern) if err != nil { return err } for _, file := range self.FileList() { match := re.FindStringSubmatch(file) if match != nil { ext := filepath.Ext(match[1]) compiler := programs.GetCompilerByExt(ext) if compiler == nil { return fmt.Errorf("Unknown solution language %s", ext) } data, err := self.ReadFile(file) if err != nil { return err } problem.Solutions[match[1]] = &model.Solution{ Name: match[1], Language: compiler.Name, SourceCode: string(data), } } } return nil }
func (self Format) ImportArchive(archive *formats.ProblemArchiveReader) (problems []*model.Problem, err error) { defer SuppressPanic(&err) data, err := archive.ReadFile("problem.xml") PanicIf(err) problem := new(Problem) xml.Unmarshal(data, problem) p := &model.Problem{ Title: problem.Names[0].Value, InputFile: problem.Judging.InputFile, OutputFile: problem.Judging.OutputFile, TimeLimit: float32(problem.Judging.TestSet.TimeLimit) / 1000, MemoryLimit: float32(problem.Judging.TestSet.MemoryLimit) / 1024 / 1024, Statement: model.RawText(""), Constraints: model.RawText(""), InputFormat: model.RawText(""), OutputFormat: model.RawText(""), Generators: make(map[string]*model.Generator), Solutions: make(map[string]*model.Solution), Images: make(model.ImagesDict), } if p.InputFile == "" { p.InputFile = "*STDIN" } if p.OutputFile == "" { p.OutputFile = "*STDOUT" } getFile := func(file *File) (*programs.Compiler, []byte, string, error) { path := file.Path name := filepath.Base(path) ext := filepath.Ext(path) compiler := programs.GetCompilerByExt(ext) if compiler == nil { return nil, nil, "", fmt.Errorf("Unknown language extension %s", ext) } data, err := archive.ReadFile(path) if err != nil { return nil, nil, "", fmt.Errorf("Cannot read file %s: %s", path, err) } return compiler, data, name, nil } var mainSolution *model.Solution for _, solution := range problem.Assets.Solutions { compiler, data, name, err := getFile(&solution.Source) PanicIf(err, "Solution error: %s", err) p.Solutions[name] = &model.Solution{ Name: name, Language: compiler.Name, SourceCode: string(data), } if solution.Tag == "main" { mainSolution = p.Solutions[name] } } getGenerator := func(name string) *model.Generator { if generator := p.Generators[name]; generator != nil { return generator } for _, executable := range problem.Files.Executables { path := executable.Source.Path filename := filepath.Base(path) ext := filepath.Ext(filename) genName := filename[:len(filename)-len(ext)] if genName == name { compiler, data, _, err := getFile(&executable.Source) PanicIf(err, "Generator error: %s", err) p.Generators[genName] = &model.Generator{ Name: genName, Language: compiler.Name, SourceCode: string(data), OutputFile: "*STDOUT", } return p.Generators[genName] } } return nil } p.Tests = make([]model.Test, len(problem.Judging.TestSet.Tests)) for i, test := range problem.Judging.TestSet.Tests { switch test.Method { case "manual": path := fmt.Sprintf(problem.Judging.TestSet.InputPathPattern, i+1) data, err := archive.ReadFile(path) PanicIf(err, "Cannot read test %d", i+1) p.Tests[i].Input = model.ConstTestData(data) case "generated": parts := strings.SplitN(test.Command, " ", 2) params := "" if len(parts) == 2 { params = parts[1] } generator := getGenerator(parts[0]) PanicIf(generator == nil, "Unknown generator %s for test %d", parts[0], i+1) p.Tests[i].Input = &model.GeneratedInput{ Generator: generator.Name, Parameters: params, } default: Panic("Unknown test method %s", test.Method) } if mainSolution != nil { p.Tests[i].Output = &model.SolutionOutput{ Solution: mainSolution.Name, } } } if checker := problem.Assets.Checker; checker != nil { compiler, data, _, err := getFile(&checker.Source) PanicIf(err, "Solution error: %s", err) p.Checker = &model.Checker{ Style: "testlib", Language: compiler.Name, SourceCode: string(data), } } for _, statement := range problem.Statements { if statement.Format == "tex" && statement.Language == problem.Names[0].Language { importStatement(archive, p, &statement) break } } return []*model.Problem{p}, nil }