+show_per_prog_results_width :: Int -> (String, [BoxValue]) -> ShowS
+show_per_prog_results_width w (prog,results)
+ = str (rjustify 15 prog)
+ . str (space 5)
+ . foldr (.) id (map (str . rjustify w . showBox) results)
+
+-- -----------------------------------------------------------------------------
+-- CSV output
+
+csvTable :: [ResultTable] -> String -> Bool -> String
+csvTable results table_name norm
+ = let
+ table_spec = [ spec | spec@(SpecP _ n _ _ _ _) <- per_prog_result_tab,
+ n == table_name ]
+ in
+ case table_spec of
+ [] -> error ("can't find table named: " ++ table_name)
+ (spec:_) -> csvProgTable results spec norm "\n"
+
+csvProgTable :: [ResultTable] -> PerProgTableSpec -> Bool -> ShowS
+csvProgTable results (SpecP long_name _ _ get_result get_status result_ok) norm
+ = csv_show_results results get_result get_status result_ok norm
+
+csv_show_results
+ :: Result a
+ => [ResultTable]
+ -> (Results -> Maybe a)
+ -> (Results -> Status)
+ -> (a -> Bool)
+ -> Bool
+ -> ShowS
+
+csv_show_results [] _ _ _ _
+ = error "csv_show_results: Can't happen?"
+csv_show_results (r:rs) f stat result_ok norm
+ = interleave "\n" results_per_prog
+ where
+ -- results_per_prog :: [ (String,[BoxValue a]) ]
+ results_per_prog = map (result_line . calc) (Map.toList r)
+ calc = calc_result rs f stat (const True) do_norm
+
+ do_norm | norm = normalise_to_base
+ | otherwise = \base res -> toBox res
+
+ result_line (prog,boxes) = interleave "," (str prog : map (str.showBox) boxes)