Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

C code pre-processor

by dgsmith_50 (Initiate)
on Feb 03, 2012 at 17:00 UTC ( #951682=perlquestion: print w/replies, xml ) Need Help??
dgsmith_50 has asked for the wisdom of the Perl Monks concerning the following question:

I work on a large codebase of code written in C for embedded processors. There are many conditionally compiled statements in the code that makes it difficult to read. I would like to know if there exists a perl script that will execute like a C pre-processor to strip away code which is not relavant based on a set of macros. The output from the script would then be used just for reading the code. I want to use PERL because I want to be able to easily modify the script. For example, in the code snippet below, I would want to include the code unmodified if the macro BCS_GFSK_TRACKING_HW_FIX if defined. I would not want to replace BCS_LINKTYPE_ACL_MDR with an actual number because I want to maintain the readability of the code.
#ifdef BCS_GFSK_TRACKING_HW_FIX // The following is HWWA for BR freq tracking switch ( logicalConnInfo ) { case BCS_LINKTYPE_ACL_MDR: case BCS_LINKTYPE_ESCO_MDR: { REG32(dcOffEstCtrl5_adr) &= ~(((UINT32)1) << TRACK_GFSK_FR +EQ_MASK_OFFSET); break; } default: { REG32(dcOffEstCtrl5_adr) |= (((UINT32)1) << TRACK_GFSK_FRE +Q_MASK_OFFSET); break; } } #endif
I found a script at the location below, but it does not appear to handle complex statements such as:
#if (defined(BCM20702) || defined(BCM20733)) && !defined(FPGA_BD_2 +045)

Replies are listed 'Best First'.
Re: C code pre-processor
by educated_foo (Vicar) on Feb 03, 2012 at 17:04 UTC
    Why not just use the C preprocessor? If you have C code, you should probably have one lying around on your system.

    EDIT: I missed the part about not wanting to expand macros in code. Try something like this:

    $ perl -pe 'y/A-Za-z/N-ZA-Mn-za-m/ unless /^\s*#/' < INPUT | cpp - | \ perl -pe 'y/A-Za-z/N-ZA-Mn-za-m/ unless /^\s*#/ > OUTPUT'
    That should hide the macros in code from CPP unless you choose really weird names.
Re: C code pre-processor
by Khen1950fx (Canon) on Feb 03, 2012 at 18:39 UTC
    Try Text::CPP. It's light, fast, and easy to use.
    #!/usr/bin/perl use strict; use warnings; use Text::CPP; my $MyData = <DATA>; my $reader = new Text::CPP( Language => 'STDC99', Options => {}, Builtins => { foo => 'this', bar => 'that', }, ); $reader->read('/root/Desktop/file.c'); while (my $token = $reader->token) { print "Token: $token\n"; } $reader->data->{MyKey} = $MyData; __DATA__ #ifdef pathtest 38. This should appear. #else #define pathtest 37. This should appear. #include test.txt 39. This should appear. #undef pathtest #endif
      It's also XS, so he'll need a C preprocessor to install it in the first place.
        Hi, I was away for the last few days so I just saw your post. What is XS?
Re: C code pre-processor
by roboticus (Chancellor) on Feb 03, 2012 at 20:46 UTC


    The following definitely doesn't do everything you want, as it's a quick knockup. It'll need some tuning, but I think you can tweak it into something useful for you:

    $ cat #!/usr/bin/perl # # see perlmonks 951682 # use strict; use warnings; my %DEF; my @fl_print = (1); while (<DATA>) { if (/^\s*#\s*define\s+(\w+)/) { $DEF{$1}=1; } elsif (/^\s*#\s*undef\s+(\w+)/) { delete $DEF{$1}; } elsif (/^\s*#\s*ifdef\s+(\w+)/) { push @fl_print, (exists($DEF{$1}) and $fl_print[-1]); } elsif (/^\s*#\s*ifndef\s+(\w+)/){ push @fl_print, (!exists($DEF{$1}) and $fl_print[-1]); } elsif (/^\s*#\s*endif/){ pop @fl_print if @fl_print > 1; } print if ($fl_print[-1]); } __DATA__ /* Foo */ #ifndef BLARG2 BAR #define BLARG #define GRAK zippy #ifdef BLARG happy #ifndef GRAK lucky #endif puppy #endif #foo #endif bloink

    It doesn't hide exactly the lines I would want to hide, but it's close...


    When your only tool is a hammer, all problems look like your thumb.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://951682]
Approved by moritz
Front-paged by tye
[ambrus]: MLX: if it's a work email, then it's probably not Uncle Sam that matters, but what the account managing server at work thinks your name is. Those can differ. For example, we've had two co-workers with identical real name at one point,
[ambrus]: so one got a stupid suffix in the email account (people have email address based on their real name here usually).

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (14)
As of 2017-01-19 14:03 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (170 votes). Check out past polls.