This is as discussed on wine-devel. I think this will make 'ok' much more consistent with all our other APIs. I refined the script because it was not good enough. It had problems with format strings that contained a comma, for instance "failed, error=%ld", and with tests that call an API with a string as parameter, for instance ok(FooA(0,"toto",NULL)==2,"blah blah"). The updated script contains a recursive descent micro parser that handles both of the above without any problem. The hardest part was actually convincing myself the parser approach was the way to go. So here is how to make the switch: * apply the patch This fixes the winetest_ok implementation, and fixes three tests that define macros around 'ok' and thus cannot be handled by the script. * run the script This fixes all other calls to ok, generating an 8500 lines diff. I checked the diff visually and it looks nice. Also, this time I made sure I could recompile the tests and also run them once modified and both worked fine. So there you go. Changelog: * include/wine/test.h, dlls/kernel/tests/locale.c, dlls/oleaut32/tests/vartest.c, dlls/user/tests/sysparams.c, many other files Change ok(0,"foo") to not print a '\n' --- cut here --- #!/usr/bin/perl -w use strict; my $verbose; my @file; my $l; my @chars; my $len; my $c; sub skip_bracket(); sub skip_parent(); sub skip_string(); sub setup_line($) { return 0 if ($l >= @file); $c=$_[0]; $len=length($file[$l]); @chars=split //,$file[$l]; print "$l,$c: $file[$l]" if ($verbose); return 1; } sub skip_bracket() { while (1) { while ($c<$len) { print "skip_bracket: $c -> '$chars[$c]'\n" if ($verbose); if ($chars[$c] eq "]") { print "skip_bracket returns 1\n" if ($verbose); return 1; } elsif ($chars[$c] eq "\"") { $c++; skip_string(); } elsif ($chars[$c] eq "(") { $c++; skip_parent(); } elsif ($chars[$c] eq "[") { $c++; skip_bracket(); } $c++; } $l++; return 0 if (!setup_line(0)); } return 0; } sub skip_parent() { while (1) { while ($c<$len) { print "skip_parent: $c -> '$chars[$c]'\n" if ($verbose); if ($chars[$c] eq ")") { print "skip_parent returns 1\n" if ($verbose); return 1; } elsif ($chars[$c] eq "\"") { $c++; skip_string(); } elsif ($chars[$c] eq "(") { $c++; skip_parent(); } elsif ($chars[$c] eq "[") { $c++; skip_bracket(); } $c++; } $l++; return 0 if (!setup_line(0)); } return 0; } sub skip_string() { my $backslash; while (1) { while ($c<$len) { print "skip_string: $c -> '$chars[$c]'\n" if ($verbose); if ($chars[$c] eq "\"") { if (!$backslash) { print "skip_string returns 1\n" if ($verbose); return 1; } $backslash=undef; } elsif ($chars[$c] eq "\\") { $backslash=($backslash?undef:1); } else { $backslash=undef; } $c++; } $l++; return 0 if (!setup_line(0)); } return 0; } sub skip_arg1() { while (1) { while ($c<$len) { print "skip_arg1: $c -> '$chars[$c]'\n" if ($verbose); if ($chars[$c] eq ",") { print "skip_arg1 returns 1\n" if ($verbose); return 1; } elsif ($chars[$c] eq "\"") { $c++; skip_string(); } elsif ($chars[$c] eq "(") { $c++; skip_parent(); } elsif ($chars[$c] eq "[") { $c++; skip_bracket(); } $c++; } $l++; return 0 if (!setup_line(0)); } return 0; } sub get_quote() { while (1) { while ($c<$len) { print "get_quote: $c -> '$chars[$c]'\n" if ($verbose); if ($chars[$c] eq "\"") { print "get_quote returns 1\n" if ($verbose); return 1; } elsif ($chars[$c] !~ /(\s|\n)/) { return 0; } $c++; } $l++; return 0 if (!setup_line(0)); } return 0; } sub fix_ok($) { # Setup setup_line($_[0]); # Locate the format string return undef if (!skip_arg1()); $c++; return undef if (!get_quote()); $c++; return undef if (!skip_string()); # Check and modify if ($c>=2 and ($chars[$c-2] ne "\\" or $chars[$c-1] ne "n")) { return substr($file[$l],0,$c) . "\\n" . substr($file[$l],$c); } return undef; } sub fix_file { my $c_file = $_[0]; open(FILE_HANDLE, "<$c_file") or die("Error opening file $c_file\n"); @file = <FILE_HANDLE>; close(FILE_HANDLE); #add a new line to the end of any ok calls we find my $modified; $l=0; while ($l<@file) { if ($file[$l] =~ /^(.*\bok\s*\()/) { my $res=fix_ok(length($1)); if (defined $res and $res ne $file[$l]) { print "\n$file[$l]$res" if ($verbose); $file[$l]=$res; $modified=1; } } $l++; } if ($modified) { open(FILE_HANDLE, ">$c_file"); print FILE_HANDLE @file; close(FILE_HANDLE); } } sub do_current_dir { my $i = 0; #get the current directory's listing opendir(DIR_HANDLE, ".") or die("Error opening .\n"); my @dir_listing = grep { !/^\.\.?/ } readdir(DIR_HANDLE); closedir(DIR_HANDLE); #for each file in the directory while($dir_listing[$i]) { #if a directory is found then do that one too if(-d $dir_listing[$i]) { chdir $dir_listing[$i]; do_current_dir(); chdir ".."; } #if it's a c file then fix the calls to ok if ($dir_listing[$i] =~ /\.c$/) { fix_file($dir_listing[$i]); } $i++; } } do_current_dir(); --- cut here --- Index: include/wine/test.h =================================================================== RCS file: /home/wine/wine/include/wine/test.h,v retrieving revision 1.10 diff -u -r1.10 test.h --- include/wine/test.h 2 Jan 2003 17:52:05 -0000 1.10 +++ include/wine/test.h 6 Jan 2003 05:45:18 -0000 @@ -171,7 +171,6 @@ vfprintf(stdout, msg, valist); va_end(valist); } - fputc( '\n', stdout ); InterlockedIncrement(&todo_failures); return 0; } @@ -190,7 +189,6 @@ vfprintf(stdout, msg, valist); va_end(valist); } - fputc( '\n', stdout ); InterlockedIncrement(&failures); return 0; } Index: dlls/kernel/tests/locale.c =================================================================== RCS file: /home/wine/wine/dlls/kernel/tests/locale.c,v retrieving revision 1.11 diff -u -r1.11 locale.c --- dlls/kernel/tests/locale.c 2 Jan 2003 17:47:22 -0000 1.11 +++ dlls/kernel/tests/locale.c 6 Jan 2003 05:45:08 -0000 @@ -25,7 +25,7 @@ #include "winnls.h" #define eq(received, expected, label, type) \ - ok((received) == (expected), "%s: got " type " instead of " type, (label),(received),(expected)) + ok((received) == (expected), "%s: got " type " instead of " type "\n", (label),(received),(expected)) #define BUFFER_SIZE 128 /* Buffer used by callback function */ Index: dlls/oleaut32/tests/vartest.c =================================================================== RCS file: /home/wine/wine/dlls/oleaut32/tests/vartest.c,v retrieving revision 1.6 diff -u -r1.6 vartest.c --- dlls/oleaut32/tests/vartest.c 2 Jan 2003 17:49:51 -0000 1.6 +++ dlls/oleaut32/tests/vartest.c 6 Jan 2003 05:45:13 -0000 @@ -1706,8 +1706,8 @@ */ trace( "\n\n======== Testing VarUI1FromXXX ========\n"); -#define XOK "should return S_OK" -#define XOV "should return DISP_E_OVERFLOW" +#define XOK "should return S_OK\n" +#define XOV "should return DISP_E_OVERFLOW\n" /* ok(S_OK == VarUI1FromI2( 0, NULL ), XOK); */ trace( "VarUI1FromI2: passing in NULL as return val makes it crash, need to write proper test.\n" ); Index: dlls/user/tests/sysparams.c =================================================================== RCS file: /home/wine/wine/dlls/user/tests/sysparams.c,v retrieving revision 1.9 diff -u -r1.9 sysparams.c --- dlls/user/tests/sysparams.c 5 Jan 2003 01:02:57 -0000 1.9 +++ dlls/user/tests/sysparams.c 6 Jan 2003 05:45:16 -0000 @@ -38,7 +38,7 @@ #endif #define eq(received, expected, label, type) \ - ok((received) == (expected), "%s: got " type " instead of " type, (label),(received),(expected)) + ok((received) == (expected), "%s: got " type " instead of " type "\n", (label),(received),(expected)) /* FIXME: should fix the tests to not require this */ -- Francois Gouget fgouget@free.fr http://fgouget.free.fr/ Any sufficiently advanced bug is indistinguishable from a feature. -- from some indian guy