diff options
Diffstat (limited to 'testutil/to-tracer-endian.c')
-rw-r--r-- | testutil/to-tracer-endian.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/testutil/to-tracer-endian.c b/testutil/to-tracer-endian.c new file mode 100644 index 0000000..53cb380 --- /dev/null +++ b/testutil/to-tracer-endian.c @@ -0,0 +1,83 @@ +/* See LICENSE file for copyright and license details. */ +#include "../libsyscalls.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */ +#endif + + +int +main(int argc, char **argv) +{ + struct libsyscalls_datatype_description type; + const char *text; + char *data; + size_t dataoff, i; + unsigned long long int value; + unsigned char high, low; + enum libsyscalls_error err; + + _Static_assert(CHAR_BIT, "We only support 8-bit char at the moment in testutil/to-tracer-endian.c"); + + if (argc < 5) { + usage: + fprintf(stderr, "usage error\n"); + return 1; + } + +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wconversion" +#endif + + text = argv[1]; + dataoff = (size_t)atol(argv[2]); + type.width_in_bits = (unsigned short int)atoi(argv[3]); + argv = &argv[4]; + i = 0; + for (; argv[i] && i < sizeof(type.byteorder) / sizeof(*type.byteorder); i++) + type.byteorder[i] = (unsigned)atoi(argv[i]); + if (argv[i]) + goto usage; + for (; i < sizeof(type.byteorder) / sizeof(*type.byteorder); i++) { + type.byteorder[i] = 0U; + type.byteorder[i] = ~type.byteorder[i]; + } + +#if defined(__clang__) +# pragma GCC diagnostic pop +#endif + + if (strlen(text) & 1 || !strlen(text)) + goto usage; + data = malloc(strlen(text) / 2); + for (i = 0; *text; i++) { + high = (unsigned char)*text++; + low = (unsigned char)*text++; + high = (unsigned char)((high & 15U) + (high > '9' ? 9U : 0U)); + low = (unsigned char)((low & 15U) + (low > '9' ? 9U : 0U)); + data[i] = (char)((high << 4) | low); + } + + err = libsyscalls_to_tracer_endian(data, dataoff, &type, &value); + free(data); + if (err == LIBSYSCALLS_E_INVAL) { + printf("inval\n"); + goto out; + } else if (err) { + libsyscalls_perror(NULL, err); + return 1; + } + printf("%llX\n", value); + +out: + if (fflush(stdout) || fclose(stdout)) { + perror(NULL); + return 1; + } + return 0; +} |