Fix string handling in wniapicheck

Francois Gouget fgouget at free.fr
Thu Oct 21 08:28:14 CDT 2004


On Thu, 21 Oct 2004, Francois Gouget wrote:

>
> winapi_check did not correctly handle escaped quotes inside strings which 
> caused this spurious warning:
>
> dlls/shlwapi/tests/path.c:96: C++ comments not allowed: 
> ///f%20o%5E%26%60%7B%7D%7C%5D%5B%22%3C%3E/%o/b%23a%20r/baz"},

This patch fixes the above problem but also fixes another parse error 
and thus supersedes the previous patch.

The 'other parse error' is:

dlls/ntdll/file.c: #include <CoreFoundation/CFNumber.h> /* for 
kCFBooleanTrue, kCFBooleanFalse */: is unparsable

This error occurred because our regular expression did not allow any '/' 
to appear before the C comment. Fixing this in a single regular 
expression would have been too complex so I rewrote that part of the 
code to work its way through the string one chunk at a time.


Changelog:

  * tools/winapi_check/winapi_parser.pm

    Fix escaped quote handling in strings.
    Properly handle C and C++ comment parsing.

-- 
Francois Gouget         fgouget at free.fr        http://fgouget.free.fr/
      Linux, WinNT, MS-DOS - also known as the Good, the Bad and the Ugly.
-------------- next part --------------
Index: tools/winapi_check/winapi_parser.pm
===================================================================
RCS file: /var/cvs/wine/tools/winapi_check/winapi_parser.pm,v
retrieving revision 1.39
diff -u -r1.39 winapi_parser.pm
--- tools/winapi_check/winapi_parser.pm	7 Oct 2004 18:53:56 -0000	1.39
+++ tools/winapi_check/winapi_parser.pm	21 Oct 2004 11:30:52 -0000
@@ -165,7 +165,7 @@
     print STDERR "Processing file '$file' ... " if $options->verbose;
     open(IN, "< $file") || die "<internal>: $file: $!\n";
     local $_ = "";
-    while($again || defined(my $line = <IN>)) {
+    readmore: while($again || defined(my $line = <IN>)) {
 	$_ = "" if !defined($_);
 	if(!$again) {
 	    chomp $line;
@@ -191,33 +191,45 @@
 	    last;
 	}
 
-	# remove C comments
-	if(s/^([^\"\/]*?(?:\"[^\"]*?\"[^\"]*?)*?)(?=\/\*)//s) {
-	    my $prefix = $1;
-	    if(s/^(\/\*.*?\*\/)//s) {
-		my @lines = split(/\n/, $1);
-		push @comment_lines, $.;
-		push @comments, $1;
-		&$c_comment_found_callback($. - $#lines, $., $1);
-		if($#lines <= 0) {
-		    $_ = "$prefix $_";
-		} else {
-		    $_ = $prefix . ("\n" x $#lines) . $_;
-		}
-		$again = 1;
-	    } else {
-		$_ = "$prefix$_";
-		$lookahead = 1;
-	    }
-	    next;
-	}
-
-	# remove C++ comments
-	while(s/^([^\"\/]*?(?:\"[^\"]*?\"[^\"]*?)*?)(\/\/.*?)$/$1/s) {
-	    &$cplusplus_comment_found_callback($., $2);
-	    $again = 1;
-	}
-	if($again) { next; }
+        my $prefix="";
+        while ($_ ne "")
+        {
+            if (s/^([^\"\/]+|\"(?:[^\\\"]*|\\.)*\")//)
+            {
+                $prefix.=$1;
+            }
+            elsif (/^\/\*/)
+            {
+                # remove C comments
+                if(s/^(\/\*.*?\*\/)//s) {
+                    my @lines = split(/\n/, $1);
+                    push @comment_lines, $.;
+                    push @comments, $1;
+                    &$c_comment_found_callback($. - $#lines, $., $1);
+                    if($#lines <= 0) {
+                        $_ = "$prefix $_";
+                    } else {
+                        $_ = $prefix . ("\n" x $#lines) . $_;
+                    }
+                    $again = 1;
+                } else {
+                    $_ = "$prefix$_";
+                    $lookahead = 1;
+                }
+                next readmore;
+            }
+            elsif (s/^(\/\/.*)$//)
+            {
+                # remove C++ comments
+                &$cplusplus_comment_found_callback($., $1);
+                $again = 1;
+            }
+            elsif (s/^(.)//)
+            {
+                $prefix.=$1;
+            }
+        }
+        $_=$prefix;
 
 	# remove preprocessor directives
 	if(s/^\s*\#/\#/s) {
@@ -652,7 +664,7 @@
 	    $output->write("$file: $.: can't parse: '$&'\n");
 	} elsif(/\'[^\']*\'/s) {
 	    $_ = $'; $again = 1;
-	} elsif(/\"[^\"]*\"/s) {
+	} elsif(/\"(?:[^\\\"]*|\\.)*\"/s) {
 	    $_ = $'; $again = 1;
 	} elsif(/;/s) {
 	    $_ = $'; $again = 1;


More information about the wine-patches mailing list