/*
   Unix SMB/CIFS implementation.
   Python 2/3 compatibility layer

   Copyright (C) Petr Viktorin 2015

     ** NOTE! The following LGPL license applies to the talloc
     ** library. This does NOT imply that all of Samba is released
     ** under the LGPL

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 3 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _PY3COMPAT_H_
#define _PY3COMPAT_H_
#include <Python.h>

#if PY_MAJOR_VERSION >= 3

/***** Python 3 *****/

#define IS_PY3 1

/* Strings */

#define PyStr_FromString PyUnicode_FromString
#define PyStr_AsString PyUnicode_AsUTF8
#define PyStr_FromFormat PyUnicode_FromFormat
#define PyStr_FromStringAndSize PyUnicode_FromStringAndSize
#define PyStr_FromFormatV PyUnicode_FromFormatV
#define PyStr_Check PyUnicode_Check
#define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize

/* Ints */

#define PyInt_FromLong PyLong_FromLong
#define PyInt_AsLong PyLong_AsLong
#define PyInt_Check PyLong_Check

/* Module init */

#define MODULE_INIT_FUNC(name) \
	PyMODINIT_FUNC PyInit_ ## name(void); \
	PyMODINIT_FUNC PyInit_ ## name(void)

/* Types */

#define Py_TPFLAGS_HAVE_WEAKREFS 0
#define Py_TPFLAGS_HAVE_ITER 0

#else

/***** Python 2 *****/

#define IS_PY3 0

/* Strings */

#define PyStr_FromString PyString_FromString
#define PyStr_AsString PyString_AsString
#define PyStr_FromFormat PyString_FromFormat
#define PyStr_FromStringAndSize PyString_FromStringAndSize
#define PyStr_FromFormatV PyString_FromFormatV
#define PyStr_Check PyString_Check

#define PyStr_AsUTF8AndSize(pystr, sizeptr) \
	((*sizeptr=PyString_Size(pystr)), PyString_AsString(pystr))

#define PyBytes_FromStringAndSize PyString_FromStringAndSize
#define PyBytes_FromString PyString_FromString
#define PyBytes_Size PyString_Size

/* Module init */

#define PyModuleDef_HEAD_INIT 0

typedef struct PyModuleDef {
	int m_base;
	const char* m_name;
	const char* m_doc;
	Py_ssize_t m_size;
	PyMethodDef *m_methods;
} PyModuleDef;

#define PyModule_Create(def) \
	Py_InitModule3((def)->m_name, (def)->m_methods, (def)->m_doc)

#define MODULE_INIT_FUNC(name) \
	static PyObject *PyInit_ ## name(void); \
	void init ## name(void); \
	void init ## name(void) { PyInit_ ## name(); } \
	static PyObject *PyInit_ ## name(void)


#endif

/***** Common *****/

/* Rich comparisons */

#ifndef Py_RETURN_NOTIMPLEMENTED
#define Py_RETURN_NOTIMPLEMENTED \
    return Py_INCREF(Py_NotImplemented), Py_NotImplemented
#endif

#define PY_RICHCMP(val1, val2, op) \
	((op) == Py_EQ) ? PyBool_FromLong((val1) == (val2)) : \
	((op) == Py_NE) ? PyBool_FromLong((val1) != (val2)) : \
	((op) == Py_LT) ? PyBool_FromLong((val1) < (val2)) : \
	((op) == Py_GT) ? PyBool_FromLong((val1) > (val2)) : \
	((op) == Py_LE) ? PyBool_FromLong((val1) <= (val2)) : \
	((op) == Py_GE) ? PyBool_FromLong((val1) >= (val2)) : \
	(Py_INCREF(Py_NotImplemented), Py_NotImplemented)

#endif // _PY3COMPAT_H_