Thread: How to eliminate irrelevant conditionals?

  1. #1
    Registered User
    Join Date
    Sep 2004
    Posts
    57

    How to eliminate irrelevant conditionals?

    Hello,

    I am trying to read source code for an editor (Vim, available at sourceforge.net) but I find the plethora of precompiler conditionals very confusing (see code below). Virtually all "portable" source code has this problem. Is there a program that will eliminate the irrelevant (to my configuration) conditional code, yet keep the important stuff (like comments).

    Thank you.

    p.s. I use the MingW gcc compiler.

    Code:
    #if defined(MSDOS) || defined(WIN32) || defined(_WIN64)
    # include <io.h>		/* for close() and dup() */
    #endif
    
    #define EXTERN
    #include "vim.h"
    
    #ifdef SPAWNO
    # include <spawno.h>		/* special MSDOS swapping library */
    #endif
    
    #ifdef HAVE_FCNTL_H
    # include <fcntl.h>
    #endif
    
    #ifdef __CYGWIN__
    # ifndef WIN32
    #  include <sys/cygwin.h>	/* for cygwin_conv_to_posix_path() */
    # endif
    # include <limits.h>
    #endif
    
    #if defined(UNIX) || defined(VMS)
    static int file_owned __ARGS((char *fname));
    #endif
    static void mainerr __ARGS((int, char_u *));
    static void main_msg __ARGS((char *s));
    static void usage __ARGS((void));
    static int get_number_arg __ARGS((char_u *p, int *idx, int def));
    static void main_start_gui __ARGS((void));
    #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
    static void check_swap_exists_action __ARGS((void));
    #endif
    #ifdef FEAT_CLIENTSERVER
    static void cmdsrv_main __ARGS((int *argc, char **argv, char_u *serverName_arg, char_u **serverStr));
    static char_u *serverMakeName __ARGS((char_u *arg, char *cmd));
    #endif

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Is there a program that will eliminate the irrelevant (to my configuration) conditional code, yet keep the important stuff (like comments).
    So you want to remove all #includes and #defines etc but keep the comments?

    You can write your own program to do this. (Or you can do it by hand.)
    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    int main(void) {
        char s[BUFSIZ], *p;
    
        while(fgets(s, sizeof(s), stdin)) {
            p = s;
            while(isspace(*p)) p ++;
            if(*p != '#') {
                printf("%s", s);
            }
        }
    }
    And to use it:
    Code:
    C:\DWK\C>copy con simple.c
    #include <stdio.h>
    
    int main(void) {
        return 0;  /* comment */
    }
    ^Z
        1 file(s) copied
    C:\DWK\C>remove_hash < simple.c > simple_nohash.txt
    
    C:\DWK\C>type simple_nohash.txt
    
    int main(void) {
        return 0;  /* comment */
    }
    
    C:\DWK\C>
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    You can use the -E option in gcc to run the preprocessor on the file. Note this will cause some problems because it will bring all those included files into your file.

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    And it will remove comments.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    How about this perl wonder?

    The test input file
    Code:
    #include <stdio.h>
    #include <string.h>
    
    #if defined(FOO)
    #define VAR 1
    #elif defined(BAR)
    #define VAR 2
    #else
    #define VAR 4
    #endif
    
    int main()
    {
      printf("%d\n", VAR);  /* what option did we choose ? */
      return 0;
    }
    Which we would compile with
    gcc -DFOO foo.c

    Using this perl program to process it, with a little help from gcc
    Code:
    #!/usr/bin/perl -w
    use strict;
    
    # Invoke with the command line you would normally use
    # to compile the program.
    # Eg. gcc -DFOO foo.c
    # Presently assumes only ONE filename, and it's the last argument
    
    # -P - don't include lines
    # -E - preprocess only
    # -C - don't delete comments
    
    my $filename = $ARGV[$#ARGV];       # the input file
    my $tempfile = "$$" . "_$filename"; # a temporary file
    #print "$filename $tempfile\n";
    $ARGV[$#ARGV] = "";
    
    my $cmdline = join(' ',@ARGV);      # the rest of the compiler command line
    $cmdline .= " -P -E -C ";           # appended with the CPP magic
    #print "$cmdline\n";
    
    # copy the source code to a temp file, protecting all
    # non-conditional hash directives with comments
    open IFH,"$filename" or die "oops\n";
    open OFH,">$tempfile" or die "oops\n";
    while ( <IFH> ) {
      chomp;
      if ( /^\s*#/ ) {    # some kind of pre-process directive
        if ( ! /^\s*#\s*(if|elif|else|endif)/i ) {
          # not a conditional, hide in a comment for now
          $_ = "/*!!" . $_ . "!!*/";
        }
      }
      print OFH "$_\n";
    }
    close IFH;
    close OFH;
    
    # run the command, and filter the output
    open IFH,"$cmdline $tempfile|" or die "oops\n";
    while ( <IFH> ) {
      chomp;
      s/\/\*!!//g;    # strip out the comments used
      s/!!\*\///g;    # as guards in the previous step.
      print "$_\n";
    }
    close IFH;
    We can run this command, and get this output
    Code:
    $ ./uncond.pl gcc -DFOO foo.c
    
    
    #include <stdio.h>
    #include <string.h>
    
    
    #define VAR 1
    
    
    
    
    
    
    int main()
    {
      printf("%d\n", VAR); /* what option did we choose ? */
      return 0;
    }
    Deleting the extra blank lines left by the pre-processor as it deletes stuff is left as an exercise for the reader

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    My code already does that.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Your's rips out all preprocessor commands
    It does not for example
    - preserve #includes
    - keep the #if conditional expressions which happen to be true.

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Oops, you're right. I didn't realize the OP wanted to keep those in.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    Registered User
    Join Date
    Sep 2004
    Posts
    57
    Quote Originally Posted by Salem
    How about this perl wonder?
    Salem, thank you. That is sort of what I am looking for. It seems this must be an age old problem, and I'm hoping there is a good program laying around somewhere. I am trying to concentrate on C, so I don't want to get diverted and bogged down on Perl. Also, I would like the program itself to figure out what is/isn't defined and put out the correct code.

    BTW, I also appreciate greatly your responses to other's questions; I always look for your posts. Quzah too, he is really good.

    Thanks.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > and I'm hoping there is a good program laying around somewhere.
    Probably so - maybe even written in perl

    > I am trying to concentrate on C, so I don't want to get diverted and bogged down on Perl
    So just use it and forget about what it's written in.
    It would not be too hard to write it in C or bash for that matter.

    > Also, I would like the program itself to figure out what is/isn't defined and put out the correct code.
    Which program would that be?
    Some of the smarter IDE's out there can be told which conditionals are true/false and filter the code accordingly.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. conditionals
    By s_siouris in forum C Programming
    Replies: 3
    Last Post: 03-11-2008, 07:29 AM
  2. Type definitions within conditionals?
    By mushu in forum C++ Programming
    Replies: 4
    Last Post: 06-11-2006, 04:16 PM
  3. circle and conditionals
    By a1pro in forum C++ Programming
    Replies: 7
    Last Post: 04-27-2005, 02:05 AM
  4. How to eliminate extra whitespaces?
    By dat in forum C Programming
    Replies: 1
    Last Post: 10-24-2002, 06:42 PM
  5. Irrelevant question?
    By f0ul in forum Linux Programming
    Replies: 25
    Last Post: 05-25-2002, 12:16 AM