summary refs log tree commit diff
path: root/string/strverscmp.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-04-07 06:20:59 +0000
committerJakub Jelinek <jakub@redhat.com>2009-04-07 06:20:59 +0000
commit11799e4168a3ef36af3cb7ffb4f5cfaed7e244d7 (patch)
treedbf8c4b86a0b68b7754f43e579c8f035d47d1ec5 /string/strverscmp.c
parent1a6da537df1fe1726d95407ec04cf65caa1f8121 (diff)
downloadglibc-11799e4168a3ef36af3cb7ffb4f5cfaed7e244d7.tar.gz
glibc-11799e4168a3ef36af3cb7ffb4f5cfaed7e244d7.tar.xz
glibc-11799e4168a3ef36af3cb7ffb4f5cfaed7e244d7.zip
Updated to fedora-glibc-20090407T0545
Diffstat (limited to 'string/strverscmp.c')
-rw-r--r--string/strverscmp.c59
1 files changed, 31 insertions, 28 deletions
diff --git a/string/strverscmp.c b/string/strverscmp.c
index 2b7ebcb8a8..2e6c96a657 100644
--- a/string/strverscmp.c
+++ b/string/strverscmp.c
@@ -18,16 +18,15 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <stdint.h>
 #include <string.h>
 #include <ctype.h>
 
 /* states: S_N: normal, S_I: comparing integral part, S_F: comparing
            fractionnal parts, S_Z: idem but with leading Zeroes only */
 #define  S_N    0x0
-#define  S_I    0x3
-#define  S_F    0x6
-#define  S_Z    0x9
+#define  S_I    0x4
+#define  S_F    0x8
+#define  S_Z    0xC
 
 /* result_type: CMP: return diff; LEN: compare using len_diff/diff */
 #define  CMP    2
@@ -46,49 +45,53 @@ __strverscmp (s1, s2)
 {
   const unsigned char *p1 = (const unsigned char *) s1;
   const unsigned char *p2 = (const unsigned char *) s2;
+  unsigned char c1, c2;
+  int state;
+  int diff;
 
-  /* Symbol(s)    0       [1-9]   others
-     Transition   (10) 0  (01) d  (00) x   */
-  static const uint8_t next_state[] =
+  /* Symbol(s)    0       [1-9]   others  (padding)
+     Transition   (10) 0  (01) d  (00) x  (11) -   */
+  static const unsigned int next_state[] =
   {
-      /* state    x    d    0  */
-      /* S_N */  S_N, S_I, S_Z,
-      /* S_I */  S_N, S_I, S_I,
-      /* S_F */  S_N, S_F, S_F,
-      /* S_Z */  S_N, S_F, S_Z
+      /* state    x    d    0    - */
+      /* S_N */  S_N, S_I, S_Z, S_N,
+      /* S_I */  S_N, S_I, S_I, S_I,
+      /* S_F */  S_N, S_F, S_F, S_F,
+      /* S_Z */  S_N, S_F, S_Z, S_Z
   };
 
-  static const int8_t result_type[] =
+  static const int result_type[] =
   {
-      /* state   x/x  x/d  x/0  d/x  d/d  d/0  0/x  0/d  0/0  */
-
-      /* S_N */  CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP,
-      /* S_I */  CMP, -1,  -1,  +1,  LEN, LEN, +1,  LEN, LEN,
-      /* S_F */  CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
-      /* S_Z */  CMP, +1,  +1,  -1,  CMP, CMP, -1,  CMP, CMP
+      /* state   x/x  x/d  x/0  x/-  d/x  d/d  d/0  d/-
+                 0/x  0/d  0/0  0/-  -/x  -/d  -/0  -/- */
+
+      /* S_N */  CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
+                 CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
+      /* S_I */  CMP, -1,  -1,  CMP, +1,  LEN, LEN, CMP,
+                 +1,  LEN, LEN, CMP, CMP, CMP, CMP, CMP,
+      /* S_F */  CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
+                 CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
+      /* S_Z */  CMP, +1,  +1,  CMP, -1,  CMP, CMP, CMP,
+                 -1,  CMP, CMP, CMP
   };
 
   if (p1 == p2)
     return 0;
 
-  unsigned char c1 = *p1++;
-  unsigned char c2 = *p2++;
+  c1 = *p1++;
+  c2 = *p2++;
   /* Hint: '0' is a digit too.  */
-  int state = S_N | ((c1 == '0') + (isdigit (c1) != 0));
+  state = S_N | ((c1 == '0') + (isdigit (c1) != 0));
 
-  int diff;
-  while ((diff = c1 - c2) == 0)
+  while ((diff = c1 - c2) == 0 && c1 != '\0')
     {
-      if (c1 == '\0')
-	return diff;
-
       state = next_state[state];
       c1 = *p1++;
       c2 = *p2++;
       state |= (c1 == '0') + (isdigit (c1) != 0);
     }
 
-  state = result_type[state * 3 | (((c2 == '0') + (isdigit (c2) != 0)))];
+  state = result_type[state << 2 | (((c2 == '0') + (isdigit (c2) != 0)))];
 
   switch (state)
   {