|
@@ -0,0 +1,214 @@
|
|
|
+#!/usr/bin/env python
|
|
|
+# "usage: txtcompile.py <input_dir> <output_dir> <output_filename>"
|
|
|
+
|
|
|
+import os
|
|
|
+import sys
|
|
|
+import re
|
|
|
+import io
|
|
|
+import xml.etree.ElementTree as ET
|
|
|
+
|
|
|
+gitBranch = "nobranch"
|
|
|
+gitBranchDetected = False
|
|
|
+
|
|
|
+try:
|
|
|
+ from pygit2 import Repository,GitError
|
|
|
+ try:
|
|
|
+ gitBranch = Repository('.').head.shorthand
|
|
|
+ gitBranchDetected = True
|
|
|
+ except GitError:
|
|
|
+ print('Git Repository not found')
|
|
|
+except ImportError:
|
|
|
+ print("Notice: you can speed up the compiler by installing pygit2.")
|
|
|
+ print("You can install it by typing: pip install pygit2")
|
|
|
+
|
|
|
+assert len(sys.argv) == 4, "usage:\ntxtcompile.py <input_dir> <output_dir> <output_filename>"
|
|
|
+
|
|
|
+inputdir = str(sys.argv[1])
|
|
|
+outputDir = sys.argv[2]+ '/' + gitBranch
|
|
|
+
|
|
|
+if not os.path.exists(outputDir):
|
|
|
+ os.makedirs(outputDir)
|
|
|
+
|
|
|
+def getProcessingArguments(text):
|
|
|
+ regex = r"\s*!!\s*PROCESS\s*:(.*)"
|
|
|
+ match = re.search(regex, text, re.IGNORECASE)
|
|
|
+
|
|
|
+ arguments = [""]
|
|
|
+
|
|
|
+ if match is not None:
|
|
|
+ arguments = [x.strip().lower() for x in match.groups()[0].split(',')]
|
|
|
+
|
|
|
+ return arguments
|
|
|
+
|
|
|
+def foreach2while(text):
|
|
|
+ regex = r"\s*foreach(X?)\s*[(]\s*(\S+)\s+as\s+(\S+)\s*=>\s*(\S+)\s*[)]{"
|
|
|
+
|
|
|
+ match = re.search(regex, text, re.IGNORECASE)
|
|
|
+
|
|
|
+ while match is not None:
|
|
|
+ currentOpen = 1
|
|
|
+ currentPos = match.end()
|
|
|
+
|
|
|
+ arrayEdit = 0
|
|
|
+
|
|
|
+ if match.groups()[0] == 'X':
|
|
|
+ arrayEdit = 1
|
|
|
+
|
|
|
+ while currentOpen > 0:
|
|
|
+
|
|
|
+ nextOpen = text.find('{',currentPos)
|
|
|
+ nextClose = text.find('}',currentPos)
|
|
|
+
|
|
|
+ if nextClose == -1:
|
|
|
+ print('Error')
|
|
|
+ sys.exit('Syntax error')
|
|
|
+
|
|
|
+ if nextOpen != -1 and nextOpen < nextClose:
|
|
|
+ currentPos = nextOpen+1
|
|
|
+ currentOpen += 1
|
|
|
+ else:
|
|
|
+ currentPos = nextClose+1
|
|
|
+ currentOpen -= 1
|
|
|
+
|
|
|
+ text = (text[:max(match.start(),0)]+'\n'+
|
|
|
+ match.groups()[2]+' = 0\n'+
|
|
|
+ 'while ('+match.groups()[2]+' < arrsize(\''+match.groups()[1]+'\')){\n'+
|
|
|
+ '\t'+match.groups()[3]+' = '+match.groups()[1]+'['+match.groups()[2]+']\n'+
|
|
|
+ text[match.end():currentPos-1]+'\n'+
|
|
|
+ '\t'+match.groups()[1]+'['+match.groups()[2]+'] = '+match.groups()[3]+'\n'+
|
|
|
+ '\t'+match.groups()[2]+'+=1\n'+
|
|
|
+ '}\n'+
|
|
|
+ 'killvar \''+match.groups()[2]+'\'\n'+
|
|
|
+ 'killvar \''+match.groups()[3]+'\'\n'+
|
|
|
+ text[currentPos:])
|
|
|
+
|
|
|
+ match = re.search(regex, text, re.IGNORECASE)
|
|
|
+
|
|
|
+ return text
|
|
|
+
|
|
|
+def syntaxAdditions2qsp(text):
|
|
|
+ # Since foreach is translated into while it has to be processed before while is processed
|
|
|
+
|
|
|
+ # FOREACH
|
|
|
+ text = foreach2while(text)
|
|
|
+
|
|
|
+ # WHILE
|
|
|
+ text = while2qsp(text)
|
|
|
+
|
|
|
+ return text
|
|
|
+
|
|
|
+def commentsPurge(text):
|
|
|
+ purgedText = "\n".join([line for line in text.split('\n') if line.strip()[0:2] != '!!'])
|
|
|
+ return purgedText
|
|
|
+
|
|
|
+def trim(text):
|
|
|
+ trimmedText = "\n".join([line.strip() for line in text.split('\n') if line.strip() != ''])
|
|
|
+ return trimmedText
|
|
|
+
|
|
|
+def while2qsp(text):
|
|
|
+
|
|
|
+ regex = r"\s*while\s*[(]\s*([^{]+)[)]{"
|
|
|
+
|
|
|
+ match = re.search(regex, text, re.IGNORECASE)
|
|
|
+
|
|
|
+ while match is not None:
|
|
|
+ currentOpen = 1
|
|
|
+ currentPos = match.end()
|
|
|
+
|
|
|
+ while currentOpen > 0:
|
|
|
+
|
|
|
+ nextOpen = text.find('{',currentPos)
|
|
|
+ nextClose = text.find('}',currentPos)
|
|
|
+
|
|
|
+ if nextClose == -1:
|
|
|
+ print('Error')
|
|
|
+ sys.exit('Syntax error')
|
|
|
+
|
|
|
+ if nextOpen != -1 and nextOpen < nextClose:
|
|
|
+ currentPos = nextOpen+1
|
|
|
+ currentOpen += 1
|
|
|
+ else:
|
|
|
+ currentPos = nextClose+1
|
|
|
+ currentOpen -= 1
|
|
|
+
|
|
|
+ loopname = 'sys_loop_'+filenameCleaned + str(match.start())
|
|
|
+
|
|
|
+ text = (text[:max(match.start(),0)]+'\n'+
|
|
|
+ ':'+loopname+'\n'
|
|
|
+ 'if '+match.groups()[0]+':\n'+
|
|
|
+ text[match.end():currentPos-1]+'\n'+
|
|
|
+ 'jump \''+loopname+'\'\n'
|
|
|
+ 'end\n'+
|
|
|
+ text[currentPos:])
|
|
|
+ #print(text)
|
|
|
+ match = re.search(regex, text, re.IGNORECASE)
|
|
|
+
|
|
|
+ return text
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#for filename in os.listdir(sys.argv[1]):
|
|
|
+for root, subdirs, files in os.walk(inputdir):
|
|
|
+ for filename in files:
|
|
|
+
|
|
|
+
|
|
|
+ filenameCleaned = ''.join(e for e in filename if e.isalnum())
|
|
|
+ filePathOld = os.path.join(root,filename)
|
|
|
+ filePathNew = filePathOld.replace(inputdir,outputDir) #os.path.join(outputDir,root,filename)
|
|
|
+
|
|
|
+ if not os.path.isfile(filePathOld):
|
|
|
+ continue
|
|
|
+
|
|
|
+ if os.path.isfile(filePathNew) and os.path.getmtime(filePathOld) <= os.path.getmtime(filePathNew) and gitBranchDetected:
|
|
|
+ continue
|
|
|
+
|
|
|
+ msgParameters = ""
|
|
|
+
|
|
|
+ with open(filePathOld, 'r', encoding='utf-8') as file:
|
|
|
+ text = file.read()
|
|
|
+
|
|
|
+ arguments = getProcessingArguments(text)
|
|
|
+
|
|
|
+ if "commentspurge" in arguments:
|
|
|
+ msgParameters += "c"
|
|
|
+
|
|
|
+ if "syntaxadditions" in arguments:
|
|
|
+ msgParameters += "s"
|
|
|
+
|
|
|
+ if "trim" in arguments:
|
|
|
+ msgParameters += "t"
|
|
|
+
|
|
|
+ print('Processing '+filename+' -> '+msgParameters)
|
|
|
+
|
|
|
+ if "syntaxadditions" in arguments:
|
|
|
+ text = syntaxAdditions2qsp(text)
|
|
|
+
|
|
|
+ if "trim" in arguments:
|
|
|
+ text = trim(text)
|
|
|
+
|
|
|
+ if "commentspurge" in arguments:
|
|
|
+ text = commentsPurge(text)
|
|
|
+
|
|
|
+ if not os.path.exists(os.path.dirname(filePathNew)):
|
|
|
+ os.makedirs(os.path.dirname(filePathNew))
|
|
|
+
|
|
|
+ with open(filePathNew, 'w', encoding='utf-16') as file:
|
|
|
+ file.write(text)
|
|
|
+
|
|
|
+
|
|
|
+outputfilename = str(sys.argv[3])
|
|
|
+
|
|
|
+with io.open(outputfilename, 'w', encoding='utf-16', newline='\r\n') as outputfile:
|
|
|
+
|
|
|
+ #for file in os.listdir(inputdir):
|
|
|
+ for root, subdirs, files in os.walk(outputDir):
|
|
|
+ for filename in files:
|
|
|
+ filepath = os.path.join(root,filename)
|
|
|
+ with io.open(filepath, 'rt', encoding='utf-16') as inputfile:
|
|
|
+ text = inputfile.read()
|
|
|
+
|
|
|
+ # EOF
|
|
|
+ if text[-1] != u'\n':
|
|
|
+ text += u'\n\n'
|
|
|
+
|
|
|
+ outputfile.write(text)
|