diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index b44d2fd068d33e14d997ab94a6090ab04606ba80..a931fe9fa24bd14c266a4dde44f0122da9e89920 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.251 2003/06/23 17:03:19 momjian Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.252 2003/06/23 19:20:24 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -2843,8 +2843,9 @@ static void defaultNoticeReceiver(void *arg, const PGresult *res) { (void) arg; /* not used */ - (*res->noticeHooks.noticeProc) (res->noticeHooks.noticeProcArg, - PQresultErrorMessage(res)); + if (res->noticeHooks.noticeProc != NULL) + (*res->noticeHooks.noticeProc) (res->noticeHooks.noticeProcArg, + PQresultErrorMessage(res)); } /* diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c index 4c96bbd386881f625fb9b5b8f809890d8d52bc0f..a1ae2612569c1444acae4b6a250a84b6ad714057 100644 --- a/src/interfaces/libpq/fe-exec.c +++ b/src/interfaces/libpq/fe-exec.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.139 2003/06/21 21:51:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.140 2003/06/23 19:20:24 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -440,18 +440,29 @@ pqPrepareAsyncResult(PGconn *conn) } /* - * pqInternalNotice - helper routine for internally-generated notices + * pqInternalNotice - produce an internally-generated notice message + * + * A format string and optional arguments can be passed. Note that we do + * libpq_gettext() here, so callers need not. * * The supplied text is taken as primary message (ie., it should not include * a trailing newline, and should not be more than one line). */ void -pqInternalNotice(const PGNoticeHooks *hooks, const char *msgtext) +pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt, ...) { + char msgBuf[1024]; + va_list args; PGresult *res; if (hooks->noticeRec == NULL) - return; /* nobody home? */ + return; /* nobody home to receive notice? */ + + /* Format the message */ + va_start(args, fmt); + vsnprintf(msgBuf, sizeof(msgBuf), libpq_gettext(fmt), args); + va_end(args); + msgBuf[sizeof(msgBuf)-1] = '\0'; /* make real sure it's terminated */ /* Make a PGresult to pass to the notice receiver */ res = PQmakeEmptyPGresult(NULL, PGRES_NONFATAL_ERROR); @@ -459,14 +470,14 @@ pqInternalNotice(const PGNoticeHooks *hooks, const char *msgtext) /* * Set up fields of notice. */ - pqSaveMessageField(res, 'M', msgtext); + pqSaveMessageField(res, 'M', msgBuf); pqSaveMessageField(res, 'S', libpq_gettext("NOTICE")); /* XXX should provide a SQLSTATE too? */ /* * Result text is always just the primary message + newline. */ - res->errMsg = (char *) pqResultAlloc(res, strlen(msgtext) + 2, FALSE); - sprintf(res->errMsg, "%s\n", msgtext); + res->errMsg = (char *) pqResultAlloc(res, strlen(msgBuf) + 2, FALSE); + sprintf(res->errMsg, "%s\n", msgBuf); /* * Pass to receiver, then free it. */ @@ -1585,16 +1596,13 @@ PQbinaryTuples(const PGresult *res) static int check_field_number(const PGresult *res, int field_num) { - char noticeBuf[128]; - if (!res) return FALSE; /* no way to display error message... */ if (field_num < 0 || field_num >= res->numAttributes) { - snprintf(noticeBuf, sizeof(noticeBuf), - libpq_gettext("column number %d is out of range 0..%d"), - field_num, res->numAttributes - 1); - PGDONOTICE(res, noticeBuf); + pqInternalNotice(&res->noticeHooks, + "column number %d is out of range 0..%d", + field_num, res->numAttributes - 1); return FALSE; } return TRUE; @@ -1604,24 +1612,20 @@ static int check_tuple_field_number(const PGresult *res, int tup_num, int field_num) { - char noticeBuf[128]; - if (!res) return FALSE; /* no way to display error message... */ if (tup_num < 0 || tup_num >= res->ntups) { - snprintf(noticeBuf, sizeof(noticeBuf), - libpq_gettext("row number %d is out of range 0..%d"), - tup_num, res->ntups - 1); - PGDONOTICE(res, noticeBuf); + pqInternalNotice(&res->noticeHooks, + "row number %d is out of range 0..%d", + tup_num, res->ntups - 1); return FALSE; } if (field_num < 0 || field_num >= res->numAttributes) { - snprintf(noticeBuf, sizeof(noticeBuf), - libpq_gettext("column number %d is out of range 0..%d"), - field_num, res->numAttributes - 1); - PGDONOTICE(res, noticeBuf); + pqInternalNotice(&res->noticeHooks, + "column number %d is out of range 0..%d", + field_num, res->numAttributes - 1); return FALSE; } return TRUE; @@ -1822,7 +1826,6 @@ PQoidValue(const PGresult *res) char * PQcmdTuples(PGresult *res) { - char noticeBuf[128]; char *p; if (!res) @@ -1850,10 +1853,9 @@ PQcmdTuples(PGresult *res) if (*p == 0) { - snprintf(noticeBuf, sizeof(noticeBuf), - libpq_gettext("could not interpret result from server: %s"), - res->cmdStatus); - PGDONOTICE(res, noticeBuf); + pqInternalNotice(&res->noticeHooks, + "could not interpret result from server: %s", + res->cmdStatus); return ""; } diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c index f10c3112d7e81419426047da57e17a2a15f5378b..9498c9e2697069a6a9cd70a6d3cbd47568e9798d 100644 --- a/src/interfaces/libpq/fe-misc.c +++ b/src/interfaces/libpq/fe-misc.c @@ -23,7 +23,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.97 2003/06/21 21:51:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.98 2003/06/23 19:20:25 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -206,7 +206,6 @@ pqGetInt(int *result, size_t bytes, PGconn *conn) { uint16 tmp2; uint32 tmp4; - char noticeBuf[64]; switch (bytes) { @@ -225,10 +224,9 @@ pqGetInt(int *result, size_t bytes, PGconn *conn) *result = (int) ntohl(tmp4); break; default: - snprintf(noticeBuf, sizeof(noticeBuf), - libpq_gettext("integer of size %lu not supported by pqGetInt"), - (unsigned long) bytes); - PGDONOTICE(conn, noticeBuf); + pqInternalNotice(&conn->noticeHooks, + "integer of size %lu not supported by pqGetInt", + (unsigned long) bytes); return EOF; } @@ -248,7 +246,6 @@ pqPutInt(int value, size_t bytes, PGconn *conn) { uint16 tmp2; uint32 tmp4; - char noticeBuf[64]; switch (bytes) { @@ -263,10 +260,9 @@ pqPutInt(int value, size_t bytes, PGconn *conn) return EOF; break; default: - snprintf(noticeBuf, sizeof(noticeBuf), - libpq_gettext("integer of size %lu not supported by pqPutInt"), - (unsigned long) bytes); - PGDONOTICE(conn, noticeBuf); + pqInternalNotice(&conn->noticeHooks, + "integer of size %lu not supported by pqPutInt", + (unsigned long) bytes); return EOF; } diff --git a/src/interfaces/libpq/fe-protocol2.c b/src/interfaces/libpq/fe-protocol2.c index 2a15e19e1d58e22bed4aee15c1f361b35a52b975..b2d8a15f7b850d4af873f915f6b3ca7f71884418 100644 --- a/src/interfaces/libpq/fe-protocol2.c +++ b/src/interfaces/libpq/fe-protocol2.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-protocol2.c,v 1.3 2003/06/21 23:25:38 tgl Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-protocol2.c,v 1.4 2003/06/23 19:20:25 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -358,7 +358,6 @@ void pqParseInput2(PGconn *conn) { char id; - char noticeWorkspace[128]; /* * Loop to parse successive complete messages available in the buffer. @@ -424,10 +423,9 @@ pqParseInput2(PGconn *conn) } else { - snprintf(noticeWorkspace, sizeof(noticeWorkspace), - libpq_gettext("message type 0x%02x arrived from server while idle"), - id); - PGDONOTICE(conn, noticeWorkspace); + pqInternalNotice(&conn->noticeHooks, + "message type 0x%02x arrived from server while idle", + id); /* Discard the unexpected message; good idea?? */ conn->inStart = conn->inEnd; break; @@ -464,12 +462,9 @@ pqParseInput2(PGconn *conn) if (pqGetc(&id, conn)) return; if (id != '\0') - { - snprintf(noticeWorkspace, sizeof(noticeWorkspace), - libpq_gettext("unexpected character %c following empty query response (\"I\" message)"), - id); - PGDONOTICE(conn, noticeWorkspace); - } + pqInternalNotice(&conn->noticeHooks, + "unexpected character %c following empty query response (\"I\" message)", + id); if (conn->result == NULL) conn->result = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY); @@ -522,9 +517,8 @@ pqParseInput2(PGconn *conn) } else { - snprintf(noticeWorkspace, sizeof(noticeWorkspace), - libpq_gettext("server sent data (\"D\" message) without prior row description (\"T\" message)")); - PGDONOTICE(conn, noticeWorkspace); + pqInternalNotice(&conn->noticeHooks, + "server sent data (\"D\" message) without prior row description (\"T\" message)"); /* Discard the unexpected message; good idea?? */ conn->inStart = conn->inEnd; return; @@ -539,9 +533,8 @@ pqParseInput2(PGconn *conn) } else { - snprintf(noticeWorkspace, sizeof(noticeWorkspace), - libpq_gettext("server sent binary data (\"B\" message) without prior row description (\"T\" message)")); - PGDONOTICE(conn, noticeWorkspace); + pqInternalNotice(&conn->noticeHooks, + "server sent binary data (\"B\" message) without prior row description (\"T\" message)"); /* Discard the unexpected message; good idea?? */ conn->inStart = conn->inEnd; return; @@ -872,7 +865,8 @@ pqGetErrorNotice2(PGconn *conn, bool isError) } else { - (*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res); + if (res->noticeHooks.noticeRec != NULL) + (*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res); PQclear(res); } @@ -1196,7 +1190,7 @@ pqEndcopy2(PGconn *conn) if (svLast == '\n') conn->errorMessage.data[conn->errorMessage.len-1] = '\0'; - PGDONOTICE(conn, conn->errorMessage.data); + pqInternalNotice(&conn->noticeHooks, "%s", conn->errorMessage.data); conn->errorMessage.data[conn->errorMessage.len-1] = svLast; } @@ -1207,7 +1201,8 @@ pqEndcopy2(PGconn *conn) * entirely due to application screwup of the copy in/out protocol. To * recover, reset the connection (talk about using a sledgehammer...) */ - PGDONOTICE(conn, libpq_gettext("lost synchronization with server, resetting connection")); + pqInternalNotice(&conn->noticeHooks, + "lost synchronization with server, resetting connection"); /* * Users doing non-blocking connections need to handle the reset diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c index 6b404c3531b947ecd1a5d34aaeb4d49d16800a4a..ac39e4adc1400159d740b29eb714c3da05fb34a1 100644 --- a/src/interfaces/libpq/fe-protocol3.c +++ b/src/interfaces/libpq/fe-protocol3.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-protocol3.c,v 1.3 2003/06/21 23:25:38 tgl Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-protocol3.c,v 1.4 2003/06/23 19:20:25 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -57,7 +57,6 @@ pqParseInput3(PGconn *conn) char id; int msgLength; int avail; - char noticeWorkspace[128]; /* * Loop to parse successive complete messages available in the buffer. @@ -172,10 +171,9 @@ pqParseInput3(PGconn *conn) } else { - snprintf(noticeWorkspace, sizeof(noticeWorkspace), - libpq_gettext("message type 0x%02x arrived from server while idle"), - id); - PGDONOTICE(conn, noticeWorkspace); + pqInternalNotice(&conn->noticeHooks, + "message type 0x%02x arrived from server while idle", + id); /* Discard the unexpected message */ conn->inCursor += msgLength; } @@ -667,7 +665,8 @@ pqGetErrorNotice3(PGconn *conn, bool isError) { /* We can cheat a little here and not copy the message. */ res->errMsg = workBuf.data; - (*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res); + if (res->noticeHooks.noticeRec != NULL) + (*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res); PQclear(res); } @@ -1119,7 +1118,7 @@ pqEndcopy3(PGconn *conn) if (svLast == '\n') conn->errorMessage.data[conn->errorMessage.len-1] = '\0'; - PGDONOTICE(conn, conn->errorMessage.data); + pqInternalNotice(&conn->noticeHooks, "%s", conn->errorMessage.data); conn->errorMessage.data[conn->errorMessage.len-1] = svLast; } diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h index f651320e1cbbe97c9a32d6d55c0dcb5d8b810577..d97db7c88b1189220fbba05b0020cb8b055f8709 100644 --- a/src/interfaces/libpq/libpq-int.h +++ b/src/interfaces/libpq/libpq-int.h @@ -12,7 +12,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: libpq-int.h,v 1.75 2003/06/21 21:51:34 tgl Exp $ + * $Id: libpq-int.h,v 1.76 2003/06/23 19:20:25 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -360,7 +360,9 @@ extern char *pqResultStrdup(PGresult *res, const char *str); extern void pqClearAsyncResult(PGconn *conn); extern void pqSaveErrorResult(PGconn *conn); extern PGresult *pqPrepareAsyncResult(PGconn *conn); -extern void pqInternalNotice(const PGNoticeHooks *hooks, const char *msgtext); +extern void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt, ...) +/* This lets gcc check the format string for consistency. */ +__attribute__((format(printf, 2, 3))); extern int pqAddTuple(PGresult *res, PGresAttValue *tup); extern void pqSaveMessageField(PGresult *res, char code, const char *value); @@ -435,10 +437,6 @@ extern void pqsecure_close(PGconn *); extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len); extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len); -/* Note: PGDONOTICE macro will work if applied to either PGconn or PGresult */ -#define PGDONOTICE(conn,message) \ - pqInternalNotice(&(conn)->noticeHooks, (message)) - /* * this is so that we can check if a connection is non-blocking internally * without the overhead of a function call diff --git a/src/interfaces/libpq/nls.mk b/src/interfaces/libpq/nls.mk index 6f0de758c0bd1c4868ea16cba80ff11195bdbf63..f4bec84496a47e2033e5d6104c04ea710eed4c5e 100644 --- a/src/interfaces/libpq/nls.mk +++ b/src/interfaces/libpq/nls.mk @@ -1,5 +1,5 @@ -# $Header: /cvsroot/pgsql/src/interfaces/libpq/nls.mk,v 1.8 2002/09/22 20:57:21 petere Exp $ +# $Header: /cvsroot/pgsql/src/interfaces/libpq/nls.mk,v 1.9 2003/06/23 19:20:25 tgl Exp $ CATALOG_NAME := libpq AVAIL_LANGUAGES := cs de es fr pt_BR ru sv zh_CN zh_TW GETTEXT_FILES := fe-auth.c fe-connect.c fe-exec.c fe-lobj.c fe-misc.c fe-secure.c -GETTEXT_TRIGGERS:= libpq_gettext +GETTEXT_TRIGGERS:= libpq_gettext pqInternalNotice:2