Commit 12eaccac authored by Damien George's avatar Damien George
Browse files

Merge branch 'master' of github.com:micropython/micropython

Conflicts:
	py/objstr.c
	py/py.mk
	py/stream.c
	unix/main.c
	unix/socket.c
parents 55baff4c 7280f790
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))
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:")
print(client_s.read(4096))
#print(client_s.readall())
client_s.write("""\
HTTP/1.0 200 OK
Hello #{} from MicroPython!
""".format(counter))
if 0:
# MicroPython rawsocket module supports file interface directly
print(client_s.read(4096))
#print(client_s.readall())
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
......@@ -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);
......
......@@ -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;
}
......@@ -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:
......
......@@ -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));
mp_obj_str_t *self = self_in;
return self->qstr;
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)));
}
/******************************************************************************/
......
......@@ -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);
......
#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;
}
}
......@@ -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'))
......
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))
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
......
......@@ -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.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment