From a4cf4136ee1265890dd1089f296b4df25d7bd479 Mon Sep 17 00:00:00 2001 From: Pragmatic Software Date: Sat, 1 Sep 2012 05:20:01 +0000 Subject: [PATCH] compiler_vm: Improve handling of \n in quoted literals --- PBot/VERSION.pm | 4 +- modules/compiler_vm/compiler_vm_client.pl | 70 ++++++++++++++++++++--- 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/PBot/VERSION.pm b/PBot/VERSION.pm index b6348d0c..6eacd2cf 100644 --- a/PBot/VERSION.pm +++ b/PBot/VERSION.pm @@ -13,8 +13,8 @@ use warnings; # These are set automatically by the build/commit script use constant { BUILD_NAME => "PBot", - BUILD_REVISION => 379, - BUILD_DATE => "2012-08-23", + BUILD_REVISION => 380, + BUILD_DATE => "2012-08-31", }; 1; diff --git a/modules/compiler_vm/compiler_vm_client.pl b/modules/compiler_vm/compiler_vm_client.pl index 680d3354..b77b285c 100755 --- a/modules/compiler_vm/compiler_vm_client.pl +++ b/modules/compiler_vm/compiler_vm_client.pl @@ -2,7 +2,7 @@ # use warnings; use strict; -use feature qw(switch); +use feature "switch"; use IPC::Open2; use Text::Balanced qw(extract_bracketed extract_delimited); @@ -37,7 +37,7 @@ sub pretty { print $fh $code; close $fh; - system("astyle", "-Ujpfnq", "prog.c"); + system("astyle", "-UHjfnq", "prog.c"); open $fh, "; @@ -591,8 +591,63 @@ if(not $found) { print "code before: [$code]\n" if $debug; $code =~ s/#include <([^>]+)>/#include <$1>\n/g; -$code =~ s/#([^ ]+) (.*?)\\n/#$1 $2\n/g; -$code =~ s/#([\w\d_]+)\\n/#$1\n/g; + +# replace \n outside of quotes with literal newline +my $new_code = ""; + +use constant { + NORMAL => 0, + DOUBLE_QUOTED => 1, + SINGLE_QUOTED => 2, +}; + +my $state = NORMAL; +my $escaped = 0; + +while($code =~ m/(.)/g) { + my $ch = $1; + + given ($ch) { + when ('\\') { + if($escaped == 0) { + $escaped = 1; + next; + } + } + + if($state == NORMAL) { + when ($_ eq '"' and not $escaped) { + $state = DOUBLE_QUOTED; + } + + when ($_ eq "'" and not $escaped) { + $state = SINGLE_QUOTED; + } + + when ($_ eq 'n' and $escaped == 1) { + $ch = "\n"; + $escaped = 0; + } + } + + if($state == DOUBLE_QUOTED) { + when ($_ eq '"' and not $escaped) { + $state = NORMAL; + } + } + + if($state == SINGLE_QUOTED) { + when ($_ eq "'" and not $escaped) { + $state = NORMAL; + } + } + } + + $new_code .= '\\' and $escaped = 0 if $escaped; + $new_code .= $ch; +} + +$code = $new_code; print "code after: [$code]\n" if $debug; @@ -703,8 +758,7 @@ print "after func extract, code: [$code]\n" if $debug; $code =~ s/\|n/\n/g; $code =~ s/^\s+//; $code =~ s/\s+$//; -$code =~ s/;\n;\n/;\n/g; -$code =~ s/^\s*;\s*$//gms; +$code =~ s/;\s+;\n/;\n/gs; my $single_quote = 0; my $double_quote = 0; @@ -828,9 +882,11 @@ if($output =~ m/^\s*$/) { $output =~ s/compilation terminated.//; $output =~ s/<'(.)' = char>/<'$1' = int>/g; $output =~ s/, //g; + $output =~ s/\s*warning: shadowed declaration is here \[-Wshadow\]//g; + $output =~ s/preprocessor macro>\s+/preprocessor macro>/g; # remove duplicate warnings/infos - $output =~ s/(warning: .*?\s)\1/$1/g; + $output =~ s/(\[*.*warning:.*?\s*)\1/$1/g; $output =~ s/(info: .*?\s)\1/$1/g; $output =~ s/^\[\s+(warning:|info:)/[$1/; # remove leading spaces in first warning/info