func (self Format) ImportArchive(archive *formats.ProblemArchiveReader) (problems []*model.Problem, err error) { defer SuppressPanic(&err) data, err := archive.ReadFile("domjudge-problem.ini") PanicIf(err, "Cannot read problem settings: %s", err) settings := ParseSettings(data) p := &model.Problem{ Title: settings["name"], TimeLimit: float32(settings.GetInt("timelimit")), MemoryLimit: 128, Solutions: make(map[string]*model.Solution), } PanicIf(archive.LoadTests(p, "(.*).in$", "(.*).out$")) PanicIf(archive.LoadSolutions(p, "sol_(.*)")) return []*model.Problem{p}, nil }
func importStatement(archive *formats.ProblemArchiveReader, problem *model.Problem, statement *Statement) { data, err := archive.ReadFile(statement.Path) PanicIf(err, "Cannot read statement %s: %s", statement.Path, err) getTeX := func(src []byte) model.FormattedText { return model.RawText(src) } if match := statementRe.FindSubmatch(data); match != nil { problem.Statement = getTeX(match[1]) problem.InputFormat = getTeX(match[2]) problem.OutputFormat = getTeX(match[3]) } matches := exampleRe.FindAllSubmatch(data, -1) problem.Samples = make([]model.Sample, len(matches)) for i, match := range matches { problem.Samples[i].Input = string(match[1]) problem.Samples[i].Output = string(match[2]) } }
func addGenerator(archive *formats.ProblemArchiveReader, problem *model.Problem, generator *Generator) { gen := problem.Generators[generator.Name] if gen == nil { gen = new(model.Generator) problem.Generators[generator.Name] = gen } gen.Name = generator.Name if generator.OutputFile != "" { gen.OutputFile = generator.OutputFile } if generator.LanguageCode != 0 || generator.Source != "" { lang := getLanguage(generator.LanguageCode, generator.Source) PanicIf(lang == nil, "Unknown generator language") gen.Language = lang.Name } if generator.Source != "" { data, err := archive.ReadFile(generator.Source) PanicIf(err) gen.SourceCode = string(data) } }
func (self Format) ImportArchive(archive *formats.ProblemArchiveReader) (problems []*model.Problem, err error) { defer SuppressPanic(&err) reader, err := archive.Open("problem.xml") PanicIf(err) defer reader.Close() problem := new(Problem) utils.NewXmlDecoder(reader).Decode(problem) testset := &problem.Script.Testset p := &model.Problem{ InputFile: testset.InputName, OutputFile: testset.OutputName, TimeLimit: float32(parseTime(testset.TimeLimit)), MemoryLimit: float32(testset.MemoryLimit) / 1024 / 1024, Tests: make([]model.Test, testset.TestCount), } inputPattern := preparePattern(testset.InputPattern) outputPattern := preparePattern(testset.AnswerPattern) for i := 0; i < testset.TestCount; i++ { inputPattern = inputPattern outputPattern = outputPattern data, err := archive.ReadFile(fmt.Sprintf(inputPattern, i+1)) PanicIf(err, "Cannot read test %d input: %s", i+1, err) p.Tests[i].Input = model.ConstTestData(data) data, err = archive.ReadFile(fmt.Sprintf(outputPattern, i+1)) PanicIf(err, "Cannot read test %d input: %s", i+1, err) p.Tests[i].Output = model.ConstSolutionData(data) } return []*model.Problem{p}, 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 }
func (self Format) ImportArchive(archive *formats.ProblemArchiveReader) (problems []*model.Problem, err error) { defer SuppressPanic(&err) files := archive.Glob("*.xml") PanicIf(len(files) == 0, "Task file not found") PanicIf(len(files) > 1, "Several xml files found in the archive") reader, err := archive.Open(files[0]) PanicIf(err) defer reader.Close() container := new(Container) utils.NewXmlDecoder(reader).Decode(container) problem := container.Problem PanicIf(problem == nil, "Problem node not found") p := &model.Problem{ Title: problem.Title, Author: problem.Author, TimeLimit: float32(problem.TimeLimit), MemoryLimit: float32(problem.MemoryLimit), Statement: parseSGML(problem.Statement), Constraints: parseSGML(problem.Constraints), InputFormat: parseSGML(problem.InputFormat), OutputFormat: parseSGML(problem.OutputFormat), Generators: make(map[string]*model.Generator), Solutions: make(map[string]*model.Solution), Images: make(model.ImagesDict), } getSample := func(res *SampleResource) string { if res.Source != "" { data, err := archive.ReadFile(res.Source) PanicIf(err) return string(data) } return res.Text } p.Samples = make([]model.Sample, len(problem.Samples)) for i, sample := range problem.Samples { p.Samples[i].Input = getSample(&sample.SampleIn) p.Samples[i].Output = getSample(&sample.SampleOut) } for _, picture := range problem.Pictures { data, err := archive.ReadFile(picture.Source) PanicIf(err) p.Images[picture.Name] = data } for _, generator := range problem.Generators { addGenerator(archive, p, &generator) } for _, genRange := range problem.GeneratorRanges { for j := genRange.From; j <= genRange.To; j++ { generator := genRange.Generator generator.Name = applyTestRank(generator.Name, j) generator.Source = applyTestRank(generator.Source, j) addGenerator(archive, p, &generator) } } for _, solution := range problem.Solutions { lang := getLanguage(solution.LanguageCode, solution.Source) PanicIf(lang == nil, "Unknown solution language") data, err := archive.ReadFile(solution.Source) PanicIf(err) p.Solutions[solution.Name] = &model.Solution{ Name: solution.Name, Language: lang.Name, SourceCode: string(data), } } convertTest := func(t *model.Test, test *Test) { t.Points = test.Points if in := test.InputFile; in != nil { if in.Source != "" { data, err := archive.ReadFile(in.Source) PanicIf(err) t.Input = model.ConstTestData(data) } else if in.Generator != "" || in.Parameters != "" { if t.Input == nil { t.Input = &model.GeneratedInput{} } if in.Generator != "" { t.Input.(*model.GeneratedInput).Generator = in.Generator } if in.Parameters != "" { t.Input.(*model.GeneratedInput).Parameters = in.Parameters } } } if out := test.OutputFile; out != nil { if out.Source != "" { data, err := archive.ReadFile(out.Source) PanicIf(err) t.Output = model.ConstSolutionData(data) } else if out.Solution != "" { t.Output = &model.SolutionOutput{Solution: out.Solution} } } } addTestGroup := func(test *Test) { for rank := range stringRange(test.Rank) { if rank < 1 { continue } for len(p.Tests) < rank { p.Tests = append(p.Tests, model.Test{}) } processedTest := *test if in := processedTest.InputFile; in != nil { processedTest.InputFile = &InputFile{ Generator: applyTestRank(in.Generator, rank), Source: applyTestRank(in.Source, rank), Parameters: applyTestRank(in.Parameters, rank), GenerateAll: in.GenerateAll, } } if out := processedTest.OutputFile; out != nil { processedTest.OutputFile = &OutputFile{ Solution: applyTestRank(out.Solution, rank), Source: applyTestRank(out.Source, rank), } } convertTest(&p.Tests[rank-1], &processedTest) } } for _, testRange := range problem.TestRanges { test := Test{ Rank: fmt.Sprintf("%d-%d", testRange.From, testRange.To), TestDataMixin: testRange.TestDataMixin, } addTestGroup(&test) } for _, test := range problem.Tests { addTestGroup(&test) } for i, test := range p.Tests { if test.Input == nil || test.Output == nil { Panic("Test %d: incomplete input or output section", i+1) } } return []*model.Problem{p}, nil }