Pattern* Pattern_regex(char *tok, char *expr) { int j; #ifdef DEBUG fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); #endif for (j = 0; j < Pattern_patterns_sz; j++) { if (strcmp(Pattern_patterns[j].tok, tok) == 0) { return &Pattern_patterns[j]; } } if (expr) { if (j >= Pattern_patterns_bsz) { /* Needs to expand block */ Pattern_patterns_bsz = Pattern_patterns_bsz + BLOCK_SIZE_PATTERNS; PyMem_Resize(Pattern_patterns, Pattern, Pattern_patterns_bsz); } Pattern_patterns[j].tok = PyMem_Strdup(tok); Pattern_patterns[j].expr = PyMem_Strdup(expr); Pattern_patterns[j].pattern = NULL; Pattern_patterns_sz = j + 1; return &Pattern_patterns[j]; } return NULL; }
PyObject *PgVersion_New(char *version) { PgVersion *self; char *s = (char *)NULL; /* writeable temporary copy of version string */ char *vstr; /* The version number from the version string */ char *token; /* parsed token */ char *save_ptr; /* saves pg_strtok_r state for subsequent calls */ long major, minor, patch, value; self = (PgVersion *)PyObject_New(PgVersion, &PgVersion_Type); if (self) { save_ptr = (char *)NULL; self->version = Py_BuildValue("s", version); s = (char *)PyMem_Strdup(version); if ((self->version == (PyObject *)NULL) || (s == (char *)NULL)) { PyErr_NoMemory(); goto new_error; } self->major = self->minor = self->patch = (PyObject *)NULL; self->value = self->post70 = (PyObject *)NULL; /***************************************************************\ | Parse out the version information from the version string. | | The expected format is 'PostgreSQL M.m.p on ...' where M is | | the major number, m is the minor number and p is the patch | | level. | \***************************************************************/ major = minor = patch = value = 0; /* Pre-set the error condition. * We'll clear it if everything's OK */ PyErr_SetString(PyExc_ValueError, "Invalid format for PgVersion construction."); token = pg_strtok_r(s, " \t", &save_ptr); if (strcmp(token, "PostgreSQL") != 0) goto new_error; vstr = pg_strtok_r((char *)NULL, " \t", &save_ptr); token = pg_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 = pg_strtok_r((char *)NULL, " \t", &save_ptr); if (strcmp(token, "on") == 0) goto new_error; /***************************************************************\ | We now have the version number (as M.m.p) in vstr. Parse it. | | Note: The minor number and patch level may not be present. | \***************************************************************/ save_ptr = (char *)NULL; /***************************************************************\ | Vendor releases e.g. from dbexperts get forgotten. | | We strip that away here. | \***************************************************************/ vstr = pg_strtok_r(vstr, "-", &save_ptr); save_ptr = (char *)NULL; token = pg_strtok_r(vstr, ".", &save_ptr); if (parseToken(token, &major)) goto new_error; token = pg_strtok_r((char *)NULL, ".", &save_ptr); if ((token != (char *)NULL) && (*token != '\0') && (parseToken(token, &minor))) goto new_error; token = pg_strtok_r((char *)NULL, ".-", &save_ptr); if ((token != (char *)NULL) && (*token != '\0') && (parseToken(token, &patch))) { goto new_error; } 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); self->patch = Py_BuildValue("i", patch); self->value = Py_BuildValue("i", value); self->post70 = Py_BuildValue("i", ((value >= 70100) ? 1l : 0l)); if (PyErr_Occurred()) goto new_error; } PyMem_Free(s); return (PyObject *)self; new_error: PyMem_Free(s); PgVersion_dealloc(self); return (PyObject *)NULL; }