The various `KERR_...' constants and `PGEN_ABORT' are canonically
negative integers, but weren't published correctly. Add a flags word to
`struct nameval' to identify constants which should really be signed,
and some fancy footwork to convert unsigned integers back to negative
values without upsetting C. Adjust the `C' macro to spot negative
constants and mark them specially.
Not all is well. In particular, the `KEXP_...' constants should /not/
be published as signed values, even if `time_t' is signed on the target
platform, because the Python bindings handle them exclusively as
`unsigned long' values. To make this work, also introduce `CF' which
allows us to set the flags explicitly, and use it for `KEXP_...'.
-struct nameval { const char *name; unsigned long value; };
+struct nameval { const char *name; unsigned f; unsigned long value; };
+#define CF_SIGNED 1u
extern void setconstants(PyObject *, const struct nameval *);
extern PyObject *mexp_common(PyObject *, PyObject *, size_t,
extern void setconstants(PyObject *, const struct nameval *);
extern PyObject *mexp_common(PyObject *, PyObject *, size_t,
/*----- Main code ---------------------------------------------------------*/
static const struct nameval consts[] = {
/*----- Main code ---------------------------------------------------------*/
static const struct nameval consts[] = {
+#define CF(f, x) { #x, f, x }
+#define C(x) { #x, (x) >= 0 ? 0 : CF_SIGNED, x }
C(FTY_PRIME), C(FTY_BINARY),
C(PGEN_PASS), C(PGEN_FAIL), C(PGEN_BEGIN), C(PGEN_TRY), C(PGEN_DONE),
C(PGEN_ABORT),
C(FTY_PRIME), C(FTY_BINARY),
C(PGEN_PASS), C(PGEN_FAIL), C(PGEN_BEGIN), C(PGEN_TRY), C(PGEN_DONE),
C(PGEN_ABORT),
C(RAND_IBITS),
C(PMODE_READ), C(PMODE_VERIFY),
C(KOPEN_READ), C(KOPEN_WRITE), C(KOPEN_NOFILE),
C(RAND_IBITS),
C(PMODE_READ), C(PMODE_VERIFY),
C(KOPEN_READ), C(KOPEN_WRITE), C(KOPEN_NOFILE),
- C(KEXP_FOREVER), C(KEXP_EXPIRE),
+ CF(0, KEXP_FOREVER), CF(0, KEXP_EXPIRE),
C(KF_ENCMASK), C(KENC_BINARY), C(KENC_MP), C(KENC_STRUCT),
C(KENC_ENCRYPT), C(KENC_STRING), C(KENC_EC),
C(KF_CATMASK), C(KCAT_SYMM), C(KCAT_PRIV), C(KCAT_PUB), C(KCAT_SHARE),
C(KF_ENCMASK), C(KENC_BINARY), C(KENC_MP), C(KENC_STRUCT),
C(KENC_ENCRYPT), C(KENC_STRING), C(KENC_EC),
C(KF_CATMASK), C(KCAT_SYMM), C(KCAT_PRIV), C(KCAT_PUB), C(KCAT_SHARE),
KEY_ERRORS(ENTRY)
#undef ENTRY
#undef C
KEY_ERRORS(ENTRY)
#undef ENTRY
#undef C
void setconstants(PyObject *mod, const struct nameval *c)
{
PyObject *x;
void setconstants(PyObject *mod, const struct nameval *c)
{
PyObject *x;
- if (c->value > LONG_MAX)
- x = PyLong_FromUnsignedLong(c->value);
- else
- x = PyInt_FromLong(c->value);
- PyModule_AddObject(mod, (/*unconst*/ char *)c->name, x);
- c++;
+ u = c->value;
+ if (u <= LONG_MAX) x = PyInt_FromLong(u);
+ else if (c->f&CF_SIGNED) x = PyInt_FromLong(-1 - (long)(ULONG_MAX - u));
+ else x = PyLong_FromUnsignedLong(u);
+ PyModule_AddObject(mod, (/*unconst*/ char *)c->name, x); c++;