| #!/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)) |
| |