Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #!/usr/bin/env python
  2. #coding=UTF-8
  3.  
  4. # Copyright © 2011 Intel Corporation
  5. #
  6. # Permission is hereby granted, free of charge, to any person obtaining a
  7. # copy of this software and associated documentation files (the "Software"),
  8. # to deal in the Software without restriction, including without limitation
  9. # the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10. # and/or sell copies of the Software, and to permit persons to whom the
  11. # Software is furnished to do so, subject to the following conditions:
  12. #
  13. # The above copyright notice and this permission notice (including the next
  14. # paragraph) shall be included in all copies or substantial portions of the
  15. # Software.
  16. #
  17. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20. # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. # SOFTWARE.
  24. #
  25. # Authors:
  26. #    Chen, Yangyang <yangyang.chen@intel.com>
  27. #    Han, Haofu     <haofu.han@intel.com>
  28. #
  29.  
  30. import sys
  31.  
  32. class Block:
  33.         def __init__(self, ln=0, s=None):
  34.                 assert type(ln) == int
  35.                 assert type(s) == str or s == None
  36.                 self.lineno = ln
  37.                 self.text = s
  38.                 self.subblocks = []
  39.  
  40.         def append(self, block):
  41.                 self.subblocks.append(block)
  42.  
  43.         def checkfor(self, line):
  44.                 import re
  45.                 p = r'\$\s*for\s*'
  46.                 if re.match(p, line) == None:
  47.                         raise Exception(self.__errmsg('syntax error'))
  48.                 tail = line.split('(', 1)[1].rsplit(')', 1)
  49.                 conds = tail[0].split(';')
  50.                 lb = tail[1]
  51.                 if lb.strip() != '{':
  52.                         raise Exception(self.__errmsg('missing "{"'))
  53.                 if len(conds) != 3:
  54.                         raise Exception(self.__errmsg('syntax error(miss ";"?)'))
  55.                 init = conds[0]
  56.                 cond = conds[1]
  57.                 step = conds[2]
  58.                 self.__parse_init(init)
  59.                 self.__parse_cond(cond)
  60.                 self.__parse_step(step)
  61.  
  62.         def __parse_init(self, init):
  63.                 inits = init.split(',')
  64.                 self.param_init = []
  65.                 for ini in inits:
  66.                         try:
  67.                                 val = eval(ini)
  68.                                 self.param_init.append(val)
  69.                         except:
  70.                                 raise Exception(self.__errmsg('non an exp: %s'%ini))
  71.                 self.param_num = len(inits)
  72.  
  73.         def __parse_cond(self, cond):
  74.                 cond = cond.strip()
  75.                 if cond[0] in ['<', '>']:
  76.                         if cond[1] == '=':
  77.                                 self.param_op = cond[:2]
  78.                                 limit = cond[2:]
  79.                         else:
  80.                                 self.param_op = cond[0]
  81.                                 limit = cond[1:]
  82.                         try:
  83.                                 self.param_limit = eval(limit)
  84.                         except:
  85.                                 raise Exception(self.__errmsg('non an exp: %s'%limit))
  86.                 else:
  87.                         raise Exception(self.__errmsg('syntax error'))
  88.  
  89.         def __parse_step(self, step):
  90.                 steps = step.split(',')
  91.                 if len(steps) != self.param_num:
  92.                         raise Exception(self.__errmsg('params number no match'))
  93.                 self.param_step = []
  94.                 for st in steps:
  95.                         try:
  96.                                 val = eval(st)
  97.                                 self.param_step.append(val)
  98.                         except:
  99.                                 raise Exception(self.__errmsg('non an exp: %s'%st))
  100.  
  101.         def __errmsg(self, msg=''):
  102.                 return '%d: %s' % (self.lineno, msg)
  103.  
  104. def readlines(f):
  105.         lines = f.readlines()
  106.         buf = []
  107.         for line in lines:
  108.                 if '\\n' in line:
  109.                         tmp = line.split('\\n')
  110.                         buf.extend(tmp)
  111.                 else:
  112.                         buf.append(line)
  113.         return buf
  114.  
  115. def parselines(lines):
  116.         root = Block(0)
  117.         stack = [root]
  118.         lineno = 0
  119.         for line in lines:
  120.                 lineno += 1
  121.                 line = line.strip()
  122.                 if line.startswith('$'):
  123.                         block = Block(lineno)
  124.                         block.checkfor(line)
  125.                         stack[-1].append(block)
  126.                         stack.append(block)
  127.                 elif line.startswith('}'):
  128.                         stack.pop()
  129.                 elif line and not line.startswith('#'):
  130.                         stack[-1].append(Block(lineno, line))
  131.         return root
  132.  
  133. def writeblocks(outfile, blocks):
  134.         buf = []
  135.  
  136.         def check_cond(op, cur, lim):
  137.                 assert op in ['<', '>', '<=', '>=']
  138.                 assert type(cur) == int
  139.                 assert type(lim) == int
  140.                 return eval('%d %s %d' % (cur, op, lim))
  141.  
  142.         def do_writeblock(block, curs):
  143.                 if block.text != None:
  144.                         import re
  145.                         p = r'\%(\d+)'
  146.                         newline = block.text
  147.                         params = set(re.findall(p, block.text))
  148.                         for param in params:
  149.                                 index = int(param) - 1
  150.                                 if index >= len(curs):
  151.                                         raise Exception('%d: too many param(%%%d)'%(block.lineno, index+1))
  152.                                 newline = newline.replace('%%%d'%(index+1), str(curs[index]))
  153.                         if newline and \
  154.                                         not newline.startswith('.') and \
  155.                                         not newline.endswith(':') and \
  156.                                         not newline.endswith(';'):
  157.                                 newline += ';'
  158.                         buf.append(newline)
  159.                 else:
  160.                         for_curs = block.param_init
  161.                         while check_cond(block.param_op, for_curs[0], block.param_limit):
  162.                                 for sblock in block.subblocks:
  163.                                         do_writeblock(sblock, for_curs)
  164.                                 for i in range(0, block.param_num):
  165.                                         for_curs[i] += block.param_step[i]
  166.  
  167.         for block in blocks.subblocks:
  168.                 do_writeblock(block, [])
  169.         outfile.write('\n'.join(buf))
  170.         outfile.write('\n')
  171.  
  172. if __name__ == '__main__':
  173.         argc = len(sys.argv)
  174.         if argc == 1:
  175.                 print >>sys.stderr, 'no input file'
  176.                 sys.exit(0)
  177.  
  178.         try:
  179.                 infile = open(sys.argv[1], 'r')
  180.         except IOError:
  181.                 print >>sys.stderr, 'can not open %s' % sys.argv[1]
  182.                 sys.exit(1)
  183.  
  184.         if argc == 2:
  185.                 outfile = sys.stdout
  186.         else:
  187.                 try:
  188.                         outfile = open(sys.argv[2], 'w')
  189.                 except IOError:
  190.                         print >>sys.stderr, 'can not write to %s' % sys.argv[2]
  191.                         sys.exit(1)
  192.  
  193.         lines = readlines(infile)
  194.         try:
  195.                 infile.close()
  196.         except IOError:
  197.                 pass
  198.  
  199.         blocks = parselines(lines)
  200.         writeblocks(outfile, blocks)
  201.