*.[ch]: Some preparatory reformatting for the Python 3 porting.
[pyke] / pyke-mLib.c
CommitLineData
c1756f78
MW
1/* -*-c-*-
2 *
3 * Pyke: the Python Kit for Extensions, mLib integration
4 *
5 * (c) 2019 Straylight/Edgeware
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of Pyke: the Python Kit for Extensions.
11 *
12 * Pyke is free software: you can redistribute it and/or modify it under
13 * the terms of the GNU General Public License as published by the Free
14 * Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * Pyke is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with Pyke. If not, write to the Free Software Foundation, Inc.,
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27/*----- Header files ------------------------------------------------------*/
28
29#include "pyke-mLib.h"
30
31/* #undef HAVE_LONG_LONG */
32
33/*----- Conversions -------------------------------------------------------*/
34
35#ifndef HAVE_LONG_LONG
36static PyObject *i32 = 0;
37static int init_i32(void)
38 { if (!i32 && (i32 = PyInt_FromLong(32)) == 0) return (-1); return (0); }
39#endif
40
41PyObject *getk64(kludge64 u)
42{
43#ifdef HAVE_LONG_LONG
44 return (PyLong_FromUnsignedLongLong(GET64(unsigned PY_LONG_LONG, u)));
45#else
46 PyObject *i = 0, *j = 0, *t;
47 PyObject *rc = 0;
48
49 if (init_i32()) goto end;
50 if ((i = PyLong_FromUnsignedLong(HI64(u))) == 0) goto end;
51 if ((t = PyNumber_InPlaceLshift(i, i32)) == 0) goto end;
52 Py_DECREF(i); i = t;
53 if ((j = PyLong_FromUnsignedLong(LO64(u))) == 0) goto end;
54 if ((t = PyNumber_InPlaceOr(i, j)) == 0) goto end;
55 Py_DECREF(i); i = t;
83a72c0d
MW
56 if ((t = PyNumber_Int(i)) == 0) goto end;
57 rc = t;
c1756f78
MW
58end:
59 Py_XDECREF(i);
60 Py_XDECREF(j);
61 return (rc);
62#endif
63}
64
65#ifdef HAVE_UINT64
66# define CONVu64(n) do { \
67 kludge64 k; \
68 uint64 t; \
69 if (!convk64(o, &k)) goto end; \
70 t = GET64(uint64, k); \
71 if (t > MASK##n) VALERR("out of range"); \
72 *p = t; \
73 } while (0)
74#else
75# define CONVu64(n) assert(!"shouldn't be possible")
76#endif
77
78#define CONVU_(n) \
79 int convu##n(PyObject *o, void *pp) \
80 { \
81 unsigned long u; \
82 uint##n *p = pp; \
83 \
84 if (MASK##n > ULONG_MAX) \
85 CONVu64(n); \
86 else { \
87 if (!convulong(o, &u)) goto end; \
88 if (u > MASK##n) VALERR("out of range"); \
89 *p = u; \
90 } \
91 return (1); \
92 end: \
93 return (0); \
94 }
95DOUINTSZ(CONVU_)
96
97int convk64(PyObject *o, void *pp)
98{
99 PyObject *i = 0;
100 int rc = 0;
101#if HAVE_LONG_LONG
102 unsigned PY_LONG_LONG t;
103#else
104 PyObject *t;
105 uint32 lo, hi;
106#endif
107
108#if HAVE_LONG_LONG
109 if ((i = PyNumber_Long(o)) == 0) goto end;
110 t = PyLong_AsUnsignedLongLong(i);
111 if (t == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) goto end;
112 ASSIGN64(*(kludge64 *)pp, t);
113#else
114 if (init_i32()) goto end;
115 if ((i = PyNumber_Int(o)) == 0) goto end;
116 lo = PyInt_AsUnsignedLongMask(i);
117 if ((t = PyNumber_InPlaceRshift(i, i32)) == 0) goto end;
118 Py_DECREF(i); i = t;
119 hi = PyInt_AsUnsignedLongMask(i);
120 if ((t = PyNumber_InPlaceRshift(i, i32)) == 0) goto end;
121 Py_DECREF(i); i = t;
122 if (PyObject_IsTrue(i)) VALERR("out of range");
123 SET64(*(kludge64 *)pp, hi, lo);
124#endif
125 rc = 1;
126
127end:
128 Py_XDECREF(i);
129 return (rc);
130}
131
132/*----- That's all, folks -------------------------------------------------*/