(root)/
gettext-0.22.4/
libtextstyle/
lib/
ialloc.h
       1  /* ialloc.h -- malloc with idx_t rather than size_t
       2  
       3     Copyright 2021-2023 Free Software Foundation, Inc.
       4  
       5     This file is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU Lesser General Public License as
       7     published by the Free Software Foundation; either version 2.1 of the
       8     License, or (at your option) any later version.
       9  
      10     This file is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public License
      16     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  #ifndef IALLOC_H_
      19  #define IALLOC_H_
      20  
      21  /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE, _GL_ATTRIBUTE_COLD,
      22     _GL_ATTRIBUTE_MALLOC.  */
      23  #if !_GL_CONFIG_H_INCLUDED
      24   #error "Please include config.h first."
      25  #endif
      26  
      27  #include "idx.h"
      28  
      29  #include <errno.h>
      30  #include <stdint.h>
      31  #include <stdlib.h>
      32  #if defined __CHERI_PURE_CAPABILITY__
      33  # include <cheri.h>
      34  #endif
      35  
      36  _GL_INLINE_HEADER_BEGIN
      37  #ifndef IALLOC_INLINE
      38  # define IALLOC_INLINE _GL_INLINE
      39  #endif
      40  
      41  #ifdef __cplusplus
      42  extern "C" {
      43  #endif
      44  
      45  IALLOC_INLINE void * _GL_ATTRIBUTE_COLD
      46  _gl_alloc_nomem (void)
      47  {
      48    errno = ENOMEM;
      49    return NULL;
      50  }
      51  
      52  /* imalloc (size) is like malloc (size).
      53     It returns a non-NULL pointer to size bytes of memory.
      54     Upon failure, it returns NULL with errno set.  */
      55  IALLOC_INLINE
      56  _GL_ATTRIBUTE_MALLOC /*_GL_ATTRIBUTE_DEALLOC_FREE*/
      57  void *
      58  imalloc (idx_t s)
      59  {
      60    return s <= SIZE_MAX ? malloc (s) : _gl_alloc_nomem ();
      61  }
      62  
      63  /* irealloc (ptr, size) is like realloc (ptr, size).
      64     It returns a non-NULL pointer to size bytes of memory.
      65     Upon failure, it returns NULL with errno set.  */
      66  IALLOC_INLINE
      67  /*_GL_ATTRIBUTE_DEALLOC_FREE*/
      68  void *
      69  irealloc (void *p, idx_t s)
      70  {
      71    if (s <= SIZE_MAX)
      72      {
      73        /* Work around GNU realloc glitch by treating a zero size as if it
      74           were 1, so that returning NULL is equivalent to failing.  */
      75        p = realloc (p, s | !s);
      76  #if defined __CHERI_PURE_CAPABILITY__
      77        if (p != NULL)
      78          p = cheri_bounds_set (p, s);
      79  #endif
      80        return p;
      81      }
      82    else
      83      return _gl_alloc_nomem ();
      84  }
      85  
      86  /* icalloc (num, size) is like calloc (num, size).
      87     It returns a non-NULL pointer to num * size bytes of memory.
      88     Upon failure, it returns NULL with errno set.  */
      89  IALLOC_INLINE
      90  _GL_ATTRIBUTE_MALLOC /*_GL_ATTRIBUTE_DEALLOC_FREE*/
      91  void *
      92  icalloc (idx_t n, idx_t s)
      93  {
      94    if (SIZE_MAX < n)
      95      {
      96        if (s != 0)
      97          return _gl_alloc_nomem ();
      98        n = 0;
      99      }
     100    if (SIZE_MAX < s)
     101      {
     102        if (n != 0)
     103          return _gl_alloc_nomem ();
     104        s = 0;
     105      }
     106    return calloc (n, s);
     107  }
     108  
     109  /* ireallocarray (ptr, num, size) is like reallocarray (ptr, num, size).
     110     It returns a non-NULL pointer to num * size bytes of memory.
     111     Upon failure, it returns NULL with errno set.  */
     112  IALLOC_INLINE void *
     113  ireallocarray (void *p, idx_t n, idx_t s)
     114  {
     115    if (n <= SIZE_MAX && s <= SIZE_MAX)
     116      {
     117        /* Work around GNU reallocarray glitch by treating a zero size as if
     118           it were 1, so that returning NULL is equivalent to failing.  */
     119        size_t nx = n;
     120        size_t sx = s;
     121        if (n == 0 || s == 0)
     122          nx = sx = 1;
     123        p = reallocarray (p, nx, sx);
     124  #if defined __CHERI_PURE_CAPABILITY__
     125        if (p != NULL && (n == 0 || s == 0))
     126          p = cheri_bounds_set (p, 0);
     127  #endif
     128        return p;
     129      }
     130    else
     131      return _gl_alloc_nomem ();
     132  }
     133  
     134  #ifdef __cplusplus
     135  }
     136  #endif
     137  
     138  _GL_INLINE_HEADER_END
     139  
     140  #endif