/* FQTN standards for Fully Qualified Type Name. Returns a pointer to out. * Only returns NULL if out is NULL or outl <= 0. */ char * pqt_fqtn(char *out, size_t outl, const char *schema, const char *typname) { int r; int have_schema = schema && *schema; if (!out || outl<=0) return NULL; *out = 0; if (!typname || !*typname) return out; r = pqt_snprintf(out, outl, "%s%s%s", have_schema ? schema : "", have_schema ? "." : "", typname); if (r < 0) { *out = 0; return out; } return out; }
char *pqt_parse(const char *format, PGtypeHandler *h, int hcnt, char *stmtBuf, size_t stmtBufLen, PGtypeHandler **out, size_t *stmtPos, int *typpos, int *flags) { int specMark; char *s = skipQuotes((char *) format); char typname[PQT_MAXIDLEN + 1]; char schema[PQT_MAXIDLEN + 1]; char tmp[200]; *out = NULL; if (!s) return NULL; /* found quotes to skip */ if (s != format) { if (stmtBuf) { size_t n = s - format; CHKSTMTBUF(n); memcpy(stmtBuf + *stmtPos, format, n); (*stmtPos) += n; } return s; } specMark = *format; if (specMark != '%' && specMark != '#') { if (stmtBuf) { CHKSTMTBUF(1); stmtBuf[*stmtPos] = *format; (*stmtPos)++; } format++; return (char *) format; } /* spec skips % or # */ if (!(s = pqt_parsetype(format + 1, schema, typname, flags, *typpos + 1))) return NULL; if (*flags & TYPFLAG_INVALID) { if (stmtBuf) { CHKSTMTBUF(1); stmtBuf[*stmtPos] = *format++; (*stmtPos)++; PQseterror(NULL); /* set by pqt_parsetype */ return (char *) format; } return NULL; } (*typpos)++; if (!(*out = pqt_gethandler(h, hcnt, schema, typname))) { PQseterror("Uknown type '%s' (position %d)", pqt_fqtn(tmp, sizeof(tmp), schema, typname), *typpos); return NULL; } if (stmtBuf) { int n = pqt_snprintf(tmp, sizeof(tmp), "$%d", *typpos); CHKSTMTBUF(n); memcpy(stmtBuf + *stmtPos, tmp, n); (*stmtPos) += n; } if (!(*out)->typput) { PGtypeHandler *o = pqt_gethandlerbyid(h, hcnt, h->base_id); if (!o || !o->typput) { PQseterror( "Type '%s' doesn't support put operations (position %d)", pqt_fqtn(tmp, sizeof(tmp), (*out)->typschema, (*out)->typname), *typpos); *out = NULL; return NULL; } *out = o; } if ((*flags & TYPFLAG_POINTER) && !pqt_allowsptr(*out)) { PQseterror( "Type '%s' doesn't support putting pointers (position %d)", pqt_fqtn(tmp, sizeof(tmp), (*out)->typschema, (*out)->typname), *typpos); *out = NULL; return NULL; } if (specMark == '#') (*flags) |= TYPFLAG_BYNAME; return s; }