aboutsummaryrefslogtreecommitdiffstats
path: root/src/blind-to-portable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/blind-to-portable.c')
-rw-r--r--src/blind-to-portable.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/src/blind-to-portable.c b/src/blind-to-portable.c
index 2d9c899..07eee62 100644
--- a/src/blind-to-portable.c
+++ b/src/blind-to-portable.c
@@ -1,4 +1,5 @@
/* See LICENSE file for copyright and license details. */
+#define INCLUDE_UINT16
#include "common.h"
/* Disable warnings in <math.h> */
@@ -9,6 +10,8 @@
USAGE("[-s]")
+static int strict = 1;
+
#define CONV(ITYPE, OTYPE, SOTYPE, EXPONENT, HA2EXPONENT, FRACTION)\
do {\
static int cache_i = 0;\
@@ -62,7 +65,7 @@ USAGE("[-s]")
return ret;\
} while (0)
-#define PROCESS(ITYPE, OTYPE, BITS)\
+#define PROCESS_FLOAT(ITYPE, OTYPE, BITS)\
do {\
size_t i, n;\
ITYPE *ibuf = (ITYPE *)(stream->buf);\
@@ -70,15 +73,19 @@ USAGE("[-s]")
: alloca(sizeof(stream->buf) / sizeof(ITYPE) * sizeof(OTYPE));\
strict *= !USING_BINARY##BITS;\
if (!strict && sizeof(ITYPE) != sizeof(OTYPE))\
- eprintf("-s is required on this machine\n");\
+ eprintf("-s is supported not on this machine\n");\
+ if (stream->endian == LITTLE_ENDIAN && !strict) {\
+ esend_stream(stream, STDOUT_FILENO, "<stdout>");\
+ break;\
+ }\
do {\
n = stream->ptr / sizeof(ITYPE);\
if (strict) {\
for (i = 0; i < n; i++)\
- obuf[i] = htole##BITS(conv_##ITYPE(ibuf[i]));\
+ obuf[i] = htole(conv_##ITYPE(ibuf[i]));\
} else {\
for (i = 0; i < n; i++)\
- obuf[i] = htole##BITS(*(OTYPE *)&ibuf[i]);\
+ obuf[i] = htole(*(OTYPE *)&ibuf[i]);\
}\
ewriteall(STDOUT_FILENO, obuf, n * sizeof(OTYPE), "<stdout>");\
n *= sizeof(ITYPE);\
@@ -88,18 +95,38 @@ USAGE("[-s]")
eprintf("%s: incomplete frame\n", stream->file);\
} while (0)
+#define PROCESS_INTEGER(TYPE)\
+ do {\
+ size_t i, n;\
+ TYPE *buf = (TYPE *)(stream->buf);\
+ if (stream->endian == LITTLE_ENDIAN) {\
+ esend_stream(stream, STDOUT_FILENO, "<stdout>");\
+ break;\
+ }\
+ do {\
+ n = stream->ptr / sizeof(TYPE);\
+ for (i = 0; i < n; i++)\
+ buf[i] = htole(buf[i]);\
+ n *= sizeof(TYPE);\
+ ewriteall(STDOUT_FILENO, buf, n, "<stdout>");\
+ memmove(stream->buf, stream->buf + n, stream->ptr -= n);\
+ } while (eread_stream(stream, SIZE_MAX));\
+ if (stream->ptr)\
+ eprintf("%s: incomplete frame\n", stream->file);\
+ } while (0)
+
static uint64_t conv_double(double host) {CONV(double, uint64_t, int64_t, 11, 1023, 52);}
static uint32_t conv_float (float host) {CONV(float, uint32_t, int32_t, 8, 127, 23);}
-static void process_lf(struct stream *stream, int strict) {PROCESS(double, uint64_t, 64);}
-static void process_f (struct stream *stream, int strict) {PROCESS(float, uint32_t, 32);}
+static void process_lf (struct stream *stream) {PROCESS_FLOAT(double, uint64_t, 64);}
+static void process_f (struct stream *stream) {PROCESS_FLOAT(float, uint32_t, 32);}
+static void process_u16(struct stream *stream) {PROCESS_INTEGER(uint16_t);}
int
main(int argc, char *argv[])
{
struct stream stream;
- int strict = 1;
- void (*process)(struct stream *stream, int strict);
+ void (*process)(struct stream *stream);
ARGBEGIN {
case 's':
@@ -113,10 +140,17 @@ main(int argc, char *argv[])
usage();
eopen_stream(&stream, NULL);
+#if defined(HOST_ENDIAN_IS_LITTLE_ENDIAN)
+ if (stream.endian == HOST_ENDIAN)
+ stream.endian = LITTLE_ENDIAN;
+#elif defined(HOST_ENDIAN_IS_BIG_ENDIAN)
+ if (stream.endian == HOST_ENDIAN)
+ stream.endian = BIG_ENDIAN;
+#endif
SELECT_PROCESS_FUNCTION(&stream);
fprint_stream_head(stdout, &stream);
efflush(stdout, "<stdout>");
- process(&stream, strict);
+ process(&stream);
return 0;
}