Ignore:
Timestamp:
Sep 19, 2024, 2:34:43 AM (10 months ago)
Author:
bird
Message:

src/sed: Merged in changes between 4.1.5 and 4.9 from the vendor branch. (svn merge /vendor/sed/4.1.5 /vendor/sed/current .)

Location:
trunk/src/sed
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/sed

  • trunk/src/sed/lib/regex_internal.c

    r2727 r3613  
    11/* Extended regular expression matching and search library.
    2    Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
     2   Copyright (C) 2002-2022 Free Software Foundation, Inc.
    33   This file is part of the GNU C Library.
    44   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
     
    1515
    1616   You should have received a copy of the GNU Lesser General Public
    17    License along with the GNU C Library; if not, write to the Free
    18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    19    02111-1307 USA.  */
    20 
    21 static void re_string_construct_common (const char *str, int len,
     17   License along with the GNU C Library; if not, see
     18   <https://www.gnu.org/licenses/>.  */
     19
     20static void re_string_construct_common (const char *str, Idx len,
    2221                                        re_string_t *pstr,
    23                                         RE_TRANSLATE_TYPE trans, int icase,
    24                                         const re_dfa_t *dfa) internal_function;
     22                                        RE_TRANSLATE_TYPE trans, bool icase,
     23                                        const re_dfa_t *dfa);
    2524static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa,
    2625                                          const re_node_set *nodes,
    27                                           unsigned int hash) internal_function;
     26                                          re_hashval_t hash);
    2827static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
    2928                                          const re_node_set *nodes,
    3029                                          unsigned int context,
    31                                           unsigned int hash) internal_function;
     30                                          re_hashval_t hash);
     31static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr,
     32                                                Idx new_buf_len);
     33static void build_wcs_buffer (re_string_t *pstr);
     34static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr);
     35static void build_upper_buffer (re_string_t *pstr);
     36static void re_string_translate_buffer (re_string_t *pstr);
     37static unsigned int re_string_context_at (const re_string_t *input, Idx idx,
     38                                          int eflags) __attribute__ ((pure));
    3239
    3340
     
    3845
    3946static reg_errcode_t
    40 internal_function
    41 re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
    42                     RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
     47__attribute_warn_unused_result__
     48re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len,
     49                    RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
    4350{
    4451  reg_errcode_t ret;
    45   int init_buf_len;
     52  Idx init_buf_len;
    4653
    4754  /* Ensure at least one character fits into the buffers.  */
     
    5259
    5360  ret = re_string_realloc_buffers (pstr, init_buf_len);
    54   if (BE (ret != REG_NOERROR, 0))
     61  if (__glibc_unlikely (ret != REG_NOERROR))
    5562    return ret;
    5663
     
    6673
    6774static reg_errcode_t
    68 internal_function
    69 re_string_construct (re_string_t *pstr, const char *str, int len,
    70                      RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
     75__attribute_warn_unused_result__
     76re_string_construct (re_string_t *pstr, const char *str, Idx len,
     77                     RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
    7178{
    7279  reg_errcode_t ret;
     
    7784    {
    7885      ret = re_string_realloc_buffers (pstr, len + 1);
    79       if (BE (ret != REG_NOERROR, 0))
     86      if (__glibc_unlikely (ret != REG_NOERROR))
    8087        return ret;
    8188    }
     
    8491  if (icase)
    8592    {
    86 #ifdef RE_ENABLE_I18N
    8793      if (dfa->mb_cur_max > 1)
    8894        {
     
    9096            {
    9197              ret = build_wcs_upper_buffer (pstr);
    92               if (BE (ret != REG_NOERROR, 0))
     98              if (__glibc_unlikely (ret != REG_NOERROR))
    9399                return ret;
    94100              if (pstr->valid_raw_len >= len)
     
    97103                break;
    98104              ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
    99               if (BE (ret != REG_NOERROR, 0))
     105              if (__glibc_unlikely (ret != REG_NOERROR))
    100106                return ret;
    101107            }
    102108        }
    103109      else
    104 #endif /* RE_ENABLE_I18N  */
    105110        build_upper_buffer (pstr);
    106111    }
    107112  else
    108113    {
    109 #ifdef RE_ENABLE_I18N
    110114      if (dfa->mb_cur_max > 1)
    111115        build_wcs_buffer (pstr);
    112116      else
    113 #endif /* RE_ENABLE_I18N  */
    114117        {
    115118          if (trans != NULL)
     
    129132
    130133static reg_errcode_t
    131 internal_function
    132 re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
    133 {
    134 #ifdef RE_ENABLE_I18N
     134__attribute_warn_unused_result__
     135re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
     136{
    135137  if (pstr->mb_cur_max > 1)
    136138    {
    137       wint_t *new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
    138       if (BE (new_wcs == NULL, 0))
     139      wint_t *new_wcs;
     140
     141      /* Avoid overflow in realloc.  */
     142      const size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx));
     143      if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size)
     144                            < new_buf_len))
     145        return REG_ESPACE;
     146
     147      new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
     148      if (__glibc_unlikely (new_wcs == NULL))
    139149        return REG_ESPACE;
    140150      pstr->wcs = new_wcs;
    141151      if (pstr->offsets != NULL)
    142152        {
    143           int *new_offsets = re_realloc (pstr->offsets, int, new_buf_len);
    144           if (BE (new_offsets == NULL, 0))
     153          Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len);
     154          if (__glibc_unlikely (new_offsets == NULL))
    145155            return REG_ESPACE;
    146156          pstr->offsets = new_offsets;
    147157        }
    148158    }
    149 #endif /* RE_ENABLE_I18N  */
    150159  if (pstr->mbs_allocated)
    151160    {
    152161      unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char,
    153162                                           new_buf_len);
    154       if (BE (new_mbs == NULL, 0))
     163      if (__glibc_unlikely (new_mbs == NULL))
    155164        return REG_ESPACE;
    156165      pstr->mbs = new_mbs;
     
    162171
    163172static void
    164 internal_function
    165 re_string_construct_common (const char *str, int len, re_string_t *pstr,
    166                             RE_TRANSLATE_TYPE trans, int icase,
     173re_string_construct_common (const char *str, Idx len, re_string_t *pstr,
     174                            RE_TRANSLATE_TYPE trans, bool icase,
    167175                            const re_dfa_t *dfa)
    168176{
     
    171179  pstr->raw_len = len;
    172180  pstr->trans = trans;
    173   pstr->icase = icase ? 1 : 0;
     181  pstr->icase = icase;
    174182  pstr->mbs_allocated = (trans != NULL || icase);
    175183  pstr->mb_cur_max = dfa->mb_cur_max;
     
    180188}
    181189
    182 #ifdef RE_ENABLE_I18N
    183190
    184191/* Build wide character buffer PSTR->WCS.
     
    194201
    195202static void
    196 internal_function
    197203build_wcs_buffer (re_string_t *pstr)
    198204{
    199205#ifdef _LIBC
    200206  unsigned char buf[MB_LEN_MAX];
    201   assert (MB_LEN_MAX >= pstr->mb_cur_max);
     207  DEBUG_ASSERT (MB_LEN_MAX >= pstr->mb_cur_max);
    202208#else
    203209  unsigned char buf[64];
    204210#endif
    205211  mbstate_t prev_st;
    206   int byte_idx, end_idx, remain_len;
     212  Idx byte_idx, end_idx, remain_len;
    207213  size_t mbclen;
    208214
     
    218224      prev_st = pstr->cur_state;
    219225      /* Apply the translation if we need.  */
    220       if (BE (pstr->trans != NULL, 0))
     226      if (__glibc_unlikely (pstr->trans != NULL))
    221227        {
    222228          int i, ch;
     
    231237      else
    232238        p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx;
    233       mbclen = mbrtowc (&wc, p, remain_len, &pstr->cur_state);
    234       if (BE (mbclen == (size_t) -2, 0))
     239      mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
     240      if (__glibc_unlikely (mbclen == (size_t) -1 || mbclen == 0
     241                            || (mbclen == (size_t) -2
     242                                && pstr->bufs_len >= pstr->len)))
     243        {
     244          /* We treat these cases as a singlebyte character.  */
     245          mbclen = 1;
     246          wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
     247          if (__glibc_unlikely (pstr->trans != NULL))
     248            wc = pstr->trans[wc];
     249          pstr->cur_state = prev_st;
     250        }
     251      else if (__glibc_unlikely (mbclen == (size_t) -2))
    235252        {
    236253          /* The buffer doesn't have enough space, finish to build.  */
    237254          pstr->cur_state = prev_st;
    238255          break;
    239         }
    240       else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0))
    241         {
    242           /* We treat these cases as a singlebyte character.  */
    243           mbclen = 1;
    244           wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
    245           if (BE (pstr->trans != NULL, 0))
    246             wc = pstr->trans[wc];
    247           pstr->cur_state = prev_st;
    248256        }
    249257
     
    261269   but for REG_ICASE.  */
    262270
    263 static int
    264 internal_function
     271static reg_errcode_t
     272__attribute_warn_unused_result__
    265273build_wcs_upper_buffer (re_string_t *pstr)
    266274{
    267275  mbstate_t prev_st;
    268   int src_idx, byte_idx, end_idx, remain_len;
     276  Idx src_idx, byte_idx, end_idx, remain_len;
    269277  size_t mbclen;
    270278#ifdef _LIBC
    271279  char buf[MB_LEN_MAX];
    272   assert (MB_LEN_MAX >= pstr->mb_cur_max);
     280  DEBUG_ASSERT (pstr->mb_cur_max <= MB_LEN_MAX);
    273281#else
    274282  char buf[64];
     
    285293        {
    286294          wchar_t wc;
    287 
    288           if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx])
    289               && mbsinit (&pstr->cur_state))
     295          unsigned char ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
     296
     297          if (isascii (ch) && mbsinit (&pstr->cur_state))
    290298            {
    291               /* In case of a singlebyte character.  */
    292               pstr->mbs[byte_idx]
    293                 = toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]);
    294299              /* The next step uses the assumption that wchar_t is encoded
    295300                 ASCII-safe: all ASCII values can be converted like this.  */
    296               pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx];
    297               ++byte_idx;
    298               continue;
     301              wchar_t wcu = __towupper (ch);
     302              if (isascii (wcu))
     303                {
     304                  pstr->mbs[byte_idx] = wcu;
     305                  pstr->wcs[byte_idx] = wcu;
     306                  byte_idx++;
     307                  continue;
     308                }
    299309            }
    300310
    301311          remain_len = end_idx - byte_idx;
    302312          prev_st = pstr->cur_state;
    303           mbclen = mbrtowc (&wc,
    304                             ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
    305                              + byte_idx), remain_len, &pstr->cur_state);
    306           if (BE (mbclen + 2 > 2, 1))
     313          mbclen = __mbrtowc (&wc,
     314                              ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
     315                               + byte_idx), remain_len, &pstr->cur_state);
     316          if (__glibc_likely (0 < mbclen && mbclen < (size_t) -2))
    307317            {
    308               wchar_t wcu = wc;
    309               if (iswlower (wc))
     318              wchar_t wcu = __towupper (wc);
     319              if (wcu != wc)
    310320                {
    311321                  size_t mbcdlen;
    312322
    313                   wcu = towupper (wc);
    314                   mbcdlen = wcrtomb (buf, wcu, &prev_st);
    315                   if (BE (mbclen == mbcdlen, 1))
     323                  mbcdlen = __wcrtomb (buf, wcu, &prev_st);
     324                  if (__glibc_likely (mbclen == mbcdlen))
    316325                    memcpy (pstr->mbs + byte_idx, buf, mbclen);
    317326                  else
     
    329338                pstr->wcs[byte_idx++] = WEOF;
    330339            }
    331           else if (mbclen == (size_t) -1 || mbclen == 0)
     340          else if (mbclen == (size_t) -1 || mbclen == 0
     341                   || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len))
    332342            {
    333               /* It is an invalid character or '\0'.  Just use the byte.  */
    334               int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
     343              /* It is an invalid character, an incomplete character
     344                 at the end of the string, or '\0'.  Just use the byte.  */
    335345              pstr->mbs[byte_idx] = ch;
    336346              /* And also cast it to wide char.  */
    337347              pstr->wcs[byte_idx++] = (wchar_t) ch;
    338               if (BE (mbclen == (size_t) -1, 0))
     348              if (__glibc_unlikely (mbclen == (size_t) -1))
    339349                pstr->cur_state = prev_st;
    340350            }
     
    358368        remain_len = end_idx - byte_idx;
    359369        prev_st = pstr->cur_state;
    360         if (BE (pstr->trans != NULL, 0))
     370        if (__glibc_unlikely (pstr->trans != NULL))
    361371          {
    362372            int i, ch;
     
    371381        else
    372382          p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;
    373         mbclen = mbrtowc (&wc, p, remain_len, &pstr->cur_state);
    374         if (BE (mbclen + 2 > 2, 1))
     383        mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
     384        if (__glibc_likely (0 < mbclen && mbclen < (size_t) -2))
    375385          {
    376             wchar_t wcu = wc;
    377             if (iswlower (wc))
     386            wchar_t wcu = __towupper (wc);
     387            if (wcu != wc)
    378388              {
    379389                size_t mbcdlen;
    380390
    381                 wcu = towupper (wc);
    382                 mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st);
    383                 if (BE (mbclen == mbcdlen, 1))
     391                mbcdlen = __wcrtomb ((char *) buf, wcu, &prev_st);
     392                if (__glibc_likely (mbclen == mbcdlen))
    384393                  memcpy (pstr->mbs + byte_idx, buf, mbclen);
    385394                else if (mbcdlen != (size_t) -1)
     
    395404                    if (pstr->offsets == NULL)
    396405                      {
    397                         pstr->offsets = re_malloc (int, pstr->bufs_len);
     406                        pstr->offsets = re_malloc (Idx, pstr->bufs_len);
    398407
    399408                        if (pstr->offsets == NULL)
     
    425434                    continue;
    426435                  }
    427                 else
    428                   memcpy (pstr->mbs + byte_idx, p, mbclen);
     436                else
     437                  memcpy (pstr->mbs + byte_idx, p, mbclen);
    429438              }
    430439            else
    431440              memcpy (pstr->mbs + byte_idx, p, mbclen);
    432441
    433             if (BE (pstr->offsets_needed != 0, 0))
     442            if (__glibc_unlikely (pstr->offsets_needed != 0))
    434443              {
    435444                size_t i;
     
    444453              pstr->wcs[byte_idx++] = WEOF;
    445454          }
    446         else if (mbclen == (size_t) -1 || mbclen == 0)
     455        else if (mbclen == (size_t) -1 || mbclen == 0
     456                 || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len))
    447457          {
    448458            /* It is an invalid character or '\0'.  Just use the byte.  */
    449459            int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx];
    450460
    451             if (BE (pstr->trans != NULL, 0))
     461            if (__glibc_unlikely (pstr->trans != NULL))
    452462              ch = pstr->trans [ch];
    453463            pstr->mbs[byte_idx] = ch;
    454464
    455             if (BE (pstr->offsets_needed != 0, 0))
     465            if (__glibc_unlikely (pstr->offsets_needed != 0))
    456466              pstr->offsets[byte_idx] = src_idx;
    457467            ++src_idx;
     
    459469            /* And also cast it to wide char.  */
    460470            pstr->wcs[byte_idx++] = (wchar_t) ch;
    461             if (BE (mbclen == (size_t) -1, 0))
     471            if (__glibc_unlikely (mbclen == (size_t) -1))
    462472              pstr->cur_state = prev_st;
    463473          }
     
    477487   Return the index.  */
    478488
    479 static int
    480 internal_function
    481 re_string_skip_chars (re_string_t *pstr, int new_raw_idx, wint_t *last_wc)
     489static Idx
     490re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc)
    482491{
    483492  mbstate_t prev_st;
    484   int rawbuf_idx;
     493  Idx rawbuf_idx;
    485494  size_t mbclen;
    486   wchar_t wc = 0;
     495  wint_t wc = WEOF;
    487496
    488497  /* Skip the characters which are not necessary to check.  */
     
    490499       rawbuf_idx < new_raw_idx;)
    491500    {
    492       int remain_len;
    493       remain_len = pstr->len - rawbuf_idx;
     501      wchar_t wc2;
     502      Idx remain_len = pstr->raw_len - rawbuf_idx;
    494503      prev_st = pstr->cur_state;
    495       mbclen = mbrtowc (&wc, (const char *) pstr->raw_mbs + rawbuf_idx,
    496                         remain_len, &pstr->cur_state);
    497       if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
    498         {
    499           /* We treat these cases as a singlebyte character.  */
     504      mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx,
     505                          remain_len, &pstr->cur_state);
     506      if (__glibc_unlikely (mbclen == (size_t) -2 || mbclen == (size_t) -1
     507                            || mbclen == 0))
     508        {
     509          /* We treat these cases as a single byte character.  */
     510          if (mbclen == 0 || remain_len == 0)
     511            wc = L'\0';
     512          else
     513            wc = *(unsigned char *) (pstr->raw_mbs + rawbuf_idx);
    500514          mbclen = 1;
    501515          pstr->cur_state = prev_st;
    502516        }
     517      else
     518        wc = wc2;
    503519      /* Then proceed the next character.  */
    504520      rawbuf_idx += mbclen;
    505521    }
    506   *last_wc = (wint_t) wc;
     522  *last_wc = wc;
    507523  return rawbuf_idx;
    508524}
    509 #endif /* RE_ENABLE_I18N  */
    510525
    511526/* Build the buffer PSTR->MBS, and apply the translation if we need.
     
    513528
    514529static void
    515 internal_function
    516530build_upper_buffer (re_string_t *pstr)
    517531{
    518   int char_idx, end_idx;
     532  Idx char_idx, end_idx;
    519533  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
    520534
     
    522536    {
    523537      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];
    524       if (BE (pstr->trans != NULL, 0))
     538      if (__glibc_unlikely (pstr->trans != NULL))
    525539        ch = pstr->trans[ch];
    526       if (islower (ch))
    527         pstr->mbs[char_idx] = toupper (ch);
    528       else
    529         pstr->mbs[char_idx] = ch;
     540      pstr->mbs[char_idx] = toupper (ch);
    530541    }
    531542  pstr->valid_len = char_idx;
     
    536547
    537548static void
    538 internal_function
    539549re_string_translate_buffer (re_string_t *pstr)
    540550{
    541   int buf_idx, end_idx;
     551  Idx buf_idx, end_idx;
    542552  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
    543553
     
    557567
    558568static reg_errcode_t
    559 internal_function
    560 re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
    561 {
    562   int offset = idx - pstr->raw_mbs_idx;
    563   if (BE (offset < 0, 0))
     569__attribute_warn_unused_result__
     570re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
     571{
     572  Idx offset;
     573
     574  if (__glibc_unlikely (pstr->raw_mbs_idx <= idx))
     575    offset = idx - pstr->raw_mbs_idx;
     576  else
    564577    {
    565578      /* Reset buffer.  */
    566 #ifdef RE_ENABLE_I18N
    567579      if (pstr->mb_cur_max > 1)
    568580        memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
    569 #endif /* RE_ENABLE_I18N */
    570581      pstr->len = pstr->raw_len;
    571582      pstr->stop = pstr->raw_stop;
     
    581592    }
    582593
    583   if (BE (offset != 0, 1))
    584     {
    585       /* Are the characters which are already checked remain?  */
    586       if (BE (offset < pstr->valid_raw_len, 1)
    587 #ifdef RE_ENABLE_I18N
    588           /* Handling this would enlarge the code too much.
    589              Accept a slowdown in that case.  */
    590           && pstr->offsets_needed == 0
    591 #endif
    592          )
     594  if (__glibc_likely (offset != 0))
     595    {
     596      /* Should the already checked characters be kept?  */
     597      if (__glibc_likely (offset < pstr->valid_raw_len))
    593598        {
    594599          /* Yes, move them to the front of the buffer.  */
    595           pstr->tip_context = re_string_context_at (pstr, offset - 1, eflags);
    596 #ifdef RE_ENABLE_I18N
    597           if (pstr->mb_cur_max > 1)
    598             memmove (pstr->wcs, pstr->wcs + offset,
    599                      (pstr->valid_len - offset) * sizeof (wint_t));
    600 #endif /* RE_ENABLE_I18N */
    601           if (BE (pstr->mbs_allocated, 0))
    602             memmove (pstr->mbs, pstr->mbs + offset,
    603                      pstr->valid_len - offset);
    604           pstr->valid_len -= offset;
    605           pstr->valid_raw_len -= offset;
    606 #if DEBUG
    607           assert (pstr->valid_len > 0);
    608 #endif
     600          if (__glibc_unlikely (pstr->offsets_needed))
     601            {
     602              Idx low = 0, high = pstr->valid_len, mid;
     603              do
     604                {
     605                  mid = (high + low) / 2;
     606                  if (pstr->offsets[mid] > offset)
     607                    high = mid;
     608                  else if (pstr->offsets[mid] < offset)
     609                    low = mid + 1;
     610                  else
     611                    break;
     612                }
     613              while (low < high);
     614              if (pstr->offsets[mid] < offset)
     615                ++mid;
     616              pstr->tip_context = re_string_context_at (pstr, mid - 1,
     617                                                        eflags);
     618              /* This can be quite complicated, so handle specially
     619                 only the common and easy case where the character with
     620                 different length representation of lower and upper
     621                 case is present at or after offset.  */
     622              if (pstr->valid_len > offset
     623                  && mid == offset && pstr->offsets[mid] == offset)
     624                {
     625                  memmove (pstr->wcs, pstr->wcs + offset,
     626                           (pstr->valid_len - offset) * sizeof (wint_t));
     627                  memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset);
     628                  pstr->valid_len -= offset;
     629                  pstr->valid_raw_len -= offset;
     630                  for (low = 0; low < pstr->valid_len; low++)
     631                    pstr->offsets[low] = pstr->offsets[low + offset] - offset;
     632                }
     633              else
     634                {
     635                  /* Otherwise, just find out how long the partial multibyte
     636                     character at offset is and fill it with WEOF/255.  */
     637                  pstr->len = pstr->raw_len - idx + offset;
     638                  pstr->stop = pstr->raw_stop - idx + offset;
     639                  pstr->offsets_needed = 0;
     640                  while (mid > 0 && pstr->offsets[mid - 1] == offset)
     641                    --mid;
     642                  while (mid < pstr->valid_len)
     643                    if (pstr->wcs[mid] != WEOF)
     644                      break;
     645                    else
     646                      ++mid;
     647                  if (mid == pstr->valid_len)
     648                    pstr->valid_len = 0;
     649                  else
     650                    {
     651                      pstr->valid_len = pstr->offsets[mid] - offset;
     652                      if (pstr->valid_len)
     653                        {
     654                          for (low = 0; low < pstr->valid_len; ++low)
     655                            pstr->wcs[low] = WEOF;
     656                          memset (pstr->mbs, 255, pstr->valid_len);
     657                        }
     658                    }
     659                  pstr->valid_raw_len = pstr->valid_len;
     660                }
     661            }
     662          else
     663            {
     664              pstr->tip_context = re_string_context_at (pstr, offset - 1,
     665                                                        eflags);
     666              if (pstr->mb_cur_max > 1)
     667                memmove (pstr->wcs, pstr->wcs + offset,
     668                         (pstr->valid_len - offset) * sizeof (wint_t));
     669              if (__glibc_unlikely (pstr->mbs_allocated))
     670                memmove (pstr->mbs, pstr->mbs + offset,
     671                         pstr->valid_len - offset);
     672              pstr->valid_len -= offset;
     673              pstr->valid_raw_len -= offset;
     674              DEBUG_ASSERT (pstr->valid_len > 0);
     675            }
    609676        }
    610677      else
    611678        {
    612679          /* No, skip all characters until IDX.  */
    613 #ifdef RE_ENABLE_I18N
    614           if (BE (pstr->offsets_needed, 0))
     680          Idx prev_valid_len = pstr->valid_len;
     681
     682          if (__glibc_unlikely (pstr->offsets_needed))
    615683            {
    616684              pstr->len = pstr->raw_len - idx + offset;
     
    618686              pstr->offsets_needed = 0;
    619687            }
    620 #endif
    621688          pstr->valid_len = 0;
    622           pstr->valid_raw_len = 0;
    623 #ifdef RE_ENABLE_I18N
    624689          if (pstr->mb_cur_max > 1)
    625690            {
    626               int wcs_idx;
     691              Idx wcs_idx;
    627692              wint_t wc = WEOF;
    628693
    629694              if (pstr->is_utf8)
    630695                {
    631                   const unsigned char *raw, *p, *q, *end;
     696                  const unsigned char *raw, *p, *end;
    632697
    633698                  /* Special case UTF-8.  Multi-byte chars start with any
     
    635700                  raw = pstr->raw_mbs + pstr->raw_mbs_idx;
    636701                  end = raw + (offset - pstr->mb_cur_max);
     702                  if (end < pstr->raw_mbs)
     703                    end = pstr->raw_mbs;
    637704                  p = raw + offset - 1;
    638705#ifdef _LIBC
    639706                  /* We know the wchar_t encoding is UCS4, so for the simple
    640707                     case, ASCII characters, skip the conversion step.  */
    641                   if (isascii (*p) && BE (pstr->trans == NULL, 1))
     708                  if (isascii (*p) && __glibc_likely (pstr->trans == NULL))
    642709                    {
    643710                      memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
    644                       pstr->valid_len = 0;
     711                      /* pstr->valid_len = 0; */
    645712                      wc = (wchar_t) *p;
    646713                    }
     
    652719                          mbstate_t cur_state;
    653720                          wchar_t wc2;
    654                           int mlen = raw + pstr->len - p;
     721                          Idx mlen = raw + pstr->len - p;
    655722                          unsigned char buf[6];
    656723                          size_t mbclen;
    657724
    658                           q = p;
    659                           if (BE (pstr->trans != NULL, 0))
     725                          const unsigned char *pp = p;
     726                          if (__glibc_unlikely (pstr->trans != NULL))
    660727                            {
    661728                              int i = mlen < 6 ? mlen : 6;
    662729                              while (--i >= 0)
    663730                                buf[i] = pstr->trans[p[i]];
    664                               q = buf;
     731                              pp = buf;
    665732                            }
    666733                          /* XXX Don't use mbrtowc, we know which conversion
    667734                             to use (UTF-8 -> UCS4).  */
    668735                          memset (&cur_state, 0, sizeof (cur_state));
    669                           mbclen = mbrtowc (&wc2, (const char *) p, mlen,
    670                                             &cur_state);
     736                          mbclen = __mbrtowc (&wc2, (const char *) pp, mlen,
     737                                              &cur_state);
    671738                          if (raw + offset - p <= mbclen
    672739                              && mbclen < (size_t) -2)
     
    683750              if (wc == WEOF)
    684751                pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx;
    685               if (BE (pstr->valid_len, 0))
     752              if (wc == WEOF)
     753                pstr->tip_context
     754                  = re_string_context_at (pstr, prev_valid_len - 1, eflags);
     755              else
     756                pstr->tip_context = ((__glibc_unlikely (pstr->word_ops_used != 0)
     757                                      && IS_WIDE_WORD_CHAR (wc))
     758                                     ? CONTEXT_WORD
     759                                     : ((IS_WIDE_NEWLINE (wc)
     760                                         && pstr->newline_anchor)
     761                                        ? CONTEXT_NEWLINE : 0));
     762              if (__glibc_unlikely (pstr->valid_len))
    686763                {
    687764                  for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
     
    691768                }
    692769              pstr->valid_raw_len = pstr->valid_len;
    693               pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0)
    694                                     && IS_WIDE_WORD_CHAR (wc))
    695                                    ? CONTEXT_WORD
    696                                    : ((IS_WIDE_NEWLINE (wc)
    697                                        && pstr->newline_anchor)
    698                                       ? CONTEXT_NEWLINE : 0));
    699770            }
    700771          else
    701 #endif /* RE_ENABLE_I18N */
    702772            {
    703773              int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];
     774              pstr->valid_raw_len = 0;
    704775              if (pstr->trans)
    705776                c = pstr->trans[c];
     
    710781            }
    711782        }
    712       if (!BE (pstr->mbs_allocated, 0))
     783      if (!__glibc_unlikely (pstr->mbs_allocated))
    713784        pstr->mbs += offset;
    714785    }
     
    718789
    719790  /* Then build the buffers.  */
    720 #ifdef RE_ENABLE_I18N
    721791  if (pstr->mb_cur_max > 1)
    722792    {
    723793      if (pstr->icase)
    724794        {
    725           int ret = build_wcs_upper_buffer (pstr);
    726           if (BE (ret != REG_NOERROR, 0))
     795          reg_errcode_t ret = build_wcs_upper_buffer (pstr);
     796          if (__glibc_unlikely (ret != REG_NOERROR))
    727797            return ret;
    728798        }
     
    731801    }
    732802  else
    733 #endif /* RE_ENABLE_I18N */
    734     if (BE (pstr->mbs_allocated, 0))
     803    if (__glibc_unlikely (pstr->mbs_allocated))
    735804      {
    736805        if (pstr->icase)
     
    747816
    748817static unsigned char
    749 internal_function __attribute ((pure))
    750 re_string_peek_byte_case (const re_string_t *pstr, int idx)
    751 {
    752   int ch, off;
     818__attribute__ ((pure))
     819re_string_peek_byte_case (const re_string_t *pstr, Idx idx)
     820{
     821  int ch;
     822  Idx off;
    753823
    754824  /* Handle the common (easiest) cases first.  */
    755   if (BE (!pstr->mbs_allocated, 1))
     825  if (__glibc_likely (!pstr->mbs_allocated))
    756826    return re_string_peek_byte (pstr, idx);
    757827
    758 #ifdef RE_ENABLE_I18N
    759828  if (pstr->mb_cur_max > 1
    760829      && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
    761830    return re_string_peek_byte (pstr, idx);
    762 #endif
    763831
    764832  off = pstr->cur_idx + idx;
    765 #ifdef RE_ENABLE_I18N
    766833  if (pstr->offsets_needed)
    767834    off = pstr->offsets[off];
    768 #endif
    769835
    770836  ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
    771837
    772 #ifdef RE_ENABLE_I18N
    773838  /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I
    774839     this function returns CAPITAL LETTER I instead of first byte of
     
    777842  if (pstr->offsets_needed && !isascii (ch))
    778843    return re_string_peek_byte (pstr, idx);
    779 #endif
    780844
    781845  return ch;
     
    783847
    784848static unsigned char
    785 internal_function
    786849re_string_fetch_byte_case (re_string_t *pstr)
    787850{
    788   if (BE (!pstr->mbs_allocated, 1))
     851  if (__glibc_likely (!pstr->mbs_allocated))
    789852    return re_string_fetch_byte (pstr);
    790853
    791 #ifdef RE_ENABLE_I18N
    792854  if (pstr->offsets_needed)
    793855    {
    794       int off, ch;
     856      Idx off;
     857      int ch;
    795858
    796859      /* For tr_TR.UTF-8 [[:islower:]] there is
     
    814877      return ch;
    815878    }
    816 #endif
    817879
    818880  return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++];
     
    820882
    821883static void
    822 internal_function
    823884re_string_destruct (re_string_t *pstr)
    824885{
    825 #ifdef RE_ENABLE_I18N
    826886  re_free (pstr->wcs);
    827887  re_free (pstr->offsets);
    828 #endif /* RE_ENABLE_I18N  */
    829888  if (pstr->mbs_allocated)
    830889    re_free (pstr->mbs);
     
    834893
    835894static unsigned int
    836 internal_function
    837 re_string_context_at (const re_string_t *input, int idx, int eflags)
     895re_string_context_at (const re_string_t *input, Idx idx, int eflags)
    838896{
    839897  int c;
    840   if (BE (idx < 0, 0))
     898  if (__glibc_unlikely (idx < 0))
    841899    /* In this case, we use the value stored in input->tip_context,
    842900       since we can't know the character in input->mbs[-1] here.  */
    843901    return input->tip_context;
    844   if (BE (idx == input->len, 0))
     902  if (__glibc_unlikely (idx == input->len))
    845903    return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
    846904            : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
    847 #ifdef RE_ENABLE_I18N
    848905  if (input->mb_cur_max > 1)
    849906    {
    850907      wint_t wc;
    851       int wc_idx = idx;
     908      Idx wc_idx = idx;
    852909      while(input->wcs[wc_idx] == WEOF)
    853910        {
    854 #ifdef DEBUG
    855           /* It must not happen.  */
    856           assert (wc_idx >= 0);
    857 #endif
     911          DEBUG_ASSERT (wc_idx >= 0);
    858912          --wc_idx;
    859913          if (wc_idx < 0)
     
    861915        }
    862916      wc = input->wcs[wc_idx];
    863       if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc))
     917      if (__glibc_unlikely (input->word_ops_used != 0)
     918          && IS_WIDE_WORD_CHAR (wc))
    864919        return CONTEXT_WORD;
    865920      return (IS_WIDE_NEWLINE (wc) && input->newline_anchor
     
    867922    }
    868923  else
    869 #endif
    870924    {
    871925      c = re_string_byte_at (input, idx);
     
    880934
    881935static reg_errcode_t
    882 internal_function
    883 re_node_set_alloc (re_node_set *set, int size)
     936__attribute_warn_unused_result__
     937re_node_set_alloc (re_node_set *set, Idx size)
    884938{
    885939  set->alloc = size;
    886940  set->nelem = 0;
    887   set->elems = re_malloc (int, size);
    888   if (BE (set->elems == NULL, 0))
     941  set->elems = re_malloc (Idx, size);
     942  if (__glibc_unlikely (set->elems == NULL)
     943      && (MALLOC_0_IS_NONNULL || size != 0))
    889944    return REG_ESPACE;
    890945  return REG_NOERROR;
     
    892947
    893948static reg_errcode_t
    894 internal_function
    895 re_node_set_init_1 (re_node_set *set, int elem)
     949__attribute_warn_unused_result__
     950re_node_set_init_1 (re_node_set *set, Idx elem)
    896951{
    897952  set->alloc = 1;
    898953  set->nelem = 1;
    899   set->elems = re_malloc (int, 1);
    900   if (BE (set->elems == NULL, 0))
     954  set->elems = re_malloc (Idx, 1);
     955  if (__glibc_unlikely (set->elems == NULL))
    901956    {
    902957      set->alloc = set->nelem = 0;
     
    908963
    909964static reg_errcode_t
    910 internal_function
    911 re_node_set_init_2 (re_node_set *set, int elem1, int elem2)
     965__attribute_warn_unused_result__
     966re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2)
    912967{
    913968  set->alloc = 2;
    914   set->elems = re_malloc (int, 2);
    915   if (BE (set->elems == NULL, 0))
     969  set->elems = re_malloc (Idx, 2);
     970  if (__glibc_unlikely (set->elems == NULL))
    916971    return REG_ESPACE;
    917972  if (elem1 == elem2)
     
    938993
    939994static reg_errcode_t
    940 internal_function
     995__attribute_warn_unused_result__
    941996re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
    942997{
     
    9451000    {
    9461001      dest->alloc = dest->nelem;
    947       dest->elems = re_malloc (int, dest->alloc);
    948       if (BE (dest->elems == NULL, 0))
     1002      dest->elems = re_malloc (Idx, dest->alloc);
     1003      if (__glibc_unlikely (dest->elems == NULL))
    9491004        {
    9501005          dest->alloc = dest->nelem = 0;
    9511006          return REG_ESPACE;
    9521007        }
    953       memcpy (dest->elems, src->elems, src->nelem * sizeof (int));
     1008      memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
    9541009    }
    9551010  else
     
    9631018
    9641019static reg_errcode_t
    965 internal_function
     1020__attribute_warn_unused_result__
    9661021re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
    9671022                           const re_node_set *src2)
    9681023{
    969   int i1, i2, is, id, delta, sbase;
     1024  Idx i1, i2, is, id, delta, sbase;
    9701025  if (src1->nelem == 0 || src2->nelem == 0)
    9711026    return REG_NOERROR;
     
    9751030  if (src1->nelem + src2->nelem + dest->nelem > dest->alloc)
    9761031    {
    977       int new_alloc = src1->nelem + src2->nelem + dest->alloc;
    978       int *new_elems = re_realloc (dest->elems, int, new_alloc);
    979       if (BE (new_elems == NULL, 0))
    980         return REG_ESPACE;
     1032      Idx new_alloc = src1->nelem + src2->nelem + dest->alloc;
     1033      Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc);
     1034      if (__glibc_unlikely (new_elems == NULL))
     1035        return REG_ESPACE;
    9811036      dest->elems = new_elems;
    9821037      dest->alloc = new_alloc;
     
    9971052            --id;
    9981053
    999           if (id < 0 || dest->elems[id] != src1->elems[i1])
     1054          if (id < 0 || dest->elems[id] != src1->elems[i1])
    10001055            dest->elems[--sbase] = src1->elems[i1];
    10011056
     
    10281083    for (;;)
    10291084      {
    1030         if (dest->elems[is] > dest->elems[id])
    1031           {
    1032             /* Copy from the top.  */
    1033             dest->elems[id + delta--] = dest->elems[is--];
    1034             if (delta == 0)
    1035               break;
    1036           }
    1037         else
    1038           {
    1039             /* Slide from the bottom.  */
    1040             dest->elems[id + delta] = dest->elems[id];
    1041             if (--id < 0)
    1042               break;
    1043           }
     1085        if (dest->elems[is] > dest->elems[id])
     1086          {
     1087            /* Copy from the top.  */
     1088            dest->elems[id + delta--] = dest->elems[is--];
     1089            if (delta == 0)
     1090              break;
     1091          }
     1092        else
     1093          {
     1094            /* Slide from the bottom.  */
     1095            dest->elems[id + delta] = dest->elems[id];
     1096            if (--id < 0)
     1097              break;
     1098          }
    10441099      }
    10451100
    10461101  /* Copy remaining SRC elements.  */
    1047   memcpy (dest->elems, dest->elems + sbase, delta * sizeof (int));
     1102  memcpy (dest->elems, dest->elems + sbase, delta * sizeof (Idx));
    10481103
    10491104  return REG_NOERROR;
     
    10541109
    10551110static reg_errcode_t
    1056 internal_function
     1111__attribute_warn_unused_result__
    10571112re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
    10581113                        const re_node_set *src2)
    10591114{
    1060   int i1, i2, id;
     1115  Idx i1, i2, id;
    10611116  if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0)
    10621117    {
    10631118      dest->alloc = src1->nelem + src2->nelem;
    1064       dest->elems = re_malloc (int, dest->alloc);
    1065       if (BE (dest->elems == NULL, 0))
     1119      dest->elems = re_malloc (Idx, dest->alloc);
     1120      if (__glibc_unlikely (dest->elems == NULL))
    10661121        return REG_ESPACE;
    10671122    }
     
    10901145    {
    10911146      memcpy (dest->elems + id, src1->elems + i1,
    1092              (src1->nelem - i1) * sizeof (int));
     1147             (src1->nelem - i1) * sizeof (Idx));
    10931148      id += src1->nelem - i1;
    10941149    }
     
    10961151    {
    10971152      memcpy (dest->elems + id, src2->elems + i2,
    1098              (src2->nelem - i2) * sizeof (int));
     1153             (src2->nelem - i2) * sizeof (Idx));
    10991154      id += src2->nelem - i2;
    11001155    }
     
    11071162
    11081163static reg_errcode_t
    1109 internal_function
     1164__attribute_warn_unused_result__
    11101165re_node_set_merge (re_node_set *dest, const re_node_set *src)
    11111166{
    1112   int is, id, sbase, delta;
     1167  Idx is, id, sbase, delta;
    11131168  if (src == NULL || src->nelem == 0)
    11141169    return REG_NOERROR;
    11151170  if (dest->alloc < 2 * src->nelem + dest->nelem)
    11161171    {
    1117       int new_alloc = 2 * (src->nelem + dest->alloc);
    1118       int *new_buffer = re_realloc (dest->elems, int, new_alloc);
    1119       if (BE (new_buffer == NULL, 0))
     1172      Idx new_alloc = 2 * (src->nelem + dest->alloc);
     1173      Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc);
     1174      if (__glibc_unlikely (new_buffer == NULL))
    11201175        return REG_ESPACE;
    11211176      dest->elems = new_buffer;
     
    11231178    }
    11241179
    1125   if (BE (dest->nelem == 0, 0))
    1126     {
     1180  if (__glibc_unlikely (dest->nelem == 0))
     1181    {
     1182      /* Although we already guaranteed above that dest->alloc != 0 and
     1183         therefore dest->elems != NULL, add a debug assertion to pacify
     1184         GCC 11.2.1's -fanalyzer.  */
     1185      DEBUG_ASSERT (dest->elems);
    11271186      dest->nelem = src->nelem;
    1128       memcpy (dest->elems, src->elems, src->nelem * sizeof (int));
     1187      memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
    11291188      return REG_NOERROR;
    11301189    }
     
    11361195    {
    11371196      if (dest->elems[id] == src->elems[is])
    1138         is--, id--;
     1197        is--, id--;
    11391198      else if (dest->elems[id] < src->elems[is])
    1140         dest->elems[--sbase] = src->elems[is--];
     1199        dest->elems[--sbase] = src->elems[is--];
    11411200      else /* if (dest->elems[id] > src->elems[is]) */
    1142         --id;
     1201        --id;
    11431202    }
    11441203
     
    11471206      /* If DEST is exhausted, the remaining items of SRC must be unique.  */
    11481207      sbase -= is + 1;
    1149       memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (int));
     1208      memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (Idx));
    11501209    }
    11511210
     
    11621221    {
    11631222      if (dest->elems[is] > dest->elems[id])
    1164         {
     1223        {
    11651224          /* Copy from the top.  */
    1166           dest->elems[id + delta--] = dest->elems[is--];
     1225          dest->elems[id + delta--] = dest->elems[is--];
    11671226          if (delta == 0)
    11681227            break;
    11691228        }
    11701229      else
    1171         {
    1172           /* Slide from the bottom.  */
    1173           dest->elems[id + delta] = dest->elems[id];
     1230        {
     1231          /* Slide from the bottom.  */
     1232          dest->elems[id + delta] = dest->elems[id];
    11741233          if (--id < 0)
    11751234            {
    11761235              /* Copy remaining SRC elements.  */
    11771236              memcpy (dest->elems, dest->elems + sbase,
    1178                       delta * sizeof (int));
     1237                      delta * sizeof (Idx));
    11791238              break;
    11801239            }
     
    11871246/* Insert the new element ELEM to the re_node_set* SET.
    11881247   SET should not already have ELEM.
    1189    return -1 if an error is occured, return 1 otherwise.  */
    1190 
    1191 static int
    1192 internal_function
    1193 re_node_set_insert (re_node_set *set, int elem)
    1194 {
    1195   int idx;
     1248   Return true if successful.  */
     1249
     1250static bool
     1251__attribute_warn_unused_result__
     1252re_node_set_insert (re_node_set *set, Idx elem)
     1253{
     1254  Idx idx;
    11961255  /* In case the set is empty.  */
    11971256  if (set->alloc == 0)
    1198     {
    1199       if (BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1))
    1200         return 1;
    1201       else
    1202         return -1;
    1203     }
    1204 
    1205   if (BE (set->nelem, 0) == 0)
    1206     {
    1207       /* We already guaranteed above that set->alloc != 0.  */
     1257    return __glibc_likely (re_node_set_init_1 (set, elem) == REG_NOERROR);
     1258
     1259  if (__glibc_unlikely (set->nelem) == 0)
     1260    {
     1261      /* Although we already guaranteed above that set->alloc != 0 and
     1262         therefore set->elems != NULL, add a debug assertion to pacify
     1263         GCC 11.2 -fanalyzer.  */
     1264      DEBUG_ASSERT (set->elems);
    12081265      set->elems[0] = elem;
    12091266      ++set->nelem;
    1210       return 1;
     1267      return true;
    12111268    }
    12121269
     
    12141271  if (set->alloc == set->nelem)
    12151272    {
    1216       int *new_elems;
     1273      Idx *new_elems;
    12171274      set->alloc = set->alloc * 2;
    1218       new_elems = re_realloc (set->elems, int, set->alloc);
    1219       if (BE (new_elems == NULL, 0))
    1220         return -1;
     1275      new_elems = re_realloc (set->elems, Idx, set->alloc);
     1276      if (__glibc_unlikely (new_elems == NULL))
     1277        return false;
    12211278      set->elems = new_elems;
    12221279    }
     
    12261283  if (elem < set->elems[0])
    12271284    {
    1228       idx = 0;
    12291285      for (idx = set->nelem; idx > 0; idx--)
    1230         set->elems[idx] = set->elems[idx - 1];
     1286        set->elems[idx] = set->elems[idx - 1];
    12311287    }
    12321288  else
    12331289    {
    12341290      for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
    1235         set->elems[idx] = set->elems[idx - 1];
     1291        set->elems[idx] = set->elems[idx - 1];
     1292      DEBUG_ASSERT (set->elems[idx - 1] < elem);
    12361293    }
    12371294
     
    12391296  set->elems[idx] = elem;
    12401297  ++set->nelem;
    1241   return 1;
     1298  return true;
    12421299}
    12431300
    12441301/* Insert the new element ELEM to the re_node_set* SET.
    12451302   SET should not already have any element greater than or equal to ELEM.
    1246    Return -1 if an error is occured, return 1 otherwise.  */
    1247 
    1248 static int
    1249 internal_function
    1250 re_node_set_insert_last (re_node_set *set, int elem)
     1303   Return true if successful.  */
     1304
     1305static bool
     1306__attribute_warn_unused_result__
     1307re_node_set_insert_last (re_node_set *set, Idx elem)
    12511308{
    12521309  /* Realloc if we need.  */
    12531310  if (set->alloc == set->nelem)
    12541311    {
    1255       int *new_elems;
     1312      Idx *new_elems;
    12561313      set->alloc = (set->alloc + 1) * 2;
    1257       new_elems = re_realloc (set->elems, int, set->alloc);
    1258       if (BE (new_elems == NULL, 0))
    1259         return -1;
     1314      new_elems = re_realloc (set->elems, Idx, set->alloc);
     1315      if (__glibc_unlikely (new_elems == NULL))
     1316        return false;
    12601317      set->elems = new_elems;
    12611318    }
     
    12631320  /* Insert the new element.  */
    12641321  set->elems[set->nelem++] = elem;
    1265   return 1;
     1322  return true;
    12661323}
    12671324
    12681325/* Compare two node sets SET1 and SET2.
    1269    return 1 if SET1 and SET2 are equivalent, return 0 otherwise.  */
    1270 
    1271 static int
    1272 internal_function __attribute ((pure))
     1326   Return true if SET1 and SET2 are equivalent.  */
     1327
     1328static bool
     1329__attribute__ ((pure))
    12731330re_node_set_compare (const re_node_set *set1, const re_node_set *set2)
    12741331{
    1275   int i;
     1332  Idx i;
    12761333  if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem)
    1277     return 0;
     1334    return false;
    12781335  for (i = set1->nelem ; --i >= 0 ; )
    12791336    if (set1->elems[i] != set2->elems[i])
    1280       return 0;
    1281   return 1;
     1337      return false;
     1338  return true;
    12821339}
    12831340
    12841341/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise.  */
    12851342
    1286 static int
    1287 internal_function __attribute ((pure))
    1288 re_node_set_contains (const re_node_set *set, int elem)
    1289 {
    1290   unsigned int idx, right, mid;
     1343static Idx
     1344__attribute__ ((pure))
     1345re_node_set_contains (const re_node_set *set, Idx elem)
     1346{
     1347  __re_size_t idx, right, mid;
    12911348  if (set->nelem <= 0)
    12921349    return 0;
     
    13071364
    13081365static void
    1309 internal_function
    1310 re_node_set_remove_at (re_node_set *set, int idx)
     1366re_node_set_remove_at (re_node_set *set, Idx idx)
    13111367{
    13121368  if (idx < 0 || idx >= set->nelem)
     
    13201376
    13211377/* Add the token TOKEN to dfa->nodes, and return the index of the token.
    1322    Or return -1, if an error will be occured.  */
    1323 
    1324 static int
    1325 internal_function
     1378   Or return -1 if an error occurred.  */
     1379
     1380static Idx
    13261381re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
    13271382{
    1328   int type = token.type;
    1329   if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0))
     1383  if (__glibc_unlikely (dfa->nodes_len >= dfa->nodes_alloc))
    13301384    {
    13311385      size_t new_nodes_alloc = dfa->nodes_alloc * 2;
    1332       int *new_nexts, *new_indices;
     1386      Idx *new_nexts, *new_indices;
    13331387      re_node_set *new_edests, *new_eclosures;
    13341388      re_token_t *new_nodes;
    13351389
    1336       /* Avoid overflows.  */
    1337       if (BE (new_nodes_alloc < dfa->nodes_alloc, 0))
     1390      /* Avoid overflows in realloc.  */
     1391      const size_t max_object_size = MAX (sizeof (re_token_t),
     1392                                          MAX (sizeof (re_node_set),
     1393                                               sizeof (Idx)));
     1394      if (__glibc_unlikely (MIN (IDX_MAX, SIZE_MAX / max_object_size)
     1395                            < new_nodes_alloc))
    13381396        return -1;
    13391397
    13401398      new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);
    1341       if (BE (new_nodes == NULL, 0))
     1399      if (__glibc_unlikely (new_nodes == NULL))
    13421400        return -1;
    13431401      dfa->nodes = new_nodes;
    1344       new_nexts = re_realloc (dfa->nexts, int, new_nodes_alloc);
    1345       new_indices = re_realloc (dfa->org_indices, int, new_nodes_alloc);
     1402      dfa->nodes_alloc = new_nodes_alloc;
     1403      new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc);
     1404      if (new_nexts != NULL)
     1405        dfa->nexts = new_nexts;
     1406      new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc);
     1407      if (new_indices != NULL)
     1408        dfa->org_indices = new_indices;
    13461409      new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);
     1410      if (new_edests != NULL)
     1411        dfa->edests = new_edests;
    13471412      new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);
    1348       if (BE (new_nexts == NULL || new_indices == NULL
    1349               || new_edests == NULL || new_eclosures == NULL, 0))
     1413      if (new_eclosures != NULL)
     1414        dfa->eclosures = new_eclosures;
     1415      if (__glibc_unlikely (new_nexts == NULL || new_indices == NULL
     1416                            || new_edests == NULL || new_eclosures == NULL))
    13501417        return -1;
    1351       dfa->nexts = new_nexts;
    1352       dfa->org_indices = new_indices;
    1353       dfa->edests = new_edests;
    1354       dfa->eclosures = new_eclosures;
    1355       dfa->nodes_alloc = new_nodes_alloc;
    13561418    }
    13571419  dfa->nodes[dfa->nodes_len] = token;
    13581420  dfa->nodes[dfa->nodes_len].constraint = 0;
    1359 #ifdef RE_ENABLE_I18N
    13601421  dfa->nodes[dfa->nodes_len].accept_mb =
    1361     (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET;
    1362 #endif
     1422    ((token.type == OP_PERIOD && dfa->mb_cur_max > 1)
     1423     || token.type == COMPLEX_BRACKET);
    13631424  dfa->nexts[dfa->nodes_len] = -1;
    13641425  re_node_set_init_empty (dfa->edests + dfa->nodes_len);
     
    13671428}
    13681429
    1369 static inline unsigned int
    1370 internal_function
     1430static re_hashval_t
    13711431calc_state_hash (const re_node_set *nodes, unsigned int context)
    13721432{
    1373   unsigned int hash = nodes->nelem + context;
    1374   int i;
     1433  re_hashval_t hash = nodes->nelem + context;
     1434  Idx i;
    13751435  for (i = 0 ; i < nodes->nelem ; i++)
    13761436    hash += nodes->elems[i];
     
    13881448
    13891449static re_dfastate_t *
    1390 internal_function
     1450__attribute_warn_unused_result__
    13911451re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
    13921452                  const re_node_set *nodes)
    13931453{
    1394   unsigned int hash;
     1454  re_hashval_t hash;
    13951455  re_dfastate_t *new_state;
    13961456  struct re_state_table_entry *spot;
    1397   int i;
    1398   if (BE (nodes->nelem == 0, 0))
     1457  Idx i;
     1458#if defined GCC_LINT || defined lint
     1459  /* Suppress bogus uninitialized-variable warnings.  */
     1460  *err = REG_NOERROR;
     1461#endif
     1462  if (__glibc_unlikely (nodes->nelem == 0))
    13991463    {
    14001464      *err = REG_NOERROR;
     
    14151479  /* There are no appropriate state in the dfa, create the new one.  */
    14161480  new_state = create_ci_newstate (dfa, nodes, hash);
    1417   if (BE (new_state == NULL, 0))
     1481  if (__glibc_unlikely (new_state == NULL))
    14181482    *err = REG_ESPACE;
    14191483
     
    14321496
    14331497static re_dfastate_t *
    1434 internal_function
     1498__attribute_warn_unused_result__
    14351499re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
    14361500                          const re_node_set *nodes, unsigned int context)
    14371501{
    1438   unsigned int hash;
     1502  re_hashval_t hash;
    14391503  re_dfastate_t *new_state;
    14401504  struct re_state_table_entry *spot;
    1441   int i;
     1505  Idx i;
     1506#if defined GCC_LINT || defined lint
     1507  /* Suppress bogus uninitialized-variable warnings.  */
     1508  *err = REG_NOERROR;
     1509#endif
    14421510  if (nodes->nelem == 0)
    14431511    {
     
    14561524        return state;
    14571525    }
    1458   /* There are no appropriate state in `dfa', create the new one.  */
     1526  /* There are no appropriate state in 'dfa', create the new one.  */
    14591527  new_state = create_cd_newstate (dfa, nodes, context, hash);
    1460   if (BE (new_state == NULL, 0))
     1528  if (__glibc_unlikely (new_state == NULL))
    14611529    *err = REG_ESPACE;
    14621530
     
    14691537
    14701538static reg_errcode_t
     1539__attribute_warn_unused_result__
    14711540register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
    1472                 unsigned int hash)
     1541                re_hashval_t hash)
    14731542{
    14741543  struct re_state_table_entry *spot;
    14751544  reg_errcode_t err;
    1476   int i;
     1545  Idx i;
    14771546
    14781547  newstate->hash = hash;
    14791548  err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem);
    1480   if (BE (err != REG_NOERROR, 0))
     1549  if (__glibc_unlikely (err != REG_NOERROR))
    14811550    return REG_ESPACE;
    14821551  for (i = 0; i < newstate->nodes.nelem; i++)
    14831552    {
    1484       int elem = newstate->nodes.elems[i];
     1553      Idx elem = newstate->nodes.elems[i];
    14851554      if (!IS_EPSILON_NODE (dfa->nodes[elem].type))
    1486         re_node_set_insert_last (&newstate->non_eps_nodes, elem);
     1555        if (! re_node_set_insert_last (&newstate->non_eps_nodes, elem))
     1556          return REG_ESPACE;
    14871557    }
    14881558
    14891559  spot = dfa->state_table + (hash & dfa->state_hash_mask);
    1490   if (BE (spot->alloc <= spot->num, 0))
    1491     {
    1492       int new_alloc = 2 * spot->num + 2;
     1560  if (__glibc_unlikely (spot->alloc <= spot->num))
     1561    {
     1562      Idx new_alloc = 2 * spot->num + 2;
    14931563      re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *,
    14941564                                              new_alloc);
    1495       if (BE (new_array == NULL, 0))
     1565      if (__glibc_unlikely (new_array == NULL))
    14961566        return REG_ESPACE;
    14971567      spot->array = new_array;
     
    15181588}
    15191589
    1520 /* Create the new state which is independ of contexts.
     1590/* Create the new state which is independent of contexts.
    15211591   Return the new state if succeeded, otherwise return NULL.  */
    15221592
    15231593static re_dfastate_t *
    1524 internal_function
     1594__attribute_warn_unused_result__
    15251595create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
    1526                     unsigned int hash)
    1527 {
    1528   int i;
     1596                    re_hashval_t hash)
     1597{
     1598  Idx i;
    15291599  reg_errcode_t err;
    15301600  re_dfastate_t *newstate;
    15311601
    15321602  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
    1533   if (BE (newstate == NULL, 0))
     1603  if (__glibc_unlikely (newstate == NULL))
    15341604    return NULL;
    15351605  err = re_node_set_init_copy (&newstate->nodes, nodes);
    1536   if (BE (err != REG_NOERROR, 0))
     1606  if (__glibc_unlikely (err != REG_NOERROR))
    15371607    {
    15381608      re_free (newstate);
     
    15471617      if (type == CHARACTER && !node->constraint)
    15481618        continue;
    1549 #ifdef RE_ENABLE_I18N
    15501619      newstate->accept_mb |= node->accept_mb;
    1551 #endif /* RE_ENABLE_I18N */
    15521620
    15531621      /* If the state has the halt node, the state is a halt state.  */
     
    15601628    }
    15611629  err = register_state (dfa, newstate, hash);
    1562   if (BE (err != REG_NOERROR, 0))
     1630  if (__glibc_unlikely (err != REG_NOERROR))
    15631631    {
    15641632      free_state (newstate);
     
    15721640
    15731641static re_dfastate_t *
    1574 internal_function
     1642__attribute_warn_unused_result__
    15751643create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
    1576                     unsigned int context, unsigned int hash)
    1577 {
    1578   int i, nctx_nodes = 0;
     1644                    unsigned int context, re_hashval_t hash)
     1645{
     1646  Idx i, nctx_nodes = 0;
    15791647  reg_errcode_t err;
    15801648  re_dfastate_t *newstate;
    15811649
    15821650  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
    1583   if (BE (newstate == NULL, 0))
     1651  if (__glibc_unlikely (newstate == NULL))
    15841652    return NULL;
    15851653  err = re_node_set_init_copy (&newstate->nodes, nodes);
    1586   if (BE (err != REG_NOERROR, 0))
     1654  if (__glibc_unlikely (err != REG_NOERROR))
    15871655    {
    15881656      re_free (newstate);
     
    15951663  for (i = 0 ; i < nodes->nelem ; i++)
    15961664    {
    1597       unsigned int constraint = 0;
    15981665      re_token_t *node = dfa->nodes + nodes->elems[i];
    15991666      re_token_type_t type = node->type;
    1600       if (node->constraint)
    1601         constraint = node->constraint;
     1667      unsigned int constraint = node->constraint;
    16021668
    16031669      if (type == CHARACTER && !constraint)
    16041670        continue;
    1605 #ifdef RE_ENABLE_I18N
    16061671      newstate->accept_mb |= node->accept_mb;
    1607 #endif /* RE_ENABLE_I18N */
    16081672
    16091673      /* If the state has the halt node, the state is a halt state.  */
     
    16121676      else if (type == OP_BACK_REF)
    16131677        newstate->has_backref = 1;
    1614       else if (type == ANCHOR)
    1615         constraint = node->opr.ctx_type;
    16161678
    16171679      if (constraint)
     
    16191681          if (newstate->entrance_nodes == &newstate->nodes)
    16201682            {
    1621               newstate->entrance_nodes = re_malloc (re_node_set, 1);
    1622               if (BE (newstate->entrance_nodes == NULL, 0))
     1683              re_node_set *entrance_nodes = re_malloc (re_node_set, 1);
     1684              if (__glibc_unlikely (entrance_nodes == NULL))
    16231685                {
    16241686                  free_state (newstate);
    16251687                  return NULL;
    16261688                }
    1627               re_node_set_init_copy (newstate->entrance_nodes, nodes);
     1689              newstate->entrance_nodes = entrance_nodes;
     1690              if (re_node_set_init_copy (newstate->entrance_nodes, nodes)
     1691                  != REG_NOERROR)
     1692                {
     1693                  free_state (newstate);
     1694                  return NULL;
     1695                }
    16281696              nctx_nodes = 0;
    16291697              newstate->has_constraint = 1;
     
    16381706    }
    16391707  err = register_state (dfa, newstate, hash);
    1640   if (BE (err != REG_NOERROR, 0))
     1708  if (__glibc_unlikely (err != REG_NOERROR))
    16411709    {
    16421710      free_state (newstate);
Note: See TracChangeset for help on using the changeset viewer.