| 131 | } |
| 132 | |
| 133 | inline bool check_interface(rdcstr &log, swig_type_info **swig_types, size_t numTypes) |
| 134 | { |
| 135 | // track all errors and fatal error at the end, so we see all of the problems at once instead of |
| 136 | // requiring rebuilds over and over. |
| 137 | // This does mean that e.g. a duplicated docstring could be reported multiple times but that's not |
| 138 | // the end of the world. |
| 139 | bool errors_found = false; |
| 140 | |
| 141 | std::set<rdcstr> struct_docstrings; |
| 142 | for(size_t i = 0; i < numTypes; i++) |
| 143 | { |
| 144 | SwigPyClientData *typeinfo = (SwigPyClientData *)swig_types[i]->clientdata; |
| 145 | |
| 146 | // opaque types have no typeinfo, skip these |
| 147 | if(!typeinfo) |
| 148 | continue; |
| 149 | |
| 150 | PyTypeObject *typeobj = typeinfo->pytype; |
| 151 | |
| 152 | rdcstr typedoc = typeobj->tp_doc; |
| 153 | |
| 154 | auto result = struct_docstrings.insert(typedoc); |
| 155 | |
| 156 | if(!result.second) |
| 157 | { |
| 158 | snprintf(convert_error, sizeof(convert_error) - 1, |
| 159 | "Duplicate docstring '%s' found on struct '%s' - are you missing a DOCUMENT()?\n", |
| 160 | typedoc.c_str(), typeobj->tp_name); |
| 161 | log += convert_error; |
| 162 | errors_found = true; |
| 163 | } |
| 164 | |
| 165 | rdcstr typeName = typeobj->tp_name; |
| 166 | errors_found |= checkname(log, "renderdoc", typeName, NameType::Type, ""); |
| 167 | |
| 168 | PyObject *dict = typeobj->tp_dict; |
| 169 | |
| 170 | if(!dict && typeobj->tp_base) |
| 171 | dict = typeobj->tp_base->tp_dict; |
| 172 | |
| 173 | // check the object's dict to see if this is an enum (or struct with constants). |
| 174 | // We require ALL constants be documented in a docstring with data:: directives |
| 175 | if(dict && PyDict_Check(dict)) |
| 176 | { |
| 177 | PyObject *keys = PyDict_Keys(dict); |
| 178 | |
| 179 | if(keys) |
| 180 | { |
| 181 | std::set<rdcstr> constants; |
| 182 | |
| 183 | Py_ssize_t len = PyList_Size(keys); |
| 184 | for(Py_ssize_t i = 0; i < len; i++) |
| 185 | { |
| 186 | PyObject *key = PyList_GetItem(keys, i); |
| 187 | PyObject *value = PyDict_GetItem(dict, key); |
| 188 | |
| 189 | // if this key is a string (it should be) |
| 190 | if(PyUnicode_Check(key)) |