[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[bug-gnulib] argp-parse.c patch to remove nonportable alignment assumpti
From: |
Paul Eggert |
Subject: |
[bug-gnulib] argp-parse.c patch to remove nonportable alignment assumption |
Date: |
Fri, 24 Dec 2004 00:10:54 -0800 |
User-agent: |
Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux) |
I installed the following patch to argp-parse.c to fix a portability
bug with alignments. I don't know of any hosts where the bug would be
manifest, but there's no sense tempting fate.
2004-12-23 Paul Eggert <address@hidden>
* argp-parse.c: Include <stddef.h>.
(alignof, alignto): New macros.
(parser_init): Don't assume that void * is aligned sufficiently
for struct option.
--- argp-parse.c 22 Dec 2004 09:50:38 -0000 1.10
+++ argp-parse.c 24 Dec 2004 08:07:29 -0000 1.12
@@ -22,6 +22,7 @@
#endif
#include <alloca.h>
+#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -42,6 +43,9 @@
#include "argp.h"
#include "argp-namefrob.h"
+#define alignof(type) offsetof (struct { char c; type x; }, x)
+#define alignto(n, d) ((((n) + (d) - 1) / (d)) * (d))
+
/* Getopt return values. */
#define KEY_END (-1) /* The end of the options. */
#define KEY_ARG 1 /* A non-option argument. */
@@ -462,6 +466,11 @@ parser_init (struct parser *parser, cons
struct group *group;
struct parser_sizes szs;
struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER;
+ char *storage;
+ size_t glen, gsum;
+ size_t clen, csum;
+ size_t llen, lsum;
+ size_t slen, ssum;
szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;
szs.long_len = 0;
@@ -472,22 +481,33 @@ parser_init (struct parser *parser, cons
calc_sizes (argp, &szs);
/* Lengths of the various bits of storage used by PARSER. */
-#define GLEN (szs.num_groups + 1) * sizeof (struct group)
-#define CLEN (szs.num_child_inputs * sizeof (void *))
-#define LLEN ((szs.long_len + 1) * sizeof (struct option))
-#define SLEN (szs.short_len + 1)
+ glen = (szs.num_groups + 1) * sizeof (struct group);
+ clen = szs.num_child_inputs * sizeof (void *);
+ llen = (szs.long_len + 1) * sizeof (struct option);
+ slen = szs.short_len + 1;
+
+ /* Sums of previous lengths, properly aligned. There's no need to
+ align gsum, since struct group is aligned at least as strictly as
+ void * (since it contains a void * member). And there's no need
+ to align lsum, since struct option is aligned at least as
+ strictly as char. */
+ gsum = glen;
+ csum = alignto (gsum + clen, alignof (struct option));
+ lsum = csum + llen;
+ ssum = lsum + slen;
- parser->storage = malloc (GLEN + CLEN + LLEN + SLEN);
+ parser->storage = malloc (ssum);
if (! parser->storage)
return ENOMEM;
+ storage = parser->storage;
parser->groups = parser->storage;
- parser->child_inputs = (void **)((char*) parser->storage + GLEN);
- parser->long_opts = (struct option *)((char*) parser->storage + GLEN + CLEN);
- parser->short_opts = (char*) parser->storage + GLEN + CLEN + LLEN;
+ parser->child_inputs = (void **) (storage + gsum);
+ parser->long_opts = (struct option *) (storage + csum);
+ parser->short_opts = storage + lsum;
parser->opt_data = opt_data;
- memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *));
+ memset (parser->child_inputs, 0, clen);
parser_convert (parser, argp, flags);
memset (&parser->state, 0, sizeof (struct argp_state));
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [bug-gnulib] argp-parse.c patch to remove nonportable alignment assumption,
Paul Eggert <=