Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
27dd4710
Commit
27dd4710
authored
Apr 19, 2014
by
Damien George
Browse files
Merge branch 'master' of github.com:micropython/micropython
parents
3d191374
206dd2a9
Changes
10
Hide whitespace changes
Inline
Side-by-side
py/binary.c
View file @
27dd4710
#include
<stdint.h>
#include
<stdlib.h>
#include
<assert.h>
#include
"misc.h"
...
...
@@ -9,34 +10,52 @@
// Helpers to work with binary-encoded data
int
mp_binary_get_size
(
char
typecode
)
{
// This assumes that unsigned and signed types are of the same type,
// which is invariant for [u]intN_t.
switch
(
typecode
)
{
case
BYTEARRAY_TYPECODE
:
case
'b'
:
case
'B'
:
return
sizeof
(
int8_t
);
case
'h'
:
case
'H'
:
return
sizeof
(
int16_t
);
case
'i'
:
case
'I'
:
return
sizeof
(
int32_t
);
case
'l'
:
case
'L'
:
return
sizeof
(
int32_t
);
case
'q'
:
case
'Q'
:
return
sizeof
(
long
long
);
#if MICROPY_ENABLE_FLOAT
case
'f'
:
return
sizeof
(
float
);
case
'd'
:
return
sizeof
(
double
);
#endif
int
mp_binary_get_size
(
char
struct_type
,
char
val_type
,
uint
*
palign
)
{
int
size
=
0
;
int
align
=
1
;
switch
(
struct_type
)
{
case
'<'
:
case
'>'
:
switch
(
val_type
)
{
case
'b'
:
case
'B'
:
size
=
1
;
break
;
case
'h'
:
case
'H'
:
size
=
2
;
break
;
case
'i'
:
case
'I'
:
size
=
4
;
break
;
case
'l'
:
case
'L'
:
size
=
4
;
break
;
case
'q'
:
case
'Q'
:
size
=
8
;
break
;
}
break
;
case
'@'
:
{
// TODO:
// The simplest heuristic for alignment is to align by value
// size, but that doesn't work for "bigger than int" types,
// for example, long long may very well have long alignment
// So, we introduce separate alignment handling, but having
// formal support for that is different from actually supporting
// particular (or any) ABI.
switch
(
val_type
)
{
case
BYTEARRAY_TYPECODE
:
case
'b'
:
case
'B'
:
align
=
size
=
1
;
break
;
case
'h'
:
case
'H'
:
align
=
size
=
sizeof
(
short
);
break
;
case
'i'
:
case
'I'
:
align
=
size
=
sizeof
(
int
);
break
;
case
'l'
:
case
'L'
:
align
=
size
=
sizeof
(
long
);
break
;
case
'q'
:
case
'Q'
:
// TODO: This is for x86
align
=
sizeof
(
int
);
size
=
sizeof
(
long
long
);
break
;
}
}
}
return
-
1
;
if
(
palign
!=
NULL
)
{
*
palign
=
align
;
}
return
size
;
}
mp_obj_t
mp_binary_get_val_array
(
char
typecode
,
void
*
p
,
int
index
)
{
...
...
@@ -80,48 +99,17 @@ mp_obj_t mp_binary_get_val_array(char typecode, void *p, int index) {
#define is_signed(typecode) (typecode > 'Z')
mp_obj_t
mp_binary_get_val
(
char
struct_type
,
char
val_type
,
byte
**
ptr
)
{
byte
*
p
=
*
ptr
;
uint
size
=
0
;
switch
(
struct_type
)
{
case
'<'
:
case
'>'
:
switch
(
val_type
)
{
case
'b'
:
case
'B'
:
size
=
1
;
break
;
case
'h'
:
case
'H'
:
size
=
2
;
break
;
case
'i'
:
case
'I'
:
size
=
4
;
break
;
case
'l'
:
case
'L'
:
size
=
4
;
break
;
}
break
;
case
'@'
:
{
// TODO:
// The simplest heuristic for alignment is to align by value
// size, but that doesn't work for "bigger than int" types,
// for example, long long may very well have long alignment
// So, we introduce separate alignment handling, but having
// formal support for that is different from actually supporting
// particular (or any) ABI.
uint
align
=
0
;
switch
(
val_type
)
{
case
'b'
:
case
'B'
:
align
=
size
=
1
;
break
;
case
'h'
:
case
'H'
:
align
=
size
=
sizeof
(
short
);
break
;
case
'i'
:
case
'I'
:
align
=
size
=
sizeof
(
int
);
break
;
case
'l'
:
case
'L'
:
align
=
size
=
sizeof
(
long
);
break
;
}
// Make pointer aligned
p
=
(
byte
*
)(((
machine_uint_t
)
p
+
align
-
1
)
&
~
(
align
-
1
));
#if MP_ENDIANNESS_LITTLE
struct_type
=
'<'
;
#else
struct_type
=
'>'
;
#endif
break
;
}
uint
align
;
int
size
=
mp_binary_get_size
(
struct_type
,
val_type
,
&
align
);
if
(
struct_type
==
'@'
)
{
// Make pointer aligned
p
=
(
byte
*
)(((
machine_uint_t
)
p
+
align
-
1
)
&
~
(
align
-
1
));
#if MP_ENDIANNESS_LITTLE
struct_type
=
'<'
;
#else
struct_type
=
'>'
;
#endif
}
int
delta
;
...
...
@@ -150,6 +138,45 @@ mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr) {
}
}
void
mp_binary_set_val
(
char
struct_type
,
char
val_type
,
mp_obj_t
val_in
,
byte
**
ptr
)
{
byte
*
p
=
*
ptr
;
uint
align
;
int
size
=
mp_binary_get_size
(
struct_type
,
val_type
,
&
align
);
if
(
struct_type
==
'@'
)
{
// Make pointer aligned
p
=
(
byte
*
)(((
machine_uint_t
)
p
+
align
-
1
)
&
~
(
align
-
1
));
#if MP_ENDIANNESS_LITTLE
struct_type
=
'<'
;
#else
struct_type
=
'>'
;
#endif
}
#if MP_ENDIANNESS_BIG
#error Not implemented
#endif
machine_int_t
val
=
mp_obj_int_get_checked
(
val_in
);
byte
*
in
=
(
byte
*
)
&
val
;
int
in_delta
,
out_delta
;
uint
val_sz
=
MIN
(
size
,
sizeof
(
val
));
if
(
struct_type
==
'>'
)
{
in_delta
=
-
1
;
out_delta
=
1
;
in
+=
val_sz
-
1
;
}
else
{
in_delta
=
out_delta
=
1
;
}
for
(
uint
i
=
val_sz
;
i
>
0
;
i
--
)
{
*
p
=
*
in
;
p
+=
out_delta
;
in
+=
in_delta
;
}
*
ptr
+=
size
;
}
void
mp_binary_set_val_array
(
char
typecode
,
void
*
p
,
int
index
,
mp_obj_t
val_in
)
{
switch
(
typecode
)
{
#if MICROPY_ENABLE_FLOAT
...
...
py/binary.h
View file @
27dd4710
...
...
@@ -2,8 +2,9 @@
// (underlyingly they're same).
#define BYTEARRAY_TYPECODE 0
int
mp_binary_get_size
(
char
typecode
);
int
mp_binary_get_size
(
char
struct_type
,
char
val_type
,
uint
*
palign
);
mp_obj_t
mp_binary_get_val_array
(
char
typecode
,
void
*
p
,
int
index
);
mp_obj_t
mp_binary_get_val
(
char
struct_type
,
char
val_type
,
byte
**
ptr
);
void
mp_binary_set_val_array
(
char
typecode
,
void
*
p
,
int
index
,
mp_obj_t
val_in
);
void
mp_binary_set_val_array_from_int
(
char
typecode
,
void
*
p
,
int
index
,
machine_int_t
val
);
mp_obj_t
mp_binary_get_val
(
char
struct_type
,
char
val_type
,
byte
**
ptr
);
void
mp_binary_set_val
(
char
struct_type
,
char
val_type
,
mp_obj_t
val_in
,
byte
**
ptr
);
py/modstruct.c
View file @
27dd4710
...
...
@@ -6,6 +6,7 @@
#include
"obj.h"
#include
"builtin.h"
#include
"objtuple.h"
#include
"objstr.h"
#include
"binary.h"
#if MICROPY_ENABLE_MOD_STRUCT
...
...
@@ -37,12 +38,14 @@ STATIC uint calcsize_items(const char *fmt) {
STATIC
mp_obj_t
struct_calcsize
(
mp_obj_t
fmt_in
)
{
const
char
*
fmt
=
mp_obj_str_get_str
(
fmt_in
);
char
fmt_type
=
get_fmt_type
(
&
fmt
);
(
void
)
fmt_type
;
machine_uint_t
size
;
for
(
size
=
0
;
*
fmt
;
fmt
++
)
{
int
sz
=
mp_binary_get_size
(
*
fmt
);
uint
align
;
int
sz
=
mp_binary_get_size
(
fmt_type
,
*
fmt
,
&
align
);
// TODO
assert
(
sz
!=
-
1
);
// Apply alignment
size
=
(
size
+
align
-
1
)
&
~
(
align
-
1
);
size
+=
sz
;
}
return
MP_OBJ_NEW_SMALL_INT
(
size
);
...
...
@@ -67,9 +70,26 @@ STATIC mp_obj_t struct_unpack(mp_obj_t fmt_in, mp_obj_t data_in) {
}
MP_DEFINE_CONST_FUN_OBJ_2
(
struct_unpack_obj
,
struct_unpack
);
STATIC
mp_obj_t
struct_pack
(
uint
n_args
,
mp_obj_t
*
args
)
{
// TODO: "The arguments must match the values required by the format exactly."
const
char
*
fmt
=
mp_obj_str_get_str
(
args
[
0
]);
char
fmt_type
=
get_fmt_type
(
&
fmt
);
int
size
=
MP_OBJ_SMALL_INT_VALUE
(
struct_calcsize
(
args
[
0
]));
byte
*
p
;
mp_obj_t
res
=
mp_obj_str_builder_start
(
&
mp_type_bytes
,
size
,
&
p
);
memset
(
p
,
0
,
size
);
for
(
uint
i
=
1
;
i
<
n_args
;
i
++
)
{
mp_binary_set_val
(
fmt_type
,
*
fmt
++
,
args
[
i
],
&
p
);
}
return
res
;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN
(
struct_pack_obj
,
1
,
-
1
,
struct_pack
);
STATIC
const
mp_map_elem_t
mp_module_struct_globals_table
[]
=
{
{
MP_OBJ_NEW_QSTR
(
MP_QSTR___name__
),
MP_OBJ_NEW_QSTR
(
MP_QSTR_struct
)
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_calcsize
),
(
mp_obj_t
)
&
struct_calcsize_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_pack
),
(
mp_obj_t
)
&
struct_pack_obj
},
{
MP_OBJ_NEW_QSTR
(
MP_QSTR_unpack
),
(
mp_obj_t
)
&
struct_unpack_obj
},
};
...
...
py/obj.h
View file @
27dd4710
...
...
@@ -418,7 +418,7 @@ machine_int_t mp_obj_int_get(mp_obj_t self_in);
#if MICROPY_ENABLE_FLOAT
mp_float_t
mp_obj_int_as_float
(
mp_obj_t
self_in
);
#endif
// Will rai
n
s exception if value doesn't fit into machine_int_t
// Will rais
e
exception if value doesn't fit into machine_int_t
machine_int_t
mp_obj_int_get_checked
(
mp_obj_t
self_in
);
// exception
...
...
py/objarray.c
View file @
27dd4710
...
...
@@ -121,7 +121,7 @@ STATIC mp_obj_t array_append(mp_obj_t self_in, mp_obj_t arg) {
assert
(
MP_OBJ_IS_TYPE
(
self_in
,
&
mp_type_array
)
||
MP_OBJ_IS_TYPE
(
self_in
,
&
mp_type_bytearray
));
mp_obj_array_t
*
self
=
self_in
;
if
(
self
->
free
==
0
)
{
int
item_sz
=
mp_binary_get_size
(
self
->
typecode
);
int
item_sz
=
mp_binary_get_size
(
'@'
,
self
->
typecode
,
NULL
);
// TODO: alloc policy
self
->
free
=
8
;
self
->
items
=
m_realloc
(
self
->
items
,
item_sz
*
self
->
len
,
item_sz
*
(
self
->
len
+
self
->
free
));
...
...
@@ -154,7 +154,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
STATIC
machine_int_t
array_get_buffer
(
mp_obj_t
o_in
,
mp_buffer_info_t
*
bufinfo
,
int
flags
)
{
mp_obj_array_t
*
o
=
o_in
;
bufinfo
->
buf
=
o
->
items
;
bufinfo
->
len
=
o
->
len
*
mp_binary_get_size
(
o
->
typecode
);
bufinfo
->
len
=
o
->
len
*
mp_binary_get_size
(
'@'
,
o
->
typecode
,
NULL
);
bufinfo
->
typecode
=
o
->
typecode
;
return
0
;
}
...
...
@@ -190,7 +190,7 @@ const mp_obj_type_t mp_type_bytearray = {
};
STATIC
mp_obj_array_t
*
array_new
(
char
typecode
,
uint
n
)
{
int
typecode_size
=
mp_binary_get_size
(
typecode
);
int
typecode_size
=
mp_binary_get_size
(
'@'
,
typecode
,
NULL
);
if
(
typecode_size
<=
0
)
{
nlr_raise
(
mp_obj_new_exception_msg
(
&
mp_type_ValueError
,
"bad typecode"
));
}
...
...
py/objstr.c
View file @
27dd4710
...
...
@@ -1415,6 +1415,7 @@ mp_obj_t mp_obj_str_builder_start(const mp_obj_type_t *type, uint len, byte **da
mp_obj_str_t
*
o
=
m_new_obj
(
mp_obj_str_t
);
o
->
base
.
type
=
type
;
o
->
len
=
len
;
o
->
hash
=
0
;
byte
*
p
=
m_new
(
byte
,
len
+
1
);
o
->
data
=
p
;
*
data
=
p
;
...
...
py/qstrdefs.h
View file @
27dd4710
...
...
@@ -139,16 +139,10 @@ Q(staticmethod)
Q
(
sum
)
Q
(
super
)
Q
(
str
)
#if MICROPY_ENABLE_MOD_STRUCT
Q
(
struct
)
#endif
Q
(
sys
)
Q
(
to_bytes
)
Q
(
tuple
)
Q
(
type
)
#if MICROPY_ENABLE_MOD_STRUCT
Q
(
unpack
)
#endif
Q
(
value
)
Q
(
zip
)
...
...
@@ -299,6 +293,12 @@ Q(version)
Q
(
version_info
)
#endif
#if MICROPY_ENABLE_MOD_STRUCT
Q
(
struct
)
Q
(
pack
)
Q
(
unpack
)
#endif
#if MICROPY_ENABLE_PROPERTY
Q
(
property
)
Q
(
getter
)
...
...
stmhal/adc.c
View file @
27dd4710
...
...
@@ -169,7 +169,7 @@ STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_
mp_buffer_info_t
bufinfo
;
mp_get_buffer_raise
(
buf_in
,
&
bufinfo
,
MP_BUFFER_WRITE
);
int
typesize
=
mp_binary_get_size
(
bufinfo
.
typecode
);
int
typesize
=
mp_binary_get_size
(
'@'
,
bufinfo
.
typecode
,
NULL
);
// Init TIM6 at the required frequency (in Hz)
timer_tim6_init
(
mp_obj_get_int
(
freq_in
));
...
...
tests/basics/struct1.py
View file @
27dd4710
...
...
@@ -6,3 +6,13 @@ print(struct.unpack(">bI", b"\x80\0\0\x01\0"))
# 32-bit little-endian specific
#print(struct.unpack("bI", b"\x80\xaa\x55\xaa\0\0\x01\0"))
print
(
struct
.
pack
(
"<i"
,
1
))
print
(
struct
.
pack
(
">i"
,
1
))
print
(
struct
.
pack
(
"<h"
,
1
))
print
(
struct
.
pack
(
">h"
,
1
))
print
(
struct
.
pack
(
"<b"
,
1
))
print
(
struct
.
pack
(
">b"
,
1
))
print
(
struct
.
pack
(
"<bI"
,
-
128
,
256
))
print
(
struct
.
pack
(
">bI"
,
-
128
,
256
))
unix/modffi.c
View file @
27dd4710
...
...
@@ -63,7 +63,8 @@ STATIC ffi_type *char2ffi_type(char c)
case
'L'
:
return
&
ffi_type_ulong
;
case
'f'
:
return
&
ffi_type_float
;
case
'd'
:
return
&
ffi_type_double
;
case
'p'
:
case
'p'
:
// Deprecated - conflicts with struct module
case
'P'
:
case
's'
:
return
&
ffi_type_pointer
;
case
'v'
:
return
&
ffi_type_void
;
default:
return
NULL
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment