How can I look for simple if statements in C source code?

I would like to search for simple statements ifin a collection of C source files.

These are expressions of the form:

if (condition)
    statement;

Any number of spaces or other sequences (for example, "} else") may appear on the same line before if. Comments may appear between "if (condition)" and "statement;".

I want to exclude compound form expressions:

if (condition)
{
    statement;
    statement;
}

I tried each of the following in awk:

awk  '/if \(.*\)[^{]+;/ {print NR $0}' file.c    # (A) No results
awk  '/if \(.*\)[^{]+/ {print NR $0}' file.c    # (B)
awk  '/if \(.*\)/ {print NR $0}' file.c          # (C)

(B) and (C) give different results. Both include the elements that I am looking for and the elements that I want to exclude. Part of the problem, obviously, is how to deal with patterns that span multiple lines.

( , ​​..) .

?

+3
4

, ( , sed 'n' , ), , , script . :

perl parse_if.pl file.c

parse_if.pl :

#!/usr/bin/perl -w

my $line_number = 0;
my $in_if = 0;
my $if_line = "";
# Scan through each line
while(<>)
{
    # Count the line number
    $line_number += 1;
    # If we're in an if block
    if ($in_if)
    {
        # Check for open braces (and ignore the rest of the if block
        # if there is one).
        if (/{/)
        {
            $in_if = 0;
        }
        # Check for semi-colons and report if present
        elsif (/;/)
        {
            print $if_line_number . ": " . $if_line;
            $in_if = 0;
        }
    }
    # If we're not in an if block, look for one and catch the end of the line
    elsif (/^[^#]*\b(?:if|else|while) \(.*\)(.*)/)
    {
        # Store the line contents
        $if_line = $_;
        $if_line_number = $line_number;
        # If the end of the line has a semicolon, report it
        if ($1 =~ ';')
        {
            print $if_line_number . ": " . $if_line;
        }
        # If the end of the line contains the opening brace, ignore this if
        elsif ($1 =~ '{')
        {
        }
        # Otherwise, read the following lines as they come in
        else
        {
            $in_if = 1;
        }
    }
}

, - ( awk), ; , I perl .

+1

Al, ( else ( if):

#!/usr/bin/perl -w

my $line_number = 0;
my $in_if = 0;
my $if_line = "";
#ifdef NEW
my $block = "";
#endif /* NEW */
# Scan through each line
while(<>)
{
    # Count the line number
    $line_number += 1;
    # If we're in an if block
    if ($in_if)
    {
        $block = $block . $line_number . "+ " . $_;
        # Check for open braces (and ignore the rest of the if block
        # if there is one).
        if (/{/)
        {
            $in_if = 0;
            $block =  "";
        }
        # Check for semi-colons and report if present
        elsif (/;/)
        {
            print $if_line;
            print $block;
            $block = "";
            $in_if = 0;
        }
    }
    # If we're not in an if block, look for one and catch the end of the line
    elsif (/(if \(.*\)|[^#]else)(.*)/)
    {
        # Store the line contents
        $if_line = $line_number . ": " .  $_;
        # If the end of the line has a semicolon, report it
        if ($2 =~ ';')
        {
            print $if_line;
        }
        # If the end of the line contains the opening brace, ignore this if
        elsif ($2 =~ '{')
        {
        }
        # Otherwise, read the following lines as they come in
        else
        {
            $in_if = 1;
        }
    }
}
+2

awk , "\n" - . , if. , awk. perl ,

open(INFO,"<file.c");
$flag=0;
while($line = <INFO>)
{
 if($line =~ m/if\s*\(/ )
  {
    print $line;
    $flag = 1;
  }
 else
 {
  print $line && $flag ;
  $flag = 0 if($flag);
 }
}
0

Awk, :

awk '
BEGIN { flag=0 }
{
    if($0 ~ /if/) {
        print $0;
        flag=NR+1
    }
    if(flag==NR)
        print $0 
}' try.c
0

Source: https://habr.com/ru/post/1711801/


All Articles