Skip to content

Commit 12eacca

Browse files
committed
Merge branch 'master' of github.com:micropython/micropython
Conflicts: py/objstr.c py/py.mk py/stream.c unix/main.c unix/socket.c
2 parents 55baff4 + 7280f79 commit 12eacca

22 files changed

Lines changed: 281 additions & 60 deletions

examples/unix/sock-client.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,32 @@
1-
mod = rawsocket
2-
s = mod.socket()
1+
try:
2+
import rawsocket as _socket
3+
except:
4+
import _socket
5+
6+
7+
s = _socket.socket()
38

49
if 1:
5-
ai = mod.getaddrinfo("google.com", 80)
10+
ai = _socket.getaddrinfo("google.com", 80)
611
print("Address infos:", ai)
712
addr = ai[0][4]
813
else:
9-
# Deprecated way to construct connection address
10-
addr = mod.sockaddr_in()
14+
# Deprecated ways to construct connection address
15+
addr = _socket.sockaddr_in()
1116
addr.sin_family = 2
1217
#addr.sin_addr = (0x0100 << 16) + 0x007f
1318
#addr.sin_addr = (0x7f00 << 16) + 0x0001
14-
#addr.sin_addr = mod.inet_aton("127.0.0.1")
15-
addr.sin_addr = mod.gethostbyname("google.com")
16-
addr.sin_port = mod.htons(80)
19+
#addr.sin_addr = _socket.inet_aton("127.0.0.1")
20+
addr.sin_addr = _socket.gethostbyname("google.com")
21+
addr.sin_port = _socket.htons(80)
1722

1823
print("Connect address:", addr)
1924
s.connect(addr)
2025

21-
s.write("GET / HTTP/1.0\n\n")
22-
print(s.readall())
26+
if 0:
27+
# MicroPython rawsocket module supports file interface directly
28+
s.write("GET / HTTP/1.0\n\n")
29+
print(s.readall())
30+
else:
31+
s.send(b"GET / HTTP/1.0\n\n")
32+
print(s.recv(4096))

examples/unix/sock-server.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
1-
mod = rawsocket
2-
s = mod.socket()
1+
try:
2+
import rawsocket as socket
3+
except:
4+
import socket
35

4-
ai = mod.getaddrinfo("127.0.0.1", 8080)
6+
7+
CONTENT = """\
8+
HTTP/1.0 200 OK
9+
10+
Hello #{} from MicroPython!
11+
"""
12+
13+
s = socket.socket()
14+
15+
ai = socket.getaddrinfo("127.0.0.1", 8080)
516
print("Bind address info:", ai)
617
addr = ai[0][4]
718

@@ -17,12 +28,13 @@
1728
print("Client address:", client_addr)
1829
print("Client socket:", client_s)
1930
print("Request:")
20-
print(client_s.read(4096))
21-
#print(client_s.readall())
22-
client_s.write("""\
23-
HTTP/1.0 200 OK
24-
25-
Hello #{} from MicroPython!
26-
""".format(counter))
31+
if 0:
32+
# MicroPython rawsocket module supports file interface directly
33+
print(client_s.read(4096))
34+
#print(client_s.readall())
35+
client_s.write(CONTENT.format(counter))
36+
else:
37+
print(client_s.recv(4096))
38+
client_s.send(bytes(CONTENT.format(counter), "ascii"))
2739
client_s.close()
2840
counter += 1

py/builtin.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,3 +350,15 @@ static mp_obj_t mp_builtin_str(mp_obj_t o_in) {
350350
}
351351

352352
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_str_obj, mp_builtin_str);
353+
354+
// TODO: This should be type, this is just quick CPython compat hack
355+
static mp_obj_t mp_builtin_bytes(uint n_args, const mp_obj_t *args) {
356+
if (!MP_OBJ_IS_QSTR(args[0]) && !MP_OBJ_IS_TYPE(args[0], &str_type)) {
357+
assert(0);
358+
}
359+
// Currently, MicroPython strings are mix between CPython byte and unicode
360+
// strings. So, conversion is null so far.
361+
return args[0];
362+
}
363+
364+
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_bytes_obj, 1, 3, mp_builtin_bytes);

py/builtin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin___repl_print___obj);
55
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_abs_obj);
66
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_all_obj);
77
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_any_obj);
8+
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_bytes_obj); // Temporary hack
89
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_callable_obj);
910
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_chr_obj);
1011
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_divmod_obj);

py/obj.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ mp_obj_t mp_obj_get_type(mp_obj_t o_in) {
2828
const char *mp_obj_get_type_str(mp_obj_t o_in) {
2929
if (MP_OBJ_IS_SMALL_INT(o_in)) {
3030
return "int";
31+
} else if (MP_OBJ_IS_QSTR(o_in)) {
32+
return "str";
3133
} else {
3234
mp_obj_base_t *o = o_in;
3335
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) {
222224
#endif
223225

224226
qstr mp_obj_get_qstr(mp_obj_t arg) {
225-
if (MP_OBJ_IS_TYPE(arg, &str_type)) {
227+
if (MP_OBJ_IS_QSTR(arg)) {
228+
return MP_OBJ_QSTR_VALUE(arg);
229+
} else if (MP_OBJ_IS_TYPE(arg, &str_type)) {
226230
return mp_obj_str_get(arg);
227231
} else {
228232
assert(0);
@@ -286,3 +290,9 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
286290
}
287291
return MP_OBJ_NEW_SMALL_INT(len);
288292
}
293+
294+
// Return input argument. Useful as .getiter for objects which are
295+
// their own iterators, etc.
296+
mp_obj_t mp_identity(mp_obj_t self) {
297+
return self;
298+
}

py/obj.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,8 @@ extern const mp_obj_type_t fun_native_type;
351351
extern const mp_obj_type_t fun_bc_type;
352352
void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code);
353353

354+
mp_obj_t mp_identity(mp_obj_t self);
355+
354356
// generator
355357
extern const mp_obj_type_t gen_instance_type;
356358

@@ -374,3 +376,6 @@ typedef struct _mp_obj_classmethod_t {
374376
mp_obj_base_t base;
375377
mp_obj_t fun;
376378
} mp_obj_classmethod_t;
379+
380+
// sequence helpers
381+
void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void *dest);

py/objlist.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,8 @@ static mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
153153
return NULL;
154154
}
155155
int n = MP_OBJ_SMALL_INT_VALUE(rhs);
156-
int len = o->len;
157-
mp_obj_list_t *s = list_new(len * n);
158-
mp_obj_t *dest = s->items;
159-
for (int i = 0; i < n; i++) {
160-
memcpy(dest, o->items, sizeof(mp_obj_t) * len);
161-
dest += len;
162-
}
156+
mp_obj_list_t *s = list_new(o->len * n);
157+
mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items);
163158
return s;
164159
}
165160
case RT_COMPARE_OP_EQUAL:

py/objstr.c

Lines changed: 66 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,8 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
6565
// TODO: need predicate to check for int-like type (bools are such for example)
6666
// ["no", "yes"][1 == 2] is common idiom
6767
if (MP_OBJ_IS_SMALL_INT(rhs_in)) {
68-
// TODO: This implements byte string access for single index so far
69-
// TODO: Handle negative indexes.
70-
return mp_obj_new_int(lhs_data[mp_obj_get_int(rhs_in)]);
68+
uint index = mp_get_index(lhs->base.type, lhs_len, rhs_in);
69+
return mp_obj_new_str(qstr_from_strn((const char*)lhs_data + index, 1));
7170
#if MICROPY_ENABLE_SLICE
7271
} else if (MP_OBJ_IS_TYPE(rhs_in, &slice_type)) {
7372
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) {
122121
return mp_const_false;
123122
}
124123
break;
124+
case RT_BINARY_OP_MULTIPLY:
125+
{
126+
if (!MP_OBJ_IS_SMALL_INT(rhs_in)) {
127+
return NULL;
128+
}
129+
int n = MP_OBJ_SMALL_INT_VALUE(rhs_in);
130+
char *s = m_new(char, lhs_len * n);
131+
mp_seq_multiply(lhs_data, sizeof(*lhs_data), lhs_len, n, s);
132+
return MP_OBJ_NEW_QSTR(qstr_from_strn_take(s, lhs_len * n, lhs_len * n));
133+
}
125134
}
126135

127136
return MP_OBJ_NULL; // op not supported
@@ -184,6 +193,45 @@ mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
184193
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "?str.join expecting a list of str's"));
185194
}
186195

