blob: 37101adc280a41b338901daff1df1f721d17a93c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
int
do_vec(lvalue,astr,arglast)
int lvalue;
STR *astr;
int *arglast;
{
STR **st = stack->ary_array;
int sp = arglast[0];
register STR *TARG = st[++sp];
register int offset = (int)str_gnum(st[++sp]);
register int size = (int)str_gnum(st[++sp]);
unsigned char *s = (unsigned char*)str_get(TARG);
unsigned long retnum;
int len;
sp = arglast[1];
offset *= size; /* turn into bit offset */
len = (offset + size + 7) / 8;
if (offset < 0 || size < 1)
retnum = 0;
else if (!lvalue && len > TARG->str_cur)
retnum = 0;
else {
if (len > TARG->str_cur) {
STR_GROW(TARG,len);
(void)memzero(TARG->str_ptr + TARG->str_cur, len - TARG->str_cur);
TARG->str_cur = len;
}
s = (unsigned char*)str_get(TARG);
if (size < 8)
retnum = (s[offset >> 3] >> (offset & 7)) & ((1 << size) - 1);
else {
offset >>= 3;
if (size == 8)
retnum = s[offset];
else if (size == 16)
retnum = ((unsigned long) s[offset] << 8) + s[offset+1];
else if (size == 32)
retnum = ((unsigned long) s[offset] << 24) +
((unsigned long) s[offset + 1] << 16) +
(s[offset + 2] << 8) + s[offset+3];
}
if (lvalue) { /* it's an lvalue! */
struct lstring *lstr = (struct lstring*)astr;
astr->str_magic = TARG;
st[sp]->str_rare = 'v';
lstr->lstr_offset = offset;
lstr->lstr_len = size;
}
}
str_numset(astr,(double)retnum);
st[sp] = astr;
return sp;
}
|