#include <my_global.h>#include <my_sys.h>#include <m_string.h>Include dependency graph for my_strtoll10.c:

Go to the source code of this file.
Defines | |
| #define | ULONGLONG_MAX (~(ulonglong) 0) |
| #define | MAX_NEGATIVE_NUMBER ((ulonglong) LL(0x8000000000000000)) |
| #define | INIT_CNT 9 |
| #define | LFACTOR ULL(1000000000) |
| #define | LFACTOR1 ULL(10000000000) |
| #define | LFACTOR2 ULL(100000000000) |
Functions | |
| longlong | my_strtoll10 (const char *nptr, char **endptr, int *error) |
Variables | |
| static unsigned long | lfactor [9] |
| #define INIT_CNT 9 |
Definition at line 33 of file my_strtoll10.c.
| #define LFACTOR ULL(1000000000) |
Definition at line 34 of file my_strtoll10.c.
| #define LFACTOR1 ULL(10000000000) |
Definition at line 35 of file my_strtoll10.c.
| #define LFACTOR2 ULL(100000000000) |
Definition at line 36 of file my_strtoll10.c.
| #define MAX_NEGATIVE_NUMBER ((ulonglong) LL(0x8000000000000000)) |
Definition at line 32 of file my_strtoll10.c.
| #define ULONGLONG_MAX (~(ulonglong) 0) |
Definition at line 30 of file my_strtoll10.c.
| longlong my_strtoll10 | ( | const char * | nptr, | |
| char ** | endptr, | |||
| int * | error | |||
| ) |
Definition at line 86 of file my_strtoll10.c.
References INIT_CNT, LFACTOR, lfactor, LFACTOR1, LFACTOR2, LONGLONG_MIN, MAX_NEGATIVE_NUMBER, MY_ERRNO_EDOM, MY_ERRNO_ERANGE, start(), and ULONGLONG_MAX.
00087 { 00088 const char *s, *end, *start, *n_end, *true_end; 00089 char *dummy; 00090 unsigned char c; 00091 unsigned long i, j, k; 00092 ulonglong li; 00093 int negative; 00094 ulong cutoff, cutoff2, cutoff3; 00095 00096 s= nptr; 00097 /* If fixed length string */ 00098 if (endptr) 00099 { 00100 end= *endptr; 00101 while (s != end && (*s == ' ' || *s == '\t')) 00102 s++; 00103 if (s == end) 00104 goto no_conv; 00105 } 00106 else 00107 { 00108 endptr= &dummy; /* Easier end test */ 00109 while (*s == ' ' || *s == '\t') 00110 s++; 00111 if (!*s) 00112 goto no_conv; 00113 /* This number must be big to guard against a lot of pre-zeros */ 00114 end= s+65535; /* Can't be longer than this */ 00115 } 00116 00117 /* Check for a sign. */ 00118 negative= 0; 00119 if (*s == '-') 00120 { 00121 *error= -1; /* Mark as negative number */ 00122 negative= 1; 00123 if (++s == end) 00124 goto no_conv; 00125 cutoff= MAX_NEGATIVE_NUMBER / LFACTOR2; 00126 cutoff2= (MAX_NEGATIVE_NUMBER % LFACTOR2) / 100; 00127 cutoff3= MAX_NEGATIVE_NUMBER % 100; 00128 } 00129 else 00130 { 00131 *error= 0; 00132 if (*s == '+') 00133 { 00134 if (++s == end) 00135 goto no_conv; 00136 } 00137 cutoff= ULONGLONG_MAX / LFACTOR2; 00138 cutoff2= ULONGLONG_MAX % LFACTOR2 / 100; 00139 cutoff3= ULONGLONG_MAX % 100; 00140 } 00141 00142 /* Handle case where we have a lot of pre-zero */ 00143 if (*s == '0') 00144 { 00145 i= 0; 00146 do 00147 { 00148 if (++s == end) 00149 goto end_i; /* Return 0 */ 00150 } 00151 while (*s == '0'); 00152 n_end= s+ INIT_CNT; 00153 } 00154 else 00155 { 00156 /* Read first digit to check that it's a valid number */ 00157 if ((c= (*s-'0')) > 9) 00158 goto no_conv; 00159 i= c; 00160 n_end= ++s+ INIT_CNT-1; 00161 } 00162 00163 /* Handle first 9 digits and store them in i */ 00164 if (n_end > end) 00165 n_end= end; 00166 for (; s != n_end ; s++) 00167 { 00168 if ((c= (*s-'0')) > 9) 00169 goto end_i; 00170 i= i*10+c; 00171 } 00172 if (s == end) 00173 goto end_i; 00174 00175 /* Handle next 9 digits and store them in j */ 00176 j= 0; 00177 start= s; /* Used to know how much to shift i */ 00178 n_end= true_end= s + INIT_CNT; 00179 if (n_end > end) 00180 n_end= end; 00181 do 00182 { 00183 if ((c= (*s-'0')) > 9) 00184 goto end_i_and_j; 00185 j= j*10+c; 00186 } while (++s != n_end); 00187 if (s == end) 00188 { 00189 if (s != true_end) 00190 goto end_i_and_j; 00191 goto end3; 00192 } 00193 if ((c= (*s-'0')) > 9) 00194 goto end3; 00195 00196 /* Handle the next 1 or 2 digits and store them in k */ 00197 k=c; 00198 if (++s == end || (c= (*s-'0')) > 9) 00199 goto end4; 00200 k= k*10+c; 00201 *endptr= (char*) ++s; 00202 00203 /* number string should have ended here */ 00204 if (s != end && (c= (*s-'0')) <= 9) 00205 goto overflow; 00206 00207 /* Check that we didn't get an overflow with the last digit */ 00208 if (i > cutoff || (i == cutoff && ((j > cutoff2 || j == cutoff2) && 00209 k > cutoff3))) 00210 goto overflow; 00211 li=i*LFACTOR2+ (ulonglong) j*100 + k; 00212 return (longlong) li; 00213 00214 overflow: /* *endptr is set here */ 00215 *error= MY_ERRNO_ERANGE; 00216 return negative ? LONGLONG_MIN : (longlong) ULONGLONG_MAX; 00217 00218 end_i: 00219 *endptr= (char*) s; 00220 return (negative ? ((longlong) -(long) i) : (longlong) i); 00221 00222 end_i_and_j: 00223 li= (ulonglong) i * lfactor[(uint) (s-start)] + j; 00224 *endptr= (char*) s; 00225 return (negative ? -((longlong) li) : (longlong) li); 00226 00227 end3: 00228 li=(ulonglong) i*LFACTOR+ (ulonglong) j; 00229 *endptr= (char*) s; 00230 return (negative ? -((longlong) li) : (longlong) li); 00231 00232 end4: 00233 li=(ulonglong) i*LFACTOR1+ (ulonglong) j * 10 + k; 00234 *endptr= (char*) s; 00235 if (negative) 00236 { 00237 if (li > MAX_NEGATIVE_NUMBER) 00238 goto overflow; 00239 return -((longlong) li); 00240 } 00241 return (longlong) li; 00242 00243 no_conv: 00244 /* There was no number to convert. */ 00245 *error= MY_ERRNO_EDOM; 00246 *endptr= (char *) nptr; 00247 return 0; 00248 }
Here is the call graph for this function:

unsigned long lfactor[9] [static] |
Initial value:
{
1L, 10L, 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L, 100000000L
}
Definition at line 38 of file my_strtoll10.c.
1.4.7

