mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
Add mysys specific error messages
Make RELAY_THREAD and alias for IO_THREAD Added new interface for string -> (unsigned) long long. include/my_sys.h: Add mysys specific error messages sql/lex.h: Make RELAY_THREAD an alias for IO_THREAD sql/sql_yacc.yy: Make RELAY_THREAD an alias for IO_THREAD
This commit is contained in:
parent
0695239a64
commit
e5c62e3280
5 changed files with 642 additions and 5 deletions
|
@ -118,8 +118,11 @@ extern int NEAR my_errno; /* Last error in mysys */
|
|||
#define MY_KEEP_PREALLOC 1
|
||||
#define MY_MARK_BLOCKS_FREE 2 /* move used to free list and reuse them */
|
||||
|
||||
/* defines when allocating data */
|
||||
/* Internal error numbers (for assembler functions) */
|
||||
#define MY_ERRNO_EDOM 33
|
||||
#define MY_ERRNO_ERANGE 34
|
||||
|
||||
/* defines when allocating data */
|
||||
#ifdef SAFEMALLOC
|
||||
#define my_malloc(SZ,FLAG) _mymalloc((SZ), __FILE__, __LINE__, FLAG )
|
||||
#define my_malloc_ci(SZ,FLAG) _mymalloc((SZ), sFile, uLine, FLAG )
|
||||
|
|
|
@ -209,7 +209,7 @@ static SYMBOL symbols[] = {
|
|||
{ "INT4", SYM(INT_SYM),0,0},
|
||||
{ "INT8", SYM(BIGINT),0,0},
|
||||
{ "INTO", SYM(INTO),0,0},
|
||||
{ "IO_THREAD", SYM(IO_THREAD),0,0},
|
||||
{ "IO_THREAD", SYM(RELAY_THREAD),0,0},
|
||||
{ "IF", SYM(IF),0,0},
|
||||
{ "IS", SYM(IS),0,0},
|
||||
{ "ISOLATION", SYM(ISOLATION),0,0},
|
||||
|
@ -313,6 +313,7 @@ static SYMBOL symbols[] = {
|
|||
{ "REFERENCES", SYM(REFERENCES),0,0},
|
||||
{ "RELAY_LOG_FILE", SYM(RELAY_LOG_FILE_SYM),0,0},
|
||||
{ "RELAY_LOG_POS", SYM(RELAY_LOG_POS_SYM),0,0},
|
||||
{ "RELAY_THREAD", SYM(RELAY_THREAD),0,0},
|
||||
{ "RELOAD", SYM(RELOAD),0,0},
|
||||
{ "REGEXP", SYM(REGEXP),0,0},
|
||||
{ "RENAME", SYM(RENAME),0,0},
|
||||
|
|
|
@ -138,7 +138,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||
%token FLUSH_SYM
|
||||
%token HELP_SYM
|
||||
%token INSERT
|
||||
%token IO_THREAD
|
||||
%token RELAY_THREAD
|
||||
%token KILL_SYM
|
||||
%token LOAD
|
||||
%token LOCKS_SYM
|
||||
|
@ -1688,7 +1688,7 @@ slave_thread_opt_list:
|
|||
slave_thread_opt:
|
||||
/*empty*/ {}
|
||||
| SQL_THREAD { Lex->slave_thd_opt|=SLAVE_SQL; }
|
||||
| IO_THREAD { Lex->slave_thd_opt|=SLAVE_IO; }
|
||||
| RELAY_THREAD { Lex->slave_thd_opt|=SLAVE_IO; }
|
||||
;
|
||||
|
||||
restore:
|
||||
|
@ -4232,7 +4232,7 @@ keyword:
|
|||
| ISSUER_SYM {}
|
||||
| INNOBASE_SYM {}
|
||||
| INSERT_METHOD {}
|
||||
| IO_THREAD {}
|
||||
| RELAY_THREAD {}
|
||||
| LAST_SYM {}
|
||||
| LEVEL_SYM {}
|
||||
| LINESTRING {}
|
||||
|
|
396
strings/my_strtoll10-x86.s
Normal file
396
strings/my_strtoll10-x86.s
Normal file
|
@ -0,0 +1,396 @@
|
|||
# Copyright (C) 2003 MySQL AB
|
||||
# This program is free software; you can resistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Implemention of my_strtoll(): Converting a string to a 64 bit integer.
|
||||
|
||||
.file "my_strtoll10-x86.s"
|
||||
.version "01.01"
|
||||
.data
|
||||
.align 32
|
||||
.type lfactor,@object
|
||||
.size lfactor,36
|
||||
lfactor:
|
||||
.long 1
|
||||
.long 10
|
||||
.long 100
|
||||
.long 1000
|
||||
.long 10000
|
||||
.long 100000
|
||||
.long 1000000
|
||||
.long 10000000
|
||||
.long 100000000
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.globl my_strtoll10
|
||||
.type my_strtoll10,@function
|
||||
|
||||
|
||||
# Used stack variables
|
||||
# ebp-4 dummy for storing endptr if endptr = 0
|
||||
# ebp-8 First 9 digits of return values
|
||||
# ebp-12 Pointer to first digit of second part
|
||||
# ebp-16 Store lowest 2 digits
|
||||
# ebp-20 != 0 if value was negative
|
||||
# ebp-24 High max value
|
||||
# ebp-28 Middle max value
|
||||
# ebp-32 Low max value
|
||||
# ebp-36 Temp value
|
||||
|
||||
# esi Pointer to input string
|
||||
# ebx End of string
|
||||
|
||||
my_strtoll10:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
subl $48,%esp
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
pushl %ebx
|
||||
movl 8(%ebp),%esi # esi= nptr
|
||||
movl 16(%ebp),%ecx # ecx= error (Will be overwritten later)
|
||||
movl 12(%ebp),%eax # eax= endptr
|
||||
cld # Move forward in esi
|
||||
cmpl $0,%eax # if (endptr)
|
||||
je .L110
|
||||
|
||||
# Fixed length string
|
||||
movl (%eax),%ebx # bx= end-of-string
|
||||
.p2align 4,,7
|
||||
.L100:
|
||||
cmpl %ebx,%esi
|
||||
je .Lno_conv
|
||||
lodsb # al= next byte
|
||||
cmpb $32,%al # Skip space
|
||||
je .L100
|
||||
cmpb $9,%al # Skip tab
|
||||
je .L100
|
||||
jmp .L130
|
||||
|
||||
# String that ends with \0
|
||||
|
||||
.L110:
|
||||
leal -4(%ebp),%edi
|
||||
movl %edi,12(%ebp) # endptr= &dummy, for easier end check
|
||||
.p2align 4,,7
|
||||
.L120:
|
||||
lodsb # al= next byte
|
||||
cmpb $32,%al
|
||||
je .L120
|
||||
cmpb $9,%al
|
||||
je .L120
|
||||
testb %al,%al # Test if we found end \0
|
||||
je .Lno_conv
|
||||
leal 65535(%esi),%ebx # ebx = end-of-string
|
||||
|
||||
.L130:
|
||||
cmpb $45,%al # Test if '-'
|
||||
jne .Lpositive
|
||||
|
||||
# negative number
|
||||
movl $-1,(%ecx) # error = -1 (mark that number is negative)
|
||||
movl $1,-20(%ebp) # negative= 1
|
||||
movl $92233720,-24(%ebp)
|
||||
movl $368547758,-28(%ebp)
|
||||
movl $8,-32(%ebp)
|
||||
jmp .L460
|
||||
|
||||
.p2align 4,,7
|
||||
.Lpositive:
|
||||
movl $0,(%ecx) # error=0
|
||||
movl $0,-20(%ebp) # negative= 0
|
||||
movl $184467440,-24(%ebp)
|
||||
movl $737095516,-28(%ebp)
|
||||
movl $15,-32(%ebp)
|
||||
cmpb $43,%al # Check if '+'
|
||||
jne .L462
|
||||
|
||||
.L460:
|
||||
cmpl %ebx,%esi # Check if overflow
|
||||
je .Lno_conv
|
||||
lodsb # al= next byte after sign
|
||||
|
||||
# Remove pre zero to be able to handle a lot of pre-zero
|
||||
.L462:
|
||||
cmpb $48,%al
|
||||
jne .L475 # Number doesn't start with 0
|
||||
movl %esi, %edi
|
||||
.p2align 4,,7
|
||||
.L481: # Skip pre zeros
|
||||
cmpl %ebx,%esi
|
||||
je .Lms_return_zero
|
||||
scasb
|
||||
je .L481
|
||||
movl %edi, %esi
|
||||
decl %esi # Point to last non '0' digit
|
||||
leal 9(%esi),%ecx # ecx = end-of-current-part
|
||||
xorl %edi,%edi # Store first 9 digits in edi
|
||||
jmp .L482
|
||||
.p2align 4,,7
|
||||
|
||||
# Check if first char is a valid number
|
||||
.L475:
|
||||
addb $-48,%al
|
||||
cmpb $9,%al
|
||||
ja .Lno_conv
|
||||
.L477:
|
||||
movzbl %al,%edi # edi = first digit
|
||||
leal 8(%esi),%ecx # ecx = end-of-current-part
|
||||
|
||||
# Handle first 8/9 digits and store them in edi
|
||||
.L482:
|
||||
cmpl %ebx,%ecx
|
||||
jbe .L522
|
||||
movl %ebx,%ecx # ecx = min(end-of-current-part, end-of-string)
|
||||
jmp .L522
|
||||
|
||||
.p2align 4,,7
|
||||
.L488:
|
||||
lodsb # al= next byte
|
||||
addb $-48,%al
|
||||
cmpb $9,%al
|
||||
ja .Lend_i_dec_esi
|
||||
|
||||
# Calculate edi= edi*10 + al
|
||||
leal (%edi,%edi,4),%edx
|
||||
movzbl %al,%eax
|
||||
leal (%eax,%edx,2),%edi
|
||||
.L522:
|
||||
cmpl %ecx,%esi # If more digits at this level
|
||||
jne .L488
|
||||
cmpl %ebx,%esi # If end of string
|
||||
je .Lend_i
|
||||
|
||||
movl %edi,-8(%ebp) # Store first 9 digits
|
||||
movl %esi,-12(%ebp) # store pos to first digit of second part
|
||||
|
||||
# Calculate next 9 digits and store them in edi
|
||||
|
||||
xorl %edi,%edi
|
||||
leal 9(%esi),%ecx # ecx= end-of-current-part
|
||||
movl %ecx,-36(%ebp) # Store max length
|
||||
cmpl %ebx,%ecx
|
||||
jbe .L498
|
||||
movl %ebx,%ecx # ecx = min(end-of-current-part, end-of-string)
|
||||
|
||||
.p2align 4,,7
|
||||
.L498:
|
||||
lodsb # al= next byte
|
||||
addb $-48,%al
|
||||
cmpb $9,%al
|
||||
ja .Lend_i_and_j_decl_esi
|
||||
|
||||
# Calculate edi= edi*10 + al
|
||||
leal (%edi,%edi,4),%edx
|
||||
movzbl %al,%eax
|
||||
leal (%eax,%edx,2),%edi
|
||||
|
||||
cmpl %ecx,%esi # If end of current part
|
||||
jne .L498
|
||||
cmpl %ebx,%esi # If end of string
|
||||
jne .L500
|
||||
cmpl -36(%ebp),%esi # Test if string is less than 18 digits
|
||||
jne .Lend_i_and_j
|
||||
jmp .Lend3 # 18 digit string
|
||||
|
||||
# Handle the possible next to last digit and store in ecx
|
||||
.L500:
|
||||
movb (%esi),%al
|
||||
addb $-48,%al
|
||||
cmpb $9,%al
|
||||
ja .Lend3
|
||||
|
||||
incl %esi
|
||||
movzbl %al,%ecx
|
||||
cmpl %ebx,%esi # If end of string
|
||||
je .Lend4
|
||||
|
||||
movb (%esi),%al # Read last digit
|
||||
addb $-48,%al
|
||||
cmpb $9,%al
|
||||
ja .Lend4
|
||||
|
||||
# ecx= ecx*10 + al
|
||||
leal (%ecx,%ecx,4),%edx
|
||||
movzbl %al,%eax
|
||||
leal (%eax,%edx,2),%ecx
|
||||
|
||||
movl 12(%ebp),%eax # eax = endptr
|
||||
incl %esi
|
||||
movl %esi,(%eax) # *endptr = end-of-string
|
||||
cmpl %ebx,%esi
|
||||
je .L505 # At end of string
|
||||
|
||||
movb (%esi),%al # check if extra digits
|
||||
addb $-48,%al
|
||||
cmpb $9,%al
|
||||
jbe .Loverflow
|
||||
|
||||
# At this point we have:
|
||||
# -8(%ebp) First 9 digits
|
||||
# edi Next 9 digits
|
||||
# ecx Last 2 digits
|
||||
# *endpos end-of-string
|
||||
|
||||
.L505: # Check that we are not going to get overflow for unsigned long long
|
||||
movl -8(%ebp),%eax # First 9 digits
|
||||
cmpl -24(%ebp),%eax
|
||||
ja .Loverflow
|
||||
jne .L507
|
||||
cmpl -28(%ebp),%edi
|
||||
ja .Loverflow
|
||||
jne .L507
|
||||
cmpl -32(%ebp),%ecx
|
||||
ja .Loverflow
|
||||
|
||||
.L507:
|
||||
movl %edi,-4(%ebp) # Save middle bytes
|
||||
movl %ecx,%esi # esi = 2 last digits
|
||||
movl $1215752192,%ecx # %ecx= lower_32_bits(100000000000)
|
||||
mull %ecx
|
||||
imull $23,-8(%ebp),%ecx
|
||||
movl $0,-36(%ebp)
|
||||
movl %eax,%ebx
|
||||
imull $1215752192,-36(%ebp),%eax
|
||||
movl %edx,%edi
|
||||
addl %ecx,%edi
|
||||
addl %eax,%edi # Temp in edi:ebx
|
||||
|
||||
movl $100,%eax # j= j*100
|
||||
mull -4(%ebp)
|
||||
addl %ebx,%eax # edx:eax+= edi:ebx
|
||||
adcl %edi,%edx
|
||||
addl %esi,%eax
|
||||
adcl $0,%edx
|
||||
jmp .Lms_return
|
||||
|
||||
.Loverflow:
|
||||
# When we come here, *endptr is already updated
|
||||
|
||||
movl 16(%ebp),%edx # edx= error
|
||||
movl $34,(%edx) # *error = 34
|
||||
movl $-1,%eax
|
||||
movl %eax,%edx
|
||||
cmpl $0,-20(%ebp) # If negative
|
||||
je .Lms_return
|
||||
xor %eax,%eax # edx:eax = LONGLONG_LMIN
|
||||
movl $-2147483648,%edx
|
||||
jmp .Lms_return
|
||||
|
||||
# Return value that is in %edi as long long
|
||||
.p2align 4,,7
|
||||
.Lend_i_dec_esi:
|
||||
decl %esi # Fix so that it points at last digit
|
||||
.Lend_i:
|
||||
xorl %edx,%edx
|
||||
movl %edi,%eax
|
||||
cmpl $0,-20(%ebp)
|
||||
je .Lreturn_save_endptr # Positive number
|
||||
negl %eax
|
||||
cltd # Negetive result in edx:eax
|
||||
jmp .Lreturn_save_endptr
|
||||
|
||||
# Return value (%ebp-8) * lfactor[(uint) (edx-start)] + edi
|
||||
.p2align 4,,7
|
||||
.Lend_i_and_j_decl_esi:
|
||||
decl %esi # Fix so that it points at last digit
|
||||
.Lend_i_and_j:
|
||||
movl %esi,%ecx
|
||||
subl -12(%ebp),%ecx # ecx= number of digits in second part
|
||||
movl lfactor(,%ecx,4),%eax
|
||||
jmp .L523
|
||||
|
||||
# Return -8(%ebp) * $1000000000 + edi
|
||||
.p2align 4,,7
|
||||
.Lend3:
|
||||
movl $1000000000,%eax
|
||||
.L523:
|
||||
mull -8(%ebp)
|
||||
addl %edi,%eax
|
||||
adcl $0,%edx
|
||||
cmpl $0,-20(%ebp) # if negative
|
||||
je .Lreturn_save_endptr
|
||||
negl %eax # Neg edx:%eax
|
||||
adcl $0,%edx
|
||||
negl %edx
|
||||
jmp .Lreturn_save_endptr
|
||||
|
||||
# Return -8(%ebp) * $10000000000 + edi*10 + ecx
|
||||
.p2align 4,,7
|
||||
.Lend4:
|
||||
movl %ecx,-16(%ebp) # store lowest digits
|
||||
movl 12(%ebp),%ebx
|
||||
movl %esi,(%ebx) # *endpos = end-of-string
|
||||
movl -8(%ebp),%eax # First 9 digits
|
||||
movl $1410065408,%ecx # ecx= lower_32_bits(10000000000)
|
||||
mull %ecx
|
||||
movl $0,-36(%ebp)
|
||||
movl %eax,%ebx # Store lowest 32 byte from multiplication
|
||||
imull $1410065408,-36(%ebp),%eax
|
||||
movl -8(%ebp),%ecx # First 9 digits
|
||||
movl %edx,%esi
|
||||
addl %ecx,%ecx
|
||||
addl %ecx,%esi
|
||||
addl %eax,%esi # %esi:%ebx now has -8(%ebp) * $10000000000
|
||||
|
||||
movl $10,%eax # Calc edi*10
|
||||
mull %edi
|
||||
addl %ebx,%eax # And add to result
|
||||
adcl %esi,%edx
|
||||
addl -16(%ebp),%eax # Add lowest digit
|
||||
adcl $0,%edx
|
||||
cmpl $0,-20(%ebp) # if negative
|
||||
je .Lms_return
|
||||
|
||||
cmpl $-2147483648,%edx # Test if too big signed integer
|
||||
ja .Loverflow
|
||||
jne .L516
|
||||
testl %eax,%eax
|
||||
ja .Loverflow
|
||||
|
||||
.L516:
|
||||
negl %eax
|
||||
adcl $0,%edx
|
||||
negl %edx
|
||||
jmp .Lms_return
|
||||
|
||||
.p2align 4,,7
|
||||
.Lno_conv: # Not a legal number
|
||||
movl 16(%ebp),%eax
|
||||
movl $33,(%eax) # error= edom
|
||||
|
||||
.Lms_return_zero:
|
||||
xorl %eax,%eax # Return zero
|
||||
xorl %edx,%edx
|
||||
|
||||
.p2align 4,,7
|
||||
.Lreturn_save_endptr:
|
||||
movl 12(%ebp),%ecx # endptr= end-of-string
|
||||
movl %esi,(%ecx) # *endptr= end-of-string
|
||||
|
||||
.Lms_return:
|
||||
popl %ebx
|
||||
popl %edi
|
||||
popl %esi
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
my_strtoll10_end:
|
||||
.size my_strtoll10,.my_strtoll10_end-my_strtoll10
|
||||
.comm res,240,32
|
||||
.comm end_ptr,120,32
|
||||
.comm error,120,32
|
||||
.ident "Monty"
|
237
strings/my_strtoll10.c
Normal file
237
strings/my_strtoll10.c
Normal file
|
@ -0,0 +1,237 @@
|
|||
/* Copyright (C) 2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <m_string.h>
|
||||
|
||||
#define ULONGLONG_MAX (~(ulonglong) 0)
|
||||
#define MAX_NEGATIVE_NUMBER ((ulonglong) 0x8000000000000000LL)
|
||||
#define INIT_CNT 9
|
||||
#define LFACTOR LL(1000000000)
|
||||
#define LFACTOR1 LL(10000000000)
|
||||
#define LFACTOR2 LL(100000000000)
|
||||
|
||||
static unsigned long lfactor[9]=
|
||||
{
|
||||
1L, 10L, 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L, 100000000L
|
||||
};
|
||||
|
||||
/*
|
||||
Convert a string to an to unsigned long long integer value
|
||||
|
||||
SYNOPSYS
|
||||
str2ull10(char *nptr, char **enptr, *long error)
|
||||
nptr in pointer to the string to be converted
|
||||
endptr in/out pointer to the end of the string/
|
||||
pointer to the stop character
|
||||
error out returned error code
|
||||
|
||||
DESCRIPTION
|
||||
This function takes the decimal representation of integer number
|
||||
from string nptr and converts it to an signed or unsigned
|
||||
long long integer value.
|
||||
Space characters and tab are ignored.
|
||||
A sign character might precede the the digit characters. The number
|
||||
may have any number of pre-zero digits.
|
||||
|
||||
The function stops reading the string nptr at the first character
|
||||
that is not a decimal digit. If endptr is not NULL then the function
|
||||
will not read characters after *endptr.
|
||||
|
||||
RETURN VALUES
|
||||
Value of string as a signed/unsigned longlong integer
|
||||
|
||||
if no error and endptr != NULL, it will be set to point at the character
|
||||
after the number
|
||||
|
||||
The error parameter contains information how things went:
|
||||
-1 Number was an ok negative number
|
||||
0 ok
|
||||
ERANGE If the the value of the converted number exceeded the
|
||||
maximum negative/unsigned long long integer.
|
||||
In this case the return value is ~0 if value was
|
||||
positive and LONGLONG_MIN if value was negative.
|
||||
EDOM If the string didn't contain any digits. In this case
|
||||
the return value is 0.
|
||||
|
||||
If endptr is not NULL the function will store the end pointer to
|
||||
the stop character here.
|
||||
*/
|
||||
|
||||
|
||||
longlong my_strtoll10(const char *nptr, char **endptr, int *error)
|
||||
{
|
||||
const char *s, *end, *start, *n_end, *true_end;
|
||||
char *dummy;
|
||||
unsigned char c;
|
||||
unsigned long i, j, k;
|
||||
ulonglong li;
|
||||
int negative;
|
||||
long cutoff, cutoff2, cutoff3;
|
||||
|
||||
s= nptr;
|
||||
/* If fixed length string */
|
||||
if (endptr)
|
||||
{
|
||||
end= *endptr;
|
||||
while (s != end && (*s == ' ' || *s == '\t'))
|
||||
s++;
|
||||
if (s == end)
|
||||
goto no_conv;
|
||||
}
|
||||
else
|
||||
{
|
||||
endptr= &dummy; /* Easier end test */
|
||||
while (*s == ' ' || *s == '\t')
|
||||
s++;
|
||||
if (!*s)
|
||||
goto no_conv;
|
||||
/* This number must be big to guard against a lot of pre-zeros */
|
||||
end= s+65535; /* Can't be longer than this */
|
||||
}
|
||||
|
||||
/* Check for a sign. */
|
||||
negative= 0;
|
||||
if (*s == '-')
|
||||
{
|
||||
*error= -1; /* Mark as negative number */
|
||||
negative= 1;
|
||||
if (++s == end)
|
||||
goto no_conv;
|
||||
cutoff= MAX_NEGATIVE_NUMBER / LL(100000000000);
|
||||
cutoff2= (MAX_NEGATIVE_NUMBER % LL(100000000000)) / 100;
|
||||
cutoff3= MAX_NEGATIVE_NUMBER % 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
*error= 0;
|
||||
if (*s == '+')
|
||||
{
|
||||
if (++s == end)
|
||||
goto no_conv;
|
||||
}
|
||||
cutoff= ULONGLONG_MAX / LL(100000000000);
|
||||
cutoff2= ULONGLONG_MAX % LL(100000000000) / 100;
|
||||
cutoff3= ULONGLONG_MAX % 100;
|
||||
}
|
||||
|
||||
/* Handle case where we have a lot of pre-zero */
|
||||
if (*s == '0')
|
||||
{
|
||||
i= 0;
|
||||
do
|
||||
{
|
||||
if (++s == end)
|
||||
goto end_i; /* Return 0 */
|
||||
}
|
||||
while (*s == '0');
|
||||
n_end= s+ INIT_CNT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read first digit to check that it's a valid number */
|
||||
if ((c= (*s-'0')) > 9)
|
||||
goto no_conv;
|
||||
i= c;
|
||||
n_end= ++s+ INIT_CNT-1;
|
||||
}
|
||||
|
||||
/* Handle first 9 digits and store them in i */
|
||||
if (n_end > end)
|
||||
n_end= end;
|
||||
for (; s != n_end ; s++)
|
||||
{
|
||||
if ((c= (*s-'0')) > 9)
|
||||
goto end_i;
|
||||
i= i*10+c;
|
||||
}
|
||||
if (s == end)
|
||||
goto end_i;
|
||||
|
||||
/* Handle next 9 digits and store them in j */
|
||||
j= 0;
|
||||
start= s; /* Used to know how much to shift i */
|
||||
n_end= true_end= s + INIT_CNT;
|
||||
if (n_end > end)
|
||||
n_end= end;
|
||||
do
|
||||
{
|
||||
if ((c= (*s-'0')) > 9)
|
||||
goto end_i_and_j;
|
||||
j= j*10+c;
|
||||
} while (++s != n_end);
|
||||
if (s == end)
|
||||
{
|
||||
if (s != true_end)
|
||||
goto end_i_and_j;
|
||||
goto end3;
|
||||
}
|
||||
if ((c= (*s-'0')) > 9)
|
||||
goto end3;
|
||||
|
||||
/* Handle the next 1 or 2 digits and store them in k */
|
||||
k=c;
|
||||
if (++s == end || (c= (*s-'0')) > 9)
|
||||
goto end4;
|
||||
k= k*10+c;
|
||||
*endptr= (char*) ++s;
|
||||
|
||||
/* number string should have ended here */
|
||||
if (s != end && (c= (*s-'0')) <= 9)
|
||||
goto overflow;
|
||||
|
||||
/* Check that we didn't get an overflow with the last digit */
|
||||
if (i > cutoff || i == cutoff && (j > cutoff2 || j == cutoff2 &&
|
||||
k > cutoff3))
|
||||
goto overflow;
|
||||
li=i*LFACTOR2+ (ulonglong) j*100 + k;
|
||||
return (longlong) li;
|
||||
|
||||
overflow: /* *endptr is set here */
|
||||
*error= MY_ERRNO_ERANGE;
|
||||
return negative ? LONGLONG_MIN : ULONGLONG_MAX;
|
||||
|
||||
end_i:
|
||||
*endptr= (char*) s;
|
||||
return (negative ? ((longlong) -(long) i) : (longlong) i);
|
||||
|
||||
end_i_and_j:
|
||||
li= (ulonglong) i * lfactor[(uint) (s-start)] + j;
|
||||
*endptr= (char*) s;
|
||||
return (negative ? -((longlong) li) : (longlong) li);
|
||||
|
||||
end3:
|
||||
li=(ulonglong) i*LFACTOR+ (ulonglong) j;
|
||||
*endptr= (char*) s;
|
||||
return (negative ? -((longlong) li) : (longlong) li);
|
||||
|
||||
end4:
|
||||
li=(ulonglong) i*LFACTOR1+ (ulonglong) j * 10 + k;
|
||||
*endptr= (char*) s;
|
||||
if (negative)
|
||||
{
|
||||
if (li > MAX_NEGATIVE_NUMBER)
|
||||
goto overflow;
|
||||
return -((longlong) li);
|
||||
}
|
||||
return (longlong) li;
|
||||
|
||||
no_conv:
|
||||
/* There was no number to convert. */
|
||||
*error= MY_ERRNO_EDOM;
|
||||
*endptr= (char *) nptr;
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue