aboutsummaryrefslogtreecommitdiffstats
path: root/pack.c
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2021-08-06 20:16:31 +0100
committerTomasz Kramkowski <tk@the-tk.com>2021-08-06 20:16:31 +0100
commit07d540498026f59622130e1f44534e32a73f23d0 (patch)
tree6582db36b005513a7be623b5b4db28010d45cb8d /pack.c
parent5edfaf66958a7ea7ae6fb7b58c037b86465340ad (diff)
downloadpack-07d540498026f59622130e1f44534e32a73f23d0.tar.gz
pack-07d540498026f59622130e1f44534e32a73f23d0.tar.xz
pack-07d540498026f59622130e1f44534e32a73f23d0.zip
use xmacros to generate type related code
Diffstat (limited to 'pack.c')
-rw-r--r--pack.c34
1 files changed, 15 insertions, 19 deletions
diff --git a/pack.c b/pack.c
index 9d7046c..f06aafe 100644
--- a/pack.c
+++ b/pack.c
@@ -32,23 +32,19 @@ enum pack_status pack(void *buf_, size_t size, const char *fmt, ...)
for (int i = 0; fmt[i] != '\0'; i++) {
bool sign;
size_t s;
- union { uintmax_t u; intmax_t s; } val;
+ union { uintmax_t unsigned_; intmax_t signed_; } v;
tr_debug("i: %d, fmt[i]: %c", i, fmt[i]);
sign = islower(fmt[i]);
switch (fmt[i]) {
case '>': endianness = PACK_ENDIAN_BIG; continue;
case '<': endianness = PACK_ENDIAN_LITTLE; continue;
- case PACK_TYPE_SCHAR: val.s = va_arg(ap, int); break;
- case PACK_TYPE_UCHAR: val.u = va_arg(ap, unsigned); break;
- case PACK_TYPE_SHORT: val.s = va_arg(ap, int); break;
- case PACK_TYPE_USHORT: val.u = va_arg(ap, unsigned); break;
- case PACK_TYPE_INT: val.s = va_arg(ap, int); break;
- case PACK_TYPE_UINT: val.u = va_arg(ap, unsigned); break;
- case PACK_TYPE_LONG: val.s = va_arg(ap, long); break;
- case PACK_TYPE_ULONG: val.u = va_arg(ap, unsigned long); break;
- case PACK_TYPE_LLONG: val.s = va_arg(ap, long long); break;
- case PACK_TYPE_ULLONG: val.u = va_arg(ap, unsigned long long); break;
- case PACK_TYPE_PADDING: val.u = 0; sign = false; break;
+ #define T(type, sign, c_type, va_type) \
+ case (char)PACK_TYPE_##type: \
+ v.sign##_ = va_arg(ap, sign va_type); \
+ break;
+ ITYPE_MACROS
+ #undef T
+ case 'x': v.unsigned_ = 0; sign = false; break;
default: return PACK_FMTINVAL;
}
tr_debug("i: %d, fmt[i]: %c, sign: %ssigned", i, fmt[i], sign ? "" : "un");
@@ -60,18 +56,18 @@ enum pack_status pack(void *buf_, size_t size, const char *fmt, ...)
if (size - offset < s) return PACK_TOOSMALL;
if (sign) {
- intmax_t n = val.s;
- tr_debug("val.s: %" PRIdMAX, val.s);
- if (val.s >= 0) {
- val.u = n;
+ intmax_t n = v.signed_;
+ tr_debug("val.s: %" PRIdMAX, v.signed_);
+ if (v.signed_ >= 0) {
+ v.unsigned_ = n;
} else {
uintmax_t offt = BITMASK(s * 8);
n += 1;
- val.u = offt + n;
+ v.unsigned_ = offt + n;
}
}
- tr_debug("val.u: %" PRIuMAX, val.u);
- write_val(&buf[offset], s, endianness, val.u);
+ tr_debug("val.u: %" PRIuMAX, v.unsigned_);
+ write_val(&buf[offset], s, endianness, v.unsigned_);
offset += s;
}