scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit fb86ba15a8c01bb5ba1c726ecc41766211abd259
parent 74488c63a586f4c4e2ab6c5b7a3b0fde8afeb021
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri, 17 Nov 2017 14:38:30 +0000

[lib/scc] Add lpack and lunpack

These are generic functions to pack/unpack little endian strings.

Diffstat:
inc/scc.h | 2++
lib/scc/libdep.mk | 2++
lib/scc/lpack.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/scc/lunpack.c | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 113 insertions(+), 0 deletions(-)

diff --git a/inc/scc.h b/inc/scc.h @@ -45,3 +45,5 @@ extern void dealloc(Alloc *allocp); extern void *new(Alloc *allocp); extern void delete(Alloc *allocp, void *p); extern int casecmp(const char *s1, const char *s2); +extern int lpack(char *dst, char *fmt, ...); +extern int lunpack(char *src, char *fmt, ...); diff --git a/lib/scc/libdep.mk b/lib/scc/libdep.mk @@ -7,3 +7,5 @@ LIB-OBJ = $(LIBDIR)/debug.o \ $(LIBDIR)/xstrdup.o \ $(LIBDIR)/alloc.o \ $(LIBDIR)/casecmp.o \ + $(LIBDIR)/lunpack.o \ + $(LIBDIR)/lpack.o \ diff --git a/lib/scc/lpack.c b/lib/scc/lpack.c @@ -0,0 +1,52 @@ +#include <stdarg.h> + +#include "../../inc/scc.h" + +int +lpack(char *dst, char *fmt, ...) +{ + 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 dst - bp; +} diff --git a/lib/scc/lunpack.c b/lib/scc/lunpack.c @@ -0,0 +1,57 @@ +#include <stdarg.h> + +#include "../../inc/scc.h" + +int +lunpack(char *src, char *fmt, ...) +{ + char *bp, *cp; + unsigned short *sp; + unsigned s; + unsigned long *lp, l; + unsigned long long *qp, q; + va_list va; + + bp = src; + va_start(va, fmt); + while (*fmt) { + switch (*fmt++) { + 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) *bp++ << 56; + q |= (unsigned long) *bp++ << 48; + q |= (unsigned long) *bp++ << 40; + q |= (unsigned long) *bp++ << 32; + q |= (unsigned long) *bp++ << 24; + q |= (unsigned long) *bp++ << 16; + q |= (unsigned long) *bp++ << 8; + q |= (unsigned long) *bp++; + *qp = q; + break; + default: + va_end(va); + return -1; + } + } + va_end(va); + + return src - bp; +}