From: kostasch Date: Wed, 5 Aug 2020 03:28:01 +0300 Subject: [PATCH] pk_equal_val_p function and tests 2020-08-05 Kostas Chasialis * libpoke/libpoke.h (pk_val_equal_p): Prototype. (pk_type_equal): Prototype. * libpoke/pk-val.c (pk_val_equal_p): Define. (pk_type_equal): Define. * libpoke/pvm-val.h: Fixd typo. * libpoke/pvm.h (pvm_val_equal_p): Prototype. * libpoke/pvm-val.c (pvm_val_equal_p): Define. (pvm_uint_value): New function. (pvm_int_value): Likewise. (pvm_val_equal_int): Likewise. (pvm_val_equal_uint): Likewise. (pvm_val_equal_str): Likewise. (pvm_val_equal_off): Likewise. (pvm_val_equal_sct): Likewise. (pvm_val_equal_arr): Likewise. (pvm_val_equal_cls): Likewise. * testsuite/poke.libpoke/values.c (test_pk_val_equal_p): New function. (test_pk_equal_file): Likewise. (compile_poke_expression): Likewise. (compile_initial_poke_code): Likewise. * testsuite/poke.libpoke/pk_equal_int.test: New test. * testsuite/poke.libpoke/pk_equal_uint.test: New test. * testsuite/poke.libpoke/pk_equal_str.test: New test. * testsuite/poke.libpoke/pk_equal_off.test: New test. * testsuite/poke.libpoke/pk_equal_sct.test: New test. * testsuite/poke.libpoke/pk_equal_arr.test: New test. * testsuite/poke.libpoke/pk_nequal_int.test: New test. * testsuite/poke.libpoke/pk_nequal_uint.test: New test. * testsuite/poke.libpoke/pk_nequal_str.test: New test. * testsuite/poke.libpoke/pk_nequal_off.test: New test. * testsuite/poke.libpoke/pk_nequal_sct.test: New test. * testsuite/poke.libpoke/pk_nequal_arr.test: New test. * testsuite/poke.libpoke/Makefile.am: Added PKGDATADIR. --- libpoke/libpoke.h | 12 + libpoke/pk-val.c | 10 + libpoke/pvm-val.c | 296 ++++++++++++++++++++- libpoke/pvm-val.h | 2 +- libpoke/pvm.h | 8 + testsuite/poke.libpoke/Makefile.am | 1 + testsuite/poke.libpoke/pk_equal_arr.test | 4 + testsuite/poke.libpoke/pk_equal_int.test | 4 + testsuite/poke.libpoke/pk_equal_off.test | 4 + testsuite/poke.libpoke/pk_equal_sct.test | 5 + testsuite/poke.libpoke/pk_equal_str.test | 4 + testsuite/poke.libpoke/pk_equal_uint.test | 4 + testsuite/poke.libpoke/pk_nequal_arr.test | 4 + testsuite/poke.libpoke/pk_nequal_int.test | 4 + testsuite/poke.libpoke/pk_nequal_off.test | 4 + testsuite/poke.libpoke/pk_nequal_sct.test | 5 + testsuite/poke.libpoke/pk_nequal_str.test | 4 + testsuite/poke.libpoke/pk_nequal_uint.test | 4 + testsuite/poke.libpoke/values.c | 165 +++++++++++- 19 files changed, 532 insertions(+), 12 deletions(-) create mode 100644 testsuite/poke.libpoke/pk_equal_arr.test create mode 100644 testsuite/poke.libpoke/pk_equal_int.test create mode 100644 testsuite/poke.libpoke/pk_equal_off.test create mode 100644 testsuite/poke.libpoke/pk_equal_sct.test create mode 100644 testsuite/poke.libpoke/pk_equal_str.test create mode 100644 testsuite/poke.libpoke/pk_equal_uint.test create mode 100644 testsuite/poke.libpoke/pk_nequal_arr.test create mode 100644 testsuite/poke.libpoke/pk_nequal_int.test create mode 100644 testsuite/poke.libpoke/pk_nequal_off.test create mode 100644 testsuite/poke.libpoke/pk_nequal_sct.test create mode 100644 testsuite/poke.libpoke/pk_nequal_str.test create mode 100644 testsuite/poke.libpoke/pk_nequal_uint.test diff --git a/libpoke/libpoke.h b/libpoke/libpoke.h index 25d9c239..60b6a436 100644 --- a/libpoke/libpoke.h +++ b/libpoke/libpoke.h @@ -812,6 +812,18 @@ pk_val pk_val_offset (pk_val val); /* Other operations on values. */ +/* Compare 2 Poke values. + + Returns 1 if they match, 0 otherwise. */ + +int pk_val_equal_p (pk_val val1, pk_val val2); + +/* Compare 2 Poke types. + + Returns 1 if they match, 0 otherwise. */ + +int pk_type_equal (pk_val type1, pk_val type2); + /* Return the type of the given value. */ pk_val pk_typeof (pk_val val); diff --git a/libpoke/pk-val.c b/libpoke/pk-val.c index 035d9fa5..5087dd7d 100644 --- a/libpoke/pk-val.c +++ b/libpoke/pk-val.c @@ -373,6 +373,16 @@ pk_array_type_bound (pk_val type) return PVM_VAL_TYP_A_BOUND (type); } +int pk_val_equal_p (pk_val val1, pk_val val2) +{ + return pvm_val_equal_p (val1, val2); +} + +int pk_type_equal (pk_val type1, pk_val type2) +{ + return pvm_type_equal (type1, type2); +} + pk_val pk_typeof (pk_val val) { diff --git a/libpoke/pvm-val.c b/libpoke/pvm-val.c index c9cbcbf9..c2087502 100644 --- a/libpoke/pvm-val.c +++ b/libpoke/pvm-val.c @@ -348,6 +348,293 @@ pvm_make_offset (pvm_val magnitude, pvm_val unit) return PVM_BOX (box); } +static uint64_t +pvm_uint_value (pvm_val val) +{ + if (PVM_IS_UINT (val)) + return PVM_VAL_UINT (val); + else + return PVM_VAL_ULONG (val); +} + +static int64_t +pvm_int_value (pvm_val val) +{ + if (PVM_IS_INT (val)) + return PVM_VAL_INT (val); + else + return PVM_VAL_LONG (val); +} + +static int +pvm_val_equal_int (pvm_val pvm_int1, pvm_val pvm_int2) +{ + /* size is checked on pvm_type_equal. */ + int64_t pvm_int1_value, pvm_int2_value; + + pvm_int1_value = pvm_int_value (pvm_int1); + pvm_int2_value = pvm_int_value (pvm_int2); + + return pvm_int1_value == pvm_int2_value; +} + +static int +pvm_val_equal_uint (pvm_val pvm_uint1, pvm_val pvm_uint2) +{ + /* size is checked on pvm_type_equal. */ + uint64_t pvm_uint1_value, pvm_uint2_value; + + pvm_uint1_value = pvm_uint_value (pvm_uint1); + pvm_uint2_value = pvm_uint_value (pvm_uint2); + + return pvm_uint1_value == pvm_uint2_value; +} + +static int +pvm_val_equal_str (pvm_val pvm_str1, pvm_val pvm_str2) +{ + char *pvm_str1_value, *pvm_str2_value; + + pvm_str1_value = PVM_VAL_STR (pvm_str1); + pvm_str2_value = PVM_VAL_STR (pvm_str2); + + return strncmp (pvm_str1_value, pvm_str2_value, strlen (pvm_str1_value)) == 0; +} + +static int +pvm_val_equal_off (pvm_val pvm_off1, pvm_val pvm_off2) +{ + pvm_val pvm_off1_magnitude, pvm_off2_magnitude; + pvm_val pvm_off1_unit, pvm_off2_unit; + pvm_val pvm_off1_base_type, pvm_off2_base_type; + int pvm_off_mag_equal, pvm_off_unit_equal, pvm_off_base_type_equal; + + pvm_off1_magnitude = PVM_VAL_OFF_MAGNITUDE (pvm_off1); + pvm_off2_magnitude = PVM_VAL_OFF_MAGNITUDE (pvm_off2); + + pvm_off1_unit = PVM_VAL_OFF_UNIT (pvm_off1); + pvm_off2_unit = PVM_VAL_OFF_UNIT (pvm_off2); + + pvm_off1_base_type = PVM_VAL_OFF_BASE_TYPE (pvm_off1); + pvm_off2_base_type = PVM_VAL_OFF_BASE_TYPE (pvm_off2); + + pvm_off_mag_equal = pvm_val_equal_p (pvm_off1_magnitude, pvm_off2_magnitude); + pvm_off_unit_equal = pvm_val_equal_p (pvm_off1_unit, pvm_off2_unit); + pvm_off_base_type_equal = pvm_val_equal_p (pvm_off1_base_type, + pvm_off2_base_type); + + return pvm_off_mag_equal && pvm_off_unit_equal && pvm_off_base_type_equal; +} + +static int +pvm_val_equal_sct (pvm_val pvm_sct1, pvm_val pvm_sct2) +{ + pvm_val pvm_sct1_field_boffset, pvm_sct2_field_boffset; + pvm_val pvm_sct1_field_value, pvm_sct2_field_value; + pvm_val pvm_sct1_field_name, pvm_sct2_field_name; + pvm_val pvm_sct1_method_name, pvm_sct2_method_name; + pvm_val pvm_sct1_method_value, pvm_sct2_method_value; + pvm_val pvm_sct1_ios, pvm_sct2_ios; + pvm_val pvm_sct1_type, pvm_sct2_type; + pvm_val pvm_sct1_off, pvm_sct2_off; + uint64_t pvm_sct1_nfields, pvm_sct2_nfields; + uint64_t pvm_sct1_nmethods, pvm_sct2_nmethods; + + pvm_sct1_nfields = pvm_uint_value (PVM_VAL_SCT_NFIELDS (pvm_sct1)); + pvm_sct2_nfields = pvm_uint_value (PVM_VAL_SCT_NFIELDS (pvm_sct2)); + + pvm_sct1_nmethods = pvm_uint_value (PVM_VAL_SCT_NMETHODS (pvm_sct1)); + pvm_sct2_nmethods = pvm_uint_value (PVM_VAL_SCT_NMETHODS (pvm_sct2)); + + if (pvm_sct1_nfields != pvm_sct2_nfields + || pvm_sct1_nmethods != pvm_sct2_nmethods) + return 0; + + pvm_sct1_ios = PVM_VAL_SCT_IOS (pvm_sct1); + pvm_sct2_ios = PVM_VAL_SCT_IOS (pvm_sct2); + + if (!(pvm_val_equal_p (pvm_sct1_ios, pvm_sct2_ios))) + return 0; + + pvm_sct1_type = PVM_VAL_SCT_TYPE (pvm_sct1); + pvm_sct2_type = PVM_VAL_SCT_TYPE (pvm_sct2); + + if (!(pvm_type_equal (pvm_sct1_type, pvm_sct2_type))) + return 0; + + pvm_sct1_off = PVM_VAL_SCT_OFFSET (pvm_sct1); + pvm_sct2_off = PVM_VAL_SCT_OFFSET (pvm_sct2); + + if (!(pvm_val_equal_p (pvm_sct1_off, pvm_sct2_off))) + return 0; + + for (size_t i = 0 ; i < pvm_sct1_nfields ; i++) + { + if (PVM_VAL_SCT_FIELD_ABSENT_P (pvm_sct1, i) + != PVM_VAL_SCT_FIELD_ABSENT_P (pvm_sct2, i)) + return 0; + + if (!PVM_VAL_SCT_FIELD_ABSENT_P (pvm_sct1, i)) + { + pvm_sct1_field_name = PVM_VAL_SCT_FIELD_NAME (pvm_sct1, i); + pvm_sct2_field_name = PVM_VAL_SCT_FIELD_NAME (pvm_sct2, i); + + pvm_sct1_field_value = PVM_VAL_SCT_FIELD_VALUE (pvm_sct1, i); + pvm_sct2_field_value = PVM_VAL_SCT_FIELD_VALUE (pvm_sct2, i); + + pvm_sct1_field_boffset = PVM_VAL_SCT_FIELD_OFFSET (pvm_sct1, i); + pvm_sct2_field_boffset = PVM_VAL_SCT_FIELD_OFFSET (pvm_sct2, i); + + if (!pvm_val_equal_p (pvm_sct1_field_name, pvm_sct2_field_name) + || !pvm_val_equal_p (pvm_sct1_field_value, pvm_sct2_field_value) + || !pvm_val_equal_p (pvm_sct1_field_boffset, + pvm_sct2_field_boffset)) + return 0; + } + } + + for (size_t i = 0 ; i < pvm_sct1_nmethods ; i++) + { + pvm_sct1_method_name = PVM_VAL_SCT_METHOD_NAME (pvm_sct1, i); + pvm_sct2_method_name = PVM_VAL_SCT_METHOD_NAME (pvm_sct2, i); + + pvm_sct1_method_value = PVM_VAL_SCT_METHOD_VALUE (pvm_sct1, i); + pvm_sct2_method_value = PVM_VAL_SCT_METHOD_VALUE (pvm_sct2, i); + + if (!pvm_val_equal_p (pvm_sct1_method_name, pvm_sct2_method_name) + || !pvm_val_equal_p (pvm_sct1_method_value, pvm_sct2_method_value)) + return 0; + } + + return 1; +} + +static int +pvm_val_equal_arr (pvm_val pvm_arr1, pvm_val pvm_arr2) +{ + pvm_val pvm_arr1_ios, pvm_arr2_ios; + pvm_val pvm_arr1_off, pvm_arr2_off; + pvm_val pvm_arr1_elems_bound, pvm_arr2_elems_bound; + pvm_val pvm_arr1_size_bound, pvm_arr2_size_bound; + pvm_val pvm_arr1_mapper, pvm_arr2_mapper; + pvm_val pvm_arr1_writer, pvm_arr2_writer; + pvm_val pvm_arr1_type, pvm_arr2_type; + pvm_val pvm_arr1_elem_value, pvm_arr2_elem_value; + pvm_val pvm_arr1_elem_offset, pvm_arr2_elem_offset; + uint64_t pvm_arr1_nelems, pvm_arr2_nelems; + + pvm_arr1_ios = PVM_VAL_ARR_IOS (pvm_arr1); + pvm_arr2_ios = PVM_VAL_ARR_IOS (pvm_arr2); + + if (!pvm_val_equal_p (pvm_arr1_ios, pvm_arr2_ios)) + return 0; + + pvm_arr1_off = PVM_VAL_ARR_OFFSET (pvm_arr1); + pvm_arr2_off = PVM_VAL_ARR_OFFSET (pvm_arr2); + + if (!pvm_val_equal_p (pvm_arr1_off, pvm_arr2_off)) + return 0; + + pvm_arr1_elems_bound = PVM_VAL_ARR_ELEMS_BOUND (pvm_arr1); + pvm_arr2_elems_bound = PVM_VAL_ARR_ELEMS_BOUND (pvm_arr2); + + if (!pvm_val_equal_p (pvm_arr1_elems_bound, pvm_arr2_elems_bound)) + return 0; + + pvm_arr1_size_bound = PVM_VAL_ARR_SIZE_BOUND (pvm_arr1); + pvm_arr2_size_bound = PVM_VAL_ARR_SIZE_BOUND (pvm_arr2); + + if (!pvm_val_equal_p (pvm_arr1_size_bound, pvm_arr2_size_bound)) + return 0; + + pvm_arr1_mapper = PVM_VAL_ARR_MAPPER (pvm_arr1); + pvm_arr2_mapper = PVM_VAL_ARR_MAPPER (pvm_arr2); + + if (!pvm_val_equal_p (pvm_arr1_mapper, pvm_arr2_mapper)) + return 0; + + pvm_arr1_writer = PVM_VAL_ARR_WRITER (pvm_arr1); + pvm_arr2_writer = PVM_VAL_ARR_WRITER (pvm_arr2); + + if (!pvm_val_equal_p (pvm_arr1_writer, pvm_arr2_writer)) + return 0; + + pvm_arr1_type = PVM_VAL_ARR_TYPE (pvm_arr1); + pvm_arr2_type = PVM_VAL_ARR_TYPE (pvm_arr2); + + if (!pvm_type_equal (pvm_arr1_type, pvm_arr2_type)) + return 0; + + pvm_arr1_nelems = pvm_uint_value (PVM_VAL_ARR_NELEM (pvm_arr1)); + pvm_arr2_nelems = pvm_uint_value (PVM_VAL_ARR_NELEM (pvm_arr2)); + + if (pvm_arr1_nelems != pvm_arr2_nelems) + return 0; + + for (size_t i = 0 ; i < pvm_arr1_nelems ; i++) + { + pvm_arr1_elem_value = PVM_VAL_ARR_ELEM_VALUE (pvm_arr1, i); + pvm_arr2_elem_value = PVM_VAL_ARR_ELEM_VALUE (pvm_arr2, i); + + pvm_arr1_elem_offset = PVM_VAL_ARR_ELEM_OFFSET (pvm_arr1, i); + pvm_arr2_elem_offset = PVM_VAL_ARR_ELEM_OFFSET (pvm_arr2, i); + + if (!pvm_val_equal_p (pvm_arr1_elem_value, pvm_arr2_elem_value) + || !pvm_val_equal_p (pvm_arr1_elem_offset, pvm_arr2_elem_offset)) + return 0; + } + + return 1; +} + +static int +pvm_val_equal_cls (pvm_val pvm_cls1, pvm_val pvm_cls2) +{ + /* TODO: ask jemarch if we need this test and information on how to test + 2 closures. */ + return 1; +} + +int +pvm_val_equal_p (pvm_val val1, pvm_val val2) +{ + if (val1 == PVM_NULL && val2 == PVM_NULL) + return 1; + + if (val1 == PVM_NULL || val2 == PVM_NULL) + return 0; + + if (!PVM_IS_TYP (val1) && !PVM_IS_TYP (val2)) + { + if (!(pvm_type_equal (pvm_typeof (val1), pvm_typeof (val2)))) + return 0; + } + else if (PVM_IS_TYP (val1) && PVM_IS_TYP (val2)) + return pvm_type_equal (val1, val2); + else + return 0; + + if (PVM_IS_INTEGRAL (val1)) + { + if (PVM_VAL_INT (PVM_VAL_TYP_I_SIGNED_P (pvm_typeof (val1)))) + return pvm_val_equal_int (val1, val2); + else + return pvm_val_equal_uint (val1, val2); + } + else if (PVM_IS_STR (val1)) + return pvm_val_equal_str (val1, val2); + else if (PVM_IS_OFF (val1)) + return pvm_val_equal_off (val1, val2); + else if (PVM_IS_SCT (val1)) + return pvm_val_equal_sct (val1, val2); + else if (PVM_IS_ARR (val1)) + return pvm_val_equal_arr (val1, val2); + else if (PVM_IS_CLS (val1)) + return pvm_val_equal_cls (val1, val2); + else + return 0; +} + void pvm_allocate_struct_attrs (pvm_val nfields, pvm_val **fnames, pvm_val **ftypes) @@ -1103,30 +1390,25 @@ pvm_type_equal (pvm_val type1, pvm_val type2) { size_t t1_size = PVM_VAL_ULONG (PVM_VAL_TYP_I_SIZE (type1)); size_t t2_size = PVM_VAL_ULONG (PVM_VAL_TYP_I_SIZE (type2)); - uint32_t t1_signed = PVM_VAL_INT (PVM_VAL_TYP_I_SIGNED_P (type1)); - uint32_t t2_signed = PVM_VAL_INT (PVM_VAL_TYP_I_SIGNED_P (type2)); + int32_t t1_signed = PVM_VAL_INT (PVM_VAL_TYP_I_SIGNED_P (type1)); + int32_t t2_signed = PVM_VAL_INT (PVM_VAL_TYP_I_SIGNED_P (type2)); return (t1_size == t2_size && t1_signed == t2_signed); - break; } case PVM_TYPE_STRING: case PVM_TYPE_ANY: return 1; - break; case PVM_TYPE_ARRAY: return pvm_type_equal (PVM_VAL_TYP_A_ETYPE (type1), PVM_VAL_TYP_A_ETYPE (type2)); - break; case PVM_TYPE_STRUCT: return (STREQ (PVM_VAL_STR (PVM_VAL_TYP_S_NAME (type1)), PVM_VAL_STR (PVM_VAL_TYP_S_NAME (type2)))); - break; case PVM_TYPE_OFFSET: return (pvm_type_equal (PVM_VAL_TYP_O_BASE_TYPE (type1), PVM_VAL_TYP_O_BASE_TYPE (type2)) && (PVM_VAL_ULONG (PVM_VAL_TYP_O_UNIT (type1)) == PVM_VAL_ULONG (PVM_VAL_TYP_O_UNIT (type2)))); - break; case PVM_TYPE_CLOSURE: { size_t i, nargs; diff --git a/libpoke/pvm-val.h b/libpoke/pvm-val.h index a2bb8cdd..4018be64 100644 --- a/libpoke/pvm-val.h +++ b/libpoke/pvm-val.h @@ -238,7 +238,7 @@ struct pvm_array_elem called structure "elements". They can be mapped in IO, or unmapped. - IO is an int<32> value that identifies the IO space where the value + IOS is an int<32> value that identifies the IO space where the value is mapped. If the structure is not mapped then this is PVM_NULL. OFFSET is an ulong<64> value holding the bit offset of in the IO diff --git a/libpoke/pvm.h b/libpoke/pvm.h index f023d123..535262aa 100644 --- a/libpoke/pvm.h +++ b/libpoke/pvm.h @@ -274,6 +274,13 @@ pvm_val pvm_make_struct (pvm_val nfields, pvm_val nmethods, pvm_val type) pvm_val pvm_make_cls (pvm_program program) __attribute__ ((visibility ("hidden"))); +/* Compare 2 PVM values. + + Returns 1 if they match, 0 otherwise. */ + +int pvm_val_equal_p (pvm_val val1, pvm_val val2) + __attribute__ ((visibility ("hidden"))); + /*** PVM values. ***/ void pvm_print_string (pvm_val string) @@ -293,6 +300,7 @@ pvm_val pvm_make_integral_type (pvm_val size, pvm_val signed_p) pvm_val pvm_make_string_type (void) __attribute__ ((visibility ("hidden"))); + pvm_val pvm_make_any_type (void) __attribute__ ((visibility ("hidden"))); diff --git a/testsuite/poke.libpoke/Makefile.am b/testsuite/poke.libpoke/Makefile.am index 36ebf2ea..3d47507d 100644 --- a/testsuite/poke.libpoke/Makefile.am +++ b/testsuite/poke.libpoke/Makefile.am @@ -23,6 +23,7 @@ values_SOURCES = $(COMMON) values.c values_CPPFLAGS = -I$(top_builddir)/gl -I$(top_srcdir)/gl \ -I$(top_srcdir)/common \ + -DPKGDATADIR=\"$(pkgdatadir)\" \ -I$(top_srcdir)/libpoke -I$(top_builddir)/libpoke values_LDADD = $(top_builddir)/gl/libgnu.la \ diff --git a/testsuite/poke.libpoke/pk_equal_arr.test b/testsuite/poke.libpoke/pk_equal_arr.test new file mode 100644 index 00000000..024b2bc2 --- /dev/null +++ b/testsuite/poke.libpoke/pk_equal_arr.test @@ -0,0 +1,4 @@ +## +[1L, 2L, 3L, 15L, 25L, -35L, 64L, 9223372036854775807L] +[1L, 2L, 3L, 15L, 25L, -35L, 64L, 9223372036854775807L] +## \ No newline at end of file diff --git a/testsuite/poke.libpoke/pk_equal_int.test b/testsuite/poke.libpoke/pk_equal_int.test new file mode 100644 index 00000000..73679d1f --- /dev/null +++ b/testsuite/poke.libpoke/pk_equal_int.test @@ -0,0 +1,4 @@ +## +-3500 as int<32> +-3500 as int<32> +## \ No newline at end of file diff --git a/testsuite/poke.libpoke/pk_equal_off.test b/testsuite/poke.libpoke/pk_equal_off.test new file mode 100644 index 00000000..02ab8da0 --- /dev/null +++ b/testsuite/poke.libpoke/pk_equal_off.test @@ -0,0 +1,4 @@ +## +25#B +25#B +## \ No newline at end of file diff --git a/testsuite/poke.libpoke/pk_equal_sct.test b/testsuite/poke.libpoke/pk_equal_sct.test new file mode 100644 index 00000000..d3a4ae6d --- /dev/null +++ b/testsuite/poke.libpoke/pk_equal_sct.test @@ -0,0 +1,5 @@ +deftype Packet = struct { int i; long j; }; +## +Packet { i = 1, j = 2 } +Packet { i = 1, j = 2 } +## \ No newline at end of file diff --git a/testsuite/poke.libpoke/pk_equal_str.test b/testsuite/poke.libpoke/pk_equal_str.test new file mode 100644 index 00000000..edc18df1 --- /dev/null +++ b/testsuite/poke.libpoke/pk_equal_str.test @@ -0,0 +1,4 @@ +## +"foo" +"foo" +## \ No newline at end of file diff --git a/testsuite/poke.libpoke/pk_equal_uint.test b/testsuite/poke.libpoke/pk_equal_uint.test new file mode 100644 index 00000000..4b4a5f1b --- /dev/null +++ b/testsuite/poke.libpoke/pk_equal_uint.test @@ -0,0 +1,4 @@ +## +18446744073709551615 as uint<64> +18446744073709551615 as uint<64> +## \ No newline at end of file diff --git a/testsuite/poke.libpoke/pk_nequal_arr.test b/testsuite/poke.libpoke/pk_nequal_arr.test new file mode 100644 index 00000000..533da000 --- /dev/null +++ b/testsuite/poke.libpoke/pk_nequal_arr.test @@ -0,0 +1,4 @@ +## +[1L, 2L, 3L, 15L, 25L, -35L, 64L, 9223372036854775807L] +[1L, 2L, 4L, 15L, -25L, -35L, 64L, 9223372036854775807L] +## \ No newline at end of file diff --git a/testsuite/poke.libpoke/pk_nequal_int.test b/testsuite/poke.libpoke/pk_nequal_int.test new file mode 100644 index 00000000..fafdbc72 --- /dev/null +++ b/testsuite/poke.libpoke/pk_nequal_int.test @@ -0,0 +1,4 @@ +## +-3500 as int<32> +-3500 as int<64> +## \ No newline at end of file diff --git a/testsuite/poke.libpoke/pk_nequal_off.test b/testsuite/poke.libpoke/pk_nequal_off.test new file mode 100644 index 00000000..fcaafd7c --- /dev/null +++ b/testsuite/poke.libpoke/pk_nequal_off.test @@ -0,0 +1,4 @@ +## +25#B +22#b +## \ No newline at end of file diff --git a/testsuite/poke.libpoke/pk_nequal_sct.test b/testsuite/poke.libpoke/pk_nequal_sct.test new file mode 100644 index 00000000..a83071ec --- /dev/null +++ b/testsuite/poke.libpoke/pk_nequal_sct.test @@ -0,0 +1,5 @@ +deftype Packet = struct { int i; long j; }; +## +Packet { i = 1, j = 2 } +Packet { i = 2, j = 2 } +## \ No newline at end of file diff --git a/testsuite/poke.libpoke/pk_nequal_str.test b/testsuite/poke.libpoke/pk_nequal_str.test new file mode 100644 index 00000000..485e182f --- /dev/null +++ b/testsuite/poke.libpoke/pk_nequal_str.test @@ -0,0 +1,4 @@ +## +"foo" +"bar" +## \ No newline at end of file diff --git a/testsuite/poke.libpoke/pk_nequal_uint.test b/testsuite/poke.libpoke/pk_nequal_uint.test new file mode 100644 index 00000000..964f7cf0 --- /dev/null +++ b/testsuite/poke.libpoke/pk_nequal_uint.test @@ -0,0 +1,4 @@ +## +18446744073709551615 as uint<64> +12312 as uint<64> +## \ No newline at end of file diff --git a/testsuite/poke.libpoke/values.c b/testsuite/poke.libpoke/values.c index 17d3378f..b8cc3fa0 100644 --- a/testsuite/poke.libpoke/values.c +++ b/testsuite/poke.libpoke/values.c @@ -18,7 +18,11 @@ #include +#include +#include +#include #include +#include #include "libpoke.h" #include "term-if.h" @@ -61,13 +65,166 @@ test_simple_values () } int -main (int argc, char *argv[]) +compile_initial_poke_code (FILE *ifp, pk_compiler pkc) { - pk_compiler pk_compiler = pk_compiler_new (".", &poke_term_if); + ssize_t nread, s_nread = 0; + char *line = NULL, *poke_code = NULL; + size_t len = 0; + int error = 1; - test_simple_values (); + while (1) + { + nread = getline (&line, &len, ifp); + if (nread == -1) + return 0; + + /* If we reached the next section of the file, break. */ + if (nread == 3 && line[0] == '#' && line[1] == '#') + break; + + line[nread - 1] = '\0'; + s_nread += nread - 1; + + if (poke_code == NULL) + { + poke_code = (char *) malloc (nread); + memcpy (poke_code, line, nread); + } + else + { + poke_code = (char *) realloc (poke_code, s_nread + 1); + strncat (poke_code, line, nread + 1); + } + } + + if (ferror (ifp)) + return 0; + + if (poke_code) + { + error = pk_compile_buffer (pkc, poke_code, NULL); + free (poke_code); + } + + free (line); + return error; +} + +/* Returns a C array containing the Poke values that were compiled. + Returns NULL on error. */ +int +compile_poke_expression (FILE *ifp, pk_compiler pkc, pk_val *val) +{ + ssize_t nread; + char *line = NULL; + size_t len = 0; + + nread = getline (&line, &len, ifp); + if (nread == -1) + return 0; + + line[nread - 1] = '\0'; + + if (pk_compile_expression (pkc, (const char *) line, NULL, val) == 0) + goto error; + + free (line); + return 1; + + error: + free (line); + return 0; +} + +#define STARTS_WITH(PREFIX, STR) (strncmp (PREFIX, STR, strlen (PREFIX)) == 0) + +void +test_pk_equal_file (const char *filename, FILE *ifp) +{ + pk_val val1, val2; + pk_compiler pkc; + int equal; + char *poke_datadir; + + poke_datadir = getenv ("POKEDATADIR"); + if (poke_datadir == NULL) + poke_datadir = PKGDATADIR; - pk_compiler_free (pk_compiler); + pkc = pk_compiler_new (poke_datadir, &poke_term_if); + + if (!pkc) + goto error; + + if (compile_initial_poke_code (ifp, pkc) == 0) + goto error; + + if (compile_poke_expression (ifp, pkc, &val1) == 0) + goto error; + + if (compile_poke_expression (ifp, pkc, &val2) == 0) + goto error; + + /* (NOTE: kostas) We should have a way to discriminate if we should check + if 2 values should match or not. + + Currently, this decision is taken based on the name of the file. + + If file begins with pk_equal we should mark the test as "passed" + if the 2 values are equal. + + If file begins with pk_nequal we should mark the test as "passed" + if the 2 values are non equal. */ + + equal = pk_val_equal_p (val1, val2); + if (STARTS_WITH ("pk_equal", filename) && equal) + pass (filename); + else if (STARTS_WITH ("pk_nequal", filename) && !equal) + pass (filename); + else + fail (filename); + + pk_compiler_free (pkc); + return; + + error: + fail (filename); +} + +void +test_pk_val_equal_p () +{ + FILE *ifp; + DIR *directory; + struct dirent *dir; + const char *extension; + + directory = opendir ("."); + if (directory) + { + while ((dir = readdir (directory)) != NULL) + { + /* If this file a .json file, proccess it. */ + extension = strrchr (dir->d_name, '.'); + if (extension) + { + if (!strncmp (extension + 1, "test", 4)) + { + ifp = fopen (dir->d_name, "r"); + if (ifp) + test_pk_equal_file (dir->d_name, ifp); + fclose (ifp); + } + } + } + closedir (directory); + } +} + +int +main (int argc, char *argv[]) +{ + test_simple_values (); + test_pk_val_equal_p (); totals (); return 0; -- 2.17.1