Dear patchers,
Please find enclosed a new patch submission which take into account
comments by Tom Lane about version 1.
(1) the function is renamed as localisation does not mean what I meant.
(2) three dots ... appear after and before the line when truncated.
However, I still put the line number that I found useful.
The new version validates for me against current cvs head.
Same comment as with version one, I don't know how to test the multi-byte
part.
Have a nice day,
--
Fabien Coelho - [EMAIL PROTECTED]*** ./src/bin/psql/common.c.origThu Mar 11 15:42:17 2004
--- ./src/bin/psql/common.c Thu Mar 11 18:05:22 2004
***
*** 345,350
--- 345,506
}
+ #define DISPLAY_SIZE (60)
+ #define MIN_RIGHT_CUT (10)
+
+ /* on errors, print syntax error position if available.
+ * the query is expected to be in the client encoding.
+ */
+ static void
+ ReportSyntaxErrorPosition(const PGresult *result, const char *query)
+ {
+ int loc = 0;
+ char * sp = PQresultErrorField(result, PG_DIAG_STATEMENT_POSITION);
+
+ if (sp sscanf(sp, %d, loc)!=1)
+ {
+ psql_error(INTERNAL ERROR: unexpected statement position '%s'\n, sp);
+ return;
+ }
+
+ /* do we have something to show? */
+ if (query!=NULL loc0)
+ {
+ int clen, slen, i, * qidx, ibeg, iend, last_nl, loc_line;
+ char *wquery, *cursor;
+ bool beg_trunc, end_trunc;
+
+ /* (1) let us first compute a character index for the query. */
+
+ /* we need a safe allocation size... */
+ slen = strlen(query);
+
+ /* the last one is needed to store last char mb length */
+ qidx = (int*) palloc(sizeof(int)*(slen+1));
+
+ qidx[0] = 0;
+ for (i=1; query[qidx[i-1]]!='\0' islen+1; i++)
+ qidx[i] = qidx[i-1] + PQmblen(query[qidx[i-1]],
pset.encoding);
+
+ clen = i-1;
+
+ /* we must be at the end! */
+ psql_assert(query[qidx[clen]] == '\0');
+
+ /* our localisation index start at 0! it must be in the query! */
+ loc--;
+ psql_assert(loc=0 locclen);
+
+ /* (2) now we build a working copy of the query. */
+ wquery = (char*) palloc(sizeof(char)*(strlen(query)+1));
+ strcpy(wquery, query);
+
+ /* the character number of the last newline. */
+ last_nl = -1;
+/* input line number of our syntax error. */
+ loc_line = 1;
+ /* first included char of extract. */
+ ibeg = 0;
+ /* last not-included char of extract. */
+ iend = clen;
+
+ /* (3) we clean wquery string from tabs, carriage return and new lines.
+* extract error line number and begin and end indexes.
+*/
+ for (i=0; iclen; i++)
+ {
+ /* how to find a '\t', a '\r' or a '\n'?
+* I assume here that all encodings must be ascii compatible...
+*/
+ if ((qidx[i+1]-qidx[i]) == 1)
+ {
+ if (wquery[qidx[i]] == '\t')
+ wquery[qidx[i]] = ' ';
+ if (wquery[qidx[i]] == '\r' || wquery[qidx[i]] == '\n')
+ {
+ /* count lines */
+ if (wquery[qidx[i]]=='\n' iloc)
+ loc_line++;
+
+ /* set extract end. */
+ if (iend==clen iloc)
+ iend = i;
+
+ wquery[qidx[i]] = ' ';
+ last_nl = i;
+ }
+ }
+ /* set extract beginning. */
+ if (i==loc last_nl!=-1)
+ ibeg = last_nl+1;
+ }
+
+ /* (4) if the line extracted is too long, we truncate it. */
+ beg_trunc = false;
+ end_trunc = false;
+ if (iend-ibeg DISPLAY_SIZE)
+ {
+ /* we first truncate right if it is enough. */
+ if (ibeg+DISPLAY_SIZE loc+MIN_RIGHT_CUT)
+ {
+ iend = ibeg+DISPLAY_SIZE;
+ end_trunc = true;
+ }
+ else
+ {
+ /* we truncate right. */
+ if (loc+MIN_RIGHT_CUT iend)
+