All pastes #276454 Raw Edit

Support for Octal Numbers in Squirrel

public text v1 · immutable
·published 2006-12-12 10:35 UTC
rendered paste body
--- ../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;
 }