1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Added text for errno in error messages by:

- Adding %M my_sprintf() modifier that prints error number - system-error-text
- Modified mysys, mysql_client and SQL error messages to use %M instead of %d
- Added my_strerror()
Updated handler errors to 5.6 error numbers
Updated text for a few error messages (to match 5.6)
Increased length of command name in error output

extra/comp_err.c:
  Added support for %M
include/my_base.h:
  Updated handler errors to 5.6 error numbers
include/my_sys.h:
  Added my_strerror()
libmysql/errmsg.c:
  Updated error messages to use %M
mysql-test/r/errors.result:
  Updated result as error message have changed
mysql-test/r/innodb_mysql_sync.result:
  Updated result with text for errno
mysql-test/r/myisam-system.result:
  Updated result with text for errno
mysql-test/r/myisam.result:
  Updated result as error message have changed
mysql-test/r/myisampack.result:
  Updated result with text for errno
mysql-test/r/mysql.result:
  Updated result with text for errno
mysql-test/r/mysql_upgrade.result:
  Updated result with text for errno
mysql-test/r/partition_datatype.result:
  Updated result as error message have changed
mysql-test/r/partition_innodb_plugin.result:
  Updated result with text for errno
mysql-test/r/ps_1general.result:
  Updated result with text for errno
mysql-test/r/trigger.result:
  Updated result with text for errno
mysql-test/r/type_bit.result:
  Updated result as error message have changed
mysql-test/r/type_bit_innodb.result:
  Updated result as error message have changed
mysql-test/r/type_blob.result:
  Updated result as error message have changed
mysql-test/suite/archive/archive.result:
  Updated result with text for errno
mysql-test/suite/binlog/r/binlog_index.result:
  Updated result with text for errno
mysql-test/suite/binlog/r/binlog_ioerr.result:
  Updated result with text for errno
mysql-test/suite/csv/csv.result:
  Updated result with text for errno
mysql-test/suite/federated/federated_bug_35333.result:
  Updated result with text for errno
mysql-test/suite/innodb/r/innodb-create-options.result:
  Updated result with text for errno
mysql-test/suite/innodb/r/innodb-index.result:
  Updated result with text for errno
mysql-test/suite/innodb/r/innodb-zip.result:
  Updated result as error message have changed
mysql-test/suite/innodb/r/innodb.result:
  Updated result with text for errno
mysql-test/suite/innodb/r/innodb_bug21704.result:
  Updated result with text for errno
mysql-test/suite/innodb/r/innodb_bug46000.result:
  Updated result with text for errno
mysql-test/suite/innodb/r/innodb_bug53591.result:
  Updated result as error message have changed
mysql-test/suite/innodb/r/innodb_corrupt_bit.result:
  New error numbers
mysql-test/suite/innodb/r/innodb_prefix_index_liftedlimit.result:
  Updated result as error message have changed
mysql-test/suite/innodb/t/innodb-create-options.test:
  Added regexp to avoid system error text
mysql-test/suite/innodb/t/innodb-zip.test:
  Added regexp to avoid system error text
mysql-test/suite/maria/maria-recovery2.result:
  Updated supression rule
mysql-test/suite/maria/maria-recovery2.test:
  Updated supression rule
mysql-test/suite/maria/maria.result:
  Updated result as error message have changed
mysql-test/suite/parts/r/partition_bit_innodb.result:
  
  Updated result as error message have changed
mysql-test/suite/parts/r/partition_bit_myisam.result:
  
  Updated result as error message have changed
mysql-test/suite/percona/percona_innodb_fake_changes.result:
  Updated result with text for errno
mysql-test/suite/perfschema/r/dml_cond_instances.result:
  Updated result as error message have changed
mysql-test/suite/perfschema/r/dml_events_waits_current.result:
  Updated result as error message have changed
mysql-test/suite/perfschema/r/dml_events_waits_history.result:
  Updated result as error message have changed
mysql-test/suite/perfschema/r/dml_events_waits_history_long.result:
  Updated result as error message have changed
mysql-test/suite/perfschema/r/dml_ews_by_instance.result:
  Updated result as error message have changed
mysql-test/suite/perfschema/r/dml_ews_by_thread_by_event_name.result:
  Updated result as error message have changed
