(root)/
glibc-2.38/
string/
strcspn.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 strcspn
      23  
      24  #ifndef STRCSPN
      25  # define STRCSPN strcspn
      26  #endif
      27  
      28  /* Return the length of the maximum initial segment of S
      29     which contains no characters from REJECT.  */
      30  size_t
      31  STRCSPN (const char *str, const char *reject)
      32  {
      33    if (__glibc_unlikely (reject[0] == '\0')
      34        || __glibc_unlikely (reject[1] == '\0'))
      35      return __strchrnul (str, reject [0]) - str;
      36  
      37    /* Use multiple small memsets to enable inlining on most targets.  */
      38    unsigned char table[256];
      39    unsigned char *p = memset (table, 0, 64);
      40    memset (p + 64, 0, 64);
      41    memset (p + 128, 0, 64);
      42    memset (p + 192, 0, 64);
      43  
      44    unsigned char *s = (unsigned char*) reject;
      45    unsigned char tmp;
      46    do
      47      p[tmp = *s++] = 1;
      48    while (tmp);
      49  
      50    s = (unsigned char*) str;
      51    if (p[s[0]]) return 0;
      52    if (p[s[1]]) return 1;
      53    if (p[s[2]]) return 2;
      54    if (p[s[3]]) return 3;
      55  
      56    s = (unsigned char *) PTR_ALIGN_DOWN (s, 4);
      57  
      58    unsigned int c0, c1, c2, c3;
      59    do
      60      {
      61        s += 4;
      62        c0 = p[s[0]];
      63        c1 = p[s[1]];
      64        c2 = p[s[2]];
      65        c3 = p[s[3]];
      66      }
      67    while ((c0 | c1 | c2 | c3) == 0);
      68  
      69    size_t count = s - (unsigned char *) str;
      70    return (c0 | c1) != 0 ? count - c0 + 1 : count - c2 + 3;
      71  }
      72  libc_hidden_builtin_def (strcspn)