*** ./src/bin/psql/common.c.orig Thu Mar 11 15:42:17 2004 --- ./src/bin/psql/common.c Thu Mar 11 15:59:50 2004 *************** *** 345,350 **** --- 345,491 ---- } + #define DISPLAY_SIZE (60) + #define MIN_RIGHT_CUT (10) + + /* on errors, print localisation information if available. + * the query is expected to be in the client encoding. + */ + static void + ReportLocalisation(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 && loc>0) + { + int clen, slen, i, * qidx, ibeg, iend, last_nl, loc_line; + char *wquery, *cursor; + + /* (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' && i=0 && locloc) + iend = i; + + wquery[qidx[i]] = ' '; + last_nl = i; + } + } + /* set extract beginning. */ + if (i==loc && last_nl!=-1) + ibeg = last_nl+1; + } + + /* (4) if the extract is too long, we truncate it. */ + 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; + else + { + /* we truncate right. */ + if (loc+MIN_RIGHT_CUT=iend from above) + * now we truncate left. + */ + if (iend-ibeg>DISPLAY_SIZE) + ibeg = iend-DISPLAY_SIZE; + } + } + + /* (5) if the line is too short, we could fix it here. */ + + /* the extract MUST contain the localisation! */ + psql_assert(ibeg<=loc && iend>loc); + + /* (6) string to show cursor position under the extract. */ + cursor = (char *) palloc(loc-ibeg+2); + for (i=0; i