1b0104773SPascal Brand /* 2b0104773SPascal Brand * Copyright (c) 1994-2009 Red Hat, Inc. 3b0104773SPascal Brand * All rights reserved. 4b0104773SPascal Brand * 5b0104773SPascal Brand * Redistribution and use in source and binary forms, with or without 6b0104773SPascal Brand * modification, are permitted provided that the following conditions are met: 7b0104773SPascal Brand * 8b0104773SPascal Brand * 1. Redistributions of source code must retain the above copyright notice, 9b0104773SPascal Brand * this list of conditions and the following disclaimer. 10b0104773SPascal Brand * 11b0104773SPascal Brand * 2. Redistributions in binary form must reproduce the above copyright notice, 12b0104773SPascal Brand * this list of conditions and the following disclaimer in the documentation 13b0104773SPascal Brand * and/or other materials provided with the distribution. 14b0104773SPascal Brand * 15b0104773SPascal Brand * 3. Neither the name of the copyright holder nor the names of its 16b0104773SPascal Brand * contributors may be used to endorse or promote products derived from this 17b0104773SPascal Brand * software without specific prior written permission. 18b0104773SPascal Brand * 19b0104773SPascal Brand * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20b0104773SPascal Brand * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21b0104773SPascal Brand * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22b0104773SPascal Brand * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23b0104773SPascal Brand * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24b0104773SPascal Brand * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25b0104773SPascal Brand * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26b0104773SPascal Brand * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27b0104773SPascal Brand * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28b0104773SPascal Brand * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29b0104773SPascal Brand * POSSIBILITY OF SUCH DAMAGE. 30b0104773SPascal Brand */ 31b0104773SPascal Brand 32b0104773SPascal Brand /* This file is copied from newlib-1.19 */ 33b0104773SPascal Brand 34b0104773SPascal Brand /* 35b0104773SPascal Brand FUNCTION 36b0104773SPascal Brand <<strcmp>>---character string compare 37b0104773SPascal Brand 38b0104773SPascal Brand INDEX 39b0104773SPascal Brand strcmp 40b0104773SPascal Brand 41b0104773SPascal Brand ANSI_SYNOPSIS 42b0104773SPascal Brand #include <string.h> 43b0104773SPascal Brand int strcmp(const char *<[a]>, const char *<[b]>); 44b0104773SPascal Brand 45b0104773SPascal Brand TRAD_SYNOPSIS 46b0104773SPascal Brand #include <string.h> 47b0104773SPascal Brand int strcmp(<[a]>, <[b]>) 48b0104773SPascal Brand char *<[a]>; 49b0104773SPascal Brand char *<[b]>; 50b0104773SPascal Brand 51b0104773SPascal Brand DESCRIPTION 52b0104773SPascal Brand <<strcmp>> compares the string at <[a]> to 53b0104773SPascal Brand the string at <[b]>. 54b0104773SPascal Brand 55b0104773SPascal Brand RETURNS 56b0104773SPascal Brand If <<*<[a]>>> sorts lexicographically after <<*<[b]>>>, 57b0104773SPascal Brand <<strcmp>> returns a number greater than zero. If the two 58b0104773SPascal Brand strings match, <<strcmp>> returns zero. If <<*<[a]>>> 59b0104773SPascal Brand sorts lexicographically before <<*<[b]>>>, <<strcmp>> returns a 60b0104773SPascal Brand number less than zero. 61b0104773SPascal Brand 62b0104773SPascal Brand PORTABILITY 63b0104773SPascal Brand <<strcmp>> is ANSI C. 64b0104773SPascal Brand 65b0104773SPascal Brand <<strcmp>> requires no supporting OS subroutines. 66b0104773SPascal Brand 67b0104773SPascal Brand QUICKREF 68b0104773SPascal Brand strcmp ansi pure 69b0104773SPascal Brand */ 70b0104773SPascal Brand 71b0104773SPascal Brand #include "_ansi.h" 72b0104773SPascal Brand #include <string.h> 73b0104773SPascal Brand #include <limits.h> 74b0104773SPascal Brand 75b0104773SPascal Brand /* Nonzero if either X or Y is not aligned on a "long" boundary. */ 76b0104773SPascal Brand #define UNALIGNED(X, Y) \ 77b0104773SPascal Brand (((long)X & (sizeof(long) - 1)) | ((long)Y & (sizeof(long) - 1))) 78b0104773SPascal Brand 79b0104773SPascal Brand /* DETECTNULL returns nonzero if (long)X contains a NULL byte. */ 80b0104773SPascal Brand #if LONG_MAX == 2147483647L 81*ba6d8df9SJens Wiklander #define DETECTNULL(X) (((X) - 0x01010101L) & ~(X) & 0x80808080UL) 82b0104773SPascal Brand #else 83b0104773SPascal Brand #if LONG_MAX == 9223372036854775807L 84*ba6d8df9SJens Wiklander #define DETECTNULL(X) (((X) - 0x0101010101010101L) & ~(X) & \ 85*ba6d8df9SJens Wiklander 0x8080808080808080UL) 86b0104773SPascal Brand #else 87b0104773SPascal Brand #error long int is not a 32bit or 64bit type. 88b0104773SPascal Brand #endif 89b0104773SPascal Brand #endif 90b0104773SPascal Brand 91b0104773SPascal Brand #ifndef DETECTNULL 92b0104773SPascal Brand #error long int is not a 32bit or 64bit byte 93b0104773SPascal Brand #endif 94b0104773SPascal Brand 95b0104773SPascal Brand int _DEFUN(strcmp, (s1, s2), _CONST char *s1 _AND _CONST char *s2) 96b0104773SPascal Brand { 97b0104773SPascal Brand #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) 98b0104773SPascal Brand while (*s1 != '\0' && *s1 == *s2) { 99b0104773SPascal Brand s1++; 100b0104773SPascal Brand s2++; 101b0104773SPascal Brand } 102b0104773SPascal Brand 103b0104773SPascal Brand return (*(unsigned char *)s1) - (*(unsigned char *)s2); 104b0104773SPascal Brand #else 105b0104773SPascal Brand unsigned long *a1; 106b0104773SPascal Brand unsigned long *a2; 107b0104773SPascal Brand 108b0104773SPascal Brand /* If s1 or s2 are unaligned, then compare bytes. */ 109b0104773SPascal Brand if (!UNALIGNED(s1, s2)) { 110b0104773SPascal Brand /* 111b0104773SPascal Brand * If s1 and s2 are word-aligned, compare them a word at a time. 112b0104773SPascal Brand */ 113b0104773SPascal Brand a1 = (unsigned long *)s1; 114b0104773SPascal Brand a2 = (unsigned long *)s2; 115b0104773SPascal Brand while (*a1 == *a2) { 116b0104773SPascal Brand /* 117b0104773SPascal Brand * To get here, *a1 == *a2, thus if we find a null in 118b0104773SPascal Brand * *a1, then the strings must be equal, so return zero. 119b0104773SPascal Brand */ 120b0104773SPascal Brand if (DETECTNULL(*a1)) 121b0104773SPascal Brand return 0; 122b0104773SPascal Brand 123b0104773SPascal Brand a1++; 124b0104773SPascal Brand a2++; 125b0104773SPascal Brand } 126b0104773SPascal Brand 127b0104773SPascal Brand /* 128b0104773SPascal Brand * A difference was detected in last few bytes of s1, so search 129b0104773SPascal Brand * bytewise. 130b0104773SPascal Brand */ 131b0104773SPascal Brand s1 = (char *)a1; 132b0104773SPascal Brand s2 = (char *)a2; 133b0104773SPascal Brand } 134b0104773SPascal Brand 135b0104773SPascal Brand while (*s1 != '\0' && *s1 == *s2) { 136b0104773SPascal Brand s1++; 137b0104773SPascal Brand s2++; 138b0104773SPascal Brand } 139b0104773SPascal Brand return (*(unsigned char *)s1) - (*(unsigned char *)s2); 140b0104773SPascal Brand #endif /* not PREFER_SIZE_OVER_SPEED */ 141b0104773SPascal Brand } 142