|
@@ -1,13 +1,8 @@
|
|
|
-
|
|
|
- */
|
|
|
-
|
|
|
|
|
|
- Copyright (C) 1997, 2002 Free Software Foundation, Inc.
|
|
|
+ Copyright (C) 1997-2015 Free Software Foundation, Inc.
|
|
|
This file is part of the GNU C Library.
|
|
|
Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
|
|
|
|
|
|
- Derived work for uClibc by Hai Zaar, Codefidence Ltd <haizaar@codefidence.com>
|
|
|
-
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
|
|
modify it under the terms of the GNU Lesser General Public
|
|
|
License as published by the Free Software Foundation; either
|
|
@@ -22,63 +17,54 @@
|
|
|
License along with the GNU C Library; if not, see
|
|
|
<http:
|
|
|
|
|
|
+#include <stdint.h>
|
|
|
#include <string.h>
|
|
|
#include <ctype.h>
|
|
|
-#include <stdint.h>
|
|
|
-
|
|
|
|
|
|
|
|
|
- fractional parts, S_Z: idem but with leading Zeroes only */
|
|
|
+ fractionnal parts, S_Z: idem but with leading Zeroes only */
|
|
|
#define S_N 0x0
|
|
|
-#define S_I 0x4
|
|
|
-#define S_F 0x8
|
|
|
-#define S_Z 0xC
|
|
|
+#define S_I 0x3
|
|
|
+#define S_F 0x6
|
|
|
+#define S_Z 0x9
|
|
|
|
|
|
|
|
|
#define CMP 2
|
|
|
#define LEN 3
|
|
|
|
|
|
-
|
|
|
-#undef isdigit
|
|
|
-#define isdigit(a) ((unsigned)((a) - '0') <= 9)
|
|
|
|
|
|
|
|
|
returning less than, equal to or greater than zero if S1 is less than,
|
|
|
equal to or greater than S2 (for more info, see the texinfo doc).
|
|
|
*/
|
|
|
+
|
|
|
int strverscmp (const char *s1, const char *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;
|
|
|
|
|
|
-
|
|
|
- Transition (10) 0 (01) d (00) x (11) - */
|
|
|
+
|
|
|
+ Transition (10) 0 (01) d (00) x */
|
|
|
static const uint8_t next_state[] =
|
|
|
{
|
|
|
-
|
|
|
- S_N, S_I, S_Z, S_N,
|
|
|
- S_N, S_I, S_I, S_I,
|
|
|
- S_N, S_F, S_F, S_F,
|
|
|
- S_N, S_F, S_Z, S_Z
|
|
|
+
|
|
|
+ S_N, S_I, S_Z,
|
|
|
+ S_N, S_I, S_I,
|
|
|
+ S_N, S_F, S_F,
|
|
|
+ S_N, S_F, S_Z
|
|
|
};
|
|
|
|
|
|
static const int8_t result_type[] =
|
|
|
{
|
|
|
-
|
|
|
- 0/x 0/d 0/0 0/- -/x -/d -/0 -/- */
|
|
|
-
|
|
|
- CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
|
|
|
- CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
|
|
|
- CMP, -1, -1, CMP, +1, LEN, LEN, CMP,
|
|
|
- +1, LEN, LEN, CMP, CMP, CMP, CMP, CMP,
|
|
|
- CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
|
|
|
- CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
|
|
|
- CMP, +1, +1, CMP, -1, CMP, CMP, CMP,
|
|
|
- -1, CMP, CMP, CMP
|
|
|
+
|
|
|
+
|
|
|
+ CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP,
|
|
|
+ CMP, -1, -1, +1, LEN, LEN, +1, LEN, LEN,
|
|
|
+ CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
|
|
|
+ CMP, +1, +1, -1, CMP, CMP, -1, CMP, CMP
|
|
|
};
|
|
|
+ unsigned char c1, c2;
|
|
|
+ int state, diff;
|
|
|
|
|
|
if (p1 == p2)
|
|
|
return 0;
|
|
@@ -86,17 +72,20 @@ int strverscmp (const char *s1, const char *s2)
|
|
|
c1 = *p1++;
|
|
|
c2 = *p2++;
|
|
|
|
|
|
- state = S_N | ((c1 == '0') + (isdigit (c1) != 0));
|
|
|
+ state = S_N + ((c1 == '0') + (isdigit (c1) != 0));
|
|
|
|
|
|
- while ((diff = c1 - c2) == 0 && c1 != '\0')
|
|
|
+ while ((diff = c1 - c2) == 0)
|
|
|
{
|
|
|
+ if (c1 == '\0')
|
|
|
+ return diff;
|
|
|
+
|
|
|
state = next_state[state];
|
|
|
c1 = *p1++;
|
|
|
c2 = *p2++;
|
|
|
- state |= (c1 == '0') + (isdigit (c1) != 0);
|
|
|
+ state += (c1 == '0') + (isdigit (c1) != 0);
|
|
|
}
|
|
|
|
|
|
- state = result_type[state << 2 | (((c2 == '0') + (isdigit (c2) != 0)))];
|
|
|
+ state = result_type[state * 3 + (((c2 == '0') + (isdigit (c2) != 0)))];
|
|
|
|
|
|
switch (state)
|
|
|
{
|