mysql-test/suite/perfschema/r/dml_ews_global_by_event_name.result:
  Updated result as error message have changed
mysql-test/suite/perfschema/r/dml_file_instances.result:
  Updated result as error message have changed
mysql-test/suite/perfschema/r/dml_file_summary_by_event_name.result:
  Updated result as error message have changed
mysql-test/suite/perfschema/r/dml_file_summary_by_instance.result:
  Updated result as error message have changed
mysql-test/suite/perfschema/r/dml_mutex_instances.result:
  Updated result as error message have changed
mysql-test/suite/perfschema/r/dml_performance_timers.result:
  Updated result as error message have changed
mysql-test/suite/perfschema/r/dml_rwlock_instances.result:
  Updated result as error message have changed
mysql-test/suite/perfschema/r/dml_threads.result:
  Updated result as error message have changed
mysql-test/suite/perfschema/r/misc.result:
  Updated result with text for errno
mysql-test/suite/perfschema/r/privilege.result:
  Updated result with text for errno
mysql-test/suite/rpl/r/rpl_EE_err.result:
  Updated result with text for errno
mysql-test/suite/rpl/r/rpl_binlog_errors.result:
  Updated result with text for errno
mysql-test/suite/rpl/r/rpl_drop_db.result:
  Updated result with text for errno
mysys/errors.c:
  Updated error messages to use %M
  Changed all errors to use Errcode: consistenly
mysys/my_handler_errors.h:
  Updated handler errors to 5.6 error numbers
sql/share/errmsg-utf8.txt:
  Updated error messages to use %M
sql/sys_vars.cc:
  Added error number to ER_EVENT_SET_VAR_ERROR
strings/my_vsnprintf.c:
  Added %M my_sprintf() modifier that prints error number - system-error-text
  Simplify code
  Movied common code to function
  Removed some casts that was not necessary when reading integer/unsigned int stored in longlong
  Added my_strerror()
unittest/mysys/my_vsnprintf-t.c:
  Added testing of %M
This commit is contained in:
Michael Widenius
2012-05-30 00:37:55 +03:00
parent 3f4ef5928e
commit aa81e025a8
66 changed files with 1063 additions and 891 deletions

View File

@ -17,10 +17,14 @@
#include "strings_def.h"
#include <m_ctype.h>
#include <stdarg.h>
#include <my_sys.h>
#include <my_base.h>
#include <../mysys/my_handler_errors.h>
#define MAX_ARGS 32 /* max positional args count*/
#define MAX_PRINT_INFO 32 /* max print position count */
#define MAX_WIDTH 65535
#define LENGTH_ARG 1
#define WIDTH_ARG 2
@ -65,6 +69,7 @@ struct print_info
static const char *get_length(const char *fmt, size_t *length, uint *pre_zero)
{
for (; my_isdigit(&my_charset_latin1, *fmt); fmt++)
{
*length= *length * 10 + (uint)(*fmt - '0');
@ -75,23 +80,27 @@ static const char *get_length(const char *fmt, size_t *length, uint *pre_zero)
}
/**
Calculates print width or index of positional argument
/*
Get argument for '*' parameter
@param fmt processed string
@param width print width or index of positional argument
@param args_arr Arguments to printf
@param arg_count Number of arguments to printf
@param length returns length of argument
@param flag returns flags with PREZERO_ARG set if necessary
@retval
string position right after width digits
@return new fmt
*/
static const char *get_width(const char *fmt, size_t *width)
static const char *get_length_arg(const char *fmt, ARGS_INFO *args_arr,
uint *arg_count, size_t *length, uint *flags)
{
for (; my_isdigit(&my_charset_latin1, *fmt); fmt++)
{
*width= *width * 10 + (uint)(*fmt - '0');
}
return fmt;
fmt= get_length(fmt+1, length, flags);
*arg_count= max(*arg_count, (uint) *length);
(*length)--;
DBUG_ASSERT(*fmt == '$' && *length < MAX_ARGS);
args_arr[*length].arg_type= 'd';
return fmt+1;
}
/**
@ -123,6 +132,8 @@ static const char *check_longlong(const char *fmt, uint *have_longlong)
fmt++;
*have_longlong= (sizeof(size_t) == sizeof(longlong));
}
if (*fmt == 'p')
*have_longlong= (sizeof(void *) == sizeof(longlong));
return fmt;
}
@ -227,7 +238,7 @@ static char *process_bin_arg(char *to, char *end, size_t width, char *par)
static char *process_dbl_arg(char *to, char *end, size_t width,
double par, char arg_type)
{
if (width == SIZE_T_MAX)
if (width == MAX_WIDTH)
width= FLT_DIG; /* width not set, use default */
else if (width >= NOT_FIXED_DEC)
width= NOT_FIXED_DEC - 1; /* max.precision for my_fcvt() */
@ -338,42 +349,31 @@ start:
/* Get print length */
if (*fmt == '*')
{
fmt++;
fmt= get_length(fmt, &print_arr[idx].length, &print_arr[idx].flags);
print_arr[idx].length--;
DBUG_ASSERT(*fmt == '$' && print_arr[idx].length < MAX_ARGS);
args_arr[print_arr[idx].length].arg_type= 'd';
fmt= get_length_arg(fmt, args_arr, &arg_count, &print_arr[idx].length,
&print_arr[idx].flags);
print_arr[idx].flags|= LENGTH_ARG;
arg_count= max(arg_count, print_arr[idx].length + 1);
fmt++;
}
else
fmt= get_length(fmt, &print_arr[idx].length, &print_arr[idx].flags);
if (*fmt == '.')
{
uint flags= 0;
fmt++;
/* Get print width */
if (*fmt == '*')
{
fmt++;
fmt= get_width(fmt, &print_arr[idx].width);
print_arr[idx].width--;
DBUG_ASSERT(*fmt == '$' && print_arr[idx].width < MAX_ARGS);
args_arr[print_arr[idx].width].arg_type= 'd';
fmt= get_length_arg(fmt, args_arr, &arg_count, &print_arr[idx].width,
&flags);
print_arr[idx].flags|= WIDTH_ARG;
arg_count= max(arg_count, print_arr[idx].width + 1);
fmt++;
}
else
fmt= get_width(fmt, &print_arr[idx].width);
fmt= get_length(fmt, &print_arr[idx].width, &flags);
}
else
print_arr[idx].width= SIZE_T_MAX;
print_arr[idx].width= MAX_WIDTH;
fmt= check_longlong(fmt, &args_arr[arg_index].have_longlong);
if (*fmt == 'p')
args_arr[arg_index].have_longlong= (sizeof(void *) == sizeof(longlong));
args_arr[arg_index].arg_type= print_arr[idx].arg_type= *fmt;
print_arr[idx].arg_idx= arg_index;
@ -412,6 +412,7 @@ start:
else
args_arr[i].longlong_arg= va_arg(ap, uint);
break;
case 'M':
case 'c':
args_arr[i].longlong_arg= va_arg(ap, int);
break;
@ -472,17 +473,34 @@ start:
? (size_t)args_arr[print_arr[i].length].longlong_arg
: print_arr[i].length;
if (args_arr[print_arr[i].arg_idx].have_longlong)
larg = args_arr[print_arr[i].arg_idx].longlong_arg;
else if (print_arr[i].arg_type == 'd' || print_arr[i].arg_type == 'i' )
larg = (int) args_arr[print_arr[i].arg_idx].longlong_arg;
else
larg= (uint) args_arr[print_arr[i].arg_idx].longlong_arg;
larg = args_arr[print_arr[i].arg_idx].longlong_arg;
to= process_int_arg(to, end, length, larg, print_arr[i].arg_type,
print_arr[i].flags);
break;
}
case 'M':
{
longlong larg;
char *org_to= to;
char errmsg_buff[MYSYS_STRERROR_SIZE];
length= (print_arr[i].flags & WIDTH_ARG)
? (size_t)args_arr[print_arr[i].width].longlong_arg
: print_arr[i].width;
larg = args_arr[print_arr[i].arg_idx].longlong_arg;
to= process_int_arg(to, end, 0, larg, 'd', print_arr[i].flags);
width-= (to - org_to);
if (width <= 4)
break;
*to++= ' ';
*to++= '-';
*to++= ' ';
my_strerror(errmsg_buff, sizeof(errmsg_buff), (int) larg);
to= process_str_arg(cs, to, end, width, errmsg_buff,
print_arr[i].flags);
break;
}
default:
break;
}
@ -490,6 +508,7 @@ start:
if (to == end)
break;
/* Copy data after the % format expression until next % */
length= min(end - to , print_arr[i].end - print_arr[i].begin);
if (to + length < end)
length++;
@ -501,13 +520,14 @@ start:
}
else
{
uint flags= 0;
/* Process next positional argument*/
DBUG_ASSERT(*fmt == '%');
print_arr[idx].end= fmt - 1;
idx++;
fmt++;
arg_index= 0;
fmt= get_width(fmt, &arg_index);
fmt= get_length(fmt, &arg_index, &flags);
DBUG_ASSERT(*fmt == '$');
fmt++;
arg_count= max(arg_count, arg_index);
@ -585,6 +605,7 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
if (*fmt == '.')
{
uint flags= 0;
fmt++;
if (*fmt == '*')
{
@ -592,10 +613,10 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
width= va_arg(ap, int);
}
else
fmt= get_width(fmt, &width);
fmt= get_length(fmt, &width, &flags);
}
else
width= SIZE_T_MAX;
width= MAX_WIDTH;
fmt= check_longlong(fmt, &have_longlong);
@ -622,8 +643,6 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
{
/* Integer parameter */
longlong larg;
if (*fmt == 'p')
have_longlong= (sizeof(void *) == sizeof(longlong));
if (have_longlong)
larg = va_arg(ap,longlong);
@ -644,6 +663,24 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
*to++= (char) larg;
continue;
}
else if (*fmt == 'M')
{
const char *org_to= to;
int larg= va_arg(ap, int);
to= process_int_arg(to, end, 0, larg, 'd', print_type);
width-= (to - org_to);
if ((end - to) >= 4 && (int) width >= 4)
{
char errmsg_buff[MYSYS_STRERROR_SIZE];
*to++= ' ';
*to++= '-';
*to++= ' ';
width-= 3;
my_strerror(errmsg_buff, sizeof(errmsg_buff), larg);
to= process_str_arg(cs, to, end, width, errmsg_buff, print_type);
}
continue;
}
/* We come here on '%%', unknown code or too long parameter */
if (to == end)
@ -697,3 +734,67 @@ int my_vfprintf(FILE *stream, const char* format, va_list args)
(void) my_vsnprintf(cvtbuf, sizeof(cvtbuf), format, args);
return fprintf(stream, "%s\n", cvtbuf);
}
/*
Return system error text for given error number
@param buf Buffer (of size MYSYS_STRERROR_SIZE)
@param len Length of buffer
@param nr Error number
*/
void my_strerror(char *buf, size_t len, int nr)
{
char *msg= NULL;
buf[0]= '\0'; /* failsafe */
if (nr <= 0)
{
strmake(buf, (nr == 0 ?
"Internal error/check (Not system error)" :
"Internal error < 0 (Not system error)"),
len-1);
return;
}
/*
These (handler-) error messages are shared by perror, as required
by the principle of least surprise.
*/
if ((nr >= HA_ERR_FIRST) && (nr <= HA_ERR_LAST))
{
msg= (char *) handler_error_messages[nr - HA_ERR_FIRST];
strmake(buf, msg, len - 1);
}
else
{
/*
On Windows, do things the Windows way. On a system that supports both
the GNU and the XSI variant, use whichever was configured (GNU); if
this choice is not advertised, use the default (POSIX/XSI). Testing
for __GNUC__ is not sufficient to determine whether this choice exists.
*/
#if defined(__WIN__)
strerror_s(buf, len, nr);
#elif ((defined _POSIX_C_SOURCE && (_POSIX_C_SOURCE >= 200112L)) || \
(defined _XOPEN_SOURCE && (_XOPEN_SOURCE >= 600))) && \
! defined _GNU_SOURCE
strerror_r(nr, buf, len); /* I can build with or without GNU */
#elif defined _GNU_SOURCE
char *r= strerror_r(nr, buf, len);
if (r != buf) /* Want to help, GNU? */
strmake(buf, r, len - 1); /* Then don't. */
#else
strerror_r(nr, buf, len);
#endif
}
/*
strerror() return values are implementation-dependent, so let's
be pragmatic.
*/
if (!buf[0])
strmake(buf, "unknown error", len - 1);
}