Click here to Skip to main content
15,893,722 members
Articles / Programming Languages / C++

Building a simple C++ script compiler from Scintilla and CINT

Rate me:
Please Sign up or sign in to vote.
4.74/5 (26 votes)
8 Jul 2006CPOL7 min read 154.4K   7.6K   85  
How to build a simple C++ script compiler from Scintilla and CINT.
IFDEF(1)                                                   IFDEF(1)


NAME
       ifdef - #ifdef/#else/#endif symbolic resolver


DESCRIPTION
        "ifdef" selectively resolves #ifdef,#ifndef,#if,#elif,
       #else and #endif in C/C++ source code. Macros that are 
       explicitly defined/undefined by -D/-U option are resolved
       and eliminated from the source code. Other #ifdefs remain
       unchanged. #if statements with multiple conditions and
       &&,|| operators will be resolved by a symbolic resolver.
       "ifdef" can be also used as a #ifdef nesting hierarchy
       analyzer.

SYNOPSIS
       ifdef <-dgmqrsuvV> <-f[deffile]> <-o[outfile]> 
             <-D[defined]<=[value]>> <-U[undefined]> <-o[outfile]> [source.c]

Option:
       [options] 
            -D [macro]<=[value]>:resolve '#ifdef [macro]' as true
            -U [macro]          :resolve '#ifdef [macro]' as false
            -f [deffile]        :define/undef macros by file
                                    #define [macro]<=[value]>
                                    #undef  [macro]
            -o [outfile]        :specify output file (default - stdout)
            -m                  :no output
          debug  . . . . . . . . . . . . . . . . . . . . . . . . .
            -q                  :quiet mode
            -g                  :preview all #ifdef (no output)
            -G                  :preview resolved #ifdef (no output)
            -d                  :display deleted lines
            -r                  :display resolved conditions
            -u                  :display unresolved conditions

EXAMPLE
            $ ifdef -D ONLINE -D MAX=1024 -U DEBUG -o newsource.c source.c
            $ ifdef -g source.c
            $ ifdef -G -d -DDEBUG1 source.c


EXAMPLE1 - #ifdef/#endif analyzer

        "ifdef" can be used as a #ifdef analyzer by using -g 
       option. Location and nesting hierarchy of all the #if,
       #ifdef,#ifndef,#elif,#endif statements will be displayed.
       For example, let's analyze #ifdef structure in 
       $CINTSYSDIR/G__ci.h. 

            $ cd $CINTSYSDIR
            $ ifdef -g G__ci.h

   21: #ifndef G__CI_H  unresolved
   54: | #ifndef G__CONSTNESSFLAG  unresolved
   58: | #endif  unresolved
   89: | #ifdef G__OLDIMPLEMENTATION1073  unresolved
   91: | #endif  unresolved
  114: | #ifndef G__OLDIMPLEMENTATION1231  unresolved
  120: | | #ifdef G__CPPIF_EXTERNC  unresolved
  121: | | | #ifndef G__CPPIF_PROJNAME  unresolved
  123: | | | #endif  unresolved
  124: | | | #ifdef G__CPPIF_STATIC  unresolved
  126: | | | #endif  unresolved
  127: | | #endif  unresolved
  129: | | #ifndef G__CPPIF_PROJNAME  unresolved
  130: | | | #ifndef G__CPPIF_STATIC  unresolved
  132: | | | #endif  unresolved
  133: | | #endif  unresolved
  135: | #endif  unresolved
  142: | #if (!defined(__MAKECINT__)) || defined(G__API) 0,4 unresolved
  145: | | #ifdef __cplusplus  unresolved
  146: | | | #ifndef G__ANSIHEADER  unresolved
             .
             .


EXAMPLE2 - #ifdef/#endif partial symbolic resolution

        The most powerful feature of "ifdef" is that it resolves
       selected macro in order to simplify C/C++ source code. For
       example, we have following source.

            /* source.c /////////////////////////////// */
            #ifdef A
            int f() { return A; }
            #else
            unsigned int f() { return 0; }
            #endif

            #ifdef B
            int g() { return B; }
            #else
            unsigned int g() { return 0; }
            #endif

            #if defined(A) && defined(B)
            int x;
            #endif

            #if !defined(A) || defined(B)
            int y;
            #endif
            /* end source.c /////////////////////////// */


       Suppose macro A is always defined, so we want to eliminate
       '#ifdef A' from the source. Use '-DA' option to specify that
       we want to eliminate '#ifdef A'.  Note that complex conditions,
       such as '!defined(A) || defined(B)' , are partially resolved.
       Also note that if A is referred as a value, it remains unchanged
       for readability.
      

            $ ifdef -DA source.c > tmp
            $ cat tmp

            /* source.c /////////////////////////////// */
            int f() { return A; }

            #ifdef B
            int g() { return B; }
            #else
            unsigned int g() { return 0; }
            #endif

            #if  defined(B)
            int x;
            #endif

            #if  defined(B)
            int y;
            #endif
            /* end source.c /////////////////////////// */


       Now, suppose macro A is always undefined, so we want to eliminate
       '#ifdef A' in the other way. Use '-UA' option in this case. 

            $ ifdef -UA source.c > tmp
            $ cat tmp

            /* source.c /////////////////////////////// */
            unsigned int f() { return 0; }
            
            #ifdef B
            int g() { return B; }
            #else
            unsigned int g() { return 0; }
            #endif
            
            
            int y;
            /* end source.c /////////////////////////// */


        You can define multiple -D, -U options. If you have many such
        definitions, you can specify them in a file. Prepare a file
        like below.

            // macros.def  - define/undef definition file
            #define A
            #undef B
            #define C
            #define D

        Then, give this file by -f option.

            $ ifdef -f macros.def source.c > tmp


EXAMPLE3 - #ifdef/#endif partial symbolic resolution preview

         You may want to make sure #ifdefs are resolved correctly.
        -G option will give you detailed information about which 
        macros and resolved.  If you add -d option, eliminated lines 
        are also displayed.

            $ ifdef -G -d -UA source.c 

            #undef  A
                2: #ifdef A  ALWAYS FALSE
            D   3: int f() { return A; }
                4: #else   ALWAYS TRUE
                6: #endif END ALWAYS
               14: #if defined(A) && defined(B) -> 0 ALWAYS FALSE
            D  15: int x;
               16: #endif END ALWAYS
               18: #if !defined(A) || defined(B) -> 1 ALWAYS TRUE
               20: #endif END ALWAYS


COMMENT
         Although included in CINT package, ifdef is an independent
        software productivity tool.


AUTHOR
       Masaharu Goto (cint@pcroot.cern.ch)
       Copyright (c) 1994~2001 Masaharu Goto

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions