scc

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

lunpack.c (1152B)


      1 #include <stdarg.h>
      2 
      3 #include "../../inc/scc.h"
      4 
      5 int
      6 lunpack(unsigned char *src, char *fmt, ...)
      7 {
      8 	unsigned char *bp, *cp;
      9 	unsigned short *sp;
     10 	unsigned s;
     11 	unsigned long *lp, l;
     12 	unsigned long long *qp, q;
     13 	va_list va;
     14 
     15 	bp = src;
     16 	va_start(va, fmt);
     17 	while (*fmt) {
     18 		switch (*fmt++) {
     19 		case 'c':
     20 			cp = va_arg(va, unsigned char *);
     21 			*cp = *bp++;
     22 			break;
     23 		case 's':
     24 			sp = va_arg(va, unsigned short *);
     25 			s =  (unsigned) *bp++ << 8;
     26 			s |= (unsigned) *bp++;
     27 			*sp = s;
     28 			break;
     29 		case 'l':
     30 			lp = va_arg(va, unsigned long *);
     31 			l =  (unsigned long) *bp++ << 24;
     32 			l |= (unsigned long) *bp++ << 16;
     33 			l |= (unsigned long) *bp++ << 8;
     34 			l |= (unsigned long) *bp++;
     35 			*lp = l;
     36 			break;
     37 		case 'q':
     38 			qp = va_arg(va, unsigned long long *);
     39 			q =  (unsigned long) *bp++ << 56;
     40 			q |= (unsigned long) *bp++ << 48;
     41 			q |= (unsigned long) *bp++ << 40;
     42 			q |= (unsigned long) *bp++ << 32;
     43 			q |= (unsigned long) *bp++ << 24;
     44 			q |= (unsigned long) *bp++ << 16;
     45 			q |= (unsigned long) *bp++ << 8;
     46 			q |= (unsigned long) *bp++;
     47 			*qp = q;
     48 			break;
     49 		default:
     50 			va_end(va);
     51 			return -1;
     52 		}
     53 	}
     54 	va_end(va);
     55 
     56 	return bp - src;
     57 }