/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ //#define DEBUG typedef PyObject *(*format_lines_func)(PyObject *self, PyObject *args, PyObject *kwds); typedef enum RepresentationKindEnum { AsObject, AsString, AsTypeString, AsTypeEnum, AsLabeledString, AsEnum, AsEnumName, AsEnumDescription, AsIndex, AsDottedDecimal, } RepresentationKind; #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif #define NSS_THREAD_LOCAL_KEY "nss" #define PyBoolAsPRBool(x) ((x) == Py_True ? PR_TRUE : PR_FALSE) #define ASSIGN_REF(dst, obj) \ do { \ PyObject *tmp; \ \ tmp = (PyObject *)dst; \ Py_INCREF(obj); \ dst = obj; \ Py_CLEAR(tmp); \ } while (0) #define ASSIGN_NEW_REF(dst, obj) \ do { \ PyObject *tmp; \ \ tmp = (PyObject *)dst; \ dst = obj; \ Py_CLEAR(tmp); \ } while (0) /******************************************************************************/ #define OCTETS_PER_LINE_DEFAULT 16 #define HEX_SEPARATOR_DEFAULT ":" #define FMT_OBJ_AND_APPEND(dst_fmt_tuples, label, src_obj, level, fail) \ { \ PyObject *fmt_tuple = NULL; \ \ if ((fmt_tuple = line_fmt_tuple(level, label, src_obj)) == NULL) { \ goto fail; \ } \ if (PyList_Append(dst_fmt_tuples, fmt_tuple) != 0) { \ Py_DECREF(fmt_tuple); \ goto fail; \ } \ } #define FMT_LABEL_AND_APPEND(dst_fmt_tuples, label, level, fail) \ { \ PyObject *fmt_tuple = NULL; \ \ if ((fmt_tuple = fmt_label(level, label)) == NULL) { \ goto fail; \ } \ if (PyList_Append(dst_fmt_tuples, fmt_tuple) != 0) { \ Py_DECREF(fmt_tuple); \ goto fail; \ } \ } #define APPEND_LINE_TUPLES_AND_CLEAR(dst_fmt_tuples, src_fmt_tuples, fail) \ { \ PyObject *src_obj; \ Py_ssize_t len, i; \ if (src_fmt_tuples) { \ len = PyList_Size(src_fmt_tuples); \ for (i = 0; i < len; i++) { \ src_obj = PyList_GetItem(src_fmt_tuples, i); \ PyList_Append(dst_fmt_tuples, src_obj); \ } \ Py_CLEAR(src_fmt_tuples); \ } \ } #define APPEND_LINES_AND_CLEAR(dst_fmt_tuples, src_lines, level, fail) \ { \ PyObject *src_obj; \ Py_ssize_t len, i; \ if (src_lines) { \ len = PySequence_Size(src_lines); \ for (i = 0; i < len; i++) { \ src_obj = PySequence_GetItem(src_lines, i); \ FMT_OBJ_AND_APPEND(dst_fmt_tuples, NULL, src_obj, level, fail); \ Py_DECREF(src_obj); \ } \ Py_CLEAR(src_lines); \ } \ } #define CALL_FORMAT_LINES_AND_APPEND(dst_fmt_tuples, obj, level, fail) \ { \ PyObject *obj_line_fmt_tuples; \ \ if ((obj_line_fmt_tuples = \ PyObject_CallMethod(obj, "format_lines", \ "(i)", level)) == NULL) { \ goto fail; \ } \ \ APPEND_LINE_TUPLES_AND_CLEAR(dst_fmt_tuples, obj_line_fmt_tuples, fail); \ } #define APPEND_OBJ_TO_HEX_LINES_AND_CLEAR(dst_fmt_tuples, obj, level, fail) \ { \ PyObject *obj_lines; \ \ if ((obj_lines = obj_to_hex(obj, OCTETS_PER_LINE_DEFAULT, \ HEX_SEPARATOR_DEFAULT)) == NULL) { \ goto fail; \ } \ Py_CLEAR(obj); \ APPEND_LINES_AND_CLEAR(dst_fmt_tuples, obj_lines, level, fail); \ } #define FMT_SEC_INT_OBJ_APPEND_AND_CLEAR(dst_fmt_tuples, label, obj, level, fail) \ { \ PyObject *obj_lines = NULL; \ SecItem *item = (SecItem *)obj; \ \ FMT_LABEL_AND_APPEND(dst_fmt_tuples, label, level, fail); \ if ((obj_lines = secitem_integer_format_lines(&item->item, level+1)) == NULL) { \ goto fail; \ } \ Py_CLEAR(obj); \ APPEND_LINE_TUPLES_AND_CLEAR(dst_fmt_tuples, obj_lines, fail); \ } /******************************************************************************/ // Gettext #ifndef _ #define _(s) s #endif #if (PY_VERSION_HEX < 0x02050000) typedef int Py_ssize_t; #define PY_SSIZE_T_MAX INT_MAX #define PY_SSIZE_T_MIN INT_MIN #define PyInt_FromSsize_t PyInt_FromLong #define PyNumber_AsSsize_t(ob, exc) PyInt_AsLong(ob) #define PyIndex_Check(ob) PyInt_Check(ob) typedef Py_ssize_t (*readbufferproc)(PyObject *, Py_ssize_t, void **); typedef Py_ssize_t (*writebufferproc)(PyObject *, Py_ssize_t, void **); typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *); typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **); typedef Py_ssize_t (*lenfunc)(PyObject *); typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t); typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t); #endif #if (PY_VERSION_HEX < 0x02060000) #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) #define PyVarObject_HEAD_INIT(type, size) \ PyObject_HEAD_INIT(type) size, #define PyImport_ImportModuleNoBlock PyImport_ImportModule #define PyLong_FromSsize_t PyInt_FromLong #define Py_TPFLAGS_HAVE_NEWBUFFER 0 #endif #define PyNone_Check(x) ((x) == Py_None) #define CALL_BASE(type, func, ...) (type)->tp_base->tp_##func(__VA_ARGS__) #define TYPE_READY(type) \ { \ if (PyType_Ready(&type) < 0) \ return; \ Py_INCREF(&type); \ PyModule_AddObject(m, rindex(type.tp_name, '.')+1, (PyObject *)&type); \ } #define AddIntConstant(c) \ { \ PyObject *dict; \ \ \ if ((dict = PyModule_GetDict(m)) == NULL) { \ PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", \ PyModule_GetName(m)); \ return; \ } \ if (PyDict_GetItemString(dict, #c)) { \ PyErr_Format(PyExc_SystemError, "module '%s' already contains %s", \ PyModule_GetName(m), #c); \ return; \ } \ if (PyModule_AddIntConstant(m, #c, c) < 0) return; \ } #define AddIntConstantName(name, c) \ { \ PyObject *dict; \ \ \ if ((dict = PyModule_GetDict(m)) == NULL) { \ PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", \ PyModule_GetName(m)); \ return; \ } \ if (PyDict_GetItemString(dict, #c)) { \ PyErr_Format(PyExc_SystemError, "module '%s' already contains %s", \ PyModule_GetName(m), #c); \ return; \ } \ if (PyModule_AddIntConstant(m, #name, c) < 0) return; \ } #ifdef DEBUG #define DumpRefCount(x) \ { \ PyObject *_obj = (PyObject *) (x); \ printf("<%s object at %p refcnt=%d>\n", Py_TYPE(_obj)->tp_name, _obj, _obj->ob_refcnt); \ } #define TraceMessage(_msg) \ { \ printf("%s\n", _msg); \ } #define TraceMethodEnter(x) \ { \ PyObject *_obj = (PyObject *) (x); \ const char *name = NULL; \ \ if (_obj) { \ name = Py_TYPE(_obj)->tp_name; \ } \ printf("%s (Enter): <%s object at %p refcnt=%d>\n", \ __FUNCTION__, name, _obj, _obj ? _obj->ob_refcnt : -9999); \ } #define TraceMethodLeave(x) \ { \ PyObject *_obj = (PyObject *) (x); \ const char *name = NULL; \ \ if (_obj) { \ name = Py_TYPE(_obj)->tp_name; \ } \ printf("%s (Leave): <%s object at %p refcnt=%d>\n", \ __FUNCTION__, name, _obj, _obj ? _obj->ob_refcnt : -9999); \ } #define TraceObjNewEnter(_tp) \ { \ PyTypeObject *tp = _tp; \ if (tp != NULL) \ printf("%s (Enter) %s\n", __FUNCTION__, tp->tp_name); \ else \ printf("%s (Enter)\n", __FUNCTION__); \ } #define TraceObjNewLeave(x) \ { \ PyObject *_obj = (PyObject *) (x); \ const char *name = NULL; \ \ if (_obj) { \ name = Py_TYPE(_obj)->tp_name; \ } \ printf("%s: returns <%s object at %p refcnt=%d>\n", \ __FUNCTION__, name, _obj, _obj ? _obj->ob_refcnt : -9999); \ } #else #define DumpRefCount(_obj) #define TraceMessage(_msg) #define TraceMethodEnter(_obj) #define TraceMethodLeave(_obj) #define TraceObjNewEnter(_tp) #define TraceObjNewLeave(_obj) #endif