diff --git a/client/mysql.cc b/client/mysql.cc index b8240ca..056777c 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -134,7 +134,8 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0, default_pager_set= 0, opt_sigint_ignore= 0, auto_vertical_output= 0, show_warnings= 0, executing_query= 0, interrupted_query= 0, - ignore_spaces= 0, sigint_received= 0, opt_syslog= 0; + ignore_spaces= 0, sigint_received= 0, opt_syslog= 0, + opt_unicode_drawing; static my_bool debug_info_flag, debug_check_flag; static my_bool column_types_flag; static my_bool preserve_comments= 0; @@ -1773,6 +1774,9 @@ static struct my_option my_long_options[] = {"i-am-a-dummy", 'U', "Synonym for option --safe-updates, -U.", &safe_updates, &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"unicode-drawing", 'd', "Use unicode drawing characters.", + &opt_unicode_drawing, &opt_unicode_drawing, 0, GET_BOOL, NO_ARG, 1, 0, 0, + 0, 0, 0}, {"verbose", 'v', "Write more. (-v -v -v gives the table output format).", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"version", 'V', "Output version information and exit.", 0, 0, 0, @@ -3826,6 +3830,8 @@ static void print_table_data(MYSQL_RES *result) { String separator(256); + String separator_end(256); + String separator_mid(256); MYSQL_ROW cur; MYSQL_FIELD *field; bool *num_flag; @@ -3840,7 +3846,17 @@ print_table_data(MYSQL_RES *result) return; mysql_field_seek(result,0); } - separator.copy("+",1,charset_info); + if (opt_unicode_drawing) + { + separator.copy("┌",3,charset_info); + separator_end.copy("└",3,charset_info); + separator_mid.copy("├",3,charset_info); + } + else + { + separator.copy("+",1,charset_info); + } + uint fieldnr = 0; while ((field = mysql_fetch_field(result))) { size_t length= column_names ? field->name_length : 0; @@ -3851,15 +3867,48 @@ print_table_data(MYSQL_RES *result) if (length < 4 && !IS_NOT_NULL(field->flags)) length=4; // Room for "NULL" field->max_length=length; - separator.fill(separator.length()+length+2,'-'); - separator.append('+'); + if (opt_unicode_drawing) + { + separator.fill((length*3)+separator.length()+6,"─"); + separator_mid.fill((length*3)+separator_mid.length()+6,"─"); + separator_end.fill((length*3)+separator_end.length()+6,"─"); + if (fieldnr+1 == result->field_count) + { + separator.append("┐"); + separator_end.append("┘"); + separator_mid.append("┤"); + } + else + { + separator.append("┬"); + separator_end.append("┴"); + separator_mid.append("┼"); + } + fieldnr++; + } + else + { + separator.fill(length+separator.length()+2,"-"); + separator.append("+"); + } } separator.append('\0'); // End marker for \0 + if (opt_unicode_drawing) + { + separator_end.append('\0'); // End marker for \0 + separator_mid.append('\0'); // End marker for \0 + } tee_puts((char*) separator.ptr(), PAGER); if (column_names) { mysql_field_seek(result,0); - (void) tee_fputs("|", PAGER); + if (opt_unicode_drawing) { + (void) tee_fputs("│", PAGER); + } + else + { + (void) tee_fputs("|", PAGER); + } for (uint off=0; (field = mysql_fetch_field(result)) ; off++) { size_t name_length= strlen(field->name); @@ -3867,13 +3916,26 @@ print_table_data(MYSQL_RES *result) field->name, field->name + name_length); size_t display_length= field->max_length + name_length - numcells; - tee_fprintf(PAGER, " %-*s |", - min(display_length, MAX_COLUMN_LENGTH), - field->name); + if (opt_unicode_drawing) { + tee_fprintf(PAGER, " %-*s │", + min(display_length, MAX_COLUMN_LENGTH), + field->name); + } else { + tee_fprintf(PAGER, " %-*s |", + min(display_length, MAX_COLUMN_LENGTH), + field->name); + } num_flag[off]= IS_NUM(field->type); } (void) tee_fputs("\n", PAGER); - tee_puts((char*) separator.ptr(), PAGER); + if (opt_unicode_drawing) + { + tee_puts((char*) separator_mid.ptr(), PAGER); + } + else + { + tee_puts((char*) separator.ptr(), PAGER); + } } while ((cur= mysql_fetch_row(result))) @@ -3881,7 +3943,13 @@ print_table_data(MYSQL_RES *result) if (interrupted_query) break; ulong *lengths= mysql_fetch_lengths(result); - (void) tee_fputs("| ", PAGER); + if (opt_unicode_drawing) { + (void) tee_fputs("│ ", PAGER); + } + else + { + (void) tee_fputs("| ", PAGER); + } mysql_field_seek(result, 0); for (uint off= 0; off < mysql_num_fields(result); off++) { @@ -3928,11 +3996,24 @@ print_table_data(MYSQL_RES *result) else tee_print_sized_data(buffer, data_length, field_max_length+extra_padding, FALSE); } - tee_fputs(" |", PAGER); + if (opt_unicode_drawing) { + tee_fputs(" │", PAGER); + } + else + { + tee_fputs(" |", PAGER); + } } (void) tee_fputs("\n", PAGER); } - tee_puts((char*) separator.ptr(), PAGER); + if (opt_unicode_drawing) + { + tee_puts((char*) separator_end.ptr(), PAGER); + } + else + { + tee_puts((char*) separator.ptr(), PAGER); + } my_safe_afree((bool *) num_flag, sz, MAX_ALLOCA_SIZE); } diff --git a/include/sql_string.h b/include/sql_string.h index 9d96386..166ab8b 100644 --- a/include/sql_string.h +++ b/include/sql_string.h @@ -462,7 +462,7 @@ public: } return 0; } - bool fill(size_t max_length,char fill); + bool fill(size_t max_length,char *fill); void strip_sp(); friend int sortcmp(const String *a,const String *b, const CHARSET_INFO *cs); friend int stringcmp(const String *a,const String *b); diff --git a/sql-common/sql_string.cc b/sql-common/sql_string.cc index 477ed7f..4d7047e 100644 --- a/sql-common/sql_string.cc +++ b/sql-common/sql_string.cc @@ -420,16 +420,20 @@ bool String::set_ascii(const char *str, size_t arg_length) /* This is used by mysql.cc */ -bool String::fill(size_t max_length,char fill_char) +bool String::fill(size_t max_length,char *fill_char) { + uint dummy_errors; if (m_length > max_length) m_ptr[m_length= max_length]= 0; else { if (mem_realloc(max_length)) return true; - memset(m_ptr + m_length, fill_char, max_length - m_length); - m_length= max_length; + while (m_length < max_length) { + m_length+= copy_and_convert(m_ptr + m_length, (uint) strlen(fill_char), m_charset, + fill_char, 4, &my_charset_utf8mb4_general_ci, + &dummy_errors); + } } return false; }