1 /* 2 * Copyright (c) 1994-2009 Red Hat, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* This file is copied from newlib-1.19 */ 33 34 /* 35 FUNCTION 36 <<strlen>>---character string length 37 38 INDEX 39 strlen 40 41 ANSI_SYNOPSIS 42 #include <string.h> 43 size_t strlen(const char *<[str]>); 44 45 TRAD_SYNOPSIS 46 #include <string.h> 47 size_t strlen(<[str]>) 48 char *<[src]>; 49 50 DESCRIPTION 51 The <<strlen>> function works out the length of the string 52 starting at <<*<[str]>>> by counting chararacters until it 53 reaches a <<NULL>> character. 54 55 RETURNS 56 <<strlen>> returns the character count. 57 58 PORTABILITY 59 <<strlen>> is ANSI C. 60 61 <<strlen>> requires no supporting OS subroutines. 62 63 QUICKREF 64 strlen ansi pure 65 */ 66 67 #include "_ansi.h" 68 #include <string.h> 69 #include <limits.h> 70 71 #define LBLOCKSIZE (sizeof(long)) 72 #define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1)) 73 74 #if LONG_MAX == 2147483647L 75 #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) 76 #else 77 #if LONG_MAX == 9223372036854775807L 78 /* Nonzero if X (a long int) contains a NULL byte. */ 79 #define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080) 80 #else 81 #error long int is not a 32bit or 64bit type. 82 #endif 83 #endif 84 85 #ifndef DETECTNULL 86 #error long int is not a 32bit or 64bit byte 87 #endif 88 89 size_t _DEFUN(strlen, (str), _CONST char *str) 90 { 91 _CONST char *start = str; 92 93 #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) 94 unsigned long *aligned_addr; 95 96 /* Align the pointer, so we can search a word at a time. */ 97 while (UNALIGNED(str)) { 98 if (!*str) 99 return str - start; 100 str++; 101 } 102 103 /* If the string is word-aligned, we can check for the presence of 104 a null in each word-sized block. */ 105 aligned_addr = (unsigned long *)str; 106 while (!DETECTNULL(*aligned_addr)) 107 aligned_addr++; 108 109 /* Once a null is detected, we check each byte in that block for a 110 precise position of the null. */ 111 str = (char *)aligned_addr; 112 113 #endif /* not PREFER_SIZE_OVER_SPEED */ 114 115 while (*str) 116 str++; 117 return str - start; 118 } 119