1cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Compare strings while treating digits characters numerically. 205436638acc7c010349a69c3395f1a57c642dc62Ying Wang Copyright (C) 1997, 2000, 2002, 2004, 2006, 2009-2012 Free Software 305436638acc7c010349a69c3395f1a57c642dc62Ying Wang Foundation, Inc. 4cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project This file is part of the GNU C Library. 5cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997. 6cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 7cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project This program is free software; you can redistribute it and/or modify 8cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project it under the terms of the GNU General Public License as published by 905436638acc7c010349a69c3395f1a57c642dc62Ying Wang the Free Software Foundation; either version 3, or (at your option) 10cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project any later version. 11cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 12cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project This program is distributed in the hope that it will be useful, 13cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project but WITHOUT ANY WARRANTY; without even the implied warranty of 14cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project GNU General Public License for more details. 16cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 17cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project You should have received a copy of the GNU General Public License along 1805436638acc7c010349a69c3395f1a57c642dc62Ying Wang with this program; if not, see <http://www.gnu.org/licenses/>. */ 19cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if !_LIBC 21cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# include <config.h> 22cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif 23cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 24cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <string.h> 25cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <ctype.h> 26cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 27cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* states: S_N: normal, S_I: comparing integral part, S_F: comparing 28cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project fractional parts, S_Z: idem but with leading Zeroes only */ 29cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#define S_N 0x0 30cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#define S_I 0x4 31cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#define S_F 0x8 32cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#define S_Z 0xC 33cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 34cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* result_type: CMP: return diff; LEN: compare using len_diff/diff */ 35cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#define CMP 2 36cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#define LEN 3 37cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 38cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 39cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* ISDIGIT differs from isdigit, as follows: 4005436638acc7c010349a69c3395f1a57c642dc62Ying Wang - Its arg may be any int or unsigned int; it need not be an unsigned char 4105436638acc7c010349a69c3395f1a57c642dc62Ying Wang or EOF. 42cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project - It's typically faster. 43cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to 4405436638acc7c010349a69c3395f1a57c642dc62Ying Wang isdigit unless it's important to use the locale's definition 4505436638acc7c010349a69c3395f1a57c642dc62Ying Wang of "digit" even when the host does not conform to POSIX. */ 46cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9) 47cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 48cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#undef __strverscmp 49cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#undef strverscmp 50cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 51cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#ifndef weak_alias 52cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# define __strverscmp strverscmp 53cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif 54cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 55cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Compare S1 and S2 as strings holding indices/version numbers, 56cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project returning less than, equal to or greater than zero if S1 is less than, 57cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project equal to or greater than S2 (for more info, see the texinfo doc). 58cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project*/ 59cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 60cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectint 61cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project__strverscmp (const char *s1, const char *s2) 62cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 63cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project const unsigned char *p1 = (const unsigned char *) s1; 64cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project const unsigned char *p2 = (const unsigned char *) s2; 65cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project unsigned char c1, c2; 66cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project int state; 67cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project int diff; 68cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 69cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* Symbol(s) 0 [1-9] others (padding) 70cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project Transition (10) 0 (01) d (00) x (11) - */ 71cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project static const unsigned int next_state[] = 72cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 73cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* state x d 0 - */ 74cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* S_N */ S_N, S_I, S_Z, S_N, 75cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* S_I */ S_N, S_I, S_I, S_I, 76cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* S_F */ S_N, S_F, S_F, S_F, 77cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* S_Z */ S_N, S_F, S_Z, S_Z 78cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project }; 79cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 80cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project static const int result_type[] = 81cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 82cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* state x/x x/d x/0 x/- d/x d/d d/0 d/- 83cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 0/x 0/d 0/0 0/- -/x -/d -/0 -/- */ 84cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 85cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* S_N */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, 86cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, 87cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* S_I */ CMP, -1, -1, CMP, 1, LEN, LEN, CMP, 88cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 1, LEN, LEN, CMP, CMP, CMP, CMP, CMP, 89cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, 90cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, 91cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* S_Z */ CMP, 1, 1, CMP, -1, CMP, CMP, CMP, 92cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project -1, CMP, CMP, CMP 93cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project }; 94cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 95cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (p1 == p2) 96cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project return 0; 97cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 98cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project c1 = *p1++; 99cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project c2 = *p2++; 100cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* Hint: '0' is a digit too. */ 101cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project state = S_N | ((c1 == '0') + (ISDIGIT (c1) != 0)); 102cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 103cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project while ((diff = c1 - c2) == 0 && c1 != '\0') 104cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 105cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project state = next_state[state]; 106cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project c1 = *p1++; 107cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project c2 = *p2++; 108cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project state |= (c1 == '0') + (ISDIGIT (c1) != 0); 109cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 110cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 111cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT (c2) != 0))]; 112cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 113cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project switch (state) 114cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 115cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project case CMP: 116cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project return diff; 117cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 118cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project case LEN: 119cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project while (ISDIGIT (*p1++)) 12005436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (!ISDIGIT (*p2++)) 12105436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 1; 122cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 123cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project return ISDIGIT (*p2) ? -1 : diff; 124cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 125cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project default: 126cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project return state; 127cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 128cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 129cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#ifdef weak_alias 130cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectweak_alias (__strverscmp, strverscmp) 131cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif 132