@@ -66,15 +66,15 @@ fn find_source_file() -> Result<String, String> {
6666 Err ( "Error: No source file found" . to_string ( ) )
6767}
6868
69- fn compile_file ( filepath : & str , debug : bool ) -> Result < ( ) , String > {
69+ fn compile_file ( filepath : & str , contest_compilation : bool ) -> Result < ( ) , String > {
7070 let path = Path :: new ( filepath) ;
7171 let ext = path. extension ( ) . and_then ( |s| s. to_str ( ) ) . unwrap_or ( "" ) ;
7272 let exe_name = path. file_stem ( ) . and_then ( |s| s. to_str ( ) ) . unwrap_or ( "a.out" ) ;
7373
7474 match ext {
7575 "ml" => {
7676 let mut args = vec ! [ "-o" , exe_name, filepath] ;
77- if debug {
77+ if !contest_compilation {
7878 args. insert ( 0 , "-g" ) ;
7979 }
8080 let status = Command :: new ( "ocamlopt" )
@@ -90,12 +90,17 @@ fn compile_file(filepath: &str, debug: bool) -> Result<(), String> {
9090 }
9191 "cpp" => {
9292 let mut args = vec ! [ "-x" , "c++" , "-std=gnu++20" ] ;
93- if debug {
94- args. push ( "-g" ) ;
95- args. push ( "-fsanitize=address,undefined" ) ;
96- } else {
93+ if contest_compilation {
9794 args. push ( "-O2" ) ;
9895 args. push ( "-static" ) ;
96+ } else {
97+ args. append ( & mut vec ! [ "-Wall" , "-Wextra" , "-Wshadow" , "-Wfloat-equal" , "-Wconversion" , "-Wlogical-op" , "-Wshift-overflow=2" , "-Wduplicated-cond" , "-Wfatal-errors" ] ) ;
98+ args. append ( & mut vec ! [ "-DISDEBUG" , "-D_GLIBCXX_DEBUG" ] ) ;
99+ args. append ( & mut vec ! [ "-fsanitize=undefined,address" , "-fstack-protector" , "-fno-sanitize-recover" ] ) ;
100+ args. push ( "-g3" ) ;
101+ args. push ( "-fsanitize=address,undefined" ) ;
102+ args. push ( "-DISDEBUG" ) ;
103+
99104 }
100105 args. push ( filepath) ;
101106 args. push ( "-o" ) ;
@@ -123,7 +128,7 @@ fn compile_file(filepath: &str, debug: bool) -> Result<(), String> {
123128 "-d" ,
124129 "." ,
125130 ] ;
126- if debug {
131+ if !contest_compilation {
127132 args. push ( "-g" ) ;
128133 }
129134 args. push ( filepath) ;
@@ -144,23 +149,23 @@ fn compile_file(filepath: &str, debug: bool) -> Result<(), String> {
144149 }
145150}
146151
147- fn find_test_files ( ) -> Vec < ( String , String ) > {
152+ fn find_test_files ( ) -> Vec < ( String , Option < String > ) > {
148153 let mut tests = Vec :: new ( ) ;
149154
150155 if let Ok ( entries) = fs:: read_dir ( "." ) {
151156 let mut inputs: Vec < String > = entries
152157 . filter_map ( |entry| entry. ok ( ) )
153158 . map ( |entry| entry. file_name ( ) . to_string_lossy ( ) . to_string ( ) )
154- . filter ( |name| name. starts_with ( "~input " ) && name. ends_with ( ".txt" ) )
159+ . filter ( |name| name. starts_with ( "in " ) && name[ 2 .. ] . chars ( ) . next ( ) . map_or ( false , |c| c . is_ascii_digit ( ) ) )
155160 . collect ( ) ;
156161
157162 inputs. sort ( ) ;
158163
159164 for input in inputs {
160- let output = input. replace ( "~input" , "~output" ) ;
161- if Path :: new ( & output) . exists ( ) {
162- tests . push ( ( input , output) ) ;
163- }
165+ let suffix = & input[ 2 .. ] ;
166+ let output = format ! ( "out{}" , suffix ) ;
167+ let output_opt = if Path :: new ( & output ) . exists ( ) { Some ( output) } else { None } ;
168+ tests . push ( ( input , output_opt ) ) ;
164169 }
165170 }
166171
@@ -176,7 +181,7 @@ fn run_tests(filepath: &str) -> Result<(), String> {
176181 let tests = find_test_files ( ) ;
177182
178183 if tests. is_empty ( ) {
179- println ! ( "No test files found (looking for ~input*.txt and ~output*.txt )" ) ;
184+ println ! ( "No test files found (looking for in1, in2, ... files )" ) ;
180185 return Ok ( ( ) ) ;
181186 }
182187
@@ -186,12 +191,14 @@ fn run_tests(filepath: &str) -> Result<(), String> {
186191 if tests. len( ) == 1 { "test" } else { "tests" }
187192 ) ;
188193 for ( test_num, ( input_file, output_file) ) in tests. iter ( ) . enumerate ( ) {
189- println ! ( "\x1B [1mTEST {}\x1B [0m" , test_num + 1 ) ;
194+ println ! ( "\x1B [1;4mTEST {}\x1B [0m" , test_num + 1 ) ;
190195
191196 let input_data =
192197 fs:: read ( & input_file) . map_err ( |e| format ! ( "Failed to read {}: {}" , input_file, e) ) ?;
193- let expected_output = fs:: read_to_string ( & output_file)
194- . map_err ( |e| format ! ( "Failed to read {}: {}" , output_file, e) ) ?;
198+ let expected_output: Option < String > = match output_file {
199+ Some ( f) => Some ( fs:: read_to_string ( f) . map_err ( |e| format ! ( "Failed to read {}: {}" , f, e) ) ?) ,
200+ None => None ,
201+ } ;
195202
196203 let output = match ext {
197204 "ml" | "cpp" => {
@@ -270,14 +277,17 @@ fn run_tests(filepath: &str) -> Result<(), String> {
270277 io:: stdout ( ) . flush ( ) . unwrap ( ) ;
271278
272279 let trimmed_output = output. trim_end ( ) ;
273- println ! ( "--- \x1b [3mExpected\x1b [0m" ) ;
274- println ! ( "{}" , expected_output. trim_end( ) ) ;
275280 println ! ( "--- \x1b [3mActual\x1b [0m" ) ;
276281 if trimmed_output. is_empty ( ) {
277282 println ! ( "\x1b [3mN/A\x1b [0m" ) ;
278283 } else {
279284 println ! ( "{}" , trimmed_output) ;
280285 }
286+ println ! ( "--- \x1b [3mExpected\x1b [0m" ) ;
287+ match & expected_output {
288+ Some ( expected) => println ! ( "{}" , expected. trim_end( ) ) ,
289+ None => println ! ( "\x1b [3mN/A\x1b [0m" ) ,
290+ }
281291 println ! ( "---" ) ;
282292
283293 if test_num != tests. len ( ) - 1 {
@@ -292,15 +302,15 @@ fn main() {
292302 let args: Vec < String > = env:: args ( ) . collect ( ) ;
293303 let mut test = false ;
294304 let mut execute = false ;
295- let mut debug = false ;
305+ let mut contest = false ;
296306 let mut filepath: Option < String > = None ;
297307 for arg in args. iter ( ) . skip ( 1 ) {
298308 match arg. as_str ( ) {
299309 "-h" => {
300310 println ! ( "Usage: cptest [OPTIONS] [FILE]" ) ;
301311 println ! ( ) ;
302312 println ! ( "OPTIONS:" ) ;
303- println ! ( " -d Compile with debug flags " ) ;
313+ println ! ( " -c Contest compilation " ) ;
304314 println ! ( " -t Run all tests" ) ;
305315 println ! ( " -x Execute the compiled program" ) ;
306316 println ! ( " -h Show this help message" ) ;
@@ -312,7 +322,7 @@ fn main() {
312322 }
313323 "-t" => test = true ,
314324 "-x" => execute = true ,
315- "-d " => debug = true ,
325+ "-c " => contest = true ,
316326 s if !s. starts_with ( '-' ) => {
317327 if filepath. is_none ( ) {
318328 filepath = Some ( s. to_string ( ) ) ;
@@ -348,7 +358,7 @@ fn main() {
348358 }
349359
350360 println ! ( "Compiling {}" , filepath) ;
351- if let Err ( e) = compile_file ( & filepath, debug ) {
361+ if let Err ( e) = compile_file ( & filepath, contest ) {
352362 eprintln ! ( "{}" , e) ;
353363 exit ( 1 ) ;
354364 }
0 commit comments