Merge branch 'master' of github.com:micropython/micropython
Conflicts: py/objstr.c py/py.mk py/stream.c unix/main.c unix/socket.c
This commit is contained in:
commit
12eaccacda
@ -1,22 +1,32 @@
|
||||
mod = rawsocket
|
||||
s = mod.socket()
|
||||
try:
|
||||
import rawsocket as _socket
|
||||
except:
|
||||
import _socket
|
||||
|
||||
|
||||
s = _socket.socket()
|
||||
|
||||
if 1:
|
||||
ai = mod.getaddrinfo("google.com", 80)
|
||||
ai = _socket.getaddrinfo("google.com", 80)
|
||||
print("Address infos:", ai)
|
||||
addr = ai[0][4]
|
||||
else:
|
||||
# Deprecated way to construct connection address
|
||||
addr = mod.sockaddr_in()
|
||||
# Deprecated ways to construct connection address
|
||||
addr = _socket.sockaddr_in()
|
||||
addr.sin_family = 2
|
||||
#addr.sin_addr = (0x0100 << 16) + 0x007f
|
||||
#addr.sin_addr = (0x7f00 << 16) + 0x0001
|
||||
#addr.sin_addr = mod.inet_aton("127.0.0.1")
|
||||
addr.sin_addr = mod.gethostbyname("google.com")
|
||||
addr.sin_port = mod.htons(80)
|
||||
#addr.sin_addr = _socket.inet_aton("127.0.0.1")
|
||||
addr.sin_addr = _socket.gethostbyname("google.com")
|
||||
addr.sin_port = _socket.htons(80)
|
||||
|
||||
print("Connect address:", addr)
|
||||
s.connect(addr)
|
||||
|
||||
s.write("GET / HTTP/1.0\n\n")
|
||||
print(s.readall())
|
||||
if 0:
|
||||
# MicroPython rawsocket module supports file interface directly
|
||||
s.write("GET / HTTP/1.0\n\n")
|
||||
print(s.readall())
|
||||
else:
|
||||
s.send(b"GET / HTTP/1.0\n\n")
|
||||
print(s.recv(4096))
|
||||
|
@ -1,7 +1,18 @@
|
||||
mod = rawsocket
|
||||
s = mod.socket()
|
||||
try:
|
||||
import rawsocket as socket
|
||||
except:
|
||||
import socket
|
||||
|
||||
ai = mod.getaddrinfo("127.0.0.1", 8080)
|
||||
|
||||
CONTENT = """\
|
||||
HTTP/1.0 200 OK
|
||||
|
||||
Hello #{} from MicroPython!
|
||||
"""
|
||||
|
||||
s = socket.socket()
|
||||
|
||||
ai = socket.getaddrinfo("127.0.0.1", 8080)
|
||||
print("Bind address info:", ai)
|
||||
addr = ai[0][4]
|
||||
|
||||
@ -17,12 +28,13 @@ while True:
|
||||
print("Client address:", client_addr)
|
||||
print("Client socket:", client_s)
|
||||
print("Request:")
|
||||
if 0:
|
||||
# MicroPython rawsocket module supports file interface directly
|
||||
print(client_s.read(4096))
|
||||
#print(client_s.readall())
|
||||
client_s.write("""\
|
||||
HTTP/1.0 200 OK
|
||||
|
||||
Hello #{} from MicroPython!
|
||||
""".format(counter))
|
||||
client_s.write(CONTENT.format(counter))
|
||||
else:
|
||||
print(client_s.recv(4096))
|
||||
client_s.send(bytes(CONTENT.format(counter), "ascii"))
|
||||
client_s.close()
|
||||
counter += 1
|
||||
|
12
py/builtin.c
12
py/builtin.c
@ -350,3 +350,15 @@ static mp_obj_t mp_builtin_str(mp_obj_t o_in) {
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_str_obj, mp_builtin_str);
|
||||
|
||||
// TODO: This should be type, this is just quick CPython compat hack
|
||||
static mp_obj_t mp_builtin_bytes(uint n_args, const mp_obj_t *args) {
|
||||
if (!MP_OBJ_IS_QSTR(args[0]) && !MP_OBJ_IS_TYPE(args[0], &str_type)) {
|
||||
assert(0);
|
||||
}
|
||||
// Currently, MicroPython strings are mix between CPython byte and unicode
|
||||
// strings. So, conversion is null so far.
|
||||
return args[0];
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_bytes_obj, 1, 3, mp_builtin_bytes);
|
||||
|
@ -5,6 +5,7 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin___repl_print___obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_abs_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_all_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_any_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_bytes_obj); // Temporary hack
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_callable_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_chr_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_divmod_obj);
|
||||
|
12
py/obj.c
12
py/obj.c
@ -28,6 +28,8 @@ mp_obj_t mp_obj_get_type(mp_obj_t o_in) {
|
||||
const char *mp_obj_get_type_str(mp_obj_t o_in) {
|
||||
if (MP_OBJ_IS_SMALL_INT(o_in)) {
|
||||
return "int";
|
||||
} else if (MP_OBJ_IS_QSTR(o_in)) {
|
||||
return "str";
|
||||
} else {
|
||||
mp_obj_base_t *o = o_in;
|
||||
return o->type->name;
|
||||
@ -222,7 +224,9 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) {
|
||||
#endif
|
||||
|
||||
qstr mp_obj_get_qstr(mp_obj_t arg) {
|
||||
if (MP_OBJ_IS_TYPE(arg, &str_type)) {
|
||||
if (MP_OBJ_IS_QSTR(arg)) {
|
||||
return MP_OBJ_QSTR_VALUE(arg);
|
||||
} else if (MP_OBJ_IS_TYPE(arg, &str_type)) {
|
||||
return mp_obj_str_get(arg);
|
||||
} else {
|
||||
assert(0);
|
||||
@ -286,3 +290,9 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
|
||||
}
|
||||
return MP_OBJ_NEW_SMALL_INT(len);
|
||||
}
|
||||
|
||||
// Return input argument. Useful as .getiter for objects which are
|
||||
// their own iterators, etc.
|
||||
mp_obj_t mp_identity(mp_obj_t self) {
|
||||
return self;
|
||||
}
|
||||
|
5
py/obj.h
5
py/obj.h
@ -351,6 +351,8 @@ extern const mp_obj_type_t fun_native_type;
|
||||
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);
|
||||
|
||||
// generator
|
||||
extern const mp_obj_type_t gen_instance_type;
|
||||
|
||||
@ -374,3 +376,6 @@ typedef struct _mp_obj_classmethod_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t fun;
|
||||
} mp_obj_classmethod_t;
|
||||
|
||||
// sequence helpers
|
||||
void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void *dest);
|
||||
|
@ -153,13 +153,8 @@ static mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
return NULL;
|
||||
}
|
||||
int n = MP_OBJ_SMALL_INT_VALUE(rhs);
|
||||
int len = o->len;
|
||||
mp_obj_list_t *s = list_new(len * n);
|
||||
mp_obj_t *dest = s->items;
|
||||
for (int i = 0; i < n; i++) {
|
||||
memcpy(dest, o->items, sizeof(mp_obj_t) * len);
|
||||
dest += len;
|
||||
}
|
||||
mp_obj_list_t *s = list_new(o->len * n);
|
||||
mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items);
|
||||
return s;
|
||||
}
|
||||
case RT_COMPARE_OP_EQUAL:
|
||||
|
83
py/objstr.c
83
py/objstr.c
@ -65,9 +65,8 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
// TODO: need predicate to check for int-like type (bools are such for example)
|
||||
// ["no", "yes"][1 == 2] is common idiom
|
||||
if (MP_OBJ_IS_SMALL_INT(rhs_in)) {
|
||||
// TODO: This implements byte string access for single index so far
|
||||
// TODO: Handle negative indexes.
|
||||
return mp_obj_new_int(lhs_data[mp_obj_get_int(rhs_in)]);
|
||||
uint index = mp_get_index(lhs->base.type, lhs_len, rhs_in);
|
||||
return mp_obj_new_str(qstr_from_strn((const char*)lhs_data + index, 1));
|
||||
#if MICROPY_ENABLE_SLICE
|
||||
} else if (MP_OBJ_IS_TYPE(rhs_in, &slice_type)) {
|
||||
machine_int_t start, stop, step;
|
||||
@ -122,6 +121,16 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
return mp_const_false;
|
||||
}
|
||||
break;
|
||||
case RT_BINARY_OP_MULTIPLY:
|
||||
{
|
||||
if (!MP_OBJ_IS_SMALL_INT(rhs_in)) {
|
||||
return NULL;
|
||||
}
|
||||
int n = MP_OBJ_SMALL_INT_VALUE(rhs_in);
|
||||
char *s = m_new(char, lhs_len * n);
|
||||
mp_seq_multiply(lhs_data, sizeof(*lhs_data), lhs_len, n, s);
|
||||
return MP_OBJ_NEW_QSTR(qstr_from_strn_take(s, lhs_len * n, lhs_len * n));
|
||||
}
|
||||
}
|
||||
|
||||
return MP_OBJ_NULL; // op not supported
|
||||
@ -184,6 +193,45 @@ bad_arg:
|
||||
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "?str.join expecting a list of str's"));
|
||||
}
|
||||
|
||||
#define is_ws(c) ((c) == ' ' || (c) == '\t')
|
||||
|
||||
static mp_obj_t str_split(uint n_args, const mp_obj_t *args) {
|
||||
int splits = -1;
|
||||
mp_obj_t sep = mp_const_none;
|
||||
if (n_args > 1) {
|
||||
sep = args[1];
|
||||
if (n_args > 2) {
|
||||
splits = MP_OBJ_SMALL_INT_VALUE(args[2]);
|
||||
}
|
||||
}
|
||||
assert(sep == mp_const_none);
|
||||
(void)sep; // unused; to hush compiler warning
|
||||
mp_obj_t res = mp_obj_new_list(0, NULL);
|
||||
const char *s = qstr_str(mp_obj_str_get(args[0]));
|
||||
const char *start;
|
||||
|
||||
// Initial whitespace is not counted as split, so we pre-do it
|
||||
while (is_ws(*s)) s++;
|
||||
while (*s && splits != 0) {
|
||||
start = s;
|
||||
while (*s != 0 && !is_ws(*s)) s++;
|
||||
rt_list_append(res, MP_OBJ_NEW_QSTR(qstr_from_strn(start, s - start)));
|
||||
if (*s == 0) {
|
||||
break;
|
||||
}
|
||||
while (is_ws(*s)) s++;
|
||||
if (splits > 0) {
|
||||
splits--;
|
||||
}
|
||||
}
|
||||
|
||||
if (*s != 0) {
|
||||
rt_list_append(res, MP_OBJ_NEW_QSTR(qstr_from_str(s)));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool chr_in_str(const char* const str, const size_t str_len, const char c) {
|
||||
for (size_t i = 0; i < str_len; i++) {
|
||||
if (str[i] == c) {
|
||||
@ -195,16 +243,8 @@ static bool chr_in_str(const char* const str, const size_t str_len, const char c
|
||||
|
||||
static mp_obj_t str_find(uint n_args, const mp_obj_t *args) {
|
||||
assert(2 <= n_args && n_args <= 4);
|
||||
assert(MP_OBJ_IS_TYPE(args[0], &str_type));
|
||||
if (!MP_OBJ_IS_TYPE(args[1], &str_type)) {
|
||||
nlr_jump(mp_obj_new_exception_msg_1_arg(
|
||||
MP_QSTR_TypeError,
|
||||
"Can't convert '%s' object to str implicitly",
|
||||
mp_obj_get_type_str(args[1])));
|
||||
}
|
||||
|
||||
const char* haystack = qstr_str(((mp_obj_str_t*)args[0])->qstr);
|
||||
const char* needle = qstr_str(((mp_obj_str_t*)args[1])->qstr);
|
||||
const char* haystack = qstr_str(mp_obj_str_get(args[0]));
|
||||
const char* needle = qstr_str(mp_obj_str_get(args[1]));
|
||||
|
||||
size_t haystack_len = strlen(haystack);
|
||||
size_t needle_len = strlen(needle);
|
||||
@ -242,14 +282,11 @@ mp_obj_t str_strip(uint n_args, const mp_obj_t *args) {
|
||||
if (n_args == 1) {
|
||||
chars_to_del = whitespace;
|
||||
} else {
|
||||
assert(MP_OBJ_IS_TYPE(args[1], &str_type));
|
||||
mp_obj_str_t *chars_to_del_obj = args[1];
|
||||
chars_to_del = qstr_str(chars_to_del_obj->qstr);
|
||||
chars_to_del = qstr_str(mp_obj_str_get(args[1]));
|
||||
}
|
||||
|
||||
const size_t chars_to_del_len = strlen(chars_to_del);
|
||||
mp_obj_str_t *self = args[0];
|
||||
const char *orig_str = qstr_str(self->qstr);
|
||||
const char *orig_str = qstr_str(mp_obj_str_get(args[0]));
|
||||
const size_t orig_str_len = strlen(orig_str);
|
||||
|
||||
size_t first_good_char_pos = 0;
|
||||
@ -307,12 +344,14 @@ mp_obj_t str_format(uint n_args, const mp_obj_t *args) {
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj, 2, 4, str_find);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_split_obj, 1, 3, str_split);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj, 1, 2, str_strip);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, str_format);
|
||||
|
||||
static const mp_method_t str_type_methods[] = {
|
||||
{ "find", &str_find_obj },
|
||||
{ "join", &str_join_obj },
|
||||
{ "split", &str_split_obj },
|
||||
{ "strip", &str_strip_obj },
|
||||
{ "format", &str_format_obj },
|
||||
{ NULL, NULL }, // end-of-list sentinel
|
||||
@ -335,9 +374,15 @@ mp_obj_t mp_obj_new_str(qstr qstr) {
|
||||
}
|
||||
|
||||
qstr mp_obj_str_get(mp_obj_t self_in) {
|
||||
assert(MP_OBJ_IS_TYPE(self_in, &str_type));
|
||||
if (MP_OBJ_IS_QSTR(self_in)) {
|
||||
return MP_OBJ_QSTR_VALUE(self_in);
|
||||
}
|
||||
if (MP_OBJ_IS_TYPE(self_in, &str_type)) {
|
||||
mp_obj_str_t *self = self_in;
|
||||
return self->qstr;
|
||||
}
|
||||
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "Can't convert '%s' object to str implicitly",
|
||||
mp_obj_get_type_str(self_in)));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
1
py/py.mk
1
py/py.mk
@ -97,6 +97,7 @@ PY_O_BASENAME = \
|
||||
objtuple.o \
|
||||
objtype.o \
|
||||
objzip.o \
|
||||
sequence.o \
|
||||
stream.o \
|
||||
builtin.o \
|
||||
builtinimport.o \
|
||||
|
@ -40,6 +40,7 @@ Q(any)
|
||||
Q(array)
|
||||
Q(bool)
|
||||
Q(bytearray)
|
||||
Q(bytes)
|
||||
Q(callable)
|
||||
Q(chr)
|
||||
Q(complex)
|
||||
|
@ -130,6 +130,7 @@ void rt_init(void) {
|
||||
mp_map_add_qstr(&map_builtins, MP_QSTR_abs, (mp_obj_t)&mp_builtin_abs_obj);
|
||||
mp_map_add_qstr(&map_builtins, MP_QSTR_all, (mp_obj_t)&mp_builtin_all_obj);
|
||||
mp_map_add_qstr(&map_builtins, MP_QSTR_any, (mp_obj_t)&mp_builtin_any_obj);
|
||||
mp_map_add_qstr(&map_builtins, MP_QSTR_bytes, (mp_obj_t)&mp_builtin_bytes_obj);
|
||||
mp_map_add_qstr(&map_builtins, MP_QSTR_callable, (mp_obj_t)&mp_builtin_callable_obj);
|
||||
mp_map_add_qstr(&map_builtins, MP_QSTR_chr, (mp_obj_t)&mp_builtin_chr_obj);
|
||||
mp_map_add_qstr(&map_builtins, MP_QSTR_divmod, (mp_obj_t)&mp_builtin_divmod_obj);
|
||||
|
25
py/sequence.c
Normal file
25
py/sequence.c
Normal file
@ -0,0 +1,25 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "map.h"
|
||||
#include "runtime0.h"
|
||||
#include "runtime.h"
|
||||
|
||||
// Helpers for sequence types
|
||||
|
||||
// Implements backend of sequence * integer operation. Assumes elements are
|
||||
// memory-adjacent in sequence.
|
||||
void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void *dest) {
|
||||
for (int i = 0; i < times; i++) {
|
||||
uint copy_sz = item_sz * len;
|
||||
memcpy(dest, items, copy_sz);
|
||||
dest = (char*)dest + copy_sz;
|
||||
}
|
||||
}
|
14
py/stream.c
14
py/stream.c
@ -30,7 +30,8 @@ static mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
|
||||
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", error));
|
||||
} else {
|
||||
// TODO don't intern this string
|
||||
return mp_obj_new_str(qstr_from_strn_take(buf, sz, out_sz));
|
||||
buf = m_realloc(buf, sz, out_sz);
|
||||
return mp_obj_new_str(qstr_from_strn_take(buf, out_sz, out_sz));
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,9 +135,18 @@ static mp_obj_t stream_unbuffered_readline(uint n_args, const mp_obj_t *args) {
|
||||
}
|
||||
// TODO don't intern this string
|
||||
vstr_shrink(vstr);
|
||||
return mp_obj_new_str(qstr_from_strn_take(vstr_str(vstr), vstr->alloc, vstr_len(vstr)));
|
||||
return MP_OBJ_NEW_QSTR(qstr_from_strn_take(vstr_str(vstr), vstr->alloc, vstr_len(vstr)));
|
||||
}
|
||||
|
||||
mp_obj_t mp_stream_unbuffered_iter(mp_obj_t self) {
|
||||
mp_obj_t l_in = stream_unbuffered_readline(1, &self);
|
||||
const char *l = qstr_str(MP_OBJ_QSTR_VALUE(l_in));
|
||||
// TODO: \0
|
||||
if (*l != 0) {
|
||||
return l_in;
|
||||
}
|
||||
return mp_const_stop_iteration;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_read_obj, 1, 2, stream_read);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(mp_stream_readall_obj, stream_readall);
|
||||
|
@ -2,3 +2,6 @@ extern const mp_obj_fun_native_t mp_stream_read_obj;
|
||||
extern const mp_obj_fun_native_t mp_stream_readall_obj;
|
||||
extern const mp_obj_fun_native_t mp_stream_unbuffered_readline_obj;
|
||||
extern const mp_obj_fun_native_t mp_stream_write_obj;
|
||||
|
||||
// Iterator which uses mp_stream_unbuffered_readline_obj
|
||||
mp_obj_t mp_stream_unbuffered_iter(mp_obj_t self);
|
||||
|
@ -8,6 +8,19 @@ print(x)
|
||||
|
||||
print('123' + "456")
|
||||
|
||||
print('123' * 5)
|
||||
|
||||
print('abc'[1])
|
||||
print('abc'[-1])
|
||||
try:
|
||||
'abc'[100]
|
||||
except IndexError:
|
||||
print('caught')
|
||||
try:
|
||||
'abc'[-4]
|
||||
except IndexError:
|
||||
print('caught2')
|
||||
|
||||
# iter
|
||||
print(list('str'))
|
||||
|
||||
|
7
tests/basics/string_split.py
Normal file
7
tests/basics/string_split.py
Normal file
@ -0,0 +1,7 @@
|
||||
print("a b".split())
|
||||
print(" a b ".split(None))
|
||||
print(" a b ".split(None, 1))
|
||||
print(" a b ".split(None, 2))
|
||||
print(" a b c ".split(None, 1))
|
||||
print(" a b c ".split(None, 0))
|
||||
print(" a b c ".split(None, -1))
|
3
tests/io/file-iter.py
Normal file
3
tests/io/file-iter.py
Normal file
@ -0,0 +1,3 @@
|
||||
f = open("io/data/file1")
|
||||
for l in f:
|
||||
print(l)
|
@ -10,7 +10,14 @@ numpassed=0
|
||||
numfailed=0
|
||||
namefailed=
|
||||
|
||||
for infile in basics/*.py io/*.py
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
tests="basics/*.py io/*.py"
|
||||
else
|
||||
tests="$@"
|
||||
fi
|
||||
|
||||
for infile in $tests
|
||||
do
|
||||
basename=`basename $infile .py`
|
||||
outfile=${basename}.out
|
||||
|
31
unix/file.c
31
unix/file.c
@ -8,6 +8,7 @@
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "stream.h"
|
||||
|
||||
typedef struct _mp_obj_fdfile_t {
|
||||
@ -15,6 +16,8 @@ typedef struct _mp_obj_fdfile_t {
|
||||
int fd;
|
||||
} mp_obj_fdfile_t;
|
||||
|
||||
static const mp_obj_type_t rawfile_type;
|
||||
|
||||
static void fdfile_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
mp_obj_fdfile_t *self = self_in;
|
||||
print(env, "<io.FileIO %d>", self->fd);
|
||||
@ -45,6 +48,13 @@ 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_fdfile_t *fdfile_new(int fd) {
|
||||
mp_obj_fdfile_t *o = m_new_obj(mp_obj_fdfile_t);
|
||||
o->base.type = &rawfile_type;
|
||||
o->fd = fd;
|
||||
return o;
|
||||
}
|
||||
|
||||
static mp_obj_t fdfile_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
|
||||
mp_obj_fdfile_t *o = m_new_obj(mp_obj_fdfile_t);
|
||||
o->base.type = type_in;
|
||||
@ -81,11 +91,11 @@ static mp_obj_t fdfile_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
|
||||
}
|
||||
}
|
||||
|
||||
o->fd = open(fname, mode, 0644);
|
||||
if (o->fd == -1) {
|
||||
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_OSError, "[Errno %d]", (const char *)(machine_int_t)errno));
|
||||
int fd = open(fname, mode, 0644);
|
||||
if (fd == -1) {
|
||||
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", errno));
|
||||
}
|
||||
return o;
|
||||
return fdfile_new(fd);
|
||||
}
|
||||
|
||||
static const mp_method_t rawfile_type_methods[] = {
|
||||
@ -102,8 +112,8 @@ static const mp_obj_type_t rawfile_type = {
|
||||
"io.FileIO",
|
||||
.print = fdfile_print,
|
||||
.make_new = fdfile_make_new,
|
||||
.getiter = NULL,
|
||||
.iternext = NULL,
|
||||
.getiter = mp_identity,
|
||||
.iternext = mp_stream_unbuffered_iter,
|
||||
.stream_p = {
|
||||
.read = fdfile_read,
|
||||
.write = fdfile_write,
|
||||
@ -117,3 +127,12 @@ mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args) {
|
||||
return fdfile_make_new((mp_obj_t)&rawfile_type, n_args, 0, args);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_open_obj, 1, 2, mp_builtin_open);
|
||||
|
||||
void file_init() {
|
||||
rt_store_name(MP_QSTR_open, (mp_obj_t)&mp_builtin_open_obj);
|
||||
|
||||
mp_obj_t m_sys = mp_obj_new_module(MP_QSTR_sys);
|
||||
rt_store_attr(m_sys, MP_QSTR_stdin, fdfile_new(STDIN_FILENO));
|
||||
rt_store_attr(m_sys, MP_QSTR_stdout, fdfile_new(STDOUT_FILENO));
|
||||
rt_store_attr(m_sys, MP_QSTR_stderr, fdfile_new(STDERR_FILENO));
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#endif
|
||||
|
||||
extern const mp_obj_fun_native_t mp_builtin_open_obj;
|
||||
void file_init();
|
||||
void rawsocket_init();
|
||||
|
||||
static void execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bool is_repl) {
|
||||
@ -222,7 +223,8 @@ int main(int argc, char **argv) {
|
||||
rt_store_attr(m_sys, MP_QSTR_argv, py_argv);
|
||||
|
||||
rt_store_name(qstr_from_str("test"), test_obj_new(42));
|
||||
rt_store_name(MP_QSTR_open, (mp_obj_t)&mp_builtin_open_obj);
|
||||
|
||||
file_init();
|
||||
rawsocket_init();
|
||||
|
||||
// Here is some example code to create a class and instance of that class.
|
||||
|
@ -3,6 +3,9 @@
|
||||
Q(sys)
|
||||
Q(argv)
|
||||
Q(open)
|
||||
Q(stdin)
|
||||
Q(stdout)
|
||||
Q(stderr)
|
||||
Q(rawsocket)
|
||||
Q(socket)
|
||||
Q(sockaddr_in)
|
||||
|
@ -127,6 +127,41 @@ static mp_obj_t socket_accept(mp_obj_t self_in) {
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept);
|
||||
|
||||
static mp_obj_t socket_recv(uint n_args, const mp_obj_t *args) {
|
||||
mp_obj_socket_t *self = args[0];
|
||||
int sz = MP_OBJ_SMALL_INT_VALUE(args[1]);
|
||||
int flags = 0;
|
||||
|
||||
if (n_args > 2) {
|
||||
flags = MP_OBJ_SMALL_INT_VALUE(args[2]);
|
||||
}
|
||||
|
||||
char *buf = m_new(char, sz);
|
||||
int out_sz = recv(self->fd, buf, sz, flags);
|
||||
RAISE_ERRNO(out_sz, errno);
|
||||
|
||||
buf = m_realloc(buf, sz, out_sz);
|
||||
return MP_OBJ_NEW_QSTR(qstr_from_strn_take(buf, out_sz, out_sz));
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_recv_obj, 2, 3, socket_recv);
|
||||
|
||||
static mp_obj_t socket_send(uint n_args, const mp_obj_t *args) {
|
||||
mp_obj_socket_t *self = args[0];
|
||||
int flags = 0;
|
||||
|
||||
if (n_args > 2) {
|
||||
flags = MP_OBJ_SMALL_INT_VALUE(args[2]);
|
||||
}
|
||||
|
||||
const char *buf = qstr_str(mp_obj_str_get(args[1]));
|
||||
int sz = strlen(buf);
|
||||
int out_sz = send(self->fd, buf, sz, flags);
|
||||
RAISE_ERRNO(out_sz, errno);
|
||||
|
||||
return MP_OBJ_NEW_SMALL_INT((machine_int_t)out_sz);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_send_obj, 2, 3, socket_send);
|
||||
|
||||
static mp_obj_t socket_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
|
||||
int family = AF_INET;
|
||||
int type = SOCK_STREAM;
|
||||
@ -159,6 +194,8 @@ static const mp_method_t rawsocket_type_methods[] = {
|
||||
{ "bind", &socket_bind_obj },
|
||||
{ "listen", &socket_listen_obj },
|
||||
{ "accept", &socket_accept_obj },
|
||||
{ "recv", &socket_recv_obj },
|
||||
{ "send", &socket_send_obj },
|
||||
{ "close", &socket_close_obj },
|
||||
#if MICROPY_SOCKET_EXTRA
|
||||
{ "recv", &mp_stream_read_obj },
|
||||
@ -280,5 +317,4 @@ void rawsocket_init() {
|
||||
STORE_INT_CONST(m, SOCK_STREAM);
|
||||
STORE_INT_CONST(m, SOCK_DGRAM);
|
||||
STORE_INT_CONST(m, SOCK_RAW);
|
||||
rt_store_name(MP_QSTR_rawsocket, m);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user