Listing 3

#!/usr/local/bin/python
import os, sys, glob, re

index = 0
text  = ''

def InjectMci(text, selective):
   if selective and text.find('INJECT_MCI') == -1:
      return text
   index = 0
   text = InjectMciHeader(text)
   text = InjectMciObjects(text, selective)
   return text

def InjectMciHeader(text):
   if text.find('#include "Mci.h"') != -1:
      return text

   lines = text.split('\n')

   index = 0
   # find index of last line that contains #include (0 if no #include
   is found)
   for i in range(len(lines)-1, 0, -1):
      if lines[i].find('#include') != -1:
         index = i+1
         break

   text = '\n'.join(lines[:index])
   text += '\n#include "Mci.h"\n'
   text += '\n'.join(lines[index:])

   return text

def GetMciLine(line):
   mci_mask = '\tMci m(__FILE__, __LINE__, "%s");'
   line = line.replace('{', ' ').strip()
   return mci_mask % line

def InjectMciObject(base, index, lines, new_lines, selective):
   line = lines[index]
   if selective:
      if lines[index+base+1].find('INJECT_MCI') != -1:
         if base == 1:
            new_lines.append(lines[index+1])
         new_lines.append(GetMciLine(line))
         index += base+2; # skip the INJECT_MCI line
      else:
         index += 1
   else:
      if base == 1:
         new_lines.append(lines[index+1])
      new_lines.append(GetMciLine(line))

      index += base+1;
   return index

def InjectMciObjects(text, selective):
   method_re = r'[ \t]*.+[ \t]+.+::.+\(.*\)[ \t]*'
   open_par_re = r'[ \t]*{[ \t]*'
   p1 = re.compile('%s$' % method_re)
   p2 = re.compile('%s$' % open_par_re)
   p3 = re.compile('%s%s$' % (method_re, open_par_re))
   lines = text.split('\n')

   new_lines = []

   index = 0
   while index < len(lines)-2:
      line = lines[index]
      new_lines.append(line)
      if p1.match(line) and p2.match(lines[index+1]):
         index = InjectMciObject(1, index, lines, new_lines, selective)
      elif p3.match(line):
         index = InjectMciObject(0, index, lines, new_lines, selective)
      else:
         index += 1

   return '\n'.join(new_lines)

if __name__ == "__main__":
   selective = len(sys.argv) > 1 and sys.argv[1] == 'selective'
   cpp_fi les = glob.glob('*.cpp')
   for f in cpp_files:
      print '-'*20
      text = open(f).read()
      text = InjectMci(text, selective)
      print text
      open(f, 'w').write(text)