196+
#define is_ws(c) ((c) == ' ' || (c) == '\t')
197+
198+
static mp_obj_t str_split(uint n_args, const mp_obj_t *args) {
199+
int splits = -1;
200+
mp_obj_t sep = mp_const_none;
201+
if (n_args > 1) {
202+
sep = args[1];
203+
if (n_args > 2) {
204+
splits = MP_OBJ_SMALL_INT_VALUE(args[2]);
205+
}
206+
}
207+
assert(sep == mp_const_none);
208+
(void)sep; // unused; to hush compiler warning
209+
mp_obj_t res = mp_obj_new_list(0, NULL);
210+
const char *s = qstr_str(mp_obj_str_get(args[0]));
211+
const char *start;
212+
213+
// Initial whitespace is not counted as split, so we pre-do it
214+
while (is_ws(*s)) s++;
215+
while (*s && splits != 0) {
216+
start = s;
217+
while (*s != 0 && !is_ws(*s)) s++;
218+
rt_list_append(res, MP_OBJ_NEW_QSTR(qstr_from_strn(start, s - start)));
219+
if (*s == 0) {
220+
break;
221+
}
222+
while (is_ws(*s)) s++;
223+
if (splits > 0) {
224+
splits--;
225+
}
226+
}
227+
228+
if (*s != 0) {
229+
rt_list_append(res, MP_OBJ_NEW_QSTR(qstr_from_str(s)));
230+
}
231+
232+
return res;
233+
}
234+
187235
static bool chr_in_str(const char* const str, const size_t str_len, const char c) {
188236
for (size_t i = 0; i < str_len; i++) {
189237
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
195243

196244
static mp_obj_t str_find(uint n_args, const mp_obj_t *args) {
197245
assert(2 <= n_args && n_args <= 4);
198-
assert(MP_OBJ_IS_TYPE(args[0], &str_type));
199-
if (!MP_OBJ_IS_TYPE(args[1], &str_type)) {
200-
nlr_jump(mp_obj_new_exception_msg_1_arg(
201-
MP_QSTR_TypeError,
202-
"Can't convert '%s' object to str implicitly",
203-
mp_obj_get_type_str(args[1])));
204-
}
205-
206-
const char* haystack = qstr_str(((mp_obj_str_t*)args[0])->qstr);
207-
const char* needle = qstr_str(((mp_obj_str_t*)args[1])->qstr);
246+
const char* haystack = qstr_str(mp_obj_str_get(args[0]));
247+
const char* needle = qstr_str(mp_obj_str_get(args[1]));
208248

209249
size_t haystack_len = strlen(haystack);
210250
size_t needle_len = strlen(needle);
@@ -242,14 +282,11 @@ mp_obj_t str_strip(uint n_args, const mp_obj_t *args) {
242282
if (n_args == 1) {
243283
chars_to_del = whitespace;
244284
} else {
245-
assert(MP_OBJ_IS_TYPE(args[1], &str_type));
246-
mp_obj_str_t *chars_to_del_obj = args[1];
247-
chars_to_del = qstr_str(chars_to_del_obj->qstr);
285+
chars_to_del = qstr_str(mp_obj_str_get(args[1]));
248286
}
249287

250288
const size_t chars_to_del_len = strlen(chars_to_del);
251-
mp_obj_str_t *self = args[0];
252-
const char *orig_str = qstr_str(self->qstr);
289+
const char *orig_str = qstr_str(mp_obj_str_get(args[0]));
253290
const size_t orig_str_len = strlen(orig_str);
254291

255292
size_t first_good_char_pos = 0;
@@ -307,12 +344,14 @@ mp_obj_t str_format(uint n_args, const mp_obj_t *args) {
307344

308345
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj, 2, 4, str_find);
309346
static MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join);
347+
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_split_obj, 1, 3, str_split);
310348
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj, 1, 2, str_strip);
311349
static MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, str_format);
312350

313351
static const mp_method_t str_type_methods[] = {
314352
{ "find", &str_find_obj },
315353
{ "join", &str_join_obj },
354+
{ "split", &str_split_obj },
316355
{ "strip", &str_strip_obj },
317356
{ "format", &str_format_obj },
318357
{ NULL, NULL }, // end-of-list sentinel
@@ -335,9 +374,15 @@ mp_obj_t mp_obj_new_str(qstr qstr) {
335374
}
336375

337376
qstr mp_obj_str_get(mp_obj_t self_in) {
338-
assert(MP_OBJ_IS_TYPE(self_in, &str_type));
339-
mp_obj_str_t *self = self_in;
340-
return self->qstr;
377+
if (MP_OBJ_IS_QSTR(self_in)) {
378+
return MP_OBJ_QSTR_VALUE(self_in);
379+
}
380+
if (MP_OBJ_IS_TYPE(self_in, &str_type)) {
381+
mp_obj_str_t *self = self_in;
382+
return self->qstr;
383+
}
384+
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "Can't convert '%s' object to str implicitly",
385+
mp_obj_get_type_str(self_in)));
341386
}
342387

343388
/******************************************************************************/

py/py.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ PY_O_BASENAME = \
9797
objtuple.o \
9898
objtype.o \
9999
objzip.o \
100+
sequence.o \
100101
stream.o \
101102
builtin.o \
102103
builtinimport.o \

py/qstrdefs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Q(any)
4040
Q(array)
4141
Q(bool)
4242
Q(bytearray)
43+
Q(bytes)
4344
Q(callable)
4445
Q(chr)
4546
Q(complex)

0 commit comments

Comments
 (0)