(root)/
glibc-2.38/
string/
strspn.c
       1  /* Copyright (C) 1991-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <string.h>
      19  #include <stdint.h>
      20  #include <libc-pointer-arith.h>
      21  
      22  #undef strspn
      23  #ifndef STRSPN
      24  # define STRSPN strspn
      25  #endif
      26  
      27  /* Return the length of the maximum initial segment
      28     of S which contains only characters in ACCEPT.  */
      29  size_t
      30  STRSPN (const char *str, const char *accept)
      31  {
      32    if (accept[0] == '\0')
      33      return 0;
      34    if (__glibc_unlikely (accept[1] == '\0'))
      35      {
      36        const char *a = str;
      37        for (; *str == *accept; str++);
      38        return str - a;
      39      }
      40  
      41    /* Use multiple small memsets to enable inlining on most targets.  */
      42    unsigned char table[256];
      43    unsigned char *p = memset (table, 0, 64);
      44    memset (p + 64, 0, 64);
      45    memset (p + 128, 0, 64);
      46    memset (p + 192, 0, 64);
      47  
      48    unsigned char *s = (unsigned char*) accept;
      49    /* Different from strcspn it does not add the NULL on the table
      50       so can avoid check if str[i] is NULL, since table['\0'] will
      51       be 0 and thus stopping the loop check.  */
      52    do
      53      p[*s++] = 1;
      54    while (*s);
      55  
      56    s = (unsigned char*) str;
      57    if (!p[s[0]]) return 0;
      58    if (!p[s[1]]) return 1;
      59    if (!p[s[2]]) return 2;
      60    if (!p[s[3]]) return 3;
      61  
      62    s = (unsigned char *) PTR_ALIGN_DOWN (s, 4);
      63  
      64    unsigned int c0, c1, c2, c3;
      65    do {
      66        s += 4;
      67        c0 = p[s[0]];
      68        c1 = p[s[1]];
      69        c2 = p[s[2]];
      70        c3 = p[s[3]];
      71    } while ((c0 & c1 & c2 & c3) != 0);
      72  
      73    size_t count = s - (unsigned char *) str;
      74    return (c0 & c1) == 0 ? count + c0 : count + c2 + 2;
      75  }
      76  libc_hidden_builtin_def (strspn)