home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 April / PCWorld_2001-04_cd.bin / Software / TemaCD / webclean / !!!python!!! / BeOpen-Python-2.0.exe / IFDEF.PY < prev    next >
Encoding:
Python Source  |  2000-09-28  |  3.2 KB  |  114 lines

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