1c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* ------------------------------------------------------------------------ 2c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 3c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Python Codec Registry and support functions 4c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 5c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielWritten by Marc-Andre Lemburg (mal@lemburg.com). 6c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 7c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielCopyright (c) Corporation for National Research Initiatives. 8c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 9c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ------------------------------------------------------------------------ */ 10c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 11c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#include "Python.h" 12c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#include <ctype.h> 13c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 14c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* --- Codec Registry ----------------------------------------------------- */ 15c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 16c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Import the standard encodings package which will register the first 17c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel codec search function. 18c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 19c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel This is done in a lazy way so that the Unicode implementation does 20c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel not downgrade startup time of scripts not needing it. 21c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 22c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ImportErrors are silently ignored by this function. Only one try is 23c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel made. 24c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 25c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 26c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 27c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int _PyCodecRegistry_Init(void); /* Forward */ 28c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 29c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielint PyCodec_Register(PyObject *search_function) 30c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 31c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyInterpreterState *interp = PyThreadState_GET()->interp; 32c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) 33c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 34c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (search_function == NULL) { 35c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_BadArgument(); 36c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 37c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 38c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!PyCallable_Check(search_function)) { 39c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_TypeError, "argument must be callable"); 40c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 41c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 42c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyList_Append(interp->codec_search_path, search_function); 43c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 44c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel onError: 45c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 46c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 47c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 48c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Convert a string to a normalized Python string: all characters are 49c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel converted to lower case, spaces are replaced with underscores. */ 50c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 51c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic 52c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *normalizestring(const char *string) 53c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 54c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel register size_t i; 55c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel size_t len = strlen(string); 56c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel char *p; 57c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *v; 58c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 59c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (len > PY_SSIZE_T_MAX) { 60c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_OverflowError, "string is too large"); 61c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 62c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 63c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 64c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel v = PyString_FromStringAndSize(NULL, len); 65c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (v == NULL) 66c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 67c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel p = PyString_AS_STRING(v); 68c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < len; i++) { 69c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel register char ch = string[i]; 70c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ch == ' ') 71c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ch = '-'; 72c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 73c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ch = Py_TOLOWER(Py_CHARMASK(ch)); 74c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel p[i] = ch; 75c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 76c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return v; 77c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 78c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 79c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Lookup the given encoding and return a tuple providing the codec 80c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel facilities. 81c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 82c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel The encoding string is looked up converted to all lower-case 83c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel characters. This makes encodings looked up through this mechanism 84c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel effectively case-insensitive. 85c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 86c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel If no codec is found, a LookupError is set and NULL returned. 87c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 88c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel As side effect, this tries to load the encodings package, if not 89c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel yet done. This is part of the lazy load strategy for the encodings 90c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel package. 91c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 92c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel*/ 93c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 94c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *_PyCodec_Lookup(const char *encoding) 95c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 96c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyInterpreterState *interp; 97c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *result, *args = NULL, *v; 98c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t i, len; 99c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 100c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (encoding == NULL) { 101c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_BadArgument(); 102c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 103c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 104c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 105c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel interp = PyThreadState_GET()->interp; 106c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) 107c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 108c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 109c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Convert the encoding to a normalized Python string: all 110c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel characters are converted to lower case, spaces and hyphens are 111c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel replaced with underscores. */ 112c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel v = normalizestring(encoding); 113c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (v == NULL) 114c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 115c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_InternInPlace(&v); 116c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 117c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* First, try to lookup the name in the registry dictionary */ 118c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel result = PyDict_GetItem(interp->codec_search_cache, v); 119c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (result != NULL) { 120c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_INCREF(result); 121c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(v); 122c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return result; 123c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 124c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 125c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Next, scan the search functions in order of registration */ 126c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel args = PyTuple_New(1); 127c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (args == NULL) 128c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 129c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyTuple_SET_ITEM(args,0,v); 130c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 131c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel len = PyList_Size(interp->codec_search_path); 132c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (len < 0) 133c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 134c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (len == 0) { 135c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_LookupError, 136c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "no codec search functions registered: " 137c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "can't find encoding"); 138c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 139c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 140c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 141c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < len; i++) { 142c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *func; 143c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 144c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel func = PyList_GetItem(interp->codec_search_path, i); 145c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (func == NULL) 146c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 147c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel result = PyEval_CallObject(func, args); 148c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (result == NULL) 149c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 150c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (result == Py_None) { 151c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(result); 152c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel continue; 153c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 154c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 4) { 155c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_TypeError, 156c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "codec search functions must return 4-tuples"); 157c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(result); 158c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 159c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 160c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel break; 161c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 162c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (i == len) { 163c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* XXX Perhaps we should cache misses too ? */ 164c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_Format(PyExc_LookupError, 165c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "unknown encoding: %s", encoding); 166c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 167c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 168c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 169c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Cache and return the result */ 170c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyDict_SetItem(interp->codec_search_cache, v, result); 171c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(args); 172c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return result; 173c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 174c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel onError: 175c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(args); 176c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 177c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 178c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 179c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic 180c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *args_tuple(PyObject *object, 181c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *errors) 182c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 183c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *args; 184c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 185c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel args = PyTuple_New(1 + (errors != NULL)); 186c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (args == NULL) 187c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 188c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_INCREF(object); 189c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyTuple_SET_ITEM(args,0,object); 190c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (errors) { 191c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *v; 192c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 193c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel v = PyString_FromString(errors); 194c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (v == NULL) { 195c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(args); 196c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 197c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 198c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyTuple_SET_ITEM(args, 1, v); 199c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 200c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return args; 201c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 202c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 203c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Helper function to get a codec item */ 204c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 205c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic 206c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *codec_getitem(const char *encoding, int index) 207c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 208c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *codecs; 209c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *v; 210c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 211c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel codecs = _PyCodec_Lookup(encoding); 212c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (codecs == NULL) 213c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 214c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel v = PyTuple_GET_ITEM(codecs, index); 215c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(codecs); 216c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_INCREF(v); 217c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return v; 218c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 219c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 220c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Helper function to create an incremental codec. */ 221c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 222c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic 223c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *codec_getincrementalcodec(const char *encoding, 224c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *errors, 225c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *attrname) 226c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 227c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *codecs, *ret, *inccodec; 228c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 229c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel codecs = _PyCodec_Lookup(encoding); 230c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (codecs == NULL) 231c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 232c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel inccodec = PyObject_GetAttrString(codecs, attrname); 233c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(codecs); 234c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (inccodec == NULL) 235c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 236c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (errors) 237c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ret = PyObject_CallFunction(inccodec, "s", errors); 238c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 239c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ret = PyObject_CallFunction(inccodec, NULL); 240c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(inccodec); 241c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return ret; 242c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 243c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 244c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Helper function to create a stream codec. */ 245c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 246c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic 247c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *codec_getstreamcodec(const char *encoding, 248c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *stream, 249c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *errors, 250c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const int index) 251c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 252c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *codecs, *streamcodec, *codeccls; 253c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 254c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel codecs = _PyCodec_Lookup(encoding); 255c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (codecs == NULL) 256c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 257c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 258c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel codeccls = PyTuple_GET_ITEM(codecs, index); 259c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (errors != NULL) 260c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel streamcodec = PyObject_CallFunction(codeccls, "Os", stream, errors); 261c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 262c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel streamcodec = PyObject_CallFunction(codeccls, "O", stream); 263c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(codecs); 264c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return streamcodec; 265c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 266c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 267c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Convenience APIs to query the Codec registry. 268c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 269c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel All APIs return a codec object with incremented refcount. 270c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 271c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel */ 272c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 273c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *PyCodec_Encoder(const char *encoding) 274c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 275c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return codec_getitem(encoding, 0); 276c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 277c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 278c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *PyCodec_Decoder(const char *encoding) 279c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 280c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return codec_getitem(encoding, 1); 281c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 282c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 283c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *PyCodec_IncrementalEncoder(const char *encoding, 284c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *errors) 285c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 286c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return codec_getincrementalcodec(encoding, errors, "incrementalencoder"); 287c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 288c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 289c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *PyCodec_IncrementalDecoder(const char *encoding, 290c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *errors) 291c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 292c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return codec_getincrementalcodec(encoding, errors, "incrementaldecoder"); 293c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 294c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 295c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *PyCodec_StreamReader(const char *encoding, 296c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *stream, 297c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *errors) 298c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 299c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return codec_getstreamcodec(encoding, stream, errors, 2); 300c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 301c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 302c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *PyCodec_StreamWriter(const char *encoding, 303c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *stream, 304c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *errors) 305c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 306c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return codec_getstreamcodec(encoding, stream, errors, 3); 307c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 308c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 309c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Encode an object (e.g. an Unicode object) using the given encoding 310c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel and return the resulting encoded object (usually a Python string). 311c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 312c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel errors is passed to the encoder factory as argument if non-NULL. */ 313c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 314c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *PyCodec_Encode(PyObject *object, 315c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *encoding, 316c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *errors) 317c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 318c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *encoder = NULL; 319c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *args = NULL, *result = NULL; 320c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *v; 321c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 322c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel encoder = PyCodec_Encoder(encoding); 323c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (encoder == NULL) 324c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 325c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 326c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel args = args_tuple(object, errors); 327c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (args == NULL) 328c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 329c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 330c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel result = PyEval_CallObject(encoder,args); 331c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (result == NULL) 332c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 333c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 334c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!PyTuple_Check(result) || 335c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyTuple_GET_SIZE(result) != 2) { 336c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_TypeError, 337c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "encoder must return a tuple (object,integer)"); 338c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 339c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 340c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel v = PyTuple_GET_ITEM(result,0); 341c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_INCREF(v); 342c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* We don't check or use the second (integer) entry. */ 343c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 344c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(args); 345c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(encoder); 346c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(result); 347c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return v; 348c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 349c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel onError: 350c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(result); 351c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(args); 352c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(encoder); 353c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 354c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 355c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 356c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Decode an object (usually a Python string) using the given encoding 357c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel and return an equivalent object (e.g. an Unicode object). 358c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 359c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel errors is passed to the decoder factory as argument if non-NULL. */ 360c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 361c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *PyCodec_Decode(PyObject *object, 362c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *encoding, 363c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel const char *errors) 364c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 365c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *decoder = NULL; 366c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *args = NULL, *result = NULL; 367c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *v; 368c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 369c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel decoder = PyCodec_Decoder(encoding); 370c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (decoder == NULL) 371c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 372c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 373c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel args = args_tuple(object, errors); 374c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (args == NULL) 375c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 376c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 377c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel result = PyEval_CallObject(decoder,args); 378c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (result == NULL) 379c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 380c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!PyTuple_Check(result) || 381c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyTuple_GET_SIZE(result) != 2) { 382c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_TypeError, 383c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "decoder must return a tuple (object,integer)"); 384c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel goto onError; 385c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 386c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel v = PyTuple_GET_ITEM(result,0); 387c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_INCREF(v); 388c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* We don't check or use the second (integer) entry. */ 389c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 390c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(args); 391c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(decoder); 392c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(result); 393c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return v; 394c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 395c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel onError: 396c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(args); 397c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(decoder); 398c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_XDECREF(result); 399c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 400c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 401c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 402c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Register the error handling callback function error under the name 403c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel name. This function will be called by the codec when it encounters 404c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel an unencodable characters/undecodable bytes and doesn't know the 405c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel callback name, when name is specified as the error parameter 406c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel in the call to the encode/decode function. 407c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Return 0 on success, -1 on error */ 408c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielint PyCodec_RegisterError(const char *name, PyObject *error) 409c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 410c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyInterpreterState *interp = PyThreadState_GET()->interp; 411c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) 412c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 413c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!PyCallable_Check(error)) { 414c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_TypeError, "handler must be callable"); 415c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 416c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 417c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyDict_SetItemString(interp->codec_error_registry, 418c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel (char *)name, error); 419c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 420c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 421c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel/* Lookup the error handling callback function registered under the 422c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel name error. As a special case NULL can be passed, in which case 423c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel the error handling callback for strict encoding will be returned. */ 424c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *PyCodec_LookupError(const char *name) 425c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 426c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *handler = NULL; 427c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 428c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyInterpreterState *interp = PyThreadState_GET()->interp; 429c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) 430c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 431c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 432c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (name==NULL) 433c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel name = "strict"; 434c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel handler = PyDict_GetItemString(interp->codec_error_registry, (char *)name); 435c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!handler) 436c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name); 437c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 438c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_INCREF(handler); 439c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return handler; 440c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 441c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 442c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic void wrong_exception_type(PyObject *exc) 443c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 444c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *type = PyObject_GetAttrString(exc, "__class__"); 445c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (type != NULL) { 446c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *name = PyObject_GetAttrString(type, "__name__"); 447c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(type); 448c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (name != NULL) { 449c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *string = PyObject_Str(name); 450c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(name); 451c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (string != NULL) { 452c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_Format(PyExc_TypeError, 453c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "don't know how to handle %.400s in error callback", 454c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyString_AS_STRING(string)); 455c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(string); 456c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 457c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 458c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 459c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 460c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 461c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *PyCodec_StrictErrors(PyObject *exc) 462c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 463c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyExceptionInstance_Check(exc)) 464c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetObject(PyExceptionInstance_Class(exc), exc); 465c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 466c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_SetString(PyExc_TypeError, "codec must pass exception instance"); 467c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 468c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 469c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 470c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 471c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#ifdef Py_USING_UNICODE 472c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *PyCodec_IgnoreErrors(PyObject *exc) 473c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 474c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t end; 475c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { 476c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyUnicodeEncodeError_GetEnd(exc, &end)) 477c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 478c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 479c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { 480c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyUnicodeDecodeError_GetEnd(exc, &end)) 481c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 482c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 483c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) { 484c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyUnicodeTranslateError_GetEnd(exc, &end)) 485c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 486c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 487c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 488c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel wrong_exception_type(exc); 489c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 490c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 491c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* ouch: passing NULL, 0, pos gives None instead of u'' */ 492c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return Py_BuildValue("(u#n)", &end, 0, end); 493c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 494c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 495c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 496c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *PyCodec_ReplaceErrors(PyObject *exc) 497c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 498c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *restuple; 499c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t start; 500c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t end; 501c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t i; 502c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 503c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { 504c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *res; 505c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_UNICODE *p; 506c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyUnicodeEncodeError_GetStart(exc, &start)) 507c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 508c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyUnicodeEncodeError_GetEnd(exc, &end)) 509c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 510c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel res = PyUnicode_FromUnicode(NULL, end-start); 511c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (res == NULL) 512c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 513c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (p = PyUnicode_AS_UNICODE(res), i = start; 514c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i<end; ++p, ++i) 515c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *p = '?'; 516c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel restuple = Py_BuildValue("(On)", res, end); 517c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(res); 518c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return restuple; 519c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 520c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { 521c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_UNICODE res = Py_UNICODE_REPLACEMENT_CHARACTER; 522c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyUnicodeDecodeError_GetEnd(exc, &end)) 523c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 524c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return Py_BuildValue("(u#n)", &res, (Py_ssize_t)1, end); 525c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 526c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) { 527c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *res; 528c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_UNICODE *p; 529c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyUnicodeTranslateError_GetStart(exc, &start)) 530c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 531c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyUnicodeTranslateError_GetEnd(exc, &end)) 532c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 533c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel res = PyUnicode_FromUnicode(NULL, end-start); 534c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (res == NULL) 535c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 536c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (p = PyUnicode_AS_UNICODE(res), i = start; 537c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel i<end; ++p, ++i) 538c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *p = Py_UNICODE_REPLACEMENT_CHARACTER; 539c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel restuple = Py_BuildValue("(On)", res, end); 540c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(res); 541c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return restuple; 542c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 543c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 544c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel wrong_exception_type(exc); 545c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 546c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 547c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 548c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 549c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) 550c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 551c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { 552c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *restuple; 553c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *object; 554c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t start; 555c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t end; 556c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *res; 557c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_UNICODE *p; 558c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_UNICODE *startp; 559c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_UNICODE *e; 560c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_UNICODE *outp; 561c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t ressize; 562c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyUnicodeEncodeError_GetStart(exc, &start)) 563c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 564c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyUnicodeEncodeError_GetEnd(exc, &end)) 565c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 566c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!(object = PyUnicodeEncodeError_GetObject(exc))) 567c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 568c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel startp = PyUnicode_AS_UNICODE(object); 569c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (end - start > PY_SSIZE_T_MAX / (2+7+1)) { 570c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel end = start + PY_SSIZE_T_MAX / (2+7+1); 571c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#ifndef Py_UNICODE_WIDE 572c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (0xD800 <= startp[end - 1] && startp[end - 1] <= 0xDBFF) 573c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel end--; 574c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#endif 575c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 576c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel e = startp + end; 577c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (p = startp+start, ressize = 0; p < e;) { 578c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_UCS4 ch = *p++; 579c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#ifndef Py_UNICODE_WIDE 580c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if ((0xD800 <= ch && ch <= 0xDBFF) && 581c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel (p < e) && 582c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel (0xDC00 <= *p && *p <= 0xDFFF)) { 583c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ch = ((((ch & 0x03FF) << 10) | 584c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ((Py_UCS4)*p++ & 0x03FF)) + 0x10000); 585c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 586c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#endif 587c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ch < 10) 588c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ressize += 2+1+1; 589c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (ch < 100) 590c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ressize += 2+2+1; 591c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (ch < 1000) 592c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ressize += 2+3+1; 593c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (ch < 10000) 594c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ressize += 2+4+1; 595c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (ch < 100000) 596c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ressize += 2+5+1; 597c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (ch < 1000000) 598c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ressize += 2+6+1; 599c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 600c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ressize += 2+7+1; 601c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 602c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* allocate replacement */ 603c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel res = PyUnicode_FromUnicode(NULL, ressize); 604c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (res == NULL) { 605c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(object); 606c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 607c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 608c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* generate replacement */ 609c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (p = startp+start, outp = PyUnicode_AS_UNICODE(res); p < e;) { 610c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int digits; 611c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int base; 612c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_UCS4 ch = *p++; 613c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#ifndef Py_UNICODE_WIDE 614c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if ((0xD800 <= ch && ch <= 0xDBFF) && 615c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel (p < startp+end) && 616c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel (0xDC00 <= *p && *p <= 0xDFFF)) { 617c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ch = ((((ch & 0x03FF) << 10) | 618c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ((Py_UCS4)*p++ & 0x03FF)) + 0x10000); 619c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 620c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#endif 621c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = '&'; 622c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = '#'; 623c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (ch < 10) { 624c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel digits = 1; 625c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel base = 1; 626c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 627c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (ch < 100) { 628c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel digits = 2; 629c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel base = 10; 630c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 631c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (ch < 1000) { 632c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel digits = 3; 633c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel base = 100; 634c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 635c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (ch < 10000) { 636c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel digits = 4; 637c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel base = 1000; 638c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 639c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (ch < 100000) { 640c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel digits = 5; 641c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel base = 10000; 642c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 643c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else if (ch < 1000000) { 644c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel digits = 6; 645c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel base = 100000; 646c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 647c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 648c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel digits = 7; 649c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel base = 1000000; 650c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 651c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel while (digits-->0) { 652c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = '0' + ch/base; 653c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ch %= base; 654c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel base /= 10; 655c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 656c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = ';'; 657c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 658c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel restuple = Py_BuildValue("(On)", res, end); 659c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(res); 660c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(object); 661c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return restuple; 662c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 663c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 664c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel wrong_exception_type(exc); 665c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 666c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 667c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 668c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 669c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic Py_UNICODE hexdigits[] = { 670c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel '0', '1', '2', '3', '4', '5', '6', '7', 671c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 672c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel}; 673c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 674c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielPyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) 675c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 676c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { 677c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *restuple; 678c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *object; 679c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t start; 680c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t end; 681c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *res; 682c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_UNICODE *p; 683c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_UNICODE *startp; 684c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_UNICODE *outp; 685c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_ssize_t ressize; 686c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyUnicodeEncodeError_GetStart(exc, &start)) 687c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 688c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyUnicodeEncodeError_GetEnd(exc, &end)) 689c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 690c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!(object = PyUnicodeEncodeError_GetObject(exc))) 691c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 692c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (end - start > PY_SSIZE_T_MAX / (1+1+8)) 693c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel end = start + PY_SSIZE_T_MAX / (1+1+8); 694c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel startp = PyUnicode_AS_UNICODE(object); 695c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (p = startp+start, ressize = 0; p < startp+end; ++p) { 696c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#ifdef Py_UNICODE_WIDE 697c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (*p >= 0x00010000) 698c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ressize += 1+1+8; 699c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 700c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#endif 701c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (*p >= 0x100) { 702c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ressize += 1+1+4; 703c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 704c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 705c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ressize += 1+1+2; 706c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 707c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel res = PyUnicode_FromUnicode(NULL, ressize); 708c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (res == NULL) { 709c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(object); 710c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 711c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 712c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (p = startp+start, outp = PyUnicode_AS_UNICODE(res); 713c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel p < startp+end; ++p) { 714c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_UNICODE c = *p; 715c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = '\\'; 716c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#ifdef Py_UNICODE_WIDE 717c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c >= 0x00010000) { 718c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = 'U'; 719c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = hexdigits[(c>>28)&0xf]; 720c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = hexdigits[(c>>24)&0xf]; 721c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = hexdigits[(c>>20)&0xf]; 722c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = hexdigits[(c>>16)&0xf]; 723c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = hexdigits[(c>>12)&0xf]; 724c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = hexdigits[(c>>8)&0xf]; 725c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 726c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 727c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#endif 728c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (c >= 0x100) { 729c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = 'u'; 730c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = hexdigits[(c>>12)&0xf]; 731c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = hexdigits[(c>>8)&0xf]; 732c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 733c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else 734c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = 'x'; 735c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = hexdigits[(c>>4)&0xf]; 736c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel *outp++ = hexdigits[c&0xf]; 737c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 738c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 739c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel restuple = Py_BuildValue("(On)", res, end); 740c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(res); 741c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(object); 742c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return restuple; 743c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 744c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel else { 745c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel wrong_exception_type(exc); 746c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return NULL; 747c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 748c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 749c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#endif 750c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 751c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic PyObject *strict_errors(PyObject *self, PyObject *exc) 752c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 753c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCodec_StrictErrors(exc); 754c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 755c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 756c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 757c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#ifdef Py_USING_UNICODE 758c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic PyObject *ignore_errors(PyObject *self, PyObject *exc) 759c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 760c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCodec_IgnoreErrors(exc); 761c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 762c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 763c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 764c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic PyObject *replace_errors(PyObject *self, PyObject *exc) 765c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 766c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCodec_ReplaceErrors(exc); 767c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 768c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 769c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 770c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic PyObject *xmlcharrefreplace_errors(PyObject *self, PyObject *exc) 771c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 772c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCodec_XMLCharRefReplaceErrors(exc); 773c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 774c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 775c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 776c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic PyObject *backslashreplace_errors(PyObject *self, PyObject *exc) 777c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 778c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return PyCodec_BackslashReplaceErrors(exc); 779c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 780c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#endif 781c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 782c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDanielstatic int _PyCodecRegistry_Init(void) 783c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel{ 784c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel static struct { 785c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel char *name; 786c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyMethodDef def; 787c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } methods[] = 788c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel { 789c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel { 790c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "strict", 791c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel { 792c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "strict_errors", 793c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel strict_errors, 794c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel METH_O, 795c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyDoc_STR("Implements the 'strict' error handling, which " 796c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "raises a UnicodeError on coding errors.") 797c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 798c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel }, 799c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#ifdef Py_USING_UNICODE 800c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel { 801c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "ignore", 802c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel { 803c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "ignore_errors", 804c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel ignore_errors, 805c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel METH_O, 806c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyDoc_STR("Implements the 'ignore' error handling, which " 807c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "ignores malformed data and continues.") 808c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 809c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel }, 810c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel { 811c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "replace", 812c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel { 813c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "replace_errors", 814c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel replace_errors, 815c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel METH_O, 816c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyDoc_STR("Implements the 'replace' error handling, which " 817c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "replaces malformed data with a replacement marker.") 818c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 819c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel }, 820c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel { 821c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "xmlcharrefreplace", 822c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel { 823c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "xmlcharrefreplace_errors", 824c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel xmlcharrefreplace_errors, 825c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel METH_O, 826c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyDoc_STR("Implements the 'xmlcharrefreplace' error handling, " 827c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "which replaces an unencodable character with the " 828c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "appropriate XML character reference.") 829c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 830c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel }, 831c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel { 832c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "backslashreplace", 833c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel { 834c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "backslashreplace_errors", 835c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel backslashreplace_errors, 836c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel METH_O, 837c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyDoc_STR("Implements the 'backslashreplace' error handling, " 838c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "which replaces an unencodable character with a " 839c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel "backslashed escape sequence.") 840c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 841c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 842c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel#endif 843c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel }; 844c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 845c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyInterpreterState *interp = PyThreadState_GET()->interp; 846c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *mod; 847c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel unsigned i; 848c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 849c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (interp->codec_search_path != NULL) 850c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 851c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 852c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel interp->codec_search_path = PyList_New(0); 853c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel interp->codec_search_cache = PyDict_New(); 854c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel interp->codec_error_registry = PyDict_New(); 855c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 856c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (interp->codec_error_registry) { 857c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel for (i = 0; i < sizeof(methods)/sizeof(methods[0]); ++i) { 858c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyObject *func = PyCFunction_New(&methods[i].def, NULL); 859c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel int res; 860c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (!func) 861c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_FatalError("can't initialize codec error registry"); 862c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel res = PyCodec_RegisterError(methods[i].name, func); 863c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(func); 864c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (res) 865c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_FatalError("can't initialize codec error registry"); 866c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 867c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 868c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 869c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (interp->codec_search_path == NULL || 870c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel interp->codec_search_cache == NULL || 871c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel interp->codec_error_registry == NULL) 872c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_FatalError("can't initialize codec registry"); 873c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel 874c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel mod = PyImport_ImportModuleLevel("encodings", NULL, NULL, NULL, 0); 875c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (mod == NULL) { 876c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel if (PyErr_ExceptionMatches(PyExc_ImportError)) { 877c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel /* Ignore ImportErrors... this is done so that 878c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel distributions can disable the encodings package. Note 879c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel that other errors are not masked, e.g. SystemErrors 880c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel raised to inform the user of an error in the Python 881c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel configuration are still reported back to the user. */ 882c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel PyErr_Clear(); 883c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 884c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 885c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return -1; 886c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel } 887c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel Py_DECREF(mod); 888c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel return 0; 889c8042e10763bca064df257547d04ae3dfcdfaf91Daryl McDaniel} 890