]> git.draconx.ca Git - cdecl99.git/commitdiff
Clean up declgen a bit.
authorNick Bowler <nbowler@draconx.ca>
Wed, 9 Feb 2022 04:37:53 +0000 (23:37 -0500)
committerNick Bowler <nbowler@draconx.ca>
Wed, 9 Feb 2022 08:17:48 +0000 (03:17 -0500)
Use wrapper functions to perform the "allocate a structure and
initialize its members" sequence which is a common sequence here,
and avoid the use of compound literals for this which improves
portability to older compilers.

test/declgen.c

index c59e86ce348fe09e99c63775220b6bccd5ca8be9..221c71ac247e885cf834fa86a4a6e4264a4a3bcb 100644 (file)
 #include "cdecl.h"
 #include "test.h"
 
+/*
+ * Return a newly-allocated null declarator.  The child member is set by the
+ * argument; other members are initialized to zero.
+ */
+struct cdecl_declarator *new_declarator(struct cdecl_declarator *child)
+{
+       struct cdecl_declarator *d, init = { child, CDECL_DECL_NULL };
+
+       d = malloc_nofail(sizeof *d);
+       *d = init;
+
+       return d;
+}
+
+/*
+ * Return a newly-allocated void specifier.  The next member is set by the
+ * argument; other members are initialized to zero.
+ */
+struct cdecl_declspec *new_specifier(struct cdecl_declspec *next)
+{
+       struct cdecl_declspec *d, init = { next, CDECL_TYPE_VOID };
+
+       d = malloc_nofail(sizeof *d);
+       *d = init;
+
+       return d;
+}
+
+/*
+ * Return a newly-allocated declaration.  The next member is set by the
+ * argument; other members are initialized to zero.
+ */
+struct cdecl *new_cdecl(struct cdecl *next)
+{
+       struct cdecl *d, init = { next };
+
+       d = malloc_nofail(sizeof *d);
+       *d = init;
+
+       return d;
+}
+
 /*
  * Generate a random identifier.  We arbitrarily pick 10 as the largest
  * possible.  Avoid generating keywords, including the English ones, by
@@ -61,14 +103,10 @@ char *gen_identifier(struct test_rng *rng)
  */
 struct cdecl_declspec *gen_qualifiers(struct test_rng *rng, bool restrictqual)
 {
-       struct cdecl_declspec *s = NULL, *p;
+       struct cdecl_declspec *s = NULL;
 
        while (test_rng_uniform(rng) < 0.5) {
-               p = s;
-               s = malloc_nofail(sizeof *s);
-               *s = (struct cdecl_declspec) {
-                       .next = p,
-               };
+               s = new_specifier(s);
 
                switch (test_rng_uniform_int(rng, 2+restrictqual)) {
                case 0:
@@ -94,16 +132,11 @@ struct cdecl_declspec *gen_qualifiers(struct test_rng *rng, bool restrictqual)
  */
 struct cdecl_declspec *gen_funcspecs(struct test_rng *rng)
 {
-       struct cdecl_declspec *s = NULL, *p;
+       struct cdecl_declspec *s = NULL;
 
        while (test_rng_uniform(rng) < 0.5) {
-               p = s;
-               s = malloc_nofail(sizeof *s);
-
-               *s = (struct cdecl_declspec) {
-                       .type = CDECL_FUNC_INLINE,
-                       .next = p,
-               };
+               s = new_specifier(s);
+               s->type = CDECL_FUNC_INLINE;
        }
 
        return s;
@@ -121,17 +154,10 @@ struct cdecl_declspec *gen_storspecs(struct test_rng *rng, bool registeronly)
        if (test_rng_uniform(rng) < 0.5)
                return NULL;
 
-       s = malloc_nofail(sizeof *s);
-       *s = (struct cdecl_declspec) {
-               .type = CDECL_STOR_REGISTER,
-       };
-
-       if (registeronly)
-               return s;
-
-       switch (test_rng_uniform_int(rng, 5)) {
-       case 0: s->type = CDECL_STOR_TYPEDEF;  break;
-       case 1: s->type = CDECL_STOR_REGISTER; break;
+       s = new_specifier(NULL);
+       switch (test_rng_uniform_int(rng, registeronly ? 1 : 5)) {
+       case 0: s->type = CDECL_STOR_REGISTER; break;
+       case 1: s->type = CDECL_STOR_TYPEDEF;  break;
        case 2: s->type = CDECL_STOR_STATIC;   break;
        case 3: s->type = CDECL_STOR_AUTO;     break;
        case 4: s->type = CDECL_STOR_EXTERN;   break;
@@ -277,26 +303,26 @@ static uintmax_t gen_uintmax(struct test_rng *rng)
  */
 static void gen_array(struct test_rng *rng, struct cdecl_declarator *d)
 {
-       d->type = CDECL_DECL_ARRAY;
-       d->u.array = (struct cdecl_array){0};
+       struct cdecl_array tmp = {0};
 
        switch (test_rng_uniform_int(rng, 4)) {
        case 0:
-               d->u.array.vla = malloc_nofail(1);
-               d->u.array.vla[0] = 0;
+               tmp.vla = malloc_nofail(1);
+               tmp.vla[0] = 0;
                break;
        case 1:
-               d->u.array.vla = gen_identifier(rng);
+               tmp.vla = gen_identifier(rng);
                break;
        case 2:
-               d->u.array.length = 0;
-               break;
+               tmp.length = gen_uintmax(rng);
        case 3:
-               d->u.array.length = gen_uintmax(rng);
                break;
        default:
                assert(0);
        }
+
+       d->type = CDECL_DECL_ARRAY;
+       d->u.array = tmp;
 }
 
 /* Generate a function declarator. */
@@ -309,11 +335,8 @@ static void gen_function(struct test_rng *rng, struct cdecl_declarator *d)
                unsigned flags = GEN_ONLY_REGISTER | GEN_NO_FUNCTION;
                struct cdecl *param;
 
-               param = malloc_nofail(sizeof *param);
-               *param = (struct cdecl) {
-                       .next = d->u.function.parameters,
-                       .declarators = gen_declarators(rng),
-               };
+               param = new_cdecl(d->u.function.parameters);
+               param->declarators = gen_declarators(rng);
 
                if (param->declarators->type != CDECL_DECL_POINTER
                    && param->declarators->type != CDECL_DECL_FUNCTION)
@@ -329,18 +352,9 @@ static void gen_function(struct test_rng *rng, struct cdecl_declarator *d)
                struct cdecl *param;
 
                /* We will never generate (void) above; do it here. */
-               param = malloc_nofail(sizeof *param);
-               *param = (struct cdecl) { 0 };
-
-               param->declarators = malloc_nofail(sizeof *param->declarators);
-               *param->declarators = (struct cdecl_declarator) {
-                       .type = CDECL_DECL_NULL,
-               };
-
-               param->specifiers = malloc_nofail(sizeof *param->specifiers);
-               *param->specifiers = (struct cdecl_declspec) {
-                       .type = CDECL_TYPE_VOID,
-               };
+               param = new_cdecl(NULL);
+               param->declarators = new_declarator(NULL);
+               param->specifiers = new_specifier(NULL);
 
                d->u.function.parameters = param;
        }
@@ -357,31 +371,19 @@ struct cdecl_declarator *gen_declarators(struct test_rng *rng)
        struct cdecl_declarator *d, *p;
        unsigned limit = 3;
 
-       d = malloc_nofail(sizeof *d);
+       d = new_declarator(NULL);
        if (test_rng_uniform(rng) < 0.5) {
-               *d = (struct cdecl_declarator) {
-                       .type = CDECL_DECL_NULL,
-               };
-       } else {
-               *d = (struct cdecl_declarator) {
-                       .type = CDECL_DECL_IDENT,
-                       .u.ident = gen_identifier(rng),
-               };
+               d->type = CDECL_DECL_IDENT;
+               d->u.ident = gen_identifier(rng);
        }
 
        while (test_rng_uniform(rng) < 0.5) {
-               p = d;
-               d = malloc_nofail(sizeof *d);
-               *d = (struct cdecl_declarator) {
-                       .child = p,
-               };
+               d = new_declarator((p = d));
 
                switch (test_rng_uniform_int(rng, limit)) {
                case 0:
                        d->type = CDECL_DECL_POINTER;
-                       d->u.pointer = (struct cdecl_pointer) {
-                               .qualifiers = gen_qualifiers(rng, true),
-                       };
+                       d->u.pointer.qualifiers = gen_qualifiers(rng, true);
                        limit = 3;
                        break;
                case 1: