blob: 701f1da044fcd74d3188949eac6c527907ca32b2 [file] [log] [blame]
#!/usr/bin/python -B
from string import Template, upper, replace
from ApiUtil import outputCode
from ApiCodeGen import *
from RegalContextInfo import cond
lookupSourceTemplate = Template( '''${AUTOGENERATED}
${LICENSE}
#include "pch.h" /* For MS precompiled header support */
#include "RegalUtil.h"
REGAL_GLOBAL_BEGIN
#include "RegalPrivate.h"
#include "RegalLookup.h"
REGAL_GLOBAL_END
REGAL_NAMESPACE_BEGIN
namespace Lookup {
${CODE}
}
REGAL_NAMESPACE_END
''')
def pointerLookupSource(api = None, names = []):
return pointerLookupByNameCode([ (j,j) for j in names ],("%s_Name"%api,"%s_Value"%api),valueCast = '(void *)(%s)')
def offsetLookupSource(api = None, names = [], table = None, exclude = set()):
names.sort()
ret = []
ret.append( 'const size_t %s_Offset[%d] = {' % (api, len(names)+1) ) # terminating NULL
for j in names:
if j in exclude:
ret.append(" 0,")
else:
ret.append(" offsetof(%s,%s)/sizeof(void *),"%(table,j))
ret.append( ' 0')
ret.append('};')
ret.append('')
return ret
def generateLookupSource(apis, args):
ret = []
for i in apis:
code = []
regalOnly = set( [ j.name for j in i.functions if getattr(j,'regalOnly',False)==True ] )
# Special handling for Regal-only function lookup
if i.name=='gl':
names = [ j.name for j in i.functions if getattr(j,'regalOnly',False)==True or j.category=='GL_REGAL_ES1_0_compatibility']
# code.extend(pointerLookupSource('regal',names))
# code.extend(offsetLookupSource('regal',names,"Dispatch::GL",regalOnly))
names = [ j.name for j in i.functions ]
conditional = None
if i.name in cond:
conditional = cond[i.name]
code.extend(pointerLookupSource(i.name,names))
# offset table
table = "Dispatch::Global"
if i.name == "gl":
table = "Dispatch::GL"
code.extend(offsetLookupSource(i.name,names,table,regalOnly))
if i.name in cond:
conditional = cond[i.name]
code = wrapIf(conditional,code)
ret.extend(code)
substitute = {}
substitute['LICENSE'] = args.license
substitute['AUTOGENERATED'] = args.generated
substitute['COPYRIGHT'] = args.copyright
substitute['CODE'] = '\n'.join(ret)
outputCode( '%s/RegalLookup.cpp' % args.srcdir, lookupSourceTemplate.substitute(substitute))
##############################################################################################
lookupHeaderTemplate = Template( '''${AUTOGENERATED}
${LICENSE}
#ifndef __${HEADER_NAME}_H__
#define __${HEADER_NAME}_H__
#include "RegalUtil.h"
REGAL_GLOBAL_BEGIN
#include <cstdlib>
#include <cstring>
REGAL_GLOBAL_END
REGAL_NAMESPACE_BEGIN
namespace Lookup {
inline int NameCmp(const void *a, const void *b)
{
return std::strcmp(*(const char **) a, *(const char **) b);
}
${CODE}
}
REGAL_NAMESPACE_END
#endif
''')
def pointerLookupHeader(api = None, names = []):
ret = []
ret.append( '' )
ret.append( 'extern const char * const %s_Name[%d];'%(api,len(names)+1) )
ret.append( 'extern const void *%s_Value[%d];'%(api,len(names)+1) )
ret.append('''
template<typename T>
T
%s(const char *name, T def = NULL)
{
const char **res = (const char **) std::bsearch(&name, %s_Name, %d, sizeof(const char *), NameCmp);
return res ? reinterpret_cast<T>(const_cast<void *>(%s_Value[(size_t) (res - %s_Name)])) : def;
}
'''%('%s_Lookup'%api,api,len(names),api,api))
return ret
def offsetLookupHeader(api = None, names = [], table = None, exclude = set()):
ret = []
ret.append( '' )
ret.append( 'extern const size_t %s_Offset[%d];'%(api,len(names)+1) )
ret.append('''
inline size_t %s(const char *name)
{
const char **res = (const char **) std::bsearch(&name, %s_Name, %d, sizeof(const char *), NameCmp);
return res ? %s_Offset[(size_t) (res - %s_Name)] : 0;
}
'''%('%s_LookupOffset'%api,api,len(names),api,api))
return ret
def generateLookupHeader(apis, args, offsetLookup = True, ifFunction = lambda i : True):
ret = []
for i in apis:
code = []
# Special handling for Regal-only function lookup
if i.name=='gl':
names = [ j.name for j in i.functions if getattr(j,'regalOnly',False)==True or j.category=='GL_REGAL_ES1_0_compatibility']
# code.extend(pointerLookupHeader('regal',names))
# code.extend(offsetLookupHeader('regal',names))
names = [ j.name for j in i.functions ]
conditional = None
if i.name in cond:
conditional = cond[i.name]
code.extend(pointerLookupHeader(i.name,names))
code.extend(offsetLookupHeader(i.name,names))
if i.name in cond:
conditional = cond[i.name]
code = wrapIf(conditional,code)
ret.extend(code)
substitute = {}
substitute['LICENSE'] = args.license
substitute['AUTOGENERATED'] = args.generated
substitute['COPYRIGHT'] = args.copyright
substitute['HEADER_NAME'] = "REGAL_LOOKUP"
substitute['CODE'] = '\n'.join(ret)
outputCode( '%s/RegalLookup.h' % args.srcdir, lookupHeaderTemplate.substitute(substitute))