+/*
+ * Same as above, except for pluralized error messages. The calling routine
+ * must be declared like "const char *fmt_singular, const char *fmt_plural,
+ * unsigned long n, ...". Translation is assumed always wanted.
+ */
+#define EVALUATE_MESSAGE_PLURAL(targetfield, appendval) \
+ { \
+ const char *fmt; \
+ char *fmtbuf; \
+ StringInfoData buf; \
+ /* Internationalize the error format string */ \
+ if (!in_error_recursion_trouble()) \
+ fmt = dngettext(edata->domain, fmt_singular, fmt_plural, n); \
+ else \
+ fmt = (n == 1 ? fmt_singular : fmt_plural); \
+ /* Expand %m in format string */ \
+ fmtbuf = expand_fmt_string(fmt, edata); \
+ initStringInfo(&buf); \
+ if ((appendval) && edata->targetfield) \
+ appendStringInfo(&buf, "%s\n", edata->targetfield); \
+ /* Generate actual output --- have to use appendStringInfoVA */ \
+ for (;;) \
+ { \
+ va_list args; \
+ bool success; \
+ va_start(args, n); \
+ success = appendStringInfoVA(&buf, fmtbuf, args); \
+ va_end(args); \
+ if (success) \
+ break; \
+ enlargeStringInfo(&buf, buf.maxlen); \
+ } \
+ /* Done with expanded fmt */ \
+ pfree(fmtbuf); \
+ /* Save the completed message into the stack item */ \
+ if (edata->targetfield) \
+ pfree(edata->targetfield); \
+ edata->targetfield = pstrdup(buf.data); \
+ pfree(buf.data); \
+ }
+