From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-3.4 required=3.0 tests=AWL,BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 0F4761F5AF for ; Mon, 29 Mar 2021 03:06:36 +0000 (UTC) Received: from localhost ([::1]:41740 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lQiEc-0002dx-Me for normalperson@yhbt.net; Sun, 28 Mar 2021 23:06:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:35990) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQiET-0002Zp-Af for bug-gnulib@gnu.org; Sun, 28 Mar 2021 23:06:25 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:54158) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lQiEP-0004e6-VB for bug-gnulib@gnu.org; Sun, 28 Mar 2021 23:06:24 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 27C9C1600BE; Sun, 28 Mar 2021 20:06:14 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id 3AMUgeQm0Dzh; Sun, 28 Mar 2021 20:06:12 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 7878A1600B7; Sun, 28 Mar 2021 20:06:12 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id HKEgku32jnGv; Sun, 28 Mar 2021 20:06:12 -0700 (PDT) Received: from penguin.CS.UCLA.EDU (Penguin.CS.UCLA.EDU [131.179.64.200]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 4C4451600A7; Sun, 28 Mar 2021 20:06:12 -0700 (PDT) From: Paul Eggert To: bug-gnulib@gnu.org, arnold@skeeve.com Subject: [PATCH] xalloc: new function xpalloc, from dfa Date: Sun, 28 Mar 2021 20:06:08 -0700 Message-Id: <20210329030608.1080047-1-eggert@cs.ucla.edu> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Received-SPF: pass client-ip=131.179.128.68; envelope-from=eggert@cs.ucla.edu; helo=zimbra.cs.ucla.edu X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: bug-gnulib@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Gnulib discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paul Eggert Errors-To: bug-gnulib-bounces+normalperson=yhbt.net@gnu.org Sender: "bug-gnulib" Move xpalloc from dfa.c to xmalloc.c and change it from static to extern. The function is useful in other contexts; I=E2=80=99m about to use it in coreutils. * lib/dfa.c: Include idx.h, instead of rolling our own idx_t and IDX_MAX. Do not include intprops.h; no longer needed. (xpalloc): Move from here ... * lib/xmalloc.c (xpalloc): ... to here, and make it extern. Include intprops.h and minmax.h, needed by xpalloc. * lib/xalloc.h: Include idx.h, for idx_t. * modules/dfa (Depends-on): Add idx; remove intprops. * modules/xalloc (Depends-on): Add idx, intprops, minmax. --- ChangeLog | 15 +++++++++++ lib/dfa.c | 68 +------------------------------------------------- lib/xalloc.h | 3 +++ lib/xmalloc.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ modules/dfa | 2 +- modules/xalloc | 3 +++ 6 files changed, 86 insertions(+), 68 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9f010fd4e..78bf3a5a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2021-03-28 Paul Eggert + + xalloc: new function xpalloc, from dfa + Move xpalloc from dfa.c to xmalloc.c and change it from static to + extern. The function is useful in other contexts; I=E2=80=99m about to + use it in coreutils. + * lib/dfa.c: Include idx.h, instead of rolling our own idx_t and + IDX_MAX. Do not include intprops.h; no longer needed. + (xpalloc): Move from here ... + * lib/xmalloc.c (xpalloc): ... to here, and make it extern. + Include intprops.h and minmax.h, needed by xpalloc. + * lib/xalloc.h: Include idx.h, for idx_t. + * modules/dfa (Depends-on): Add idx; remove intprops. + * modules/xalloc (Depends-on): Add idx, intprops, minmax. + 2021-03-28 Bruno Haible =20 linked-list tests: Add another test for SIGNAL_SAFE_LIST. diff --git a/lib/dfa.c b/lib/dfa.c index 4929e4c34..33de2fb82 100644 --- a/lib/dfa.c +++ b/lib/dfa.c @@ -25,6 +25,7 @@ #include "dfa.h" =20 #include "flexmember.h" +#include "idx.h" =20 #include #include @@ -34,12 +35,6 @@ #include #include =20 -/* Another name for ptrdiff_t, for sizes of objects and nonnegative - indexes into objects. It is signed to help catch integer overflow. - It has its own name because it is for nonnegative values only. */ -typedef ptrdiff_t idx_t; -static idx_t const IDX_MAX =3D PTRDIFF_MAX; - static bool streq (char const *a, char const *b) { @@ -57,7 +52,6 @@ isasciidigit (char c) =20 #include =20 -#include "intprops.h" #include "xalloc.h" #include "localeinfo.h" =20 @@ -791,66 +785,6 @@ emptyset (charclass const *s) return w =3D=3D 0; } =20 -/* Grow PA, which points to an array of *NITEMS items, and return the - location of the reallocated array, updating *NITEMS to reflect its - new size. The new array will contain at least NITEMS_INCR_MIN more - items, but will not contain more than NITEMS_MAX items total. - ITEM_SIZE is the size of each item, in bytes. - - ITEM_SIZE and NITEMS_INCR_MIN must be positive. *NITEMS must be - nonnegative. If NITEMS_MAX is -1, it is treated as if it were - infinity. - - If PA is null, then allocate a new array instead of reallocating - the old one. - - Thus, to grow an array A without saving its old contents, do - { free (A); A =3D xpalloc (NULL, &AITEMS, ...); }. */ - -static void * -xpalloc (void *pa, idx_t *nitems, idx_t nitems_incr_min, - ptrdiff_t nitems_max, idx_t item_size) -{ - idx_t n0 =3D *nitems; - - /* The approximate size to use for initial small allocation - requests. This is the largest "small" request for the GNU C - library malloc. */ - enum { DEFAULT_MXFAST =3D 64 * sizeof (size_t) / 4 }; - - /* If the array is tiny, grow it to about (but no greater than) - DEFAULT_MXFAST bytes. Otherwise, grow it by about 50%. - Adjust the growth according to three constraints: NITEMS_INCR_MIN, - NITEMS_MAX, and what the C language can represent safely. */ - - idx_t n, nbytes; - if (INT_ADD_WRAPV (n0, n0 >> 1, &n)) - n =3D IDX_MAX; - if (0 <=3D nitems_max && nitems_max < n) - n =3D nitems_max; - - idx_t adjusted_nbytes - =3D ((INT_MULTIPLY_WRAPV (n, item_size, &nbytes) || SIZE_MAX < nbyte= s) - ? MIN (IDX_MAX, SIZE_MAX) - : nbytes < DEFAULT_MXFAST ? DEFAULT_MXFAST : 0); - if (adjusted_nbytes) - { - n =3D adjusted_nbytes / item_size; - nbytes =3D adjusted_nbytes - adjusted_nbytes % item_size; - } - - if (! pa) - *nitems =3D 0; - if (n - n0 < nitems_incr_min - && (INT_ADD_WRAPV (n0, nitems_incr_min, &n) - || (0 <=3D nitems_max && nitems_max < n) - || INT_MULTIPLY_WRAPV (n, item_size, &nbytes))) - xalloc_die (); - pa =3D xrealloc (pa, nbytes); - *nitems =3D n; - return pa; -} - /* Ensure that the array addressed by PA holds at least I + 1 items. Either return PA, or reallocate the array and return its new address. Although PA may be null, the returned value is never null. diff --git a/lib/xalloc.h b/lib/xalloc.h index 7ab68f4e6..76d83c63c 100644 --- a/lib/xalloc.h +++ b/lib/xalloc.h @@ -21,6 +21,7 @@ #include #include =20 +#include "idx.h" #include "xalloc-oversized.h" =20 #ifndef _GL_INLINE_HEADER_BEGIN @@ -59,6 +60,8 @@ void *xcalloc (size_t n, size_t s) void *xrealloc (void *p, size_t s) _GL_ATTRIBUTE_ALLOC_SIZE ((2)); void *x2realloc (void *p, size_t *pn); +void *xpalloc (void *pa, idx_t *nitems, idx_t nitems_incr_min, + ptrdiff_t nitems_max, idx_t item_size); void *xmemdup (void const *p, size_t s) _GL_ATTRIBUTE_ALLOC_SIZE ((2)); char *xstrdup (char const *str) diff --git a/lib/xmalloc.c b/lib/xmalloc.c index 4203f19ce..faeccacc9 100644 --- a/lib/xmalloc.c +++ b/lib/xmalloc.c @@ -21,6 +21,9 @@ =20 #include "xalloc.h" =20 +#include "intprops.h" +#include "minmax.h" + #include #include =20 @@ -87,6 +90,66 @@ x2realloc (void *p, size_t *pn) return x2nrealloc (p, pn, 1); } =20 +/* Grow PA, which points to an array of *NITEMS items, and return the + location of the reallocated array, updating *NITEMS to reflect its + new size. The new array will contain at least NITEMS_INCR_MIN more + items, but will not contain more than NITEMS_MAX items total. + ITEM_SIZE is the size of each item, in bytes. + + ITEM_SIZE and NITEMS_INCR_MIN must be positive. *NITEMS must be + nonnegative. If NITEMS_MAX is -1, it is treated as if it were + infinity. + + If PA is null, then allocate a new array instead of reallocating + the old one. + + Thus, to grow an array A without saving its old contents, do + { free (A); A =3D xpalloc (NULL, &AITEMS, ...); }. */ + +void * +xpalloc (void *pa, idx_t *nitems, idx_t nitems_incr_min, + ptrdiff_t nitems_max, idx_t item_size) +{ + idx_t n0 =3D *nitems; + + /* The approximate size to use for initial small allocation + requests. This is the largest "small" request for the GNU C + library malloc. */ + enum { DEFAULT_MXFAST =3D 64 * sizeof (size_t) / 4 }; + + /* If the array is tiny, grow it to about (but no greater than) + DEFAULT_MXFAST bytes. Otherwise, grow it by about 50%. + Adjust the growth according to three constraints: NITEMS_INCR_MIN, + NITEMS_MAX, and what the C language can represent safely. */ + + idx_t n, nbytes; + if (INT_ADD_WRAPV (n0, n0 >> 1, &n)) + n =3D IDX_MAX; + if (0 <=3D nitems_max && nitems_max < n) + n =3D nitems_max; + + idx_t adjusted_nbytes + =3D ((INT_MULTIPLY_WRAPV (n, item_size, &nbytes) || SIZE_MAX < nbyte= s) + ? MIN (IDX_MAX, SIZE_MAX) + : nbytes < DEFAULT_MXFAST ? DEFAULT_MXFAST : 0); + if (adjusted_nbytes) + { + n =3D adjusted_nbytes / item_size; + nbytes =3D adjusted_nbytes - adjusted_nbytes % item_size; + } + + if (! pa) + *nitems =3D 0; + if (n - n0 < nitems_incr_min + && (INT_ADD_WRAPV (n0, nitems_incr_min, &n) + || (0 <=3D nitems_max && nitems_max < n) + || INT_MULTIPLY_WRAPV (n, item_size, &nbytes))) + xalloc_die (); + pa =3D xrealloc (pa, nbytes); + *nitems =3D n; + return pa; +} + /* Allocate N bytes of zeroed memory dynamically, with error checking. There's no need for xnzalloc (N, S), since it would be equivalent to xcalloc (N, S). */ diff --git a/modules/dfa b/modules/dfa index 303957fa5..4b78ef487 100644 --- a/modules/dfa +++ b/modules/dfa @@ -12,7 +12,7 @@ assert c99 ctype flexmember -intprops +idx locale regex stdbool diff --git a/modules/xalloc b/modules/xalloc index 65007561b..5fa386a5d 100644 --- a/modules/xalloc +++ b/modules/xalloc @@ -9,6 +9,9 @@ m4/xalloc.m4 Depends-on: c99 extern-inline +idx +intprops +minmax stdint xalloc-die xalloc-oversized --=20 2.30.2