Hi

I have a small patch (it is attached just for reference) to make TH1
use the integers also in other formats (hexadecimal and octal forms).

For example, we would use the same expressions then

  %  expr {010+10+0x10}
  34

Could we add such a support in Fossil TH1? I believe the TH1 stands for
"Test Harness 1" and I use TH1 core with the extensions in my embedded
projects and it is pity that I cannot just type 0x... :-)

Could anyone take a look on the workaround, please? Well, Th_ToInt()
become itself a bit more slow, but I think it is still more fast than
strtoll(). At the least, I can say that the patch does not break the
existing Fossil TH1 tests.

Thanks for Fossil!

Sergei
Index: src/th.c
==================================================================
--- src/th.c
+++ src/th.c
@@ -1867,10 +1867,12 @@
   {"|",  OP_BITWISE_OR,    10, ARG_INTEGER},
 
   {0,0,0,0}
 };
 
+int th_ishexdig(char c);
+
 /*
 ** The first part of the string (zInput,nInput) contains a number.
 ** Set *pnVarname to the number of bytes in the numeric string.
 */
 static int thNextNumber(
@@ -1877,15 +1879,20 @@
   Th_Interp *interp,
   const char *zInput,
   int nInput,
   int *pnLiteral
 ){
-  int i;
+  int i = 0;
   int seenDot = 0;
-  for(i=0; i<nInput; i++){
+  int (*isdigit)(char) = th_isdigit;
+  if( nInput>2 && zInput[0]=='0' && (zInput[1]=='x' || zInput[1]=='X') ){
+    i=2;
+    isdigit = th_ishexdig;
+  }
+  for(; i<nInput; i++){
     char c = zInput[i];
-    if( (seenDot || c!='.') && !th_isdigit(c) ) break;
+    if( (seenDot || c!='.') && !isdigit(c) ) break;
     if( c=='.' ) seenDot = 1;
   }
   *pnLiteral = i;
   return TH_OK;
 }
@@ -2411,11 +2418,12 @@
 **     '\f'   0x0C
 **     '\r'   0x0D
 **
 ** Whitespace characters have the 0x01 flag set. Decimal digits have the
 ** 0x2 flag set. Single byte printable characters have the 0x4 flag set.
-** Alphabet characters have the 0x8 bit set.
+** Alphabet characters have the 0x8 bit set. Hexadecimal digits have the
+** 0x20 flag set. Octal digits have the 0x40 flag set.
 **
 ** The special list characters have the 0x10 flag set
 **
 **    { } [ ] \ ; ' "
 **
@@ -2424,14 +2432,14 @@
 */
 static unsigned char aCharProp[256] = {
   0,  0,  0,  0,  0,  0,  0,  0,     0,  1,  1,  1,  1,  1,  0,  0,   /* 0x0. */
   0,  0,  1,  1,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0,   /* 0x1. */
   5,  4, 20,  4,  4,  4,  4,  4,     4,  4,  4,  4,  4,  4,  4,  4,   /* 0x2. */
-  6,  6,  6,  6,  6,  6,  6,  6,     6,  6,  4, 20,  4,  4,  4,  4,   /* 0x3. */
-  4, 12, 12, 12, 12, 12, 12, 12,    12, 12, 12, 12, 12, 12, 12, 12,   /* 0x4. */
+102,102,102,102,102,102,102,102,    102,102, 4, 20,  4,  4,  4,  4,   /* 0x3. */
+  4, 44, 44, 44, 44, 44, 44, 12,    12, 12, 12, 12, 12, 12, 12, 12,   /* 0x4. */
  12, 12, 12, 12, 12, 12, 12, 12,    12, 12, 12, 20, 20, 20,  4,  4,   /* 0x5. */
-  4, 12, 12, 12, 12, 12, 12, 12,    12, 12, 12, 12, 12, 12, 12, 12,   /* 0x6. */
+  4, 44, 44, 44, 44, 44, 44, 12,    12, 12, 12, 12, 12, 12, 12, 12,   /* 0x6. */
  12, 12, 12, 12, 12, 12, 12, 12,    12, 12, 12, 20,  4, 20,  4,  4,   /* 0x7. */
 
   0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0,   /* 0x8. */
   0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0,   /* 0x9. */
   0,  0,  0,  0,  0,  0,  0,  0,     0,  0,  0,  0,  0,  0,  0,  0,   /* 0xA. */
@@ -2455,10 +2463,16 @@
   return (aCharProp[(unsigned char)c] & 0x11);
 }
 int th_isalnum(char c){
   return (aCharProp[(unsigned char)c] & 0x0A);
 }
+int th_ishexdig(char c){
+  return (aCharProp[(unsigned char)c] & 0x20);
+}
+int th_isoctdig(char c){
+  return (aCharProp[(unsigned char)c] & 0x40);
+}
 
 #ifndef LONGDOUBLE_TYPE
 # define LONGDOUBLE_TYPE long double
 #endif
 
@@ -2571,24 +2585,43 @@
 ** interpreter result too.
 */
 int Th_ToInt(Th_Interp *interp, const char *z, int n, int *piOut){
   int i = 0;
   int iOut = 0;
+  int base = 10;
+  int (*isdigit)(char) = th_isdigit;
 
   if( n<0 ){
     n = th_strlen(z);
   }
 
   if( n>0 && (z[0]=='-' || z[0]=='+') ){
     i = 1;
   }
+  if( n>2 && z[i]=='0' && (z[i+1]=='x' || z[i+1]=='X') ){
+    i += 2;
+    base = 16;
+    isdigit = th_ishexdig;
+  }else if( n>1 && z[i]=='0' ){
+    i += 1;
+    base = 8;
+    isdigit = th_isoctdig;
+  }
   for(; i<n; i++){
-    if( !th_isdigit(z[i]) ){
+    int shift;
+    if( !isdigit(z[i]) ){
       Th_ErrorMessage(interp, "expected integer, got: \"", z, n);
       return TH_ERROR;
     }
-    iOut = iOut * 10 + (z[i] - 48);
+    if( z[i]>='a' ){
+      shift = 87;
+    }else if( z[i]>='A' ){
+      shift = 55;
+    }else{
+      shift = 48;
+    }
+    iOut = iOut * base + (z[i] - shift);
   }
 
   if( n>0 && z[0]=='-' ){
     iOut *= -1;
   }

_______________________________________________
fossil-users mailing list
fossil-users@lists.fossil-scm.org
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users

Reply via email to