1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

new string-to-number functions

This commit is contained in:
bar@bar.mysql.r18.ru
2002-11-27 18:08:31 +04:00
parent 61141a30ee
commit 95930f129e
5 changed files with 921 additions and 43 deletions

View File

@ -15,12 +15,13 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include "my_sys.h"
#include "m_ctype.h"
#include "m_string.h"
#include "m_ctype.h"
#include "my_sys.h" /* defines errno */
#include "stdarg.h"
#include "assert.h"
int my_strnxfrm_simple(CHARSET_INFO * cs,
uchar *dest, uint len,
const uchar *src, uint srclen)
@ -244,34 +245,468 @@ void my_hash_sort_simple(CHARSET_INFO *cs,
}
}
long my_strntol_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *s, uint l, char **e, int base)
#define MY_ERRNO(y)
long my_strntol_8bit(CHARSET_INFO *cs,
const char *nptr, uint l, char **endptr, int base)
{
return 0;
int negative;
register ulong cutoff;
register unsigned int cutlim;
register ulong i;
register const char *s;
register unsigned char c;
const char *save, *e;
int overflow;
if (base < 0 || base == 1 || base > 36)
base = 10;
s = nptr;
e = nptr+l;
for ( ; s<e && my_isspace(cs, *s) ; s++);
if (s == e)
{
goto noconv;
}
/* Check for a sign. */
if (*s == '-')
{
negative = 1;
++s;
}
else if (*s == '+')
{
negative = 0;
++s;
}
else
negative = 0;
if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
s += 2;
if (base == 0)
{
if (*s == '0')
{
if (s[1]=='X' || s[1]=='x')
{
s += 2;
base = 16;
}
else
base = 8;
}
else
base = 10;
}
save = s;
cutoff = ((ulong)~0L) / (unsigned long int) base;
cutlim = (uint) (((ulong)~0L) % (unsigned long int) base);
overflow = 0;
i = 0;
for (c = *s; s != e; c = *++s)
{
if (c>='0' && c<='9')
c -= '0';
else if (c>='A' && c<='F')
c = c - 'A' + 10;
else if (c>='a' && c<='f')
c = c - 'a' + 10;
else
break;
if (c >= base)
break;
if (i > cutoff || (i == cutoff && c > cutlim))
overflow = 1;
else
{
i *= (ulong) base;
i += c;
}
}
if (s == save)
goto noconv;
if (endptr != NULL)
*endptr = (char *) s;
if (negative)
{
if (i > (ulong) LONG_MIN)
overflow = 1;
}
else if (i > (ulong) LONG_MAX)
overflow = 1;
if (overflow)
{
MY_ERRNO(ERANGE);
return negative ? LONG_MIN : LONG_MAX;
}
return (negative ? -((long) i) : (long) i);
noconv:
MY_ERRNO(EDOM);
if (endptr != NULL)
*endptr = (char *) nptr;
return 0L;
}
ulong my_strntoul_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *s, uint l, char **e, int base)
ulong my_strntoul_8bit(CHARSET_INFO *cs,
const char *nptr, uint l, char **endptr, int base)
{
return 0;
int negative;
register ulong cutoff;
register unsigned int cutlim;
register ulong i;
register const char *s;
register unsigned char c;
const char *save, *e;
int overflow;
if (base < 0 || base == 1 || base > 36)
base = 10;
s = nptr;
e = nptr+l;
for( ; s<e && my_isspace(cs, *s); s++);
if (s==e)
{
goto noconv;
}
if (*s == '-')
{
negative = 1;
++s;
}
else if (*s == '+')
{
negative = 0;
++s;
}
else
negative = 0;
if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
s += 2;
if (base == 0)
{
if (*s == '0')
{
if (s[1]=='X' || s[1]=='x')
{
s += 2;
base = 16;
}
else
base = 8;
}
else
base = 10;
}
save = s;
cutoff = ((ulong)~0L) / (unsigned long int) base;
cutlim = (uint) (((ulong)~0L) % (unsigned long int) base);
overflow = 0;
i = 0;
for (c = *s; s != e; c = *++s)
{
if (c>='0' && c<='9')
c -= '0';
else if (c>='A' && c<='F')
c = c - 'A' + 10;
else if (c>='a' && c<='a')
c = c - 'a' + 10;
else
break;
if (c >= base)
break;
if (i > cutoff || (i == cutoff && c > cutlim))
overflow = 1;
else
{
i *= (ulong) base;
i += c;
}
}
if (s == save)
goto noconv;
if (endptr != NULL)
*endptr = (char *) s;
if (overflow)
{
MY_ERRNO(ERANGE);
return ((ulong)~0L);
}
return (negative ? -((long) i) : (long) i);
noconv:
MY_ERRNO(EDOM);
if (endptr != NULL)
*endptr = (char *) nptr;
return 0L;
}
longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *s, uint l, char **e, int base)
const char *nptr, uint l, char **endptr, int base)
{
return 0;
int negative;
register ulonglong cutoff;
register unsigned int cutlim;
register ulonglong i;
register const char *s, *e;
register unsigned char c;
const char *save;
int overflow;
if (base < 0 || base == 1 || base > 36)
base = 10;
s = nptr;
e = nptr+l;
for(; s<e && my_isspace(cs,*s); s++);
if (s == e)
{
goto noconv;
}
if (*s == '-')
{
negative = 1;
++s;
}
else if (*s == '+')
{
negative = 0;
++s;
}
else
negative = 0;
if (base == 16 && s[0] == '0' && (s[1]=='X'|| s[1]=='x'))
s += 2;
if (base == 0)
{
if (*s == '0')
{
if (s[1]=='X' || s[1]=='x')
{
s += 2;
base = 16;
}
else
base = 8;
}
else
base = 10;
}
save = s;
cutoff = (~(ulonglong) 0) / (unsigned long int) base;
cutlim = (uint) ((~(ulonglong) 0) % (unsigned long int) base);
overflow = 0;
i = 0;
for (c = *s; s != e; c = *++s)
{
if (c>='0' && c<='9')
c -= '0';
else if (c>='A' && c<='F')
c = c - 'A' + 10;
else if (c>='a' && c<='f')
c = c - 'a' + 10;
else
break;
if (c >= base)
break;
if (i > cutoff || (i == cutoff && c > cutlim))
overflow = 1;
else
{
i *= (ulonglong) base;
i += c;
}
}
if (s == save)
goto noconv;
if (endptr != NULL)
*endptr = (char *) s;
if (negative)
{
if (i > (ulonglong) LONGLONG_MIN)
overflow = 1;
}
else if (i > (ulonglong) LONGLONG_MAX)
overflow = 1;
if (overflow)
{
MY_ERRNO(ERANGE);
return negative ? LONGLONG_MIN : LONGLONG_MAX;
}
return (negative ? -((longlong) i) : (longlong) i);
noconv:
MY_ERRNO(EDOM);
if (endptr != NULL)
*endptr = (char *) nptr;
return 0L;
}
ulonglong my_strntoull_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *s, uint l, char **e, int base)
ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
const char *nptr, uint l, char **endptr, int base)
{
return 0;
int negative;
register ulonglong cutoff;
register unsigned int cutlim;
register ulonglong i;
register const char *s, *e;
register unsigned char c;
const char *save;
int overflow;
if (base < 0 || base == 1 || base > 36)
base = 10;
s = nptr;
e = nptr+l;
for(; s<e && my_isspace(cs,*s); s++);
if (s == e)
{
goto noconv;
}
if (*s == '-')
{
negative = 1;
++s;
}
else if (*s == '+')
{
negative = 0;
++s;
}
else
negative = 0;
if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
s += 2;
if (base == 0)
{
if (*s == '0')
{
if (s[1]=='X' || s[1]=='x')
{
s += 2;
base = 16;
}
else
base = 8;
}
else
base = 10;
}
save = s;
cutoff = (~(ulonglong) 0) / (unsigned long int) base;
cutlim = (uint) ((~(ulonglong) 0) % (unsigned long int) base);
overflow = 0;
i = 0;
for (c = *s; s != e; c = *++s)
{
if (c>='0' && c<='9')
c -= '0';
else if (c>='A' && c<='F')
c = c - 'A' + 10;
else if (c>='a' && c<='f')
c = c - 'a' + 10;
else
break;
if (c >= base)
break;
if (i > cutoff || (i == cutoff && c > cutlim))
overflow = 1;
else
{
i *= (ulonglong) base;
i += c;
}
}
if (s == save)
goto noconv;
if (endptr != NULL)
*endptr = (char *) s;
if (overflow)
{
MY_ERRNO(ERANGE);
return (~(ulonglong) 0);
}
return (negative ? -((longlong) i) : (longlong) i);
noconv:
MY_ERRNO(EDOM);
if (endptr != NULL)
*endptr = (char *) nptr;
return 0L;
}
double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *s, uint l, char **e)
{
return 0;
char buf[256];
double res;
if((l+1)>sizeof(buf))
{
if (e)
memcpy(*e,s,sizeof(s));
return 0;
}
strncpy(buf,s,l);
buf[l]='\0';
res=strtod(buf,e);
if (e)
memcpy(*e,*e-buf+s,sizeof(s));
return res;
}