diff options
author | Michael Widenius <monty@askmonty.org> | 2012-05-30 00:37:55 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2012-05-30 00:37:55 +0300 |
commit | aa81e025a88d13c5040bb3fe808d70fd6d1e560c (patch) | |
tree | b4c742ede7e98215c740c143681d91ad53dce998 /strings | |
parent | 3f4ef5928e72faf2b7fd0c98c8705ac649d2faf9 (diff) | |
download | mariadb-git-aa81e025a88d13c5040bb3fe808d70fd6d1e560c.tar.gz |
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
Diffstat (limited to 'strings')
-rw-r--r-- | strings/my_vsnprintf.c | 185 |
1 files changed, 143 insertions, 42 deletions
diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index 64c37ca0537..7ace577130f 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -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); +} |