blob: 1ef4fb7922e266214487877f7fbc619d49c28ad4 [file] [log] [blame]
from SCons.Environment import Environment as Environment
import re,fileinput,os
from string import join as sjoin
from os.path import join as pjoin
def _sedit(input,output,substs):
res = []
f=open(output[0].path,'w')
for subst in substs:
res.append(re.compile(subst[0],re.MULTILINE|re.DOTALL))
lines =""
for line in fileinput.input(input[0].path):
lines+= line
count = 0
for r in res:
lines = res[count].sub(substs[count][1],lines,0)
count += 1
lines += '\n'
f.write(lines)
f.close()
return 0
def QuoteSourceAction(target,source,env):
if env.Execute(env['with_xmllint'] + ' --relaxng ' + source[0].path +
' test/return0/helloworld.hlx >/dev/null'):
return 1
substs = [
['<!--.*?-->',''],
['<annotation>.*?</annotation>',''],
['^[ \\t]*<','<'],
['^[ \\t]*([^<])',' \\1'],
['[\\\\]','\\\\\\\\'],
['"','\\"'],
['^([^\\n]*)$','"\\1"'],
['^"[ \\t]*?"$\\n','']
]
return _sedit(source,target,substs)
def QuoteSourceMessage(target,source,env):
return "Converting %s to %s as quoted source" % (source[0],target[0])
def RNGQuoteSource(env):
a = env.Action(QuoteSourceAction,QuoteSourceMessage)
b = env.Builder(action=a,suffix='inc',src_suffix='rng',single_source=1)
env.Append(BUILDERS = {'RNGQuoteSource':b})
return b
def getSchemaTokens(fname):
elemPat = re.compile('<element[^>]*name[ ]*=[ ]*"([^"]*)"')
attrPat = re.compile('<attribute[^>]*name[ ]*=[ ]*"([^"]*)"')
valuPat = re.compile('<value>\s*([^<\s]*)')
subsPat = re.compile('[^A-Za-z0-9_]');
tokens = []
for line in fileinput.input(fname):
tokens += elemPat.findall(line)
tokens += attrPat.findall(line)
tokens += valuPat.findall(line)
dict = {}
for tok in tokens:
clean_tok = subsPat.sub('_',tok);
dict[clean_tok] = 1
result = list(dict.keys())
result.sort()
return result
def processFile(preamble,tmplt,output,substs):
res = []
for subst in substs:
res.append(re.compile(subst[0]))
outf = open(output,"w")
for infile in [preamble,tmplt]:
for line in fileinput.input(infile):
count = 0
for r in res:
line = res[count].sub(substs[count][1],line,0)
count += 1
outf.write(line)
outf.close()
def RNGTokenizerAction(target,source,env):
tgtDir = target[0].dir.path
ModulePath = re.sub(pjoin(env['BuildDir'],'hlvm','')+'(.*)','\\1',tgtDir)
Module = re.sub('[/\\\\]','_',ModulePath)
Schema = re.sub('.*/(.*).rng','\\1',source[0].path)
PreambleFile = "utils/tmplt/Preamble_Code";
HeaderTemplate = "utils/tmplt/Tokenizer_Template.h";
SourceTemplate = "utils/tmplt/Tokenizer_Template.cpp";
HeaderFile = pjoin(tgtDir,Schema) + "Tokenizer.h";
SourceFile = pjoin(tgtDir,Schema) + "Tokenizer.cpp";
TokenHashClass = Schema + "TokenHash";
TokenHashFile = pjoin(tgtDir,TokenHashClass) + ".i";
tokens = []
tokens = getSchemaTokens(source[0].path)
tknFilename = pjoin(tgtDir,Schema) + "Tokens.tmp"
tknFile = open(tknFilename,"w")
tknFile.write('struct TokenMap {\n')
tknFile.write('const char *name; HLVM_'+Module+'::'+Schema+'Tokens token;\n')
tknFile.write('};\n%%\n')
for tkn in tokens:
tknFile.write('"' + tkn + '", HLVM_'+Module+'::TKN_' + tkn + ',\n')
tknFile.write('%%\n')
tknFile.close()
gperfAction = env.Action(
env['with_gperf'] + " -tcDCIoGl --fast 0 -L C++ -Z " + TokenHashClass +
" -s 2 -S 1 -k '*' " + tknFilename + " >" + TokenHashFile)
if env.Execute(gperfAction):
return 1;
tokenList = ""
for tkn in tokens:
tokenList += "TKN_" + tkn + ",\n "
from datetime import date
substs = [
['%SCHEMA_NAME%',Schema],
['%AUTHOR%','Generated By HLVM build system'],
['%DATE%',date.today().strftime('%c')],
['%MODULE%',Module],
['%MODULE_PATH%',ModulePath],
['%TOKEN_LIST%',tokenList]
]
processFile(PreambleFile,HeaderTemplate,HeaderFile,substs)
processFile(PreambleFile,SourceTemplate,SourceFile,substs)
return 0
def RNGTokenizerMessage(target,source,env):
return "Generating Perfect Hash Tokenizer For " + source[0].path
def RNGTokenizer(env):
a = env.Action(RNGTokenizerAction,RNGTokenizerMessage)
b = env.Builder(action=a,suffix='h',src_suffix='rng',single_source=1)
env.Append(BUILDERS = {'RNGTokenizer':b})
return 1
def ConfigFileMessage(target,source,env):
return "Generating Configuration File " + target[0].path
def ConfigFileAction(target,source,env):
pat = re.compile('@([^@]+)@')
tgt = open(target[0].path,'w')
for line in fileinput.input(source[0].path):
matchobj = pat.search(line)
if None != matchobj:
var = matchobj.expand('\\1')
if env._dict.has_key(var):
substval = env[var]
if type(substval) != str:
substval = `env[var]`
line = pat.sub(substval,line)
tgt.write(line)
continue
tgt.close()
def ConfigFile(env):
action = env.Action(ConfigFileAction,ConfigFileMessage)
builder = env.Builder(action=action,src_suffix='.in',single_source=1)
env.Append(BUILDERS = {'ConfigFile':builder})
return 1