--- ../squirrel/squirrel/sqlexer.cpp 2006-03-18 13:11:53.000000000 +0300 +++ squirrel/sqlexer.cpp 2006-12-12 12:35:45.000000000 +0300 @@ -358,8 +358,19 @@ while(*s != 0) { if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0'); - else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10); - else { assert(0); } + else *res = (*res)*16+(toupper(*s++)-'A'+10); + // the following 2 lines are actually not required as validation is done in SQLexer::ReadNumber() function + //else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10); + //else { assert(0); } + } +} + +void LexOctal(const SQChar *s,SQUnsignedInteger *res) +{ + *res = 0; + while(*s != 0) + { + *res = (*res)*8+((*s++)-'0'); } } @@ -372,26 +383,39 @@ } } +SQInteger isodigit(SQInteger c) { return c >= '0' && c <= '7'; } SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; } #define MAX_HEX_DIGITS (sizeof(SQInteger)*2) +#define MAX_OCTAL_DIGITS ((MAX_HEX_DIGITS/2)*3-(MAX_HEX_DIGITS/8)) SQInteger SQLexer::ReadNumber() { #define TINT 1 #define TFLOAT 2 #define THEX 3 #define TSCIENTIFIC 4 +#define TOCTAL 5 SQInteger type = TINT, firstchar = CUR_CHAR; SQChar *sTemp; INIT_TEMP_STRING(); NEXT(); - if(firstchar == _SC('0') && toupper(CUR_CHAR) == _SC('X')) { + if(firstchar == _SC('0')) { + if (toupper(CUR_CHAR) == _SC('X')) { NEXT(); type = THEX; while(isxdigit(CUR_CHAR)) { APPEND_CHAR(CUR_CHAR); NEXT(); } - if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number")); + if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for a Hex number")); + } + else { + type = TOCTAL; + while(isodigit(CUR_CHAR)) { + APPEND_CHAR(CUR_CHAR); + NEXT(); + } + if(_longstr.size() > MAX_OCTAL_DIGITS) Error(_SC("too many digits for an Octal number")); + } } else { APPEND_CHAR((int)firstchar); @@ -425,6 +449,9 @@ case THEX: LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); return TK_INTEGER; + case TOCTAL: + LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); + return TK_INTEGER; } return 0; }