#### 39 lines 1011 B C Raw Normal View History

 2001-02-02 17:54:47 +00:00 ```#include "scan.h" ``` ``` ``` 2014-03-14 00:24:02 +00:00 `static const unsigned int maxshort = ((unsigned short)-1)>>1;` ``` ``` 2006-11-07 17:56:05 +00:00 `size_t scan_short(const char* src,short* dest) {` 2014-03-14 00:24:02 +00:00 ` register const char *tmp;` ` register short l;` ` register unsigned char c;` ` int neg;` ` int ok;` ` tmp=src; l=0; ok=neg=0;` ` switch (*tmp) {` ` case '-': neg=1;` ` case '+': ++tmp;` ` }` ` while ((c=(unsigned char)(*tmp-'0'))<10) {` ` unsigned long int n;` ``` /* we want to do: l=l*10+c ``` ` * but we need to check for integer overflow.` ` * to check whether l*10 overflows, we could do` ` * if ((l*10)/10 != l)` ` * however, multiplication and division are expensive.` ` * so instead of *10 we do (l<<3) (i.e. *8) + (l<<1) (i.e. *2)` ` * and check for overflow on all the intermediate steps */` ` n=(unsigned int)l<<3; if ((n>>3)!=(unsigned int)l) break;` ` if (n+(l<<1) < n) break;` ` n+=l<<1;` ` if (n+c < n) break;` ` n+=c;` ` if (n > maxshort+neg) break;` ` l=n;` ` ++tmp;` ` ok=1;` ` }` ` if (!ok) return 0;` ` *dest=(neg?-l:l);` ` return (size_t)(tmp-src);` 2001-02-02 17:54:47 +00:00 `}`