I wrote a text parser which generates a necessary file. Python 2.5 is used because the code was mostly written and tested on my old Nokia with Python 2.5 onboard.

Parser designed to project - scummvm

from __future__ import with_statement
import os, re, shutil

# pt - path where parser works
pt = '..\..\..\..\engines'
# pt = 'e:\engines'
t = os.listdir(pt)


# build = 'full'
build = 'release'


# Python appends crlf to lines if '\n'
endline = '\n'
# endline = '\r\n'


# This function is frozen! Don't edit!
#ignore unfinished engines in release build
def CheckForRelease(line_):
   if 'no' in line_:
      return build != 'release'
   else:
      return True


# This function is frozen! Don't edit!
def processengine(path):
   f = open(os.path.join(path, "configure.engine"))
   ff = f.readlines()
   ff = ff[2:]
   f.close()

   ff = [ n.split('"', 2) for n in ff]
   ff = [ n[0] + n[2] for n in ff]
   f = [n.split() for n in ff]

   if f[0][2] == 'no' and build == "release":
      return None
   else:
      buildparam = ["MACRO   ENABLE_%s" %f[0][1].upper()]

   if len(f) == 1:
      return buildparam

   if len(f[0]) > 3:
      f = f[1:]

   for i in f:
      if CheckForRelease(i[2]):
         buildparam += ["   MACRO   ENABLE_%s" %i[1].upper()]

   return buildparam

# This function is frozen! Don't edit!
def processModule_mk(path, buildparams):
   ff = open(os.path.join(path, "module.mk"))
   f = ff.readlines()
   ff.close()

   src = []
   addsrc = None

   for i in f:
#add engine base source code first
      if "MODULE_OBJS" in i:
         if addsrc is None:
            addsrc = True
      elif "ifdef ENABLE_" in i:
         for x in buildparams:
            if "MACRO   %s"%i.strip()[6:] in x:
               addsrc = True
               src += ["// Subengine %s"%x[18:]]
      elif addsrc is True:
         if ".o \\" in i[-5:]:
            src += ["SOURCE   " + i[1:-5] + ".cpp"]
         elif ".o" in i[-3:]:
            src += ["SOURCE   " + i[1:-3] + ".cpp"]
         elif len(i) == 1:
            addsrc = False
   return src


# Searches for duplicates in .cpp, add per engine fixes
def CheckEngine(lst, game):
   if game == "sword25":
      return None
   return lst


def FixSrc(source, game):
   """Function saves file duplicates with new name, origin remains as is."""
   ourDict = {}
   for item in source:
      n = os.path.split(item)
      if "SOURCE" in n[1]:
         n = n[1][9:]
      else: n = n[1]
      try: ourDict[n] += 1
      except: ourDict[n] = 1
   [ourDict.pop(n) for n, v in ourDict.items() if v < 2]
   if len(ourDict) != 0:
      print ourDict
      while(len(ourDict) != 0):
         (key, val) = ourDict.popitem()
         while(val > 0):
            for item in source:
               pos = len(item) - len(key)
               if key in item[pos:]:
                  print "%s/%s"%(game, item[9:])

### This is future expansion. Simple loggin suffice for now.
                  # print "%s\t%s" %(item, new_item)
                  # new_item = item[9:-4] + "(%s)"%val + item[-4:]
                  # tmp = os.path.join( os.path.join(pt, game) , "tmp")
                  # source = os.path.join( os.path.join(pt, game) , item[9:])
                  # dst = os.path.join( tmp, new_item)
                  # print item[:9] + new_item
                  # shutil.copy2(source, dst)
                  # item = item[:9] + new_item
                  val -= 1
   # print source
   return source


# This function is frozen! Don't edit!
def SafeWriteFile(path, mode, data):
   """Save list elments as strings. Save strings as is"""
   with open(path, mode) as f:
      if type(data) is list:
         for s in data:
            f.write(s + '\n')
      else:
         f.write(data)


firstRun = True

def MakeMMP(engine):
   global firstRun
   pth = os.path.join(pt, engine)
   macrolist = processengine(pth)

   if macrolist is None:
      return

   src = processModule_mk(pth, macrolist)

   mmp = """TARGET scummvm_%s.lib
TARGETTYPE lib\n
#include "config.mmh"
#include "macros.mmh"\n
USERINCLUDE    ..\..\..\..\engines\%s\n
// *** SOURCE files
SOURCEPATH   ..\..\..\..\engines\%s\n
""" %(engine, engine, engine)

   mmp = CheckEngine(mmp, engine)
   if mmp is None:
      return

   # src = FixSrc(src, engine)
   FixSrc(src, engine)

   plugins_table = """
#if PLUGIN_ENABLED_STATIC(%s)
LINK_PLUGIN(%s)
#endif
""" %(engine.upper(), engine.upper())

#replace files and add bld.inf header
   if firstRun is True:
      # SafeWriteFile("e:\\engines\\bld.inf", 'w', "PRJ_MMPFILES" + endline)
      # SafeWriteFile("e:\engines\macros.mmh", 'w', "")
      # SafeWriteFile("e:\engines\plugins_table.h", 'w', "")

      SafeWriteFile("bld.inf", 'w', "PRJ_MMPFILES" + endline)
      SafeWriteFile(os.path.join(pt, "plugins_table.h"), 'w', "")
      SafeWriteFile("macros.mmh", 'w', "")
      firstRun = False

   # SafeWriteFile("e:\engines\%s.mmp" %engine, 'w', mmp)
   # SafeWriteFile("e:\engines\%s.mmp" %engine, 'a', src)
   # SafeWriteFile("e:\engines\macros.mmh", 'a', macrolist)
   # SafeWriteFile("e:\engines\\bld.inf", 'a', engine + ".mmp")
   # SafeWriteFile("e:\engines\plugins_table.h", 'a', "")

   SafeWriteFile("%s.mmp" %engine, 'w', mmp)
   SafeWriteFile("%s.mmp" %engine, 'a', src)
   SafeWriteFile(os.path.join(pt, "plugins_table.h"), 'a', plugins_table)
   SafeWriteFile("macros.mmh", 'a', macrolist)
   SafeWriteFile("bld.inf", 'a', engine + ".mmp%s" %endline)


if __name__ == "__main__":
   [MakeMMP(m) for m in t if os.path.isdir(os.path.join(pt, m))]
share|improve this question
2  
Can you really not change the name of CheckForRelease? It violates PEP8. Or can you and you're just telling a user not to modify it? – Dair Oct 10 '16 at 21:47
    
Yep, I telling a user not to modify it in future. They works as expected, but any enhancement to 'pythonify', avioding errors, speedups are welcome, cleaning code etc... – Fedor Oct 11 '16 at 13:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.