home *** CD-ROM | disk | FTP | other *** search
/ Freelog 33 / Freelog033.iso / Progr / Python-2.2.1.exe / IFDEF.PY < prev    next >
Encoding:
Python Source  |  2001-01-17  |  3.7 KB  |  114 lines

  1. #! /usr/bin/env python
  2.  
  3. # Selectively preprocess #ifdef / #ifndef statements.
  4. # Usage:
  5. # ifdef [-Dname] ... [-Uname] ... [file] ...
  6. #
  7. # This scans the file(s), looking for #ifdef and #ifndef preprocessor
  8. # commands that test for one of the names mentioned in the -D and -U
  9. # options.  On standard output it writes a copy of the input file(s)
  10. # minus those code sections that are suppressed by the selected
  11. # combination of defined/undefined symbols.  The #if(n)def/#else/#else
  12. # lines themselfs (if the #if(n)def tests for one of the mentioned
  13. # names) are removed as well.
  14.  
  15. # Features: Arbitrary nesting of recognized and unrecognized
  16. # preprocesor statements works correctly.  Unrecognized #if* commands
  17. # are left in place, so it will never remove too much, only too
  18. # little.  It does accept whitespace around the '#' character.
  19.  
  20. # Restrictions: There should be no comments or other symbols on the
  21. # #if(n)def lines.  The effect of #define/#undef commands in the input
  22. # file or in included files is not taken into account.  Tests using
  23. # #if and the defined() pseudo function are not recognized.  The #elif
  24. # command is not recognized.  Improperly nesting is not detected.
  25. # Lines that look like preprocessor commands but which are actually
  26. # part of comments or string literals will be mistaken for
  27. # preprocessor commands.
  28.  
  29. import sys
  30. import regex
  31. import getopt
  32. import string
  33.  
  34. defs = []
  35. undefs = []
  36.  
  37. def main():
  38.     opts, args = getopt.getopt(sys.argv[1:], 'D:U:')
  39.     for o, a in opts:
  40.         if o == '-D':
  41.             defs.append(a)
  42.         if o == '-U':
  43.             undefs.append(a)
  44.     if not args:
  45.         args = ['-']
  46.     for file in args:
  47.         if file == '-':
  48.             process(sys.stdin, sys.stdout)
  49.         else:
  50.             f = open(file, 'r')
  51.             process(f, sys.stdout)
  52.             f.close()
  53.  
  54. def process(fpi, fpo):
  55.     keywords = ('if', 'ifdef', 'ifndef', 'else', 'endif')
  56.     ok = 1
  57.     stack = []
  58.     while 1:
  59.         line = fpi.readline()
  60.         if not line: break
  61.         while line[-2:] == '\\\n':
  62.             nextline = fpi.readline()
  63.             if not nextline: break
  64.             line = line + nextline
  65.         tmp = string.strip(line)
  66.         if tmp[:1] != '#':
  67.             if ok: fpo.write(line)
  68.             continue
  69.         tmp = string.strip(tmp[1:])
  70.         words = string.split(tmp)
  71.         keyword = words[0]
  72.         if keyword not in keywords:
  73.             if ok: fpo.write(line)
  74.             continue
  75.         if keyword in ('ifdef', 'ifndef') and len(words) == 2:
  76.             if keyword == 'ifdef':
  77.                 ko = 1
  78.             else:
  79.                 ko = 0
  80.             word = words[1]
  81.             if word in defs:
  82.                 stack.append((ok, ko, word))
  83.                 if not ko: ok = 0
  84.             elif word in undefs:
  85.                 stack.append((ok, not ko, word))
  86.                 if ko: ok = 0
  87.             else:
  88.                 stack.append((ok, -1, word))
  89.                 if ok: fpo.write(line)
  90.         elif keyword == 'if':
  91.             stack.append((ok, -1, ''))
  92.             if ok: fpo.write(line)
  93.         elif keyword == 'else' and stack:
  94.             s_ok, s_ko, s_word = stack[-1]
  95.             if s_ko < 0:
  96.                 if ok: fpo.write(line)
  97.             else:
  98.                 s_ko = not s_ko
  99.                 ok = s_ok
  100.                 if not s_ko: ok = 0
  101.                 stack[-1] = s_ok, s_ko, s_word
  102.         elif keyword == 'endif' and stack:
  103.             s_ok, s_ko, s_word = stack[-1]
  104.             if s_ko < 0:
  105.                 if ok: fpo.write(line)
  106.             del stack[-1]
  107.             ok = s_ok
  108.         else:
  109.             sys.stderr.write('Unknown keyword %s\n' % keyword)
  110.     if stack:
  111.         sys.stderr.write('stack: %s\n' % stack)
  112.  
  113. main()
  114.