alx-tools / Betty

Holberton-style C code checker written in Perl
GNU General Public License v3.0
1.26k stars 1.77k forks source link

False "Multiple instructions" error lead to questioning Betty's ability to see escaped double quotes #31

Open allelomorph opened 3 years ago

allelomorph commented 3 years ago

Hi all-

I found an edge case in the Betty styling that is a bit specific but might point to a general improvement for future development. When working on a project emulating sh/dash, I needed produce error messages such as:

$ ls ;; ls
sh: 1: Syntax error: ";;" unexpected

And I noticed when I had strings in my code including escaped double quotes and semicolons "\";;\"" Betty would interpret that as multiple instructions on the same line:

shell_loop.c:184: WARNING: Multiple instructions on a single line is forbidden

However, it was smart enough to disregard the semicolons when in a string without escaped quotes ";;". So it seems like in the above example it fails to see two of the quotes as escaped, and thinks instead that there are two strings with semicolons between them.

The general improvement I hinted at is that if escaped quotes are indeed not seen by Betty overall, it could be the source of other false positives for style violations inside strings.

I found the relevant section of betty-style.pl for my particular issue, seen below. I have not yet scanned the codebase to see if escaped quote blindness is an issue elsewhere.

vagrant@vagrant-ubuntu-trusty-64:~/Betty$ grep -nB 10 "Multiple instructions" betty-style.pl
3119-# check for multiple instructions on a single line
3120-           if ($rawline =~ /;/) {
3121-                   my $pure = $rawline;
3122-                   $pure =~ s/\/\*+.*//;
3123-                   $pure =~ s/.*\*+\///;
3124-                   $pure =~ s/['][^']*[']//g;
3125-                   $pure =~ s/["][^"]*["]//g;
3126-                   my $count = () = $pure =~ /;/g;
3127-                   if ($count > 1 && $pure !~ /\bfor\b/) {
3128-                           WARN("MULTI_INS",
3129:                               "Multiple instructions on a single line is forbidden\n");

Thanks for looking.