link split, atos, printf, image # # s. testN.out # diff testN.out master global run_config global problems # table of problem objects procedure tester_main(args) run_config := config(args) every student := !run_config.get_students() do { bar("Student: "||student) every probnm := !run_config.get_problem_names() do { if /problems[probnm] then stop("Error: problem '", probnm, "' not found") problems[probnm].test(student, listing) new_page() } end_student() } end procedure path(p[]) return atos(p, "/") end procedure shell(p[]) cmd := atos(p, " ") \show_shell & write("Shell: ", cmd) return system(cmd) end procedure trace(a[]) local tsave tsave := &trace &trace := 1 _trace_(a) &trace := tsave end procedure _trace_(a) end procedure bar(a) local len, bar a := ((type(a) ~== "list") & [a]) len := 60 bar := repl("-",len) write() write(bar) every center_bar(!([""] ||| a ||| [""]), len) write(bar) write() end procedure center_bar(s, len) write("|",center(s,len-2),"|") end procedure list_file(fname) if f := open(fname) then { while write(read(f)) close(f) return } else { write("*** file not found ***") fail } end procedure show_diff(fname, maxlines) f := open(fname) | stop("show_diff: can't open", fname) every 1 to 2 do write(read(f)) blocks := [] while line := read(f) do { if line == "***************" then { put(blocks, \lines) lines := [line, read(f)] } else { put(lines, line) # # If we get more than 100 lines of diff output, we just don't # process the rest. # #if *lines > 100 then #break } } put(blocks, \lines) #write(Image(blocks)) excess_blocks := *blocks - 3 every show_diff_block(blocks[1 to 3], maxlines) if excess_blocks > 0 then write("[*** ", excess_blocks, " additional blocks of diff output not shown ***]") close(f) end procedure show_diff_block(block, maxlines) lines := linesA := [] while line := get(block) do { line ? { (="--- " & tab(many(&digits)) & ="" | (="," & tab(many(&digits))) & =" ----") & (lines := /linesB := [])| stop("**Multiple splits?!**", line) } put(lines, line) } # # If show_diff exceeded the line limit we may have a block that doesn't # have a second half. If so, linesB will be null. If that's the case, # just make it an empty list. /linesB := [] #write(Image([linesA,linesB])) #write("linesA: ", *linesA) #write("linesB: ", *linesB) every lines := (linesA | linesB) do { linecount := 0 while line := get(lines) do { #write("line: ", image(line)) # # Code below was used when printing listings, folding lines to # 80 characters, but letting those folds contribute to the count # for the maxlines limit. # # Now that we're email-based, we don't worry about that folding and # instead just write the line and check the line count. # limit := 500 msg := "[...%d additional characters not shown...]" if *line <= limit + *msg then write(line) else write(line[1+:limit], sprintf(msg, *line[limit:-1])) linecount +:= 1 if linecount > maxlines then break next # SKIP THE OLD CODE BELOW line ? { while outline := move(80) do { #write("outline: ", image(outline)) write(outline) linecount +:= 1 if linecount > maxlines then break break } if &pos ~= 0 then { write(tab(0)) linecount +:= 1 if linecount > maxlines then break } } } #write("*lines = ", *lines) if *lines = 0 then next if *lines = 1 & *lines[1] <= 80 then write(lines[1]) else { #write("[*** ", *lines, #" additional lines of diff output not shown ***]") write("[*** additional lines of diff output not shown ***]") } } return end procedure new_page() \listing & write("") return end procedure end_student() \listing & write("") return end