pack.c - scc - simple c99 compiler
(HTM) git clone git://git.simple-cc.org/scc
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
pack.c (2141B)
---
1 #include <ctype.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 #include <scc/mach.h>
7 #include "libmach.h"
8
9 static int
10 lpack(unsigned char *dst, char *fmt, va_list va)
11 {
12 unsigned char *bp, *cp;
13 unsigned s;
14 unsigned long l;
15 unsigned long long q;
16 int n;
17
18 bp = dst;
19 while (*fmt) {
20 switch (*fmt++) {
21 case '\'':
22 n = atoi(fmt);
23 while (isdigit(*fmt))
24 fmt++;
25 cp = va_arg(va, unsigned char *);
26 while (n--)
27 *bp++ = *cp++;
28 break;
29 case 'c':
30 *bp++ = va_arg(va, unsigned);
31 break;
32 case 's':
33 s = va_arg(va, unsigned);
34 *bp++ = s;
35 *bp++ = s >> 8;
36 break;
37 case 'l':
38 l = va_arg(va, unsigned long);
39 *bp++ = l;
40 *bp++ = l >> 8;
41 *bp++ = l >> 16;
42 *bp++ = l >> 24;
43 break;
44 case 'q':
45 q = va_arg(va, unsigned long long);
46 *bp++ = q;
47 *bp++ = q >> 8;
48 *bp++ = q >> 16;
49 *bp++ = q >> 24;
50 *bp++ = q >> 32;
51 *bp++ = q >> 40;
52 *bp++ = q >> 48;
53 *bp++ = q >> 56;
54 break;
55 default:
56 return -1;
57 }
58 }
59
60 return bp - dst;
61 }
62
63 static int
64 bpack(unsigned char *dst, char *fmt, va_list va)
65 {
66 unsigned char *bp, *cp;
67 unsigned s;
68 unsigned long l;
69 unsigned long long q;
70 int n;
71
72 bp = dst;
73 while (*fmt) {
74 switch (*fmt++) {
75 case '\'':
76 n = atoi(fmt);
77 while (isdigit(*fmt))
78 fmt++;
79 cp = va_arg(va, unsigned char *);
80 while (n--)
81 *bp++ = *cp++;
82 break;
83 case 'c':
84 *bp++ = va_arg(va, unsigned);
85 break;
86 case 's':
87 s = va_arg(va, unsigned);
88 *bp++ = s >> 8;
89 *bp++ = s;
90 break;
91 case 'l':
92 l = va_arg(va, unsigned long);
93 *bp++ = l >> 24;
94 *bp++ = l >> 16;
95 *bp++ = l >> 8;
96 *bp++ = l;
97 break;
98 case 'q':
99 q = va_arg(va, unsigned long long);
100 *bp++ = q >> 56;
101 *bp++ = q >> 48;
102 *bp++ = q >> 40;
103 *bp++ = q >> 32;
104 *bp++ = q >> 24;
105 *bp++ = q >> 16;
106 *bp++ = q >> 8;
107 *bp++ = q;
108 break;
109 default:
110 return -1;
111 }
112 }
113
114 return bp - dst;
115 }
116
117 int
118 pack(int order, unsigned char *dst, char *fmt, ...)
119 {
120 int r;
121 int (*fn)(unsigned char *dst, char *fmt, va_list va);
122 va_list va;
123
124 va_start(va, fmt);
125 fn = (order == LITTLE_ENDIAN) ? lpack : bpack;
126 r = (*fn)(dst, fmt, va);
127 va_end(va);
128
129 return r;
130 }