]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
xgettext: Convert a struct to a flexible-member struct.
authorBruno Haible <bruno@clisp.org>
Tue, 5 May 2026 19:23:01 +0000 (21:23 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 5 May 2026 19:53:06 +0000 (21:53 +0200)
* gettext-tools/src/xg-arglist-callshape.h: Include flexmember.h.
(struct callshapes): Convert the 'shapes' field to a flexible array member.
* gettext-tools/src/xg-arglist-callshape.c (insert_keyword_callshape): Compute
the needed memory using FLEXSIZEOF.
* gettext-tools/src/x-perl.c (extract_variable): Use a union to allocate a
'struct callshapes' on the stack.

gettext-tools/src/x-perl.c
gettext-tools/src/xg-arglist-callshape.c
gettext-tools/src/xg-arglist-callshape.h

index 0c6f5bcf5851acf271ee63cb45c243f42e073db5..11cada1f353ea63affa230cddf1a506eeb0a235a 100644 (file)
@@ -1532,17 +1532,25 @@ extract_variable (struct perl_extractor *xp, token_ty *tp, int first)
               const struct callshapes *shapes =
                 (const struct callshapes *) keyword_value;
               */
-              struct callshapes shapes;
-              shapes.keyword = tp->string; /* XXX storage duration? */
-              shapes.keyword_len = strlen (tp->string);
-              shapes.nshapes = 1;
-              shapes.shapes[0].argnum1 = 1;
-              shapes.shapes[0].argnum2 = 0;
-              shapes.shapes[0].argnumc = 0;
-              shapes.shapes[0].argnum1_glib_context = false;
-              shapes.shapes[0].argnum2_glib_context = false;
-              shapes.shapes[0].argtotal = 0;
-              string_list_init (&shapes.shapes[0].xcomments);
+              /* Allocating a 'struct callshapes' on the stack requires
+                 a union.  */
+              union
+                {
+                  struct callshapes _main;
+                  char room[FLEXSIZEOF (struct callshapes,
+                                        shapes, 1 * sizeof (struct callshape))];
+                } u;
+              #define simple_shapes u._main
+              simple_shapes.keyword = tp->string; /* XXX storage duration? */
+              simple_shapes.keyword_len = strlen (tp->string);
+              simple_shapes.nshapes = 1;
+              simple_shapes.shapes[0].argnum1 = 1;
+              simple_shapes.shapes[0].argnum2 = 0;
+              simple_shapes.shapes[0].argnumc = 0;
+              simple_shapes.shapes[0].argnum1_glib_context = false;
+              simple_shapes.shapes[0].argnum2_glib_context = false;
+              simple_shapes.shapes[0].argtotal = 0;
+              string_list_init (&simple_shapes.shapes[0].xcomments);
 
               {
                 /* Extract a possible string from the key.  Before proceeding
@@ -1593,10 +1601,11 @@ extract_variable (struct perl_extractor *xp, token_ty *tp, int first)
                                           token_type_rbrace, true,
                                           false, false, false,
                                           null_context_region (), context_iter,
-                                          1, arglist_parser_alloc (xp->mlp, &shapes)))
+                                          1, arglist_parser_alloc (xp->mlp, &simple_shapes)))
                       return;
                   }
               }
+              #undef simple_shapes
             }
           else
             {
index 495c37d8cfb8dd8cb38c03ab6bb9c22945693011..cd92f6f4baf4911ecbefff29adf9d8966594f1db 100644 (file)
@@ -174,7 +174,10 @@ insert_keyword_callshape (hash_table *table,
   if (hash_find_entry (table, keyword, keyword_len, &old_value))
     {
       /* Create a one-element 'struct callshapes'.  */
-      struct callshapes *shapes = XMALLOC (struct callshapes);
+      struct callshapes *shapes =
+        (struct callshapes *)
+        xmalloc (FLEXSIZEOF (struct callshapes, shapes,
+                             1 * sizeof (struct callshape)));
       shapes->nshapes = 1;
       shapes->shapes[0] = *shape;
       keyword =
@@ -211,9 +214,9 @@ insert_keyword_callshape (hash_table *table,
           /* Replace the existing 'struct callshapes' with a new one.  */
           struct callshapes *shapes =
             (struct callshapes *)
-            xmalloc (xsum (sizeof (struct callshapes),
-                           xtimes (old_shapes->nshapes,
-                                   sizeof (struct callshape))));
+            xmalloc (FLEXSIZEOF (struct callshapes, shapes,
+                                 xtimes (old_shapes->nshapes + 1,
+                                         sizeof (struct callshape))));
 
           shapes->keyword = old_shapes->keyword;
           shapes->keyword_len = old_shapes->keyword_len;
index 9c6af6a98a409d52f5e6cf9e36a3e3949e656653..2a0febc4f5dd81654ee127dbc948d239819e4eb6 100644 (file)
@@ -23,6 +23,7 @@
 #include <stdbool.h>
 #include <stddef.h>
 
+#include "flexmember.h"
 #include "str-list.h"
 #include "mem-hash-map.h"
 
@@ -53,7 +54,7 @@ struct callshapes
   const char *keyword;          /* the keyword, not NUL terminated */
   size_t keyword_len;           /* the keyword's length */
   size_t nshapes;
-  struct callshape shapes[1];   /* actually nshapes elements */
+  struct callshape shapes[FLEXIBLE_ARRAY_MEMBER]; /* nshapes elements */
 };
 
 /* Insert a (keyword, callshape) pair into a hash table mapping keyword to