Commit 0c6bdfaa authored by unknown's avatar unknown

Made my_snprintf() behavior snprintf() compatible when printing %x arguments (it should

produce hex digits in lower case). (fixed version)

Replaced _dig_vec array with two _dig_vec_upper/_dig_vec_lower arrays.
Added extra argument to int2str function which controls case of digits you get.
Replaced lot of invocations of int2str for decimal radix with more optimized int10_to_str()
function.
Removed unused my_itoa/my_ltoa functions.


client/mysql.cc:
  Replaced int2str invocations with radix argument equal to 10 with optimized int10_to_str()
  call.
client/mysqladmin.c:
  Replaced int2str invocations with radix argument equal to 10 with optimized int10_to_str()
  call.
dbug/dbug.c:
   _dig_vec became _dig_vec_upper.
include/m_string.h:
  _dig_vec is obsoleted by _dig_vec_upper/_dig_vec_lower.
  my_itoa()/my_ltoa() functions were removed because they were never used in our code.
  int2str() now has one more argument which controls case of digits it will produce.
include/my_global.h:
  my_itoa()/my_ltoa() functions were removed because they were never used in our code.
isam/isamchk.c:
  Replaced int2str invocations with radix argument equal to 10 with optimized int10_to_str()
  call.
libmysql/libmysql.def:
  _dig_vec is obsoleted by _dig_vec_upper/_dig_vec_lower.
myisam/myisamchk.c:
  Replaced int2str invocation with radix argument equal to 10 with optimized int10_to_str()
  call.
mysys/mf_tempfile.c:
  _dig_vec became _dig_vec_upper.
mysys/my_error.c:
  Replaced int2str invocations with radix argument equal to 10 with optimized int10_to_str()
  call.
mysys/my_tempnam.c:
  _dig_vec became _dig_vec_upper.
sql-common/client.c:
  Replaced int2str invocation with radix argument equal to 10 with optimized int10_to_str()
  call.
sql/item_strfunc.cc:
  _dig_vec became _dig_vec_upper. Also we don't need hex[] array in this file now because we
  have _dig_vec_lower instead.
sql/mysqld.cc:
  Replaced int2str invocations with radix argument equal to 10 with optimized int10_to_str()
  call.
sql/password.c:
  _dig_vec became _dig_vec_upper.
sql/sql_bitmap.h:
  _dig_vec became _dig_vec_upper.
strings/int2str.c:
  Replaced _dig_vec by _dig_vec_upper/_dig_vec_lower pair.
  int2str() now has one more argument which controls case of digits it will produce.
  my_itoa()/my_ltoa() functions were removed because they were never used in our code.
strings/longlong2str-x86.s:
  _dig_vec became _dig_vec_upper.
strings/longlong2str.c:
  _dig_vec became _dig_vec_upper.
strings/my_vsnprintf.c:
  If my_snprintf() is printing %x argument it should produce lower case hexadecimal digits
  to be snprintf() compatible.
parent 72e2e58e
......@@ -1872,7 +1872,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
{
*pos++= ',';
*pos++= ' ';
pos=int2str(warnings, pos, 10);
pos=int10_to_str(warnings, pos, 10);
pos=strmov(pos, " warning");
if (warnings != 1)
*pos++= 's';
......@@ -3090,21 +3090,21 @@ static void nice_time(double sec,char *buff,bool part_second)
{
tmp=(ulong) floor(sec/(3600.0*24));
sec-=3600.0*24*tmp;
buff=int2str((long) tmp,buff,10);
buff=int10_to_str((long) tmp, buff, 10);
buff=strmov(buff,tmp > 1 ? " days " : " day ");
}
if (sec >= 3600.0)
{
tmp=(ulong) floor(sec/3600.0);
sec-=3600.0*tmp;
buff=int2str((long) tmp,buff,10);
buff=int10_to_str((long) tmp, buff, 10);
buff=strmov(buff,tmp > 1 ? " hours " : " hour ");
}
if (sec >= 60.0)
{
tmp=(ulong) floor(sec/60.0);
sec-=60.0*tmp;
buff=int2str((long) tmp,buff,10);
buff=int10_to_str((long) tmp, buff, 10);
buff=strmov(buff," min ");
}
if (part_second)
......
......@@ -961,24 +961,24 @@ static void nice_time(ulong sec,char *buff)
{
tmp=sec/(3600L*24);
sec-=3600L*24*tmp;
buff=int2str(tmp,buff,10);
buff=int10_to_str(tmp, buff, 10);
buff=strmov(buff,tmp > 1 ? " days " : " day ");
}
if (sec >= 3600L)
{
tmp=sec/3600L;
sec-=3600L*tmp;
buff=int2str(tmp,buff,10);
buff=int10_to_str(tmp, buff, 10);
buff=strmov(buff,tmp > 1 ? " hours " : " hour ");
}
if (sec >= 60)
{
tmp=sec/60;
sec-=60*tmp;
buff=int2str(tmp,buff,10);
buff=int10_to_str(tmp, buff, 10);
buff=strmov(buff," min ");
}
strmov(int2str(sec,buff,10)," sec");
strmov(int10_to_str(sec, buff, 10)," sec");
}
......
......@@ -985,8 +985,8 @@ uint length)
fputc('\n',_db_fp_);
pos=3;
}
fputc(_dig_vec[((tmp >> 4) & 15)], _db_fp_);
fputc(_dig_vec[tmp & 15], _db_fp_);
fputc(_dig_vec_upper[((tmp >> 4) & 15)], _db_fp_);
fputc(_dig_vec_upper[tmp & 15], _db_fp_);
fputc(' ',_db_fp_);
}
(void) fputc('\n',_db_fp_);
......
......@@ -95,7 +95,9 @@ extern char *stpcpy(char *, const char *); /* For AIX with gcc 2.95.3 */
#endif
#endif
extern char NEAR _dig_vec[]; /* Declared in int2str() */
/* Declared in int2str() */
extern char NEAR _dig_vec_upper[];
extern char NEAR _dig_vec_lower[];
#ifdef BAD_STRING_COMPILER
#define strmov(A,B) (memccpy(A,B,0,INT_MAX)-1)
......@@ -113,8 +115,6 @@ extern char NEAR _dig_vec[]; /* Declared in int2str() */
#ifdef MSDOS
#undef bmove_align
#define bmove512(A,B,C) bmove_align(A,B,C)
#define my_itoa(A,B,C) itoa(A,B,C)
#define my_ltoa(A,B,C) ltoa(A,B,C)
extern void bmove_align(gptr dst,const gptr src,uint len);
#endif
......@@ -219,24 +219,19 @@ extern int is_prefix(const char *, const char *);
double my_strtod(const char *str, char **end);
double my_atof(const char *nptr);
#ifdef USE_MY_ITOA
extern char *my_itoa(int val,char *dst,int radix);
extern char *my_ltoa(long val,char *dst,int radix);
#endif
extern char *llstr(longlong value,char *buff);
#ifndef HAVE_STRTOUL
extern long strtol(const char *str, char **ptr, int base);
extern ulong strtoul(const char *str, char **ptr, int base);
#endif
extern char *int2str(long val,char *dst,int radix);
extern char *int2str(long val, char *dst, int radix, char upcase);
extern char *int10_to_str(long val,char *dst,int radix);
extern char *str2int(const char *src,int radix,long lower,long upper,
long *val);
longlong my_strtoll10(const char *nptr, char **endptr, int *error);
#if SIZEOF_LONG == SIZEOF_LONG_LONG
#define longlong2str(A,B,C) int2str((A),(B),(C))
#define longlong2str(A,B,C) int2str((A),(B),(C),1)
#define longlong10_to_str(A,B,C) int10_to_str((A),(B),(C))
#undef strtoll
#define strtoll(A,B,C) strtol((A),(B),(C))
......
......@@ -587,12 +587,6 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define USE_MY_STAT_STRUCT /* For my_lib */
#endif
/* Some things that this system does have */
#ifndef HAVE_ITOA
#define USE_MY_ITOA /* There is no itoa */
#endif
/* Some defines of functions for portability */
#undef remove /* Crashes MySQL on SCO 5.0.0 */
......
......@@ -1800,12 +1800,12 @@ my_string name;
if (buff[0] == ',')
strmov(buff,buff+2);
#endif
len=(uint) (int2str((long) share->rec[field].base.length,length,10) -
len=(uint) (int10_to_str((long) share->rec[field].base.length,length,10) -
length);
if (type == FIELD_BLOB)
{
length[len]='+';
VOID(int2str((long) sizeof(char*),length+len+1,10));
VOID(int10_to_str((long) sizeof(char*),length+len+1,10));
}
printf("%-6d%-6d%-7s%-35s",field+1,start,length,buff);
#ifndef NOT_PACKED_DATABASES
......
......@@ -2,7 +2,8 @@ LIBRARY LIBMYSQL
DESCRIPTION 'MySQL 4.1 Client Library'
VERSION 6.0
EXPORTS
_dig_vec
_dig_vec_lower
_dig_vec_upper
bmove_upp
delete_dynamic
free_defaults
......
......@@ -1389,7 +1389,7 @@ static void descript(MI_CHECK *param, register MI_INFO *info, my_string name)
}
if (buff[0] == ',')
strmov(buff,buff+2);
int2str((long) share->rec[field].length,length,10);
int10_to_str((long) share->rec[field].length,length,10);
null_bit[0]=null_pos[0]=0;
if (share->rec[field].null_bit)
{
......
......@@ -181,7 +181,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
for (length=0 ; length < 8 && uniq ; length++)
{
*end_pos++= _dig_vec[(int) (uniq & 31)];
*end_pos++= _dig_vec_upper[(int) (uniq & 31)];
uniq >>= 5;
}
(void) strmov(end_pos,TMP_EXT);
......
......@@ -90,9 +90,9 @@ int my_error(int nr,myf MyFlags, ...)
register int iarg;
iarg = va_arg(ap, int);
if (*tpos == 'd')
plen= (uint) (int2str((long) iarg,endpos, -10) - endpos);
plen= (uint) (int10_to_str((long) iarg, endpos, -10) - endpos);
else
plen= (uint) (int2str((long) (uint) iarg,endpos,10)- endpos);
plen= (uint) (int10_to_str((long) (uint) iarg, endpos, 10) - endpos);
if (olen + plen < ERRMSGSIZE+2) /* Replace parameter if possible */
{
endpos+=plen;
......
......@@ -161,7 +161,7 @@ my_string my_tempnam(const char *dir, const char *pfx,
for (length=0 ; length < 8 && uniq ; length++)
{
*end_pos++= _dig_vec[(int) (uniq & 31)];
*end_pos++= _dig_vec_upper[(int) (uniq & 31)];
uniq >>= 5;
}
VOID(strmov(end_pos,TMP_EXT));
......
......@@ -451,7 +451,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
/* Get number of connection */
connect_number = uint4korr(handle_connect_map);/*WAX2*/
p= int2str(connect_number, connect_number_char, 10);
p= int10_to_str(connect_number, connect_number_char, 10);
/*
The name of event and file-mapping events create agree next rule:
......
......@@ -2285,8 +2285,8 @@ String *Item_func_hex::val_str(String *str)
from++, to+=2)
{
uint tmp=(uint) (uchar) *from;
to[0]=_dig_vec[tmp >> 4];
to[1]=_dig_vec[tmp & 15];
to[0]=_dig_vec_upper[tmp >> 4];
to[1]=_dig_vec_upper[tmp & 15];
}
return &tmp_value;
}
......@@ -2746,9 +2746,6 @@ static uint nanoseq;
static ulonglong uuid_time=0;
static char clock_seq_and_node_str[]="-0000-000000000000";
/* we cannot use _dig_vec[] as letters should be lowercase */
static const char hex[] = "0123456789abcdef";
/* number of 100-nanosecond intervals between
1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00 */
#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 )
......@@ -2761,7 +2758,7 @@ static void tohex(char *to, uint from, uint len)
to+= len;
while (len--)
{
*--to= hex[from & 15];
*--to= _dig_vec_lower[from & 15];
from >>= 4;
}
}
......@@ -2798,8 +2795,8 @@ String *Item_func_uuid::val_str(String *str)
s=clock_seq_and_node_str+sizeof(clock_seq_and_node_str)-1;
for (i=sizeof(mac)-1 ; i>=0 ; i--)
{
*--s=hex[mac[i] & 15];
*--s=hex[mac[i] >> 4];
*--s=_dig_vec_lower[mac[i] & 15];
*--s=_dig_vec_lower[mac[i] >> 4];
}
randominit(&uuid_rand, tmp + (ulong)start_time, tmp + bytes_sent);
set_clock_seq_str();
......
......@@ -3015,7 +3015,7 @@ int main(int argc, char **argv)
need to have an unique named hEventShudown through the
application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
*/
int2str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
"MySQLShutdown"), 10);
/* Must be initialized early for comparison of service name */
......@@ -3635,7 +3635,7 @@ pthread_handler_decl(handle_connections_shared_memory,arg)
HANDLE event_server_read= 0;
THD *thd= 0;
p= int2str(connect_number, connect_number_char, 10);
p= int10_to_str(connect_number, connect_number_char, 10);
/*
The name of event and file-mapping events create agree next rule:
shared_memory_base_name+unique_part+number_of_connection
......@@ -6224,7 +6224,7 @@ static void create_pid_file()
O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0)
{
char buff[21], *end;
end= int2str((long) getpid(), buff, 10);
end= int10_to_str((long) getpid(), buff, 10);
*end++= '\n';
(void) my_write(file, (byte*) buff, (uint) (end-buff),MYF(MY_WME));
(void) my_close(file, MYF(0));
......
......@@ -321,8 +321,8 @@ octet2hex(char *to, const uint8 *str, uint len)
const uint8 *str_end= str + len;
for (; str != str_end; ++str)
{
*to++= _dig_vec[(*str & 0xF0) >> 4];
*to++= _dig_vec[*str & 0x0F];
*to++= _dig_vec_upper[(*str & 0xF0) >> 4];
*to++= _dig_vec_upper[*str & 0x0F];
}
*to= '\0';
}
......
......@@ -64,15 +64,15 @@ template <uint default_width> class Bitmap
char *s=buf; int i;
for (i=sizeof(buffer)-1; i>=0 ; i--)
{
if ((*s=_dig_vec[buffer[i] >> 4]) != '0')
if ((*s=_dig_vec_upper[buffer[i] >> 4]) != '0')
break;
if ((*s=_dig_vec[buffer[i] & 15]) != '0')
if ((*s=_dig_vec_upper[buffer[i] & 15]) != '0')
break;
}
for (s++, i-- ; i>=0 ; i--)
{
*s++=_dig_vec[buffer[i] >> 4];
*s++=_dig_vec[buffer[i] & 15];
*s++=_dig_vec_upper[buffer[i] >> 4];
*s++=_dig_vec_upper[buffer[i] & 15];
}
*s=0;
return buf;
......
......@@ -14,42 +14,50 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Defines: int2str(), itoa(), ltoa()
int2str(dst, radix, val)
converts the (long) integer "val" to character form and moves it to
the destination string "dst" followed by a terminating NUL. The
result is normally a pointer to this NUL character, but if the radix
is dud the result will be NullS and nothing will be changed.
If radix is -2..-36, val is taken to be SIGNED.
If radix is 2.. 36, val is taken to be UNSIGNED.
That is, val is signed if and only if radix is. You will normally
use radix -10 only through itoa and ltoa, for radix 2, 8, or 16
unsigned is what you generally want.
_dig_vec is public just in case someone has a use for it.
The definitions of itoa and ltoa are actually macros in m_string.h,
but this is where the code is.
Note: The standard itoa() returns a pointer to the argument, when int2str
returns the pointer to the end-null.
itoa assumes that 10 -base numbers are allways signed and other arn't.
*/
#include <my_global.h>
#include "m_string.h"
char NEAR _dig_vec[] =
/*
_dig_vec arrays are public because they are used in several outer places.
*/
char NEAR _dig_vec_upper[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char NEAR _dig_vec_lower[] =
"0123456789abcdefghijklmnopqrstuvwxyz";
char *int2str(register long int val, register char *dst, register int radix)
/*
Convert integer to its string representation in given scale of notation.
SYNOPSIS
int2str()
val - value to convert
dst - points to buffer where string representation should be stored
radix - radix of scale of notation
upcase - flag indicating that whenever we should use upper-case digits
DESCRIPTION
Converts the (long) integer value to its character form and moves it to
the destination buffer followed by a terminating NUL.
If radix is -2..-36, val is taken to be SIGNED, if radix is 2..36, val is
taken to be UNSIGNED. That is, val is signed if and only if radix is.
All other radixes treated as bad and nothing will be changed in this case.
For conversion to decimal representation (radix is -10 or 10) one can use
optimized int10_to_str() function.
RETURN VALUE
Pointer to ending NUL character or NullS if radix is bad.
*/
char *
int2str(register long int val, register char *dst, register int radix,
char upcase)
{
char buffer[65];
register char *p;
long int new_val;
char *dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower;
if (radix < 0) {
if (radix < -36 || radix > -2) return NullS;
......@@ -75,21 +83,21 @@ char *int2str(register long int val, register char *dst, register int radix)
p = &buffer[sizeof(buffer)-1];
*p = '\0';
new_val=(ulong) val / (ulong) radix;
*--p = _dig_vec[(uchar) ((ulong) val- (ulong) new_val*(ulong) radix)];
*--p = dig_vec[(uchar) ((ulong) val- (ulong) new_val*(ulong) radix)];
val = new_val;
#ifdef HAVE_LDIV
while (val != 0)
{
ldiv_t res;
res=ldiv(val,radix);
*--p = _dig_vec[res.rem];
*--p = dig_vec[res.rem];
val= res.quot;
}
#else
while (val != 0)
{
new_val=val/radix;
*--p = _dig_vec[(uchar) (val-new_val*radix)];
*--p = dig_vec[(uchar) (val-new_val*radix)];
val= new_val;
}
#endif
......@@ -99,8 +107,21 @@ char *int2str(register long int val, register char *dst, register int radix)
/*
This is a faster version of the above optimized for the normal case of
radix 10 / -10
Converts integer to its string representation in decimal notation.
SYNOPSIS
int10_to_str()
val - value to convert
dst - points to buffer where string representation should be stored
radix - flag that shows whenever val should be taken as signed or not
DESCRIPTION
This is version of int2str() function which is optimized for normal case
of radix 10/-10. It takes only sign of radix parameter into account and
not its absolute value.
RETURN VALUE
Pointer to ending NUL character.
*/
char *int10_to_str(long int val,char *dst,int radix)
......@@ -133,22 +154,3 @@ char *int10_to_str(long int val,char *dst,int radix)
while ((*dst++ = *p++) != 0) ;
return dst-1;
}
#ifdef USE_MY_ITOA
/* Change to less general itoa interface */
char *my_itoa(int val, char *dst, int radix)
{
VOID(int2str((long) val,dst,(radix == 10 ? -10 : radix)));
return dst;
}
char *my_ltoa(long int val, char *dst, int radix)
{
VOID(int2str((long) val,dst,(radix == 10 ? -10 : radix)));
return dst;
}
#endif
......@@ -83,7 +83,7 @@ longlong2str:
divl %ebx
decl %ecx
movl %eax,%esi # quotent in ebp:esi
movb _dig_vec(%edx),%al # al is faster than dl
movb _dig_vec_upper(%edx),%al # al is faster than dl
movb %al,(%ecx) # store value in buff
.align 4
.L155:
......@@ -93,7 +93,7 @@ longlong2str:
jl .L153
je .L10_mov # Ready
movl %esi,%eax
movl $_dig_vec,%ebp
movl $_dig_vec_upper,%ebp
.align 4
.L154: # Do rest with integer precision
......
......@@ -43,8 +43,6 @@
#if defined(HAVE_LONG_LONG) && !defined(longlong2str) && !defined(HAVE_LONGLONG2STR)
extern char NEAR _dig_vec[];
/*
This assumes that longlong multiplication is faster than longlong division.
*/
......@@ -81,14 +79,14 @@ char *longlong2str(longlong val,char *dst,int radix)
{
ulonglong quo=(ulonglong) val/(uint) radix;
uint rem= (uint) (val- quo* (uint) radix);
*--p = _dig_vec[rem];
*--p = _dig_vec_upper[rem];
val= quo;
}
long_val= (long) val;
while (long_val != 0)
{
long quo= long_val/radix;
*--p = _dig_vec[(uchar) (long_val - quo*radix)];
*--p = _dig_vec_upper[(uchar) (long_val - quo*radix)];
long_val= quo;
}
while ((*dst++ = *p++) != 0) ;
......@@ -126,14 +124,14 @@ char *longlong10_to_str(longlong val,char *dst,int radix)
{
ulonglong quo=(ulonglong) val/(uint) 10;
uint rem= (uint) (val- quo* (uint) 10);
*--p = _dig_vec[rem];
*--p = _dig_vec_upper[rem];
val= quo;
}
long_val= (long) val;
while (long_val != 0)
{
long quo= long_val/10;
*--p = _dig_vec[(uchar) (long_val - quo*10)];
*--p = _dig_vec_upper[(uchar) (long_val - quo*10)];
long_val= quo;
}
while ((*dst++ = *p++) != 0) ;
......
......@@ -118,7 +118,7 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
if (*fmt== 'u')
store_end= int10_to_str(larg, store_start, 10);
else
store_end= int2str(larg, store_start, 16);
store_end= int2str(larg, store_start, 16, 0);
if ((res_length= (uint) (store_end - store_start)) > to_length)
break; /* num doesn't fit in output */
/* If %#d syntax was used, we have to pre-zero/pre-space the string */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment