Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.2:Update
firebird-classic
firebird-2.5.2-isqlalign.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File firebird-2.5.2-isqlalign.patch of Package firebird-classic
From: asfernandes <asfernandes@de594faa-8d1b-4a0c-9a6a-a7de5f8bf859> Date: Tue, 5 Apr 2011 21:30:27 +0000 Subject: Fixed CORE-3431 - ISQL pads UTF-8 data incorrectly. git-svn-id: https://firebird.svn.sourceforge.net/svnroot/firebird/firebird/trunk@52676 de594faa-8d1b-4a0c-9a6a-a7de5f8bf859 Conflicts: src/isql/isql.epp --- src/isql/isql.epp | 159 +++++++++++++++++++++++++++++++++++++++++++--------- src/isql/isql.h | 1 + 2 files changed, 132 insertions(+), 28 deletions(-) diff --git a/src/isql/isql.epp b/src/isql/isql.epp index d764102..dc0936d 100644 --- a/src/isql/isql.epp +++ b/src/isql/isql.epp @@ -131,6 +131,8 @@ using MsgFormat::SafeArg; #include "../isql/InputDevices.h" #include "../isql/OptionsBase.h" +#include "../intl/charsets.h" +#include <unicode/utf8.h> DATABASE DB = COMPILETIME "yachts.lnk"; @@ -245,6 +247,98 @@ const switch_info switches[] = }; +namespace IcuUtil +{ + // Duplicate from ICU to not need to link ISQL with it. It's used by U8_NEXT_UNSAFE. + static const uint8_t utf8_countTrailBytes[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, + 3, 3, 3, /* illegal in Unicode */ + 4, 4, 4, 4, /* illegal in Unicode */ + 5, 5, /* illegal in Unicode */ + 0, 0 /* illegal bytes 0xfe and 0xff */ + }; + + // Return the number of characters of a string. + static unsigned charLength(SSHORT sqlsubtype, unsigned len, const char* str) + { + if (sqlsubtype != CS_UNICODE_FSS && sqlsubtype != CS_UTF8) + return len; + + unsigned charLen = 0; + unsigned i = 0; + + while (i < len) + { + UChar32 c; + U8_NEXT_UNSAFE(str, i, c); + ++charLen; + } + + return charLen; + } + + // Pads a string to a specified column width. + static void pad(char* buffer, SSHORT sqlsubtype, unsigned len, const char* str, unsigned width, + bool right) + { + if (sqlsubtype != CS_UNICODE_FSS && sqlsubtype != CS_UTF8) + { + // Truncate if necessary. + if (len > width) + len = width; + + sprintf(buffer, (right ? "%*.*s" : "%-*.*s"), width, len, str); + return; + } + + unsigned i = 0; + + while (i < len && width > 0) + { + UChar32 c; + U8_NEXT_UNSAFE(str, i, c); + --width; + } + + if (right) + { + while (width-- > 0) + *buffer++ = ' '; + } + + memcpy(buffer, str, i); + buffer += i; + + if (!right) + { + while (width-- > 0) + *buffer++ = ' '; + } + + *buffer = '\0'; + } +} + + static inline bool commit_trans(isc_tr_handle* x) { if (isc_commit_transaction (isc_status, x)) { @@ -583,6 +677,7 @@ int ISQL_main(int argc, char* argv[]) TEXT tabname[WORDLENGTH]; tabname[0] = '\0'; isqlGlob.db_SQL_dialect = 0; + isqlGlob.att_charset = 0; // Output goes to stdout by default isqlGlob.Out = stdout; @@ -5862,6 +5957,7 @@ void ISQL_get_version(bool call_by_create_db) isc_info_ods_version, isc_info_ods_minor_version, isc_info_db_sql_dialect, + frb_info_att_charset, Version_info ? isc_info_firebird_version: isc_info_end, isc_info_end }; @@ -6018,6 +6114,10 @@ void ISQL_get_version(bool call_by_create_db) } break; + case frb_info_att_charset: + isqlGlob.att_charset = gds__vax_integer(p, length); + break; + default: isqlGlob.printf("Internal error: Unexpected isc_info_value %d%s", item, NEWLINE); @@ -7358,18 +7458,6 @@ static bool checkSpecial(TEXT* const p, const int length, const double value) } -static void align_string(char* out, unsigned clen, unsigned slen, const char* s) -{ - if (slen > clen) - slen = clen; - memcpy(out, s, slen); - if (clen > slen) - memset(out + slen, ' ', clen - slen); - out[clen] = ' '; - out[clen + 1] = '\0'; -} - - static SSHORT print_item(TEXT** s, XSQLVAR* var, const int length) { /************************************** @@ -7657,12 +7745,12 @@ static SSHORT print_item(TEXT** s, XSQLVAR* var, const int length) sprintf(p, "%-*s ", length, buff2); ISQL_FREE(buff2); } - else if (List) { + else if (List) isqlGlob.printf("%s%s", string, NEWLINE); - } else { - align_string(p, length, var->sqllen, var->sqldata); + IcuUtil::pad(p, var->sqlsubtype, strlen(var->sqldata), var->sqldata, length, false); + strcat(p, " "); } break; @@ -7750,12 +7838,12 @@ static SSHORT print_item(TEXT** s, XSQLVAR* var, const int length) } ISQL_FREE(buff2); } - else if (List) { + else if (List) isqlGlob.printf("%s%s", avary->vary_string, NEWLINE); - } else { - align_string(p, length, avary->vary_length, avary->vary_string); + IcuUtil::pad(p, var->sqlsubtype, avary->vary_length, avary->vary_string, length, false); + strcat(p, " "); } break; } @@ -8193,16 +8281,20 @@ static void process_header(const XSQLDA* sqlda, const int pad[], TEXT header[], for (const XSQLVAR* const end = var + sqlda->sqld; var < end; var++, i++) { const SSHORT type = var->sqltype & ~1; - if (type == SQL_TEXT || type == SQL_VARYING) - sprintf(p, "%-*.*s ", pad[i], pad[i], var->aliasname); - else - sprintf(p, "%*s ", pad[i], var->aliasname); + + IcuUtil::pad(p, isqlGlob.att_charset, var->aliasname_length, var->aliasname, pad[i], + (type != SQL_TEXT && type != SQL_VARYING)); + strcat(p, " "); + + p += strlen(p); + // Separators need not go on forever no more than a line - size_t limit = strlen(p); - for (size_t j = 1; j < limit && j < 80; j++) + unsigned limit = IcuUtil::charLength(isqlGlob.att_charset, var->aliasname_length, var->aliasname); + limit = MAX(limit, pad[i]) + 1; + + for (unsigned j = 1; j < limit && j < 80; j++) *p2++ = '='; *p2++ = BLANK; - p += limit; } *p2 = '\0'; } @@ -8441,7 +8533,7 @@ static SLONG process_sqlda_display(XSQLDA* const sqlda, SLONG buffer[], int pad[ USHORT data_length, disp_length, alignment; data_length = disp_length = alignment = var->sqllen; - SSHORT namelength = var->aliasname_length; + SSHORT namelength = IcuUtil::charLength(isqlGlob.att_charset, var->aliasname_length, var->aliasname); // Minimum display length should not be less than that needed // for displaying null @@ -8483,6 +8575,8 @@ static SLONG process_sqlda_display(XSQLDA* const sqlda, SLONG buffer[], int pad[ // OCTETS data is displayed in hex if (var->sqlsubtype == 1) disp_length = 2 * var->sqllen; + else if (var->sqlsubtype == 4) + disp_length /= 4; break; case SQL_VARYING: data_length += sizeof(USHORT) + 1; @@ -8490,6 +8584,8 @@ static SLONG process_sqlda_display(XSQLDA* const sqlda, SLONG buffer[], int pad[ // OCTETS data is displayed in hex if (var->sqlsubtype == 1) disp_length = 2 * var->sqllen; + else if (var->sqlsubtype == 4) + disp_length /= 4; break; case SQL_SHORT: disp_length = SHORT_LEN; @@ -8520,7 +8616,10 @@ static SLONG process_sqlda_display(XSQLDA* const sqlda, SLONG buffer[], int pad[ // This is the print width of each column - pad[i] = (disp_length > namelength ? disp_length : namelength); + if (disp_length < namelength) + disp_length = namelength; + + pad[i] = disp_length; // Is there a collist entry, then use that width, but only for text if (type == SQL_TEXT || type == SQL_VARYING) @@ -8529,8 +8628,11 @@ static SLONG process_sqlda_display(XSQLDA* const sqlda, SLONG buffer[], int pad[ pad[i] = global_Col_default; } + if ((type == SQL_TEXT || type == SQL_VARYING) && var->sqlsubtype == 4) + disp_length *= 4; + // The total line length - linelength += pad[i] + 1; + linelength += disp_length + 1; // Allocate space in buffer for data @@ -8538,6 +8640,7 @@ static SLONG process_sqlda_display(XSQLDA* const sqlda, SLONG buffer[], int pad[ var->sqldata = (SCHAR*) buffer + offset; offset += data_length; } + return linelength; } diff --git a/src/isql/isql.h b/src/isql/isql.h index e076c3c..9d350e4 100644 --- a/src/isql/isql.h +++ b/src/isql/isql.h @@ -362,6 +362,7 @@ public: // from isql.epp USHORT major_ods; USHORT minor_ods; + USHORT att_charset; void printf(const char* buffer, ...); void prints(const char* buffer); }; -- 1.7.7
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor