From a46515fe7a31d72bb7f0130f7df9a9ca77a9b153 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Wed, 11 Aug 2021 01:22:34 +0100 Subject: test_gen: implement unpack_struct test generation --- test_gen.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 97 insertions(+), 10 deletions(-) diff --git a/test_gen.c b/test_gen.c index 27643af..217e6ca 100644 --- a/test_gen.c +++ b/test_gen.c @@ -22,21 +22,23 @@ struct { struct fmtinfo { char fmt; + char *ptype; + char *cfmt; char *type; intmax_t min; uintmax_t max; size_t size; } fmtinfo[] = { - { 'b', "signed char", INTMAX_C( -128), UINTMAX_C( 127), 1 }, - { 'B', "unsigned char", INTMAX_C( 0), UINTMAX_C( 255), 1 }, - { 'h', "signed short", INTMAX_C( -32768), UINTMAX_C( 32767), 2 }, - { 'H', "unsigned short", INTMAX_C( 0), UINTMAX_C( 65535), 2 }, - { 'i', "signed int", INTMAX_C( -32768), UINTMAX_C( 32767), 2 }, - { 'I', "unsigned int", INTMAX_C( 0), UINTMAX_C( 65535), 2 }, - { 'l', "signed long", INTMAX_C( -2147483648), UINTMAX_C( 2147483647), 4 }, - { 'L', "unsigned long", INTMAX_C( 0), UINTMAX_C( 4294967295), 4 }, - { 'q', "signed long long", -INTMAX_C(9223372036854775807) - 1, UINTMAX_C( 9223372036854775807), 8 }, - { 'Q', "unsigned long long", INTMAX_C( 0), UINTMAX_C(18446744073709551615), 8 }, + { 'b', "SCHAR", "d", "signed char", INTMAX_C( -128), UINTMAX_C( 127), 1 }, + { 'B', "UCHAR", "u", "unsigned char", INTMAX_C( 0), UINTMAX_C( 255), 1 }, + { 'h', "SHORT", "d", "signed short", INTMAX_C( -32768), UINTMAX_C( 32767), 2 }, + { 'H', "USHORT", "u", "unsigned short", INTMAX_C( 0), UINTMAX_C( 65535), 2 }, + { 'i', "INT", "d", "signed int", INTMAX_C( -32768), UINTMAX_C( 32767), 2 }, + { 'I', "UINT", "u", "unsigned int", INTMAX_C( 0), UINTMAX_C( 65535), 2 }, + { 'l', "LONG", "ld", "signed long", INTMAX_C( -2147483648), UINTMAX_C( 2147483647), 4 }, + { 'L', "ULONG", "lu", "unsigned long", INTMAX_C( 0), UINTMAX_C( 4294967295), 4 }, + { 'q', "LLONG", "lld", "signed long long", -INTMAX_C(9223372036854775807) - 1, UINTMAX_C( 9223372036854775807), 8 }, + { 'Q', "ULLONG", "llu", "unsigned long long", INTMAX_C( 0), UINTMAX_C(18446744073709551615), 8 }, }; static char cchar(char c) @@ -150,6 +152,86 @@ static void unpack_gen(FILE *out, const struct fmtinfo *fi, int arraysize) fprintf(out, "}\n"); } +static void unpack_struct_signed(FILE *out, const struct fmtinfo *fi, enum endian e, intmax_t testval, int arraysize) +{ + char sizeprefix[11] = ""; + const char *data; + + if (arraysize >= 1) + snprintf(sizeprefix, sizeof sizeprefix, "%d", arraysize); + else + arraysize = 1; + + fprintf(out, "\tCHECK_UNPACK_STRUCT(DATA("); + data = i2bytes(e, fi->size, testval); + for (int i = 0; i < arraysize; i++) + fprintf(out, "%s%s", i == 0 ? "" : ", ", data); + fprintf(out, "), &args, &v);\n"); + for (int i = 0; i < arraysize; i++) + fprintf(out, "\tCHECK_EQUAL(\"%s\", v.field[%d], (%s)-INTMAX_C(%" PRIdMAX ")-1);\n", + fi->cfmt, i, fi->type, -(testval + 1)); +} + +static void unpack_struct_unsigned(FILE *out, const struct fmtinfo *fi, enum endian e, uintmax_t testval, int arraysize) +{ + char sizeprefix[11] = ""; + const char *data; + + if (arraysize >= 1) + snprintf(sizeprefix, sizeof sizeprefix, "%d", arraysize); + else + arraysize = 1; + + fprintf(out, "\tCHECK_UNPACK_STRUCT(DATA("); + data = u2bytes(e, fi->size, testval); + for (int i = 0; i < arraysize; i++) + fprintf(out, "%s%s", i == 0 ? "" : ", ", data); + fprintf(out, "), &args, &v);\n"); + for (int i = 0; i < arraysize; i++) + fprintf(out, "\tCHECK_EQUAL(\"%s\", v.field[%d], (%s)UINTMAX_C(%" PRIuMAX "));\n", \ + fi->cfmt, i, fi->type, testval); +} + +static void unpack_struct_gen(FILE *out, const struct fmtinfo *fi, int arraysize) +{ + int realsize = arraysize == 0 ? 1 : arraysize; + bool sign; + + sign = islower(fi->fmt); + + fprintf(out, "TEST(unpack_struct_simple%d_%s, \"unpack_struct simple", \ + arraysize, cname(fi->type)); + if (arraysize != 0) + fprintf(out, " array[%d]", arraysize); + fprintf(out, " %s\")\n", fi->type); + fprintf(out, "{\n"); + fprintf(out, "\tstruct dest {\n"); + fprintf(out, "\t\t%s field[%d];\n", fi->type, realsize); + fprintf(out, "\t} v = {{ "); + for (int i = 0; i < realsize; i++) + fprintf(out, "%s(__LINE__ + %d) %% UINTMAX_C(%" PRIuMAX ")", + i == 0 ? "" : ", ", i, fi->max); + fprintf(out, " }};\n"); + fprintf(out, "\tstruct pack_args args = {\n"); + fprintf(out, "\t\t.fields = (struct pack_field []){\n"); + fprintf(out, "\t\t\t{ PACK_TYPE_%s, %d, offsetof(struct dest, field) }\n", + fi->ptype, realsize); + fprintf(out, "\t\t},\n"); + fprintf(out, "\t\t.num_fields = 1,\n"); + fprintf(out, "\t};\n"); + for (enum endian e = BIG; e <= LITTLE; e++) { + fprintf(out, "\targs.endian = PACK_ENDIAN_%s;\n", + e == BIG ? "BIG" : "LITTLE"); + for (int i = sign ? -1 : 0; i <= 1; i++) + unpack_struct_signed(out, fi, e, i, arraysize); + if (sign) + unpack_struct_signed(out, fi, e, fi->min, arraysize); + unpack_struct_unsigned(out, fi, e, fi->max, arraysize); + } + fprintf(out, "\treturn true;\n"); + fprintf(out, "}\n"); +} + int main(void) { FILE *out = stdout; @@ -158,4 +240,9 @@ int main(void) for (int j = 2; j < 4; j++) unpack_gen(out, &fmtinfo[i], j); } + for (size_t i = 0; i < sizeof fmtinfo / sizeof fmtinfo[0]; i++) { + unpack_struct_gen(out, &fmtinfo[i], 0); + for (int j = 2; j < 4; j++) + unpack_struct_gen(out, &fmtinfo[i], j); + } } -- cgit v1.2.3-54-g00ecf