diff options
| author | Tobin Ehlis <tobin@lunarg.com> | 2014-12-17 17:44:50 -0700 |
|---|---|---|
| committer | Courtney Goeltzenleuchter <courtney@LunarG.com> | 2015-02-04 17:58:05 -0700 |
| commit | ad0170c34eef4e8ee453cc0e0b3facace2e73bf5 (patch) | |
| tree | 00c9fd454a352b0d26c7020f01cac2ed507da817 /xgl-layer-generate.py | |
| parent | 269cd0d3ebdc54730181d1e09cdb0a9e6784ad25 (diff) | |
| download | usermoji-ad0170c34eef4e8ee453cc0e0b3facace2e73bf5.tar.xz | |
layers: Initial ParamChecker layer
ParamChecker layer is generated and currently only checks that ENUM input to functions or ENUMS as part of input structs have valid values.
Conflicts:
layers/CMakeLists.txt
Diffstat (limited to 'xgl-layer-generate.py')
| -rwxr-xr-x | xgl-layer-generate.py | 132 |
1 files changed, 119 insertions, 13 deletions
diff --git a/xgl-layer-generate.py b/xgl-layer-generate.py index d19a63f8..7e2cb742 100755 --- a/xgl-layer-generate.py +++ b/xgl-layer-generate.py @@ -26,8 +26,10 @@ # Chia-I Wu <olv@lunarg.com> import sys +import os import xgl +import xgl_helper class Subcommand(object): def __init__(self, argv): @@ -434,10 +436,9 @@ class Subcommand(object): (pft, pfi) = ("%s", '"addr"') log_func += '%s = %s, ' % (p.name, pft) print_vals += ', %s' % (pfi) - # TODO : Just want this to be simple check for params of STRUCT type - if "pCreateInfo" in p.name or ('const' in p.ty and '*' in p.ty and False not in [tmp_ty not in p.ty for tmp_ty in ['XGL_CHAR', 'XGL_VOID', 'XGL_CMD_BUFFER', 'XGL_QUEUE_SEMAPHORE', 'XGL_FENCE', 'XGL_SAMPLER', 'XGL_UINT32']]): - if 'Wsi' not in proto.name: - cis_param_index.append(pindex) + # 'format' gets special treatment as a small struct that we print inline + if 'Wsi' not in proto.name and 'format' != p.name and xgl_helper.is_type(p.ty.strip('*').strip('const '), 'struct'): + cis_param_index.append(pindex) pindex += 1 log_func = log_func.strip(', ') if proto.ret != "XGL_VOID": @@ -624,13 +625,96 @@ class Subcommand(object): '%s%s' '%s' '}' % (qual, decl, proto.params[0].name, using_line, ret_val, c_call, create_line, destroy_line, stmt)) - - # TODO : Put this code somewhere so it gets called at the end if objects not deleted : - # // Report any remaining objects in LL - # objNode *pTrav = pObjLLHead; - # while (pTrav) { - # printf("WARN : %s object %p has not been destroyed.\n", pTrav->objType, pTrav->pObj); - # } + elif "ParamChecker" == layer: + # TODO : Need to fix up the non-else cases below to do param checking as well + decl = proto.c_func(prefix="xgl", attr="XGLAPI") + param0_name = proto.params[0].name + ret_val = '' + stmt = '' + param_checks = [] + # Add code to check enums and structs + # TODO : Currently only validating enum values, need to validate everything + str_decl = False + for p in proto.params: + if xgl_helper.is_type(p.ty.strip('*').strip('const '), 'enum'): + if not str_decl: + param_checks.append(' char str[1024];') + str_decl = True + param_checks.append(' if (!validate_%s(%s)) {' % (p.ty, p.name)) + param_checks.append(' char str[1024];') + param_checks.append(' sprintf(str, "Parameter %s to function %s has invalid value of %%i.", (int)%s);' % (p.name, proto.name, p.name)) + param_checks.append(' layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);') + param_checks.append(' }') + elif xgl_helper.is_type(p.ty.strip('*').strip('const '), 'struct') and 'const' in p.ty: + if not str_decl: + param_checks.append(' char str[1024];') + str_decl = True + if '*' in p.ty: # First check for null ptr + param_checks.append(' if (!%s) {' % p.name) + param_checks.append(' sprintf(str, "Struct ptr parameter %s to function %s is NULL.");' % (p.name, proto.name)) + param_checks.append(' layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);') + param_checks.append(' }') + param_checks.append(' else if (!xgl_validate_%s(%s)) {' % (p.ty.strip('*').strip('const ').lower(), p.name)) + else: + param_checks.append(' if (!xgl_validate_%s(%s)) {' % (p.ty.strip('const ').lower(), p.name)) + param_checks.append(' sprintf(str, "Parameter %s to function %s contains an invalid value.");' % (p.name, proto.name)) + param_checks.append(' layerCbMsg(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, NULL, 0, 1, "PARAMCHECK", str);') + param_checks.append(' }') + if proto.ret != "XGL_VOID": + ret_val = "XGL_RESULT result = " + stmt = " return result;\n" + if proto.name == "EnumerateLayers": + c_call = proto.c_call().replace("(" + proto.params[0].name, "((XGL_PHYSICAL_GPU)gpuw->nextObject", 1) + funcs.append('%s%s\n' + '{\n' + ' char str[1024];\n' + ' if (gpu != NULL) {\n' + ' XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) %s;\n' + ' sprintf(str, "At start of layered %s\\n");\n' + ' layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, gpu, 0, 0, "PARAMCHECK", str);\n' + ' pCurObj = gpuw;\n' + ' pthread_once(&tabOnce, initLayerTable);\n' + ' %snextTable.%s;\n' + ' sprintf(str, "Completed layered %s\\n");\n' + ' layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, gpu, 0, 0, "PARAMCHECK", str);\n' + ' fflush(stdout);\n' + ' %s' + ' } else {\n' + ' if (pOutLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)\n' + ' return XGL_ERROR_INVALID_POINTER;\n' + ' // This layer compatible with all GPUs\n' + ' *pOutLayerCount = 1;\n' + ' strncpy(pOutLayers[0], "%s", maxStringSize);\n' + ' return XGL_SUCCESS;\n' + ' }\n' + '}' % (qual, decl, proto.params[0].name, proto.name, ret_val, c_call, proto.name, stmt, layer_name)) + elif 'DbgRegisterMsgCallback' == proto.name: + funcs.append(self._gen_layer_dbg_callback_register()) + elif 'DbgUnregisterMsgCallback' == proto.name: + funcs.append(self._gen_layer_dbg_callback_unregister()) + elif proto.params[0].ty != "XGL_PHYSICAL_GPU": + funcs.append('%s%s\n' + '{\n' + '%s\n' + ' %snextTable.%s;\n' + '%s' + '}' % (qual, decl, "\n".join(param_checks), ret_val, proto.c_call(), stmt)) + else: + c_call = proto.c_call().replace("(" + proto.params[0].name, "((XGL_PHYSICAL_GPU)gpuw->nextObject", 1) + funcs.append('%s%s\n' + '{\n' + ' char str[1024];' + ' XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) %s;\n' + ' sprintf(str, "At start of layered %s\\n");\n' + ' layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, gpuw, 0, 0, "PARAMCHECK", str);\n' + ' pCurObj = gpuw;\n' + ' pthread_once(&tabOnce, initLayerTable);\n' + ' %snextTable.%s;\n' + ' sprintf(str, "Completed layered %s\\n");\n' + ' layerCbMsg(XGL_DBG_MSG_UNKNOWN, XGL_VALIDATION_LEVEL_0, gpuw, 0, 0, "PARAMCHECK", str);\n' + ' fflush(stdout);\n' + '%s' + '}' % (qual, decl, proto.params[0].name, proto.name, ret_val, c_call, proto.name, stmt)) return "\n\n".join(funcs) @@ -1086,6 +1170,18 @@ class ObjectTrackerSubcommand(Subcommand): return "\n\n".join(body) +class ParamCheckerSubcommand(Subcommand): + def generate_header(self): + return '#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#include <pthread.h>\n#include "xglLayer.h"\n#include "xgl_enum_validate_helper.h"\n#include "xgl_struct_validate_helper.h"\n\nstatic XGL_LAYER_DISPATCH_TABLE nextTable;\nstatic XGL_BASE_LAYER_OBJECT *pCurObj;\nstatic pthread_once_t tabOnce = PTHREAD_ONCE_INIT;\n' + + def generate_body(self): + body = [self._gen_layer_dbg_callback_header(), + self._generate_layer_dispatch_table(), + self._generate_dispatch_entrypoints("XGL_LAYER_EXPORT", "ParamChecker"), + self._generate_layer_gpa_function()] + + return "\n\n".join(body) + def main(): subcommands = { "layer-funcs" : LayerFuncsSubcommand, @@ -1097,14 +1193,24 @@ def main(): "ApiDumpCpp" : ApiDumpCppSubcommand, "ApiDumpNoAddrCpp" : ApiDumpNoAddrCppSubcommand, "ObjectTracker" : ObjectTrackerSubcommand, + "ParamChecker" : ParamCheckerSubcommand, } - if len(sys.argv) < 2 or sys.argv[1] not in subcommands: - print("Usage: %s <subcommand> [options]" % sys.argv[0]) + if len(sys.argv) < 3 or sys.argv[1] not in subcommands or not os.path.exists(sys.argv[2]): + print("Usage: %s <subcommand> <input_header> [options]" % sys.argv[0]) print print("Available sucommands are: %s" % " ".join(subcommands)) exit(1) + hfp = xgl_helper.HeaderFileParser(sys.argv[2]) + hfp.parse() + xgl_helper.enum_val_dict = hfp.get_enum_val_dict() + xgl_helper.enum_type_dict = hfp.get_enum_type_dict() + xgl_helper.struct_dict = hfp.get_struct_dict() + xgl_helper.typedef_fwd_dict = hfp.get_typedef_fwd_dict() + xgl_helper.typedef_rev_dict = hfp.get_typedef_rev_dict() + xgl_helper.types_dict = hfp.get_types_dict() + subcmd = subcommands[sys.argv[1]](sys.argv[2:]) subcmd.run() |
