aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2021-08-11 01:22:34 +0100
committerTomasz Kramkowski <tk@the-tk.com>2021-08-11 01:32:48 +0100
commita46515fe7a31d72bb7f0130f7df9a9ca77a9b153 (patch)
tree9b8ffe7bcf75c1b33bf4804427c0f2a10b8fec73
parent5b31a09c18ee399869590d9b44eab0665b13c3ab (diff)
downloadpack-a46515fe7a31d72bb7f0130f7df9a9ca77a9b153.tar.gz
pack-a46515fe7a31d72bb7f0130f7df9a9ca77a9b153.tar.xz
pack-a46515fe7a31d72bb7f0130f7df9a9ca77a9b153.zip
test_gen: implement unpack_struct test generation
-rw-r--r--test_gen.c107
1 files 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);
+ }
}