|
From: Billy G. A. <bal...@us...> - 2001-09-14 04:01:40
|
Update of /cvsroot/pypgsql/pypgsql
In directory usw-pr-cvs1:/tmp/cvs-serv14906
Modified Files:
pgversion.c
Log Message:
12SEP2001 bga Improved detection of erronious input strings.
--- Various minor bug fixes and code cleanup.
--- Made constructed version string more closely mimic the actual
format of the PostgreSQL version string.
09SEP2001 bga Fixed the broken comparison function. This proved to be a not
so easy task since any errors set in the extensions module's
coerce() function are ignored (unless called by Python's built-
in coerce() function). Python will clear the error and try to
convert the PgVersion object to the other type if the coersion
to PgVersion fails. I do not want that to happen. If the ob-
ject can't be coerced to a PgVersion, then the comparison does
not make sense, so an exception should occur. To get this be-
haviour required a bit sneaky-ness. See the comments in
the code for details. A concequence of this change is that
coerce will always succeed. I can not see any way around this.
--- Having a __dict__ attribute and calling PyMember_Get() in the
PyVersion_getattr function causes dir() to do strange things
(like list members twice). I've removed the __dict__ attribute
and adding methods to emulate a mapping object to PgVersion.
A PgVersion object will now act like a dictionary, so use
version[key] instead of version.__dict__[key].
Index: pgversion.c
===================================================================
RCS file: /cvsroot/pypgsql/pypgsql/pgversion.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** pgversion.c 2001/09/10 04:41:32 1.7
--- pgversion.c 2001/09/14 04:01:37 1.8
***************
*** 32,35 ****
--- 32,39 ----
| Date Ini Description |
| --------- --- ------------------------------------------------------- |
+ | 12SEP2001 bga Improved detection of erronious input strings. |
+ | --- Various minor bug fixes and code cleanup. |
+ | --- Made constructed version string more closely mimic the |
+ | actual format of the PostgreSQL version string. |
| 09SEP2001 bga Fixed the broken comparison function. This proved to |
| be a not so easy task since any errors set in the ex- |
***************
*** 76,79 ****
--- 80,84 ----
#include <ctype.h>
#include <limits.h>
+ #include <errno.h>
#include <Python.h>
#include <structmember.h>
***************
*** 90,95 ****
PyObject *minor;
PyObject *patch;
- PyObject *value;
PyObject *post70;
} PgVersion;
--- 95,100 ----
PyObject *minor;
PyObject *patch;
PyObject *post70;
+ PyObject *value;
} PgVersion;
***************
*** 110,126 ****
char *last;
! *result = strtol(token, &last, 0);
! if ((token == (char *)NULL) ||
! (*token == '\0') ||
! isspace(*token) ||
! (*last != 0))
! {
! PyErr_SetString(PyExc_ValueError,
! "Invalid format for PgVersion construction.");
! return (1);
! }
! return (0);
}
--- 115,134 ----
char *last;
! /*******************************************************************\
! | For our purposes, an error occurs when parsing a token if: |
! | 1. the 1st character of token is not a digit. |
! | 2. strtol() set errno to something other than 0. |
! | 3. strtol() could not translate the entire token (i.e. *last is |
! | not the ASCII NUL character). |
! \*******************************************************************/
! if (!isdigit(*token))
! return 1;
! errno = 0;
!
! *result = strtol(token, &last, 0);
!
! return ((errno != 0) || (*last != (char)0));
}
***************
*** 159,164 ****
if ((self->version == (PyObject *)NULL) || (s == (char *)NULL))
{
! PyErr_SetString(PyExc_MemoryError,
! "Can't allocate memory in PgVersion_New().");
goto new_error;
}
--- 167,171 ----
if ((self->version == (PyObject *)NULL) || (s == (char *)NULL))
{
! PyErr_NoMemory();
goto new_error;
}
***************
*** 176,186 ****
major = minor = patch = value = 0;
token = strtok_r(s, " \t", &save_ptr);
if (strcmp(token, "PostgreSQL") != 0)
- {
- PyErr_SetString(PyExc_ValueError,
- "Ivalid format for PgVersion construction.");
goto new_error;
- }
vstr = strtok_r((char *)NULL, " \t", &save_ptr);
--- 183,196 ----
major = minor = patch = value = 0;
+ /* Pre-set the error condition.
+ * We'll clear it if everything's OK
+ */
+ PyErr_SetString(PyExc_ValueError,
+ "Ivalid format for PgVersion construction.");
+
+
token = strtok_r(s, " \t", &save_ptr);
if (strcmp(token, "PostgreSQL") != 0)
goto new_error;
vstr = strtok_r((char *)NULL, " \t", &save_ptr);
***************
*** 188,196 ****
token = strtok_r((char *)NULL, " \t", &save_ptr);
if (strcmp(token, "on") != 0)
- {
- PyErr_SetString(PyExc_ValueError,
- "Ivalid format for PgVersion construction.");
goto new_error;
! }
/***************************************************************\
--- 198,211 ----
token = strtok_r((char *)NULL, " \t", &save_ptr);
if (strcmp(token, "on") != 0)
goto new_error;
!
! /***************************************************************\
! | This test is in case someone tries to compares against a |
! | string such as '7.2 on'. |
! \***************************************************************/
!
! token = strtok_r((char *)NULL, " \t", &save_ptr);
! if (strcmp(token, "on") == 0)
! goto new_error;
/***************************************************************\
***************
*** 217,220 ****
--- 232,241 ----
value = (((major * 100) + minor) * 100) + patch;
+ /* OK, the version information has been parsed,
+ * Clear the pre-set error
+ */
+ (void)PyErr_Clear();
+
+ /* And build the attributes */
self->major = Py_BuildValue("i", major);
self->minor = Py_BuildValue("i", minor);
***************
*** 227,231 ****
PyMem_Free(s);
-
return (PyObject *)self;
--- 248,251 ----
***************
*** 249,264 ****
{
PgVersion *s;
char *vstr;
if (PyString_Check(*r))
{
! vstr = PyMem_Malloc(32 + strlen(PyString_AsString(*r)));
! if (vstr == (char *)NULL)
! {
! PyErr_SetString(PyExc_MemoryError,
! "Can't allocate memory in PgVersion_coerce().");
! return (1);
! }
! sprintf(vstr, "PostgreSQL %s on Dummy", PyString_AsString(*r));
}
else
--- 269,285 ----
{
PgVersion *s;
+ PyObject *exception, *message, *traceback;
char *vstr;
+ if ((vstr = PyMem_Malloc(128)) == (char *)NULL)
+ {
+ PyErr_NoMemory();
+ return (1);
+ }
+
if (PyString_Check(*r))
{
! sprintf(vstr, "PostgreSQL %.80s on UNKNOWN, compiled by UNKNOWN",
! PyString_AsString(*r));
}
else
***************
*** 266,275 ****
long value = 0;
- if ((vstr = PyMem_Malloc(128)) == (char *)NULL)
- {
- PyErr_NoMemory();
- return (1);
- }
-
if (PgInt2_Check(*r))
{
--- 287,290 ----
***************
*** 295,299 ****
{
PyErr_SetString(PyExc_OverflowError,
! "converting Float to Integer");
}
else
--- 310,314 ----
{
PyErr_SetString(PyExc_OverflowError,
! "float too large to convert");
}
else
***************
*** 304,310 ****
goto coerce_error;
! sprintf(vstr, "PostgreSQL %ld.%ld.%ld on Dummy", (value / 10000),
! ((value / 100) % 100), (value % 100));
}
s = (PgVersion *)PgVersion_New(vstr);
--- 319,326 ----
goto coerce_error;
! sprintf(vstr, "PostgreSQL %ld.%ld.%ld on UNKNOWN, compiled by UNKNOWN",
! (value / 10000), ((value / 100) % 100), (value % 100));
}
+
s = (PgVersion *)PgVersion_New(vstr);
***************
*** 336,347 ****
PyMem_Free(vstr);
s = (PgVersion *)PyObject_New(PgVersion, &PgVersion_Type);
if (s == (PgVersion *)NULL)
return (1);
! PyErr_Fetch(&s->major, &s->version, &s->minor);
! s->value = Py_BuildValue("i", -1);
! s->patch = Py_None; Py_INCREF(Py_None);
! s->post70 = Py_None; Py_INCREF(Py_None);
if (PyErr_Occurred())
--- 352,367 ----
PyMem_Free(vstr);
+ PyErr_Fetch(&exception, &message, &traceback);
+
s = (PgVersion *)PyObject_New(PgVersion, &PgVersion_Type);
if (s == (PgVersion *)NULL)
return (1);
! s->version = message;
! s->major = exception;
! s->minor = traceback;
! s->patch = Py_None; Py_INCREF(Py_None);
! s->post70 = Py_None; Py_INCREF(Py_None);
! s->value = Py_BuildValue("i", -1);
if (PyErr_Occurred())
***************
*** 462,468 ****
PyErr_Restore(t->major, t->version, t->minor);
! Py_XINCREF(t->major);
! Py_XINCREF(t->version);
! Py_XINCREF(t->minor);
}
return (left < right) ? -1 : (left > right) ? 1 : 0;
--- 482,488 ----
PyErr_Restore(t->major, t->version, t->minor);
! t->major = Py_None; Py_XINCREF(t->major);
! t->version = Py_None; Py_XINCREF(t->version);
! t->minor = Py_None; Py_XINCREF(t->minor);
}
return (left < right) ? -1 : (left > right) ? 1 : 0;
|