diff --git a/src/binarydiff.c b/src/binarydiff.c index e7b3dd102..8ef5c4b2a 100644 --- a/src/binarydiff.c +++ b/src/binarydiff.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "particle.h" #include "rebound.h" @@ -86,6 +87,36 @@ const struct reb_binary_field_descriptor reb_binary_field_descriptor_for_name(co return bfd; } +static int print_reb_type(FILE * restrict stream, int dtype, char* pointer){ + switch (dtype){ + case REB_DOUBLE: + fprintf(stream, "%e",*(double*)(pointer)); + break; + case REB_INT: + fprintf(stream, "%d",*(int*)(pointer)); + break; + case REB_UINT: + fprintf(stream, "%u",*(unsigned int*)(pointer)); + break; + case REB_UINT32: + fprintf(stream, "%"PRIu32,*(uint32_t*)(pointer)); // PRIu32 defined in inttypes.h + break; + case REB_LONG: + fprintf(stream, "%ld",*(long*)(pointer)); + break; + case REB_ULONG: + fprintf(stream, "%lu",*(unsigned long*)(pointer)); + break; + case REB_ULONGLONG: + fprintf(stream, "%llu",*(unsigned long long*)(pointer)); + break; + default: + return 0; // Not implemented + break; + } + return 1; +} + int reb_binary_diff_with_options(char* buf1, size_t size1, char* buf2, size_t size2, char** bufp, size_t* sizep, int output_option){ if (!buf1 || !buf2 || size1<64 || size2<64){ printf("Cannot read input buffers.\n"); @@ -157,7 +188,7 @@ int reb_binary_diff_with_options(char* buf1, size_t size1, char* buf2, size_t si case 1: { const char* name = reb_binary_field_descriptor_for_type(field1.type).name; - printf("Field \"%s\" (type=%d) not in simulation 2.\n",name, field1.type); + printf("Field '%s' (type=%d) not in simulation 2.\n",name, field1.type); } break; default: @@ -198,8 +229,14 @@ int reb_binary_diff_with_options(char* buf1, size_t size1, char* buf2, size_t si break; case 1: { - const char* name = reb_binary_field_descriptor_for_type(field1.type).name; - printf("Field \"%s\" (type=%d) differs.\n",name, field1.type); + const struct reb_binary_field_descriptor fd = reb_binary_field_descriptor_for_type(field1.type); + printf("Field '%s' (type=%d) differs. ",fd.name, field1.type); + if (print_reb_type(stdout, fd.dtype, buf1+pos1)){ + printf(" != "); + print_reb_type(stdout, fd.dtype, buf2+pos2); + } + printf("\n"); + } break; default: @@ -267,7 +304,7 @@ int reb_binary_diff_with_options(char* buf1, size_t size1, char* buf2, size_t si case 1: { const char* name = reb_binary_field_descriptor_for_type(field2.type).name; - printf("Field \"%s\" (type=%d) not in simulation 1.\n",name, field2.type); + printf("Field '%s\' (type=%d) not in simulation 1.\n",name, field2.type); } break; default: diff --git a/src/rebound.c b/src/rebound.c index ad45a2b46..7621725ca 100644 --- a/src/rebound.c +++ b/src/rebound.c @@ -1051,7 +1051,7 @@ const struct reb_binary_field_descriptor reb_binary_field_descriptor_list[]= { { 141, REB_UINT, "ri_saba.is_synchronized", offsetof(struct reb_simulation, ri_saba.is_synchronized)}, { 143, REB_UINT, "ri_whfast.corrector2", offsetof(struct reb_simulation, ri_whfast.corrector2)}, { 144, REB_INT, "ri_whfast.kernel", offsetof(struct reb_simulation, ri_whfast.kernel)}, - { 145, REB_DOUBLE, "dti_last_done", offsetof(struct reb_simulation, dt_last_done)}, + { 145, REB_DOUBLE, "dt_last_done", offsetof(struct reb_simulation, dt_last_done)}, { 146, REB_INT, "ri_saba.type", offsetof(struct reb_simulation, ri_saba.type)}, { 147, REB_UINT, "ri_saba.keep_unsynchronized", offsetof(struct reb_simulation, ri_saba.keep_unsynchronized)}, { 148, REB_INT, "ri_eos.phi0", offsetof(struct reb_simulation, ri_eos.phi0)}, diff --git a/src/rebound.h b/src/rebound.h index 896ace983..a501ebae2 100644 --- a/src/rebound.h +++ b/src/rebound.h @@ -920,7 +920,7 @@ const struct reb_binary_field_descriptor reb_binary_field_descriptor_for_type(in const struct reb_binary_field_descriptor reb_binary_field_descriptor_for_name(const char* name); struct reb_binary_field_descriptor { - unsigned int type; + unsigned int type; // Unique id for each field. Should not change between versions. Ids should not be reused. enum { REB_DOUBLE, REB_INT, @@ -934,14 +934,14 @@ struct reb_binary_field_descriptor { REB_POINTER, REB_POINTER_ALIGNED, // memory aligned to 64 bit boundary for AVX512 REB_DP7, // Special datatype for IAS15 - REB_OTHER, + REB_OTHER, // Fields that need special treatment during input and/or output REB_FIELD_END, // Special type to indicate end of blob REB_FIELD_NOT_FOUND, // Special type used to throw error messages } dtype; char name[1024]; - size_t offset; - size_t offset_N; - size_t element_size; + size_t offset; // Offset of the storage location relative to the beginning of reb_simulation + size_t offset_N; // Offset of the storage location for the size relative to the beginning of reb_simulation + size_t element_size; // Size in bytes of each element (only used for pointers, dp7, etc) }; extern const struct reb_binary_field_descriptor reb_binary_field_descriptor_list[];