scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 2ed9319063abaddf86c95e0bfa0247b24674ca94
parent e69bb726e983797ef0d094e1622465cb35ec3814
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed,  7 Mar 2018 20:51:05 +0100

[lib/scc] Add bpack() and bunpack()

These are the big endian versions of lunpack and lpack. This patch
also fixes lpack() and lunpack() because they were doing the
big endian job.

Diffstat:
Alib/scc/bpack.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Alib/scc/bunpack.c | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mlib/scc/libdep.mk | 2++
Mlib/scc/lpack.c | 24++++++++++++------------
Mlib/scc/lunpack.c | 38++++++++++++++++++++++++++------------
5 files changed, 163 insertions(+), 24 deletions(-)

diff --git a/lib/scc/bpack.c b/lib/scc/bpack.c @@ -0,0 +1,52 @@ +#include <stdarg.h> + +#include "../../inc/scc.h" + +int +bpack(unsigned char *dst, char *fmt, ...) +{ + unsigned char *bp; + unsigned s; + unsigned long l; + unsigned long long q; + va_list va; + + bp = dst; + va_start(va, fmt); + while (*fmt) { + switch (*fmt++) { + case 'c': + *bp++ = va_arg(va, unsigned); + break; + case 's': + s = va_arg(va, unsigned); + *bp++ = s >> 8; + *bp++ = s; + break; + case 'l': + l = va_arg(va, unsigned long); + *bp++ = l >> 24; + *bp++ = l >> 16; + *bp++ = l >> 8; + *bp++ = l; + break; + case 'q': + q = va_arg(va, unsigned long long); + *bp++ = q >> 56; + *bp++ = q >> 48; + *bp++ = q >> 40; + *bp++ = q >> 32; + *bp++ = q >> 24; + *bp++ = q >> 16; + *bp++ = q >> 8; + *bp++ = q; + break; + default: + va_end(va); + return -1; + } + } + va_end(va); + + return bp - dst; +} diff --git a/lib/scc/bunpack.c b/lib/scc/bunpack.c @@ -0,0 +1,71 @@ +static char sccsid[] = "@(#) ./lib/scc/lunpack.c"; + +#include <ctype.h> +#include <stdarg.h> + +#include "../../inc/scc.h" + +int +lunpack(unsigned char *src, char *fmt, ...) +{ + unsigned char *bp, *cp; + unsigned short *sp; + unsigned s; + unsigned long *lp, l; + unsigned long long *qp, q; + va_list va; + size_t n; + int d; + + bp = src; + va_start(va, fmt); + while (*fmt) { + switch (*fmt++) { + case '\'': + for (n = 0; isdigit(*fmt); n += d) { + n *= 10; + d = *fmt++ - '0'; + } + cp = va_arg(va, char *); + while (n--) + *cp++ = *bp++; + break; + case 'c': + cp = va_arg(va, unsigned char *); + *cp = *bp++; + break; + case 's': + sp = va_arg(va, unsigned short *); + s = (unsigned) *bp++ << 8; + s |= (unsigned) *bp++; + *sp = s; + break; + case 'l': + lp = va_arg(va, unsigned long *); + l = (unsigned long) *bp++ << 24; + l |= (unsigned long) *bp++ << 16; + l |= (unsigned long) *bp++ << 8; + l |= (unsigned long) *bp++; + *lp = l; + break; + case 'q': + qp = va_arg(va, unsigned long long *); + q = (unsigned long long) *bp++ << 56; + q |= (unsigned long long) *bp++ << 48; + q |= (unsigned long long) *bp++ << 40; + q |= (unsigned long long) *bp++ << 32; + q |= (unsigned long long) *bp++ << 24; + q |= (unsigned long long) *bp++ << 16; + q |= (unsigned long long) *bp++ << 8; + q |= (unsigned long long) *bp++; + *qp = q; + break; + default: + va_end(va); + return -1; + } + } + va_end(va); + + return bp - src; +} diff --git a/lib/scc/libdep.mk b/lib/scc/libdep.mk @@ -9,5 +9,7 @@ LIB-OBJ = $(LIBDIR)/debug.o \ $(LIBDIR)/casecmp.o \ $(LIBDIR)/lunpack.o \ $(LIBDIR)/lpack.o \ + $(LIBDIR)/bunpack.o \ + $(LIBDIR)/bpack.o \ $(LIBDIR)/wmyro.o \ $(LIBDIR)/rmyro.o \ diff --git a/lib/scc/lpack.c b/lib/scc/lpack.c @@ -3,7 +3,7 @@ #include "../../inc/scc.h" int -lpack(unsigned char *dst, char *fmt, ...) +bpack(unsigned char *dst, char *fmt, ...) { unsigned char *bp; unsigned s; @@ -20,26 +20,26 @@ lpack(unsigned char *dst, char *fmt, ...) break; case 's': s = va_arg(va, unsigned); - *bp++ = s >> 8; *bp++ = s; + *bp++ = s >> 8; break; case 'l': l = va_arg(va, unsigned long); - *bp++ = l >> 24; - *bp++ = l >> 16; - *bp++ = l >> 8; *bp++ = l; + *bp++ = l >> 8; + *bp++ = l >> 16; + *bp++ = l >> 24; break; case 'q': q = va_arg(va, unsigned long long); - *bp++ = q >> 56; - *bp++ = q >> 48; - *bp++ = q >> 40; - *bp++ = q >> 32; - *bp++ = q >> 24; - *bp++ = q >> 16; - *bp++ = q >> 8; *bp++ = q; + *bp++ = q >> 8; + *bp++ = q >> 16; + *bp++ = q >> 24; + *bp++ = q >> 32; + *bp++ = q >> 40; + *bp++ = q >> 48; + *bp++ = q >> 56; break; default: va_end(va); diff --git a/lib/scc/lunpack.c b/lib/scc/lunpack.c @@ -1,3 +1,6 @@ +static char sccsid[] = "@(#) ./lib/scc/lunpack.c"; + +#include <ctype.h> #include <stdarg.h> #include "../../inc/scc.h" @@ -11,39 +14,50 @@ lunpack(unsigned char *src, char *fmt, ...) unsigned long *lp, l; unsigned long long *qp, q; va_list va; + size_t n; + int d; bp = src; va_start(va, fmt); while (*fmt) { switch (*fmt++) { + case '\'': + for (n = 0; isdigit(*fmt); n += d) { + n *= 10; + d = *fmt++ - '0'; + } + cp = va_arg(va, char *); + while (n--) + *cp++ = *bp++; + break; case 'c': cp = va_arg(va, unsigned char *); *cp = *bp++; break; case 's': sp = va_arg(va, unsigned short *); - s = (unsigned) *bp++ << 8; - s |= (unsigned) *bp++; + s = (unsigned) *bp++; + s |= (unsigned) *bp++ << 8; *sp = s; break; case 'l': lp = va_arg(va, unsigned long *); - l = (unsigned long) *bp++ << 24; - l |= (unsigned long) *bp++ << 16; + l = (unsigned long) *bp++; l |= (unsigned long) *bp++ << 8; - l |= (unsigned long) *bp++; + l |= (unsigned long) *bp++ << 16; + l |= (unsigned long) *bp++ << 24; *lp = l; break; case 'q': qp = va_arg(va, unsigned long long *); - q = (unsigned long long) *bp++ << 56; - q |= (unsigned long long) *bp++ << 48; - q |= (unsigned long long) *bp++ << 40; - q |= (unsigned long long) *bp++ << 32; - q |= (unsigned long long) *bp++ << 24; - q |= (unsigned long long) *bp++ << 16; + q = (unsigned long long) *bp++; q |= (unsigned long long) *bp++ << 8; - q |= (unsigned long long) *bp++; + q |= (unsigned long long) *bp++ << 16; + q |= (unsigned long long) *bp++ << 24; + q |= (unsigned long long) *bp++ << 32; + q |= (unsigned long long) *bp++ << 40; + q |= (unsigned long long) *bp++ << 48; + q |= (unsigned long long) *bp++ << 56; *qp = q; break; default: