diff --git a/examples/unix/sock-client.py b/examples/unix/sock-client.py index 08a39b196a..858420b99f 100644 --- a/examples/unix/sock-client.py +++ b/examples/unix/sock-client.py @@ -1,5 +1,5 @@ try: - import rawsocket as _socket + import microsocket as _socket except: import _socket diff --git a/examples/unix/sock-server.py b/examples/unix/sock-server.py index f08aede3c1..f99d7974a7 100644 --- a/examples/unix/sock-server.py +++ b/examples/unix/sock-server.py @@ -1,5 +1,5 @@ try: - import rawsocket as socket + import microsocket as socket except: import socket diff --git a/py/obj.c b/py/obj.c index e21596fdf5..e3e9dbfd55 100644 --- a/py/obj.c +++ b/py/obj.c @@ -253,3 +253,4 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) { mp_obj_t mp_identity(mp_obj_t self) { return self; } +MP_DEFINE_CONST_FUN_OBJ_1(mp_identity_obj, mp_identity); diff --git a/py/obj.h b/py/obj.h index f99bcc40e7..48d332e200 100644 --- a/py/obj.h +++ b/py/obj.h @@ -370,6 +370,7 @@ extern const mp_obj_type_t fun_bc_type; void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code); mp_obj_t mp_identity(mp_obj_t self); +MP_DECLARE_CONST_FUN_OBJ(mp_identity_obj); // super extern const mp_obj_type_t super_type; @@ -397,5 +398,9 @@ typedef struct _mp_obj_static_class_method_t { // sequence helpers void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void *dest); bool m_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, machine_uint_t *begin, machine_uint_t *end); -#define m_seq_copy(dest, src, len, item_sz) memcpy(dest, src, len * sizeof(item_sz)) +#define m_seq_copy(dest, src, len, item_t) memcpy(dest, src, len * sizeof(item_t)) +#define m_seq_cat(dest, src1, len1, src2, len2, item_t) { memcpy(dest, src1, len1 * sizeof(item_t)); memcpy(dest + len1, src2, len2 * sizeof(item_t)); } bool mp_seq_cmp_bytes(int op, const byte *data1, uint len1, const byte *data2, uint len2); +bool mp_seq_cmp_objs(int op, const mp_obj_t *items1, uint len1, const mp_obj_t *items2, uint len2); +mp_obj_t mp_seq_index_obj(const mp_obj_t *items, uint len, uint n_args, const mp_obj_t *args); +mp_obj_t mp_seq_count_obj(const mp_obj_t *items, uint len, mp_obj_t value); diff --git a/py/objlist.c b/py/objlist.c index 14f3a5760a..35bab2a398 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -75,51 +75,8 @@ static bool list_cmp_helper(int op, mp_obj_t self_in, mp_obj_t another_in) { } mp_obj_list_t *self = self_in; mp_obj_list_t *another = another_in; - if (op == RT_BINARY_OP_EQUAL && self->len != another->len) { - return false; - } - // Let's deal only with > & >= - if (op == RT_BINARY_OP_LESS || op == RT_BINARY_OP_LESS_EQUAL) { - mp_obj_t t = self; - self = another; - another = t; - if (op == RT_BINARY_OP_LESS) { - op = RT_BINARY_OP_MORE; - } else { - op = RT_BINARY_OP_MORE_EQUAL; - } - } - - int len = self->len < another->len ? self->len : another->len; - bool eq_status = true; // empty lists are equal - bool rel_status; - for (int i = 0; i < len; i++) { - eq_status = mp_obj_equal(self->items[i], another->items[i]); - if (op == RT_BINARY_OP_EQUAL && !eq_status) { - return false; - } - rel_status = (rt_binary_op(op, self->items[i], another->items[i]) == mp_const_true); - if (!eq_status && !rel_status) { - return false; - } - } - - // If we had tie in the last element... - if (eq_status) { - // ... and we have lists of different lengths... - if (self->len != another->len) { - if (self->len < another->len) { - // ... then longer list length wins (we deal only with >) - return false; - } - } else if (op == RT_BINARY_OP_MORE) { - // Otherwise, if we have strict relation, equality means failure - return false; - } - } - - return true; + return mp_seq_cmp_objs(op, self->items, self->len, another->items, another->len); } static mp_obj_t list_unary_op(int op, mp_obj_t self_in) { @@ -157,8 +114,7 @@ static mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { } mp_obj_list_t *p = rhs; mp_obj_list_t *s = list_new(o->len + p->len); - memcpy(s->items, o->items, sizeof(mp_obj_t) * o->len); - memcpy(s->items + o->len, p->items, sizeof(mp_obj_t) * p->len); + m_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); return s; } case RT_BINARY_OP_INPLACE_ADD: @@ -304,38 +260,14 @@ static mp_obj_t list_copy(mp_obj_t self_in) { static mp_obj_t list_count(mp_obj_t self_in, mp_obj_t value) { assert(MP_OBJ_IS_TYPE(self_in, &list_type)); mp_obj_list_t *self = self_in; - int count = 0; - for (int i = 0; i < self->len; i++) { - if (mp_obj_equal(self->items[i], value)) { - count++; - } - } - - return mp_obj_new_int(count); + return mp_seq_count_obj(self->items, self->len, value); } static mp_obj_t list_index(uint n_args, const mp_obj_t *args) { assert(2 <= n_args && n_args <= 4); assert(MP_OBJ_IS_TYPE(args[0], &list_type)); mp_obj_list_t *self = args[0]; - mp_obj_t *value = args[1]; - uint start = 0; - uint stop = self->len; - - if (n_args >= 3) { - start = mp_get_index(self->base.type, self->len, args[2]); - if (n_args >= 4) { - stop = mp_get_index(self->base.type, self->len, args[3]); - } - } - - for (uint i = start; i < stop; i++) { - if (mp_obj_equal(self->items[i], value)) { - return mp_obj_new_int(i); - } - } - - nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "object not in list")); + return mp_seq_index_obj(self->items, self->len, n_args, args); } static mp_obj_t list_insert(mp_obj_t self_in, mp_obj_t idx, mp_obj_t obj) { diff --git a/py/objtuple.c b/py/objtuple.c index 3e5041c9dd..7221db7746 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -74,6 +74,18 @@ static mp_obj_t tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m } } +// Don't pass RT_BINARY_OP_NOT_EQUAL here +static bool tuple_cmp_helper(int op, mp_obj_t self_in, mp_obj_t another_in) { + assert(MP_OBJ_IS_TYPE(self_in, &tuple_type)); + if (!MP_OBJ_IS_TYPE(another_in, &tuple_type)) { + return false; + } + mp_obj_tuple_t *self = self_in; + mp_obj_tuple_t *another = another_in; + + return mp_seq_cmp_objs(op, self->items, self->len, another->items, another->len); +} + static mp_obj_t tuple_unary_op(int op, mp_obj_t self_in) { mp_obj_tuple_t *self = self_in; switch (op) { @@ -102,6 +114,35 @@ static mp_obj_t tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { uint index = mp_get_index(o->base.type, o->len, rhs); return o->items[index]; } + case RT_BINARY_OP_ADD: + { + if (!MP_OBJ_IS_TYPE(rhs, &tuple_type)) { + return NULL; + } + mp_obj_tuple_t *p = rhs; + mp_obj_tuple_t *s = mp_obj_new_tuple(o->len + p->len, NULL); + m_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); + return s; + } + case RT_BINARY_OP_MULTIPLY: + { + if (!MP_OBJ_IS_SMALL_INT(rhs)) { + return NULL; + } + int n = MP_OBJ_SMALL_INT_VALUE(rhs); + mp_obj_tuple_t *s = mp_obj_new_tuple(o->len * n, NULL); + mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items); + return s; + } + case RT_BINARY_OP_EQUAL: + case RT_BINARY_OP_LESS: + case RT_BINARY_OP_LESS_EQUAL: + case RT_BINARY_OP_MORE: + case RT_BINARY_OP_MORE_EQUAL: + return MP_BOOL(tuple_cmp_helper(op, lhs, rhs)); + case RT_BINARY_OP_NOT_EQUAL: + return MP_BOOL(!tuple_cmp_helper(RT_BINARY_OP_EQUAL, lhs, rhs)); + default: // op not supported return NULL; @@ -112,6 +153,26 @@ static mp_obj_t tuple_getiter(mp_obj_t o_in) { return mp_obj_new_tuple_iterator(o_in, 0); } +static mp_obj_t tuple_count(mp_obj_t self_in, mp_obj_t value) { + assert(MP_OBJ_IS_TYPE(self_in, &tuple_type)); + mp_obj_tuple_t *self = self_in; + return mp_seq_count_obj(self->items, self->len, value); +} +static MP_DEFINE_CONST_FUN_OBJ_2(tuple_count_obj, tuple_count); + +static mp_obj_t tuple_index(uint n_args, const mp_obj_t *args) { + assert(MP_OBJ_IS_TYPE(args[0], &tuple_type)); + mp_obj_tuple_t *self = args[0]; + return mp_seq_index_obj(self->items, self->len, n_args, args); +} +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(tuple_index_obj, 2, 4, tuple_index); + +static const mp_method_t tuple_type_methods[] = { + { "count", &tuple_count_obj }, + { "index", &tuple_index_obj }, + { NULL, NULL }, // end-of-list sentinel +}; + const mp_obj_type_t tuple_type = { { &mp_const_type }, "tuple", @@ -120,6 +181,7 @@ const mp_obj_type_t tuple_type = { .unary_op = tuple_unary_op, .binary_op = tuple_binary_op, .getiter = tuple_getiter, + .methods = tuple_type_methods, }; // the zero-length tuple diff --git a/py/qstrdefs.h b/py/qstrdefs.h index 3d4f4e2488..680c4bcf73 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -37,6 +37,7 @@ Q(IndentationError) Q(IndexError) Q(KeyError) Q(NameError) +Q(NotImplementedError) Q(OSError) Q(SyntaxError) Q(TypeError) diff --git a/py/runtime.c b/py/runtime.c index 0ac470fbc2..aaac884d65 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -177,6 +177,7 @@ void rt_init(void) { mp_map_add_qstr(&map_builtins, MP_QSTR_OverflowError, mp_obj_new_exception(MP_QSTR_OverflowError)); mp_map_add_qstr(&map_builtins, MP_QSTR_OSError, mp_obj_new_exception(MP_QSTR_OSError)); mp_map_add_qstr(&map_builtins, MP_QSTR_AssertionError, mp_obj_new_exception(MP_QSTR_AssertionError)); + mp_map_add_qstr(&map_builtins, MP_QSTR_NotImplementedError, mp_obj_new_exception(MP_QSTR_NotImplementedError)); mp_map_add_qstr(&map_builtins, MP_QSTR_StopIteration, mp_obj_new_exception(MP_QSTR_StopIteration)); // built-in objects diff --git a/py/sequence.c b/py/sequence.c index 74b4fcfdf8..d8cfd9f3e9 100644 --- a/py/sequence.c +++ b/py/sequence.c @@ -91,3 +91,88 @@ bool mp_seq_cmp_bytes(int op, const byte *data1, uint len1, const byte *data2, u } return true; } + +// Special-case comparison function for sequences of mp_obj_t +// Don't pass RT_BINARY_OP_NOT_EQUAL here +bool mp_seq_cmp_objs(int op, const mp_obj_t *items1, uint len1, const mp_obj_t *items2, uint len2) { + if (op == RT_BINARY_OP_EQUAL && len1 != len2) { + return false; + } + + // Let's deal only with > & >= + if (op == RT_BINARY_OP_LESS || op == RT_BINARY_OP_LESS_EQUAL) { + SWAP(const mp_obj_t *, items1, items2); + SWAP(uint, len1, len2); + if (op == RT_BINARY_OP_LESS) { + op = RT_BINARY_OP_MORE; + } else { + op = RT_BINARY_OP_MORE_EQUAL; + } + } + + int len = len1 < len2 ? len1 : len2; + bool eq_status = true; // empty lists are equal + bool rel_status; + for (int i = 0; i < len; i++) { + eq_status = mp_obj_equal(items1[i], items2[i]); + if (op == RT_BINARY_OP_EQUAL && !eq_status) { + return false; + } + rel_status = (rt_binary_op(op, items1[i], items2[i]) == mp_const_true); + if (!eq_status && !rel_status) { + return false; + } + } + + // If we had tie in the last element... + if (eq_status) { + // ... and we have lists of different lengths... + if (len1 != len2) { + if (len1 < len2) { + // ... then longer list length wins (we deal only with >) + return false; + } + } else if (op == RT_BINARY_OP_MORE) { + // Otherwise, if we have strict relation, equality means failure + return false; + } + } + + return true; +} + +// Special-case of index() which searches for mp_obj_t +mp_obj_t mp_seq_index_obj(const mp_obj_t *items, uint len, uint n_args, const mp_obj_t *args) { + mp_obj_type_t *type = mp_obj_get_type(args[0]); + mp_obj_t *value = args[1]; + uint start = 0; + uint stop = len; + + if (n_args >= 3) { + start = mp_get_index(type, len, args[2]); + if (n_args >= 4) { + stop = mp_get_index(type, len, args[3]); + } + } + + for (uint i = start; i < stop; i++) { + if (mp_obj_equal(items[i], value)) { + // Common sense says this cannot overflow small int + return MP_OBJ_NEW_SMALL_INT(i); + } + } + + nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "object not in sequence")); +} + +mp_obj_t mp_seq_count_obj(const mp_obj_t *items, uint len, mp_obj_t value) { + uint count = 0; + for (uint i = 0; i < len; i++) { + if (mp_obj_equal(items[i], value)) { + count++; + } + } + + // Common sense says this cannot overflow small int + return MP_OBJ_NEW_SMALL_INT(count); +} diff --git a/tests/basics/tuple1.py b/tests/basics/tuple1.py index b64720b3eb..53eac2a306 100644 --- a/tests/basics/tuple1.py +++ b/tests/basics/tuple1.py @@ -14,3 +14,5 @@ except AttributeError: print(x[1:]) print(x[:-1]) print(x[2:3]) + +print(x + (10, 100, 10000)) diff --git a/tests/basics/tuple_compare.py b/tests/basics/tuple_compare.py new file mode 100644 index 0000000000..8bdb2bcf98 --- /dev/null +++ b/tests/basics/tuple_compare.py @@ -0,0 +1,50 @@ +print(() == ()) +print(() > ()) +print(() < ()) +print(() == (1,)) +print((1,) == ()) +print(() > (1,)) +print((1,) > ()) +print(() < (1,)) +print((1,) < ()) +print(() >= (1,)) +print((1,) >= ()) +print(() <= (1,)) +print((1,) <= ()) + +print((1,) == (1,)) +print((1,) != (1,)) +print((1,) == (2,)) +print((1,) == (1, 0,)) + +print((1,) > (1,)) +print((1,) > (2,)) +print((2,) > (1,)) +print((1, 0,) > (1,)) +print((1, -1,) > (1,)) +print((1,) > (1, 0,)) +print((1,) > (1, -1,)) + +print((1,) < (1,)) +print((2,) < (1,)) +print((1,) < (2,)) +print((1,) < (1, 0,)) +print((1,) < (1, -1,)) +print((1, 0,) < (1,)) +print((1, -1,) < (1,)) + +print((1,) >= (1,)) +print((1,) >= (2,)) +print((2,) >= (1,)) +print((1, 0,) >= (1,)) +print((1, -1,) >= (1,)) +print((1,) >= (1, 0,)) +print((1,) >= (1, -1,)) + +print((1,) <= (1,)) +print((2,) <= (1,)) +print((1,) <= (2,)) +print((1,) <= (1, 0,)) +print((1,) <= (1, -1,)) +print((1, 0,) <= (1,)) +print((1, -1,) <= (1,)) diff --git a/tests/basics/tuple_count.py b/tests/basics/tuple_count.py new file mode 100644 index 0000000000..7f42ede28c --- /dev/null +++ b/tests/basics/tuple_count.py @@ -0,0 +1,5 @@ +a = (1, 2, 3) +a = a + a + a +b = (0, 0, a, 0, a, 0) +print(a.count(2)) +print(b.count(a)) diff --git a/tests/basics/tuple_index.py b/tests/basics/tuple_index.py new file mode 100644 index 0000000000..1aef100d78 --- /dev/null +++ b/tests/basics/tuple_index.py @@ -0,0 +1,24 @@ +a = (1, 2, 3) +print(a.index(1)) +print(a.index(2)) +print(a.index(3)) +print(a.index(3, 2)) +try: + print(a.index(3, 2, 2)) +except ValueError: + print("Raised ValueError") +else: + print("Did not raise ValueError") + +a = a + a +b = (0, 0, a) +print(a.index(2)) +print(b.index(a)) +print(a.index(2, 2)) + +try: + a.index(2, 2, 2) +except ValueError: + print("Raised ValueError") +else: + print("Did not raise ValueError") diff --git a/tests/basics/tuple_mult.py b/tests/basics/tuple_mult.py new file mode 100644 index 0000000000..f8350f2f27 --- /dev/null +++ b/tests/basics/tuple_mult.py @@ -0,0 +1,4 @@ +print((0,) * 5) +a = (1, 2, 3) +c = a * 3 +print(c) diff --git a/tests/io/file-stdio.py b/tests/io/file-stdio.py new file mode 100644 index 0000000000..cbdb070163 --- /dev/null +++ b/tests/io/file-stdio.py @@ -0,0 +1,4 @@ +import sys + +print(sys.stdin.fileno()) +print(sys.stdout.fileno()) diff --git a/unix/ffi.c b/unix/ffi.c index b40e9a4ee6..b83fc120a9 100644 --- a/unix/ffi.c +++ b/unix/ffi.c @@ -71,7 +71,7 @@ static ffi_type *get_ffi_type(mp_obj_t o_in) { if (MP_OBJ_IS_STR(o_in)) { uint len; - const byte *s = mp_obj_str_get_data(o_in, &len); + const char *s = mp_obj_str_get_data(o_in, &len); ffi_type *t = char2ffi_type(*s); if (t != NULL) { return t; diff --git a/unix/file.c b/unix/file.c index 5249b5bba3..7bbe3bfd00 100644 --- a/unix/file.c +++ b/unix/file.c @@ -48,6 +48,12 @@ static mp_obj_t fdfile_close(mp_obj_t self_in) { } static MP_DEFINE_CONST_FUN_OBJ_1(fdfile_close_obj, fdfile_close); +static mp_obj_t fdfile_fileno(mp_obj_t self_in) { + mp_obj_fdfile_t *self = self_in; + return MP_OBJ_NEW_SMALL_INT(self->fd); +} +static MP_DEFINE_CONST_FUN_OBJ_1(fdfile_fileno_obj, fdfile_fileno); + static mp_obj_fdfile_t *fdfile_new(int fd) { mp_obj_fdfile_t *o = m_new_obj(mp_obj_fdfile_t); o->base.type = &rawfile_type; @@ -99,6 +105,7 @@ static mp_obj_t fdfile_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const } static const mp_method_t rawfile_type_methods[] = { + { "fileno", &fdfile_fileno_obj }, { "read", &mp_stream_read_obj }, { "readall", &mp_stream_readall_obj }, { "readline", &mp_stream_unbuffered_readline_obj}, diff --git a/unix/main.c b/unix/main.c index 9fb25a43e2..5fdfbc36aa 100644 --- a/unix/main.c +++ b/unix/main.c @@ -23,7 +23,7 @@ extern const mp_obj_fun_native_t mp_builtin_open_obj; void file_init(); -void rawsocket_init(); +void microsocket_init(); void time_init(); void ffi_init(); @@ -265,7 +265,7 @@ int main(int argc, char **argv) { rt_store_name(qstr_from_str("qstr_info"), rt_make_function_n(0, qstr_info)); file_init(); - rawsocket_init(); + microsocket_init(); #if MICROPY_MOD_TIME time_init(); #endif diff --git a/unix/qstrdefsport.h b/unix/qstrdefsport.h index 598f23bef2..9f28c607e2 100644 --- a/unix/qstrdefsport.h +++ b/unix/qstrdefsport.h @@ -12,4 +12,4 @@ Q(htons) Q(inet_aton) Q(gethostbyname) Q(getaddrinfo) -Q(rawsocket) +Q(microsocket) diff --git a/unix/socket.c b/unix/socket.c index 28749f3bef..eb4ea1e043 100644 --- a/unix/socket.c +++ b/unix/socket.c @@ -24,7 +24,7 @@ typedef struct _mp_obj_socket_t { int fd; } mp_obj_socket_t; -static const mp_obj_type_t rawsocket_type; +static const mp_obj_type_t microsocket_type; // Helper functions #define RAISE_ERRNO(err_flag, error_val) \ @@ -48,7 +48,7 @@ error: static mp_obj_socket_t *socket_new(int fd) { mp_obj_socket_t *o = m_new_obj(mp_obj_socket_t); - o->base.type = &rawsocket_type; + o->base.type = µsocket_type; o->fd = fd; return o; } @@ -84,6 +84,12 @@ static mp_obj_t socket_close(mp_obj_t self_in) { } static MP_DEFINE_CONST_FUN_OBJ_1(socket_close_obj, socket_close); +static mp_obj_t socket_fileno(mp_obj_t self_in) { + mp_obj_socket_t *self = self_in; + return MP_OBJ_NEW_SMALL_INT(self->fd); +} +static MP_DEFINE_CONST_FUN_OBJ_1(socket_fileno_obj, socket_fileno); + static mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { mp_obj_socket_t *self = self_in; buffer_info_t bufinfo; @@ -208,7 +214,9 @@ static mp_obj_t socket_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const return socket_new(fd); } -static const mp_method_t rawsocket_type_methods[] = { +static const mp_method_t microsocket_type_methods[] = { + { "fileno", &socket_fileno_obj }, + { "makefile", &mp_identity_obj }, { "read", &mp_stream_read_obj }, { "readall", &mp_stream_readall_obj }, { "readline", &mp_stream_unbuffered_readline_obj}, @@ -228,7 +236,7 @@ static const mp_method_t rawsocket_type_methods[] = { { NULL, NULL }, }; -static const mp_obj_type_t rawsocket_type = { +static const mp_obj_type_t microsocket_type = { { &mp_const_type }, "socket", .print = socket_print, @@ -239,7 +247,7 @@ static const mp_obj_type_t rawsocket_type = { .read = socket_read, .write = socket_write, }, - .methods = rawsocket_type_methods, + .methods = microsocket_type_methods, }; static mp_obj_t mod_socket_htons(mp_obj_t arg) { @@ -283,8 +291,8 @@ static mp_obj_t mod_socket_getaddrinfo(uint n_args, const mp_obj_t *args) { // getaddrinfo accepts port in string notation, so however // it may seem stupid, we need to convert int to str if (MP_OBJ_IS_SMALL_INT(args[1])) { - int port = MP_OBJ_SMALL_INT_VALUE(args[1]); - static char buf[20]; + int port = (short)MP_OBJ_SMALL_INT_VALUE(args[1]); + char buf[6]; sprintf(buf, "%d", port); serv = buf; } else { @@ -325,7 +333,7 @@ extern mp_obj_type_t sockaddr_in_type; #define C(name) { #name, name } -struct sym_entry { +static const struct sym_entry { const char *sym; int val; } constants[] = { @@ -351,9 +359,9 @@ struct sym_entry { #undef C -void rawsocket_init() { - mp_obj_t m = mp_obj_new_module(MP_QSTR_rawsocket); - rt_store_attr(m, MP_QSTR_socket, (mp_obj_t)&rawsocket_type); +void microsocket_init() { + mp_obj_t m = mp_obj_new_module(MP_QSTR_microsocket); + rt_store_attr(m, MP_QSTR_socket, (mp_obj_t)µsocket_type); #if MICROPY_SOCKET_EXTRA rt_store_attr(m, MP_QSTR_sockaddr_in, (mp_obj_t)&sockaddr_in_type); rt_store_attr(m, MP_QSTR_htons, (mp_obj_t)&mod_socket_htons_obj); @@ -361,7 +369,7 @@ void rawsocket_init() { rt_store_attr(m, MP_QSTR_gethostbyname, (mp_obj_t)&mod_socket_gethostbyname_obj); #endif rt_store_attr(m, MP_QSTR_getaddrinfo, (mp_obj_t)&mod_socket_getaddrinfo_obj); - for (struct sym_entry *p = constants; p->sym != NULL; p++) { + for (const struct sym_entry *p = constants; p->sym != NULL; p++) { rt_store_attr(m, QSTR_FROM_STR_STATIC(p->sym), MP_OBJ_NEW_SMALL_INT((machine_int_t)p->val)); } } diff --git a/unix/time.c b/unix/time.c index 9d8cf497c4..6dba9f0d09 100644 --- a/unix/time.c +++ b/unix/time.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include "misc.h" #include "mpconfig.h" @@ -23,8 +25,24 @@ static mp_obj_t mod_time_clock() { } static MP_DEFINE_CONST_FUN_OBJ_0(mod_time_clock_obj, mod_time_clock); +static mp_obj_t mod_time_sleep(mp_obj_t arg) { +#if MICROPY_ENABLE_FLOAT + struct timeval tv; + machine_float_t val = mp_obj_get_float(arg); + double ipart; + tv.tv_usec = round(modf(val, &ipart) * 1000000); + tv.tv_sec = ipart; + select(0, NULL, NULL, NULL, &tv); +#else + sleep(mp_obj_get_int(arg)); +#endif + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(mod_time_sleep_obj, mod_time_sleep); + void time_init() { mp_obj_t m = mp_obj_new_module(QSTR_FROM_STR_STATIC("time")); rt_store_attr(m, QSTR_FROM_STR_STATIC("time"), (mp_obj_t)&mod_time_time_obj); rt_store_attr(m, QSTR_FROM_STR_STATIC("clock"), (mp_obj_t)&mod_time_clock_obj); + rt_store_attr(m, QSTR_FROM_STR_STATIC("sleep"), (mp_obj_t)&mod_time_sleep_obj); }