From 36d74b32b98a931cbf2c57750bf31e3ad0831bf3 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 11 Jun 2020 17:09:16 +0100 Subject: [PATCH] Add optional output file for qrenderdoc unit tests --- qrenderdoc/Code/pyrenderdoc/PythonContext.cpp | 10 +++--- qrenderdoc/Code/pyrenderdoc/PythonContext.h | 2 +- qrenderdoc/Code/pyrenderdoc/interface_check.h | 31 ++++++++++--------- qrenderdoc/Code/pyrenderdoc/qrenderdoc.i | 4 +-- qrenderdoc/Code/pyrenderdoc/renderdoc.i | 4 +-- qrenderdoc/Code/qrenderdoc.cpp | 27 ++++++++++++---- 6 files changed, 47 insertions(+), 31 deletions(-) diff --git a/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp b/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp index 8afa4845b..c8369ce24 100644 --- a/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp +++ b/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp @@ -69,8 +69,8 @@ PyTypeObject **SbkPySide2_QtWidgetsTypes = NULL; #include "version.h" // exported by generated files, used to check interface compliance -bool CheckCoreInterface(); -bool CheckQtInterface(); +bool CheckCoreInterface(rdcstr &log); +bool CheckQtInterface(rdcstr &log); // defined in SWIG-generated renderdoc_python.cpp extern "C" PyObject *PyInit_renderdoc(void); @@ -457,13 +457,13 @@ PythonContext::~PythonContext() outputTick(); } -bool PythonContext::CheckInterfaces() +bool PythonContext::CheckInterfaces(rdcstr &log) { bool errors = false; PyGILState_STATE gil = PyGILState_Ensure(); - errors |= CheckCoreInterface(); - errors |= CheckQtInterface(); + errors |= CheckCoreInterface(log); + errors |= CheckQtInterface(log); PyGILState_Release(gil); return errors; diff --git a/qrenderdoc/Code/pyrenderdoc/PythonContext.h b/qrenderdoc/Code/pyrenderdoc/PythonContext.h index 6f2e9001c..74417e2da 100644 --- a/qrenderdoc/Code/pyrenderdoc/PythonContext.h +++ b/qrenderdoc/Code/pyrenderdoc/PythonContext.h @@ -61,7 +61,7 @@ public: rdcarray> &args); static void FreePyArgs(rdcarray> &args); - bool CheckInterfaces(); + bool CheckInterfaces(rdcstr &log); QString versionString(); diff --git a/qrenderdoc/Code/pyrenderdoc/interface_check.h b/qrenderdoc/Code/pyrenderdoc/interface_check.h index 268e07382..c893c7c50 100644 --- a/qrenderdoc/Code/pyrenderdoc/interface_check.h +++ b/qrenderdoc/Code/pyrenderdoc/interface_check.h @@ -43,7 +43,7 @@ enum class NameType Member, }; -inline bool checkname(const char *baseType, rdcstr name, NameType nameType) +inline bool checkname(rdcstr &log, const char *baseType, rdcstr name, NameType nameType) { // skip __ prefixed names if(name.beginsWith("__")) @@ -106,9 +106,9 @@ inline bool checkname(const char *baseType, rdcstr name, NameType nameType) snprintf(convert_error, sizeof(convert_error) - 1, "Name of %s '%s.%s' does not match naming scheme.\n" - "Should start with %s letter and not contain underscores", + "Should start with %s letter and not contain underscores\n", nameTypeStr, baseType, name.c_str(), member ? "lowercase" : "uppercase"); - RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error); + log += convert_error; return true; } @@ -116,7 +116,7 @@ inline bool checkname(const char *baseType, rdcstr name, NameType nameType) return false; } -inline bool check_interface(swig_type_info **swig_types, size_t numTypes) +inline bool check_interface(rdcstr &log, swig_type_info **swig_types, size_t numTypes) { // track all errors and fatal error at the end, so we see all of the problems at once instead of // requiring rebuilds over and over. @@ -142,13 +142,13 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes) if(!result.second) { snprintf(convert_error, sizeof(convert_error) - 1, - "Duplicate docstring '%s' found on struct '%s' - are you missing a DOCUMENT()?", + "Duplicate docstring '%s' found on struct '%s' - are you missing a DOCUMENT()?\n", typedoc.c_str(), typeobj->tp_name); - RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error); + log += convert_error; errors_found = true; } - errors_found |= checkname("renderdoc", typeobj->tp_name, NameType::Type); + errors_found |= checkname(log, "renderdoc", typeobj->tp_name, NameType::Type); PyObject *dict = typeobj->tp_dict; @@ -179,8 +179,9 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes) if(str == NULL || len == 0) { snprintf(convert_error, sizeof(convert_error) - 1, - "Couldn't get member name for %i'th member of '%s'", (int)i, typeobj->tp_name); - RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error); + "Couldn't get member name for %i'th member of '%s'\n", (int)i, + typeobj->tp_name); + log += convert_error; errors_found = true; } else @@ -198,7 +199,7 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes) // if it's a callable it's a method, ignore it if(!PyCallable_Check(value) && !PyType_IsSubtype(value->ob_type, &PyStaticMethod_Type)) - errors_found |= checkname(typeobj->tp_name, name, nameType); + errors_found |= checkname(log, typeobj->tp_name, name, nameType); } Py_DecRef(bytes); @@ -241,9 +242,9 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes) if(documented.find(*it) == documented.end()) { snprintf(convert_error, sizeof(convert_error) - 1, - "'%s::%s' is not documented in class docstring", typeobj->tp_name, + "'%s::%s' is not documented in class docstring\n", typeobj->tp_name, it->c_str()); - RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error); + log += convert_error; errors_found = true; } } @@ -257,7 +258,7 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes) { rdcstr method_doc = method->ml_doc; - errors_found |= checkname(typeobj->tp_name, method->ml_name, NameType::Method); + errors_found |= checkname(log, typeobj->tp_name, method->ml_name, NameType::Method); int32_t i = 0; while(method_doc[i] == '\n') @@ -278,9 +279,9 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes) { snprintf( convert_error, sizeof(convert_error) - 1, - "Duplicate docstring '%s' found on method '%s.%s' - are you missing a DOCUMENT()?", + "Duplicate docstring '%s' found on method '%s.%s' - are you missing a DOCUMENT()?\n", method_doc.c_str(), typeobj->tp_name, method->ml_name); - RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error); + log += convert_error; errors_found = true; } } diff --git a/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i b/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i index f91a0197a..9bfcf2147 100644 --- a/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i +++ b/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i @@ -120,7 +120,7 @@ TEMPLATE_ARRAY_INSTANTIATE_PTR(rdcarray, ICaptureViewer) static swig_type_info **interfaceCheckTypes; static size_t interfaceCheckNumTypes = 0; - bool CheckQtInterface() + bool CheckQtInterface(rdcstr &log) { #if defined(RELEASE) return false; @@ -128,7 +128,7 @@ TEMPLATE_ARRAY_INSTANTIATE_PTR(rdcarray, ICaptureViewer) if(interfaceCheckNumTypes == 0) return false; - return check_interface(interfaceCheckTypes, interfaceCheckNumTypes); + return check_interface(log, interfaceCheckTypes, interfaceCheckNumTypes); #endif } %} diff --git a/qrenderdoc/Code/pyrenderdoc/renderdoc.i b/qrenderdoc/Code/pyrenderdoc/renderdoc.i index e81312485..020992ee1 100644 --- a/qrenderdoc/Code/pyrenderdoc/renderdoc.i +++ b/qrenderdoc/Code/pyrenderdoc/renderdoc.i @@ -489,7 +489,7 @@ extern "C" PyObject *RENDERDOC_DumpObject(PyObject *obj) static swig_type_info **interfaceCheckTypes; static size_t interfaceCheckNumTypes = 0; - bool CheckCoreInterface() + bool CheckCoreInterface(rdcstr &log) { #if defined(RELEASE) return false; @@ -497,7 +497,7 @@ extern "C" PyObject *RENDERDOC_DumpObject(PyObject *obj) if(interfaceCheckNumTypes == 0) return false; - return check_interface(interfaceCheckTypes, interfaceCheckNumTypes); + return check_interface(log, interfaceCheckTypes, interfaceCheckNumTypes); #endif } %} diff --git a/qrenderdoc/Code/qrenderdoc.cpp b/qrenderdoc/Code/qrenderdoc.cpp index 87375a86e..8249b6a7e 100644 --- a/qrenderdoc/Code/qrenderdoc.cpp +++ b/qrenderdoc/Code/qrenderdoc.cpp @@ -22,6 +22,7 @@ * THE SOFTWARE. ******************************************************************************/ +#include #include #include #include @@ -104,21 +105,35 @@ int main(int argc, char *argv[]) bool errors = false; - qInfo() << "Checking python binding consistency."; + FILE *logOut = NULL; + + if(argc >= 3) + logOut = fopen(argv[2], "w"); + + if(logOut == NULL) + logOut = stdout; + + fputs("Checking python binding consistency.\n", logOut); + + rdcstr errorLog; { PythonContextHandle py; - errors = py.ctx().CheckInterfaces(); + errors = py.ctx().CheckInterfaces(errorLog); } if(errors) { - qCritical() << "Found errors in python bindings. Please fix!"; + RENDERDOC_LogMessage(LogType::Error, "EXTN", __FILE__, __LINE__, errorLog.c_str()); + fputs("Found errors in python bindings. Please fix!\n", logOut); + fputs(errorLog.c_str(), logOut); return 1; } - - qInfo() << "Python bindings are consistent."; - return 0; + else + { + fputs("Python bindings are consistent.\n", logOut); + return 0; + } } #endif