#include "bits.h"
#include "buf.h"
#include "fltfmt.h"
+#include "macros.h"
-/*----- External functions ------------------------------------------------*/
+/*----- Constants ---------------------------------------------------------*/
+
+/* Tolerable errors. These aren't great, and all of them imply a failure to
+ * faithfully pass the value on, but they're also the inevitable consequence
+ * of having different floating-point systems.
+ */
+#define IGNERR (FLTERR_INEXACT | FLTERR_OFLOW | FLTERR_UFLOW)
+
+/*----- Main code ---------------------------------------------------------*/
+
+#define FORMATS(_) \
+ _(flt, float, f32, 4) \
+ _(dbl, double, f64, 8)
/* --- @buf_getf{32,64}{,l,b} --- *
*
* the usual round-to-nearest/ties-to-even rounding mode.
*/
-int buf_getf32(buf *b, float *x_out)
-{
- const octet *p;
-
- p = buf_get(b, 4); if (!p) return (-1);
- fltfmt_f32btoflt(x_out, p, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_getf32l(buf *b, float *x_out)
-{
- const octet *p;
-
- p = buf_get(b, 4); if (!p) return (-1);
- fltfmt_f32ltoflt(x_out, p, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_getf32b(buf *b, float *x_out)
-{
- const octet *p;
-
- p = buf_get(b, 4); if (!p) return (-1);
- fltfmt_f32ltoflt(x_out, p, FLTRND_NEAREVEN); return (0);
-}
-
-int (dbuf_getf32)(dbuf *db, float *x_out)
- { return (dbuf_getf32(db, x_out)); }
-int (dbuf_getf32l)(dbuf *db, float *x_out)
- { return (dbuf_getf32l(db, x_out)); }
-int (dbuf_getf32b)(dbuf *db, float *x_out)
- { return (dbuf_getf32b(db, x_out)); }
-
-int buf_getf64(buf *b, double *x_out)
-{
- const octet *p;
-
- p = buf_get(b, 8); if (!p) return (-1);
- fltfmt_f64btodbl(x_out, p, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_getf64l(buf *b, double *x_out)
-{
- const octet *p;
-
- p = buf_get(b, 8); if (!p) return (-1);
- fltfmt_f64ltodbl(x_out, p, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_getf64b(buf *b, double *x_out)
-{
- const octet *p;
-
- p = buf_get(b, 8); if (!p) return (-1);
- fltfmt_f64ltodbl(x_out, p, FLTRND_NEAREVEN); return (0);
-}
-
-int (dbuf_getf64)(dbuf *db, double *x_out)
- { return (dbuf_getf64(db, x_out)); }
-int (dbuf_getf64l)(dbuf *db, double *x_out)
- { return (dbuf_getf64l(db, x_out)); }
-int (dbuf_getf64b)(dbuf *db, double *x_out)
- { return (dbuf_getf64b(db, x_out)); }
+#define DEFGET1(ty, cty, fty, e, xe, w) \
+ int GLUE3(buf_get, fty, xe)(buf *b, cty *x_out) \
+ { \
+ const octet *p; \
+ unsigned err; \
+ \
+ p = buf_get(b, w); if (!p) return (-1); \
+ err = fltfmt_##fty##e##to##ty(x_out, p, FLTRND_NEAREVEN); \
+ if (err&~IGNERR) { BBREAK(b); return (-1); } \
+ return (0); \
+ } \
+ int (GLUE3(dbuf_get, fty, xe))(dbuf *db, cty *x_out) \
+ { return (GLUE3(dbuf_get, fty, xe)(db, x_out)); }
+
+#define DEFGET(ty, cty, fty, w) \
+ DEFGET1(ty, cty, fty, b, EMPTY, w) \
+ DEFGET1(ty, cty, fty, l, l, w) \
+ DEFGET1(ty, cty, fty, b, b, w)
+
+FORMATS(DEFGET)
+
+#undef DEFGET1
+#undef DEFGET
/* --- @buf_putf{32,64}{,l,b} --- *
*
* the usual round-to-nearest/ties-to-even rounding mode.
*/
-int buf_putf32(buf *b, float x)
-{
- octet *p;
-
- p = buf_get(b, 4); if (!p) return (-1);
- fltfmt_flttof32b(p, x, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_putf32l(buf *b, float x)
-{
- octet *p;
-
- p = buf_get(b, 4); if (!p) return (-1);
- fltfmt_flttof32l(p, x, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_putf32b(buf *b, float x)
-{
- octet *p;
-
- p = buf_get(b, 4); if (!p) return (-1);
- fltfmt_flttof32b(p, x, FLTRND_NEAREVEN); return (0);
-}
-
-int (dbuf_putf32)(dbuf *db, float x)
- { return (dbuf_putf32(db, x)); }
-int (dbuf_putf32l)(dbuf *db, float x)
- { return (dbuf_putf32l(db, x)); }
-int (dbuf_putf32b)(dbuf *db, float x)
- { return (dbuf_putf32b(db, x)); }
-
-int buf_putf64(buf *b, double x)
-{
- octet *p;
-
- p = buf_get(b, 8); if (!p) return (-1);
- fltfmt_dbltof64b(p, x, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_putf64l(buf *b, double x)
-{
- octet *p;
-
- p = buf_get(b, 8); if (!p) return (-1);
- fltfmt_dbltof64l(p, x, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_putf64b(buf *b, double x)
-{
- octet *p;
-
- p = buf_get(b, 8); if (!p) return (-1);
- fltfmt_dbltof64b(p, x, FLTRND_NEAREVEN); return (0);
-}
-
-int (dbuf_putf64)(dbuf *db, double x)
- { return (dbuf_putf64(db, x)); }
-int (dbuf_putf64l)(dbuf *db, double x)
- { return (dbuf_putf64l(db, x)); }
-int (dbuf_putf64b)(dbuf *db, double x)
- { return (dbuf_putf64b(db, x)); }
+#define DEFPUT1(ty, cty, fty, e, xe, w) \
+ int GLUE3(buf_put, fty, xe)(buf *b, cty x) \
+ { \
+ octet *p; \
+ unsigned err; \
+ \
+ p = buf_get(b, w); if (!p) return (-1); \
+ err = fltfmt_##ty##to##fty##e(p, x, FLTRND_NEAREVEN); \
+ if (err&~IGNERR) { BBREAK(b); return (-1); } \
+ return (0); \
+ } \
+ int (GLUE3(dbuf_put, fty, xe))(dbuf *db, cty x) \
+ { return (GLUE3(dbuf_put, fty, xe)(db, x)); }
+
+#define DEFPUT(ty, cty, fty, w) \
+ DEFPUT1(ty, cty, fty, b, EMPTY, w) \
+ DEFPUT1(ty, cty, fty, l, l, w) \
+ DEFPUT1(ty, cty, fty, b, b, w)
+
+FORMATS(DEFPUT)
+
+#undef DEFPUT1
+#undef DEFPUT
/*----- That's all, folks -------------------------------------------------*/