summaryrefslogtreecommitdiff
path: root/py/objstr.c
diff options
context:
space:
mode:
authorScott Shawcroft <scott.shawcroft@gmail.com>2017-06-20 10:56:05 -0700
committerScott Shawcroft <scott.shawcroft@gmail.com>2017-06-20 10:56:05 -0700
commit30ee7019ca651bce1fe966c1089fe977d51dc92b (patch)
tree0114b6f744dd175b7722dd8edcbe24f4ee84bb45 /py/objstr.c
parent97fcdfbd08c922efd7470d6482d7c7c703ffc0ae (diff)
parent869cdcfdfc860b1177baf9b0f8818915ba54f3f5 (diff)
Merge tag 'v1.9.1'2.0.0-alpha.0
Fixes for stmhal USB mass storage, lwIP bindings and VFS regressions This release provides an important fix for the USB mass storage device in the stmhal port by implementing the SCSI SYNCHRONIZE_CACHE command, which is now require by some Operating Systems. There are also fixes for the lwIP bindings to improve non-blocking sockets and error codes. The VFS has some regressions fixed including the ability to statvfs the root. All changes are listed below. py core: - modbuiltins: add core-provided version of input() function - objstr: catch case of negative "maxsplit" arg to str.rsplit() - persistentcode: allow to compile with complex numbers disabled - objstr: allow to compile with obj-repr D, and unicode disabled - modsys: allow to compile with obj-repr D and PY_ATTRTUPLE disabled - provide mp_decode_uint_skip() to help reduce stack usage - makeqstrdefs.py: make script run correctly with Python 2.6 - objstringio: if created from immutable object, follow copy on write policy extmod: - modlwip: connect: for non-blocking mode, return EINPROGRESS - modlwip: fix error codes for duplicate calls to connect() - modlwip: accept: fix error code for non-blocking mode - vfs: allow to statvfs the root directory - vfs: allow "buffering" and "encoding" args to VFS's open() - modframebuf: fix signed/unsigned comparison pendantic warning lib: - libm: use isfinite instead of finitef, for C99 compatibility - utils/interrupt_char: remove support for KBD_EXCEPTION disabled tests: - basics/string_rsplit: add tests for negative "maxsplit" argument - float: convert "sys.exit()" to "raise SystemExit" - float/builtin_float_minmax: PEP8 fixes - basics: convert "sys.exit()" to "raise SystemExit" - convert remaining "sys.exit()" to "raise SystemExit" unix port: - convert to use core-provided version of built-in import() - Makefile: replace references to make with $(MAKE) windows port: - convert to use core-provided version of built-in import() qemu-arm port: - Makefile: adjust object-file lists to get correct dependencies - enable micropython.mem_*() functions to allow more tests stmhal port: - boards: enable DAC for NUCLEO_F767ZI board - add support for NUCLEO_F446RE board - pass USB handler as parameter to allow more than one USB handler - usb: use local USB handler variable in Start-of-Frame handler - usb: make state for USB device private to top-level USB driver - usbdev: for MSC implement SCSI SYNCHRONIZE_CACHE command - convert from using stmhal's input() to core provided version cc3200 port: - convert from using stmhal's input() to core provided version teensy port: - convert from using stmhal's input() to core provided version esp8266 port: - Makefile: replace references to make with $(MAKE) - Makefile: add clean-modules target - convert from using stmhal's input() to core provided version zephyr port: - modusocket: getaddrinfo: Fix mp_obj_len() usage - define MICROPY_PY_SYS_PLATFORM (to "zephyr") - machine_pin: use native Zephyr types for Zephyr API calls docs: - machine.Pin: remove out_value() method - machine.Pin: add on() and off() methods - esp8266: consistently replace Pin.high/low methods with .on/off - esp8266/quickref: polish Pin.on()/off() examples - network: move confusingly-named cc3200 Server class to its reference - uos: deconditionalize, remove minor port-specific details - uos: move cc3200 port legacy VFS mounting functions to its ref doc - machine: sort machine classes in logical order, not alphabetically - network: first step to describe standard network class interface examples: - embedding: use core-provided KeyboardInterrupt object
Diffstat (limited to 'py/objstr.c')
-rw-r--r--py/objstr.c164
1 files changed, 88 insertions, 76 deletions
diff --git a/py/objstr.c b/py/objstr.c
index ea4ae717e..93c9a8344 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -36,15 +36,15 @@
#include "py/runtime.h"
#include "py/stackctrl.h"
-STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, mp_uint_t n_args, const mp_obj_t *args, mp_obj_t dict);
+STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_t *args, mp_obj_t dict);
-STATIC mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str);
+STATIC mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf);
STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in);
/******************************************************************************/
/* str */
-void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, mp_uint_t str_len, bool is_bytes) {
+void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, size_t str_len, bool is_bytes) {
// this escapes characters, but it will be very slow to print (calling print many times)
bool has_single_quote = false;
bool has_double_quote = false;
@@ -231,11 +231,12 @@ STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size
vstr_init(&vstr, len);
}
- mp_obj_t iterable = mp_getiter(args[0]);
+ mp_obj_iter_buf_t iter_buf;
+ mp_obj_t iterable = mp_getiter(args[0], &iter_buf);
mp_obj_t item;
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
mp_int_t val = mp_obj_get_int(item);
- #if MICROPY_CPYTHON_COMPAT
+ #if MICROPY_FULL_CHECKS
if (val < 0 || val > 255) {
mp_raise_ValueError("bytes value out of range");
}
@@ -251,9 +252,9 @@ wrong_args:
// like strstr but with specified length and allows \0 bytes
// TODO replace with something more efficient/standard
-const byte *find_subbytes(const byte *haystack, mp_uint_t hlen, const byte *needle, mp_uint_t nlen, mp_int_t direction) {
+const byte *find_subbytes(const byte *haystack, size_t hlen, const byte *needle, size_t nlen, int direction) {
if (hlen >= nlen) {
- mp_uint_t str_index, str_index_end;
+ size_t str_index, str_index_end;
if (direction > 0) {
str_index = 0;
str_index_end = hlen - nlen;
@@ -282,19 +283,14 @@ const byte *find_subbytes(const byte *haystack, mp_uint_t hlen, const byte *need
mp_obj_t mp_obj_str_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
// check for modulo
if (op == MP_BINARY_OP_MODULO) {
- mp_obj_t *args;
- mp_uint_t n_args;
+ mp_obj_t *args = &rhs_in;
+ size_t n_args = 1;
mp_obj_t dict = MP_OBJ_NULL;
if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_tuple)) {
// TODO: Support tuple subclasses?
mp_obj_tuple_get(rhs_in, &n_args, &args);
} else if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_dict)) {
- args = NULL;
- n_args = 0;
dict = rhs_in;
- } else {
- args = &rhs_in;
- n_args = 1;
}
return str_modulo_format(lhs_in, n_args, args, dict);
}
@@ -338,7 +334,7 @@ mp_obj_t mp_obj_str_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
// size and execution time so we don't.
const byte *rhs_data;
- mp_uint_t rhs_len;
+ size_t rhs_len;
if (lhs_type == mp_obj_get_type(rhs_in)) {
GET_STR_DATA_LEN(rhs_in, rhs_data_, rhs_len_);
rhs_data = rhs_data_;
@@ -358,6 +354,13 @@ mp_obj_t mp_obj_str_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
switch (op) {
case MP_BINARY_OP_ADD:
case MP_BINARY_OP_INPLACE_ADD: {
+ if (lhs_len == 0 && mp_obj_get_type(rhs_in) == lhs_type) {
+ return rhs_in;
+ }
+ if (rhs_len == 0) {
+ return lhs_in;
+ }
+
vstr_t vstr;
vstr_init_len(&vstr, lhs_len + rhs_len);
memcpy(vstr.buf, lhs_data, lhs_len);
@@ -385,7 +388,7 @@ mp_obj_t mp_obj_str_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
// objstrunicode defines own version
const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, size_t self_len,
mp_obj_t index, bool is_slice) {
- mp_uint_t index_val = mp_get_index(type, self_len, index, is_slice);
+ size_t index_val = mp_get_index(type, self_len, index, is_slice);
return self_data + index_val;
}
#endif
@@ -405,7 +408,7 @@ STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
return mp_obj_new_str_of_type(type, self_data + slice.start, slice.stop - slice.start);
}
#endif
- mp_uint_t index_val = mp_get_index(type, self_len, index, false);
+ size_t index_val = mp_get_index(type, self_len, index, false);
// If we have unicode enabled the type will always be bytes, so take the short cut.
if (MICROPY_PY_BUILTINS_STR_UNICODE || type == &mp_type_bytes) {
return MP_OBJ_NEW_SMALL_INT(self_data[index_val]);
@@ -425,22 +428,19 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
GET_STR_DATA_LEN(self_in, sep_str, sep_len);
// process args
- mp_uint_t seq_len;
+ size_t seq_len;
mp_obj_t *seq_items;
- if (MP_OBJ_IS_TYPE(arg, &mp_type_tuple)) {
- mp_obj_tuple_get(arg, &seq_len, &seq_items);
- } else {
- if (!MP_OBJ_IS_TYPE(arg, &mp_type_list)) {
- // arg is not a list, try to convert it to one
- // TODO: Try to optimize?
- arg = mp_type_list.make_new(&mp_type_list, 1, 0, &arg);
- }
- mp_obj_list_get(arg, &seq_len, &seq_items);
+
+ if (!MP_OBJ_IS_TYPE(arg, &mp_type_list) && !MP_OBJ_IS_TYPE(arg, &mp_type_tuple)) {
+ // arg is not a list nor a tuple, try to convert it to a list
+ // TODO: Try to optimize?
+ arg = mp_type_list.make_new(&mp_type_list, 1, 0, &arg);
}
+ mp_obj_get_array(arg, &seq_len, &seq_items);
// count required length
- mp_uint_t required_len = 0;
- for (mp_uint_t i = 0; i < seq_len; i++) {
+ size_t required_len = 0;
+ for (size_t i = 0; i < seq_len; i++) {
if (mp_obj_get_type(seq_items[i]) != self_type) {
mp_raise_TypeError(
"join expects a list of str/bytes objects consistent with self object");
@@ -456,7 +456,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
vstr_t vstr;
vstr_init_len(&vstr, required_len);
byte *data = (byte*)vstr.buf;
- for (mp_uint_t i = 0; i < seq_len; i++) {
+ for (size_t i = 0; i < seq_len; i++) {
if (i > 0) {
memcpy(data, sep_str, sep_len);
data += sep_len;
@@ -513,7 +513,7 @@ mp_obj_t mp_obj_str_split(size_t n_args, const mp_obj_t *args) {
bad_implicit_conversion(sep);
}
- mp_uint_t sep_len;
+ size_t sep_len;
const char *sep_str = mp_obj_str_get_data(sep, &sep_len);
if (sep_len == 0) {
@@ -602,6 +602,11 @@ STATIC mp_obj_t str_rsplit(size_t n_args, const mp_obj_t *args) {
GET_STR_DATA_LEN(args[0], s, len);
mp_int_t splits = mp_obj_get_int(args[2]);
+ if (splits < 0) {
+ // Negative limit means no limit, so delegate to split().
+ return mp_obj_str_split(n_args, args);
+ }
+
mp_int_t org_splits = splits;
// Preallocate list to the max expected # of elements, as we
// will fill it from the end.
@@ -611,7 +616,7 @@ STATIC mp_obj_t str_rsplit(size_t n_args, const mp_obj_t *args) {
if (sep == mp_const_none) {
mp_raise_NotImplementedError("rsplit(None,n)");
} else {
- mp_uint_t sep_len;
+ size_t sep_len;
const char *sep_str = mp_obj_str_get_data(sep, &sep_len);
if (sep_len == 0) {
@@ -642,7 +647,7 @@ STATIC mp_obj_t str_rsplit(size_t n_args, const mp_obj_t *args) {
}
if (idx != 0) {
// We split less parts than split limit, now go cleanup surplus
- mp_int_t used = org_splits + 1 - idx;
+ size_t used = org_splits + 1 - idx;
memmove(res->items, &res->items[idx], used * sizeof(mp_obj_t));
mp_seq_clear(res->items, used, res->alloc, sizeof(*res->items));
res->len = used;
@@ -652,7 +657,7 @@ STATIC mp_obj_t str_rsplit(size_t n_args, const mp_obj_t *args) {
return MP_OBJ_FROM_PTR(res);
}
-STATIC mp_obj_t str_finder(mp_uint_t n_args, const mp_obj_t *args, mp_int_t direction, bool is_index) {
+STATIC mp_obj_t str_finder(size_t n_args, const mp_obj_t *args, int direction, bool is_index) {
const mp_obj_type_t *self_type = mp_obj_get_type(args[0]);
mp_check_self(MP_OBJ_IS_STR_OR_BYTES(args[0]));
@@ -738,7 +743,7 @@ STATIC mp_obj_t str_endswith(size_t n_args, const mp_obj_t *args) {
enum { LSTRIP, RSTRIP, STRIP };
-STATIC mp_obj_t str_uni_strip(int type, mp_uint_t n_args, const mp_obj_t *args) {
+STATIC mp_obj_t str_uni_strip(int type, size_t n_args, const mp_obj_t *args) {
mp_check_self(MP_OBJ_IS_STR_OR_BYTES(args[0]));
const mp_obj_type_t *self_type = mp_obj_get_type(args[0]);
@@ -760,16 +765,16 @@ STATIC mp_obj_t str_uni_strip(int type, mp_uint_t n_args, const mp_obj_t *args)
GET_STR_DATA_LEN(args[0], orig_str, orig_str_len);
- mp_uint_t first_good_char_pos = 0;
+ size_t first_good_char_pos = 0;
bool first_good_char_pos_set = false;
- mp_uint_t last_good_char_pos = 0;
- mp_uint_t i = 0;
- mp_int_t delta = 1;
+ size_t last_good_char_pos = 0;
+ size_t i = 0;
+ int delta = 1;
if (type == RSTRIP) {
i = orig_str_len - 1;
delta = -1;
}
- for (mp_uint_t len = orig_str_len; len > 0; len--) {
+ for (size_t len = orig_str_len; len > 0; len--) {
if (find_subbytes(chars_to_del, chars_to_del_len, &orig_str[i], 1, 1) == NULL) {
if (!first_good_char_pos_set) {
first_good_char_pos_set = true;
@@ -798,8 +803,8 @@ STATIC mp_obj_t str_uni_strip(int type, mp_uint_t n_args, const mp_obj_t *args)
}
assert(last_good_char_pos >= first_good_char_pos);
- //+1 to accomodate the last character
- mp_uint_t stripped_len = last_good_char_pos - first_good_char_pos + 1;
+ //+1 to accommodate the last character
+ size_t stripped_len = last_good_char_pos - first_good_char_pos + 1;
if (stripped_len == orig_str_len) {
// If nothing was stripped, don't bother to dup original string
// TODO: watch out for this case when we'll get to bytearray.strip()
@@ -890,7 +895,7 @@ STATIC NORETURN void terse_str_format_value_error(void) {
#define terse_str_format_value_error()
#endif
-STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *arg_i, mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
+STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *arg_i, size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
vstr_t vstr;
mp_print_t print;
vstr_init_print(&vstr, 16, &print);
@@ -1305,12 +1310,12 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar
switch (type) {
case '\0': // no explicit format type implies 's'
case 's': {
- mp_uint_t slen;
+ size_t slen;
const char *s = mp_obj_str_get_data(arg, &slen);
if (precision < 0) {
precision = slen;
}
- if (slen > (mp_uint_t)precision) {
+ if (slen > (size_t)precision) {
slen = precision;
}
mp_print_strn(&print, s, slen, flags, fill, width);
@@ -1341,13 +1346,13 @@ mp_obj_t mp_obj_str_format(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
return mp_obj_new_str_from_vstr(&mp_type_str, &vstr);
}
-STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, mp_uint_t n_args, const mp_obj_t *args, mp_obj_t dict) {
+STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_t *args, mp_obj_t dict) {
mp_check_self(MP_OBJ_IS_STR_OR_BYTES(pattern));
GET_STR_DATA_LEN(pattern, str, len);
const byte *start_str = str;
bool is_bytes = MP_OBJ_IS_TYPE(pattern, &mp_type_bytes);
- int arg_i = 0;
+ size_t arg_i = 0;
vstr_t vstr;
mp_print_t print;
vstr_init_print(&vstr, 16, &print);
@@ -1368,6 +1373,10 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, mp_uint_t n_args, const mp_o
// Dictionary value lookup
if (*str == '(') {
+ if (dict == MP_OBJ_NULL) {
+ mp_raise_TypeError("format requires a dict");
+ }
+ arg_i = 1; // we used up the single dict argument
const byte *key = ++str;
while (*str != ')') {
if (str >= top) {
@@ -1402,7 +1411,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, mp_uint_t n_args, const mp_o
int width = 0;
if (str < top) {
if (*str == '*') {
- if ((uint)arg_i >= n_args) {
+ if (arg_i >= n_args) {
goto not_enough_args;
}
width = mp_obj_get_int(args[arg_i++]);
@@ -1415,7 +1424,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, mp_uint_t n_args, const mp_o
if (str < top && *str == '.') {
if (++str < top) {
if (*str == '*') {
- if ((uint)arg_i >= n_args) {
+ if (arg_i >= n_args) {
goto not_enough_args;
}
prec = mp_obj_get_int(args[arg_i++]);
@@ -1438,7 +1447,7 @@ incomplete_format:
// Tuple value lookup
if (arg == MP_OBJ_NULL) {
- if ((uint)arg_i >= n_args) {
+ if (arg_i >= n_args) {
not_enough_args:
mp_raise_TypeError("not enough arguments for format string");
}
@@ -1447,7 +1456,7 @@ not_enough_args:
switch (*str) {
case 'c':
if (MP_OBJ_IS_STR(arg)) {
- mp_uint_t slen;
+ size_t slen;
const char *s = mp_obj_str_get_data(arg, &slen);
if (slen != 1) {
mp_raise_TypeError("%%c requires int or char");
@@ -1526,7 +1535,7 @@ not_enough_args:
}
}
- if ((uint)arg_i != n_args) {
+ if (arg_i != n_args) {
mp_raise_TypeError("not all arguments converted during string formatting");
}
@@ -1581,11 +1590,11 @@ STATIC mp_obj_t str_replace(size_t n_args, const mp_obj_t *args) {
// first pass computes the required length of the replaced string
// second pass does the replacements
for (;;) {
- mp_uint_t replaced_str_index = 0;
- mp_uint_t num_replacements_done = 0;
+ size_t replaced_str_index = 0;
+ size_t num_replacements_done = 0;
const byte *old_occurrence;
const byte *offset_ptr = str;
- mp_uint_t str_len_remain = str_len;
+ size_t str_len_remain = str_len;
if (old_len == 0) {
// if old_str is empty, copy new_str to start of replaced string
// copy the replacement string
@@ -1595,7 +1604,7 @@ STATIC mp_obj_t str_replace(size_t n_args, const mp_obj_t *args) {
replaced_str_index += new_len;
num_replacements_done++;
}
- while (num_replacements_done != (mp_uint_t)max_rep && str_len_remain > 0 && (old_occurrence = find_subbytes(offset_ptr, str_len_remain, old, old_len, 1)) != NULL) {
+ while (num_replacements_done != (size_t)max_rep && str_len_remain > 0 && (old_occurrence = find_subbytes(offset_ptr, str_len_remain, old, old_len, 1)) != NULL) {
if (old_len == 0) {
old_occurrence += 1;
}
@@ -1681,7 +1690,7 @@ STATIC mp_obj_t str_count(size_t n_args, const mp_obj_t *args) {
}
#if MICROPY_PY_BUILTINS_STR_PARTITION
-STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, mp_int_t direction) {
+STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, int direction) {
mp_check_self(MP_OBJ_IS_STR_OR_BYTES(self_in));
mp_obj_type_t *self_type = mp_obj_get_type(self_in);
if (self_type != mp_obj_get_type(arg)) {
@@ -1714,7 +1723,7 @@ STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, mp_int_t directi
const byte *position_ptr = find_subbytes(str, str_len, sep, sep_len, direction);
if (position_ptr != NULL) {
- mp_uint_t position = position_ptr - str;
+ size_t position = position_ptr - str;
result[0] = mp_obj_new_str_of_type(self_type, str, position);
result[1] = arg;
result[2] = mp_obj_new_str_of_type(self_type, str + position + sep_len, str_len - position - sep_len);
@@ -1738,7 +1747,7 @@ STATIC mp_obj_t str_caseconv(unichar (*op)(unichar), mp_obj_t self_in) {
vstr_t vstr;
vstr_init_len(&vstr, self_len);
byte *data = (byte*)vstr.buf;
- for (mp_uint_t i = 0; i < self_len; i++) {
+ for (size_t i = 0; i < self_len; i++) {
*data++ = op(*self_data++);
}
return mp_obj_new_str_from_vstr(mp_obj_get_type(self_in), &vstr);
@@ -1760,7 +1769,7 @@ STATIC mp_obj_t str_uni_istype(bool (*f)(unichar), mp_obj_t self_in) {
}
if (f != unichar_isupper && f != unichar_islower) {
- for (mp_uint_t i = 0; i < self_len; i++) {
+ for (size_t i = 0; i < self_len; i++) {
if (!f(*self_data++)) {
return mp_const_false;
}
@@ -1768,7 +1777,7 @@ STATIC mp_obj_t str_uni_istype(bool (*f)(unichar), mp_obj_t self_in) {
} else {
bool contains_alpha = false;
- for (mp_uint_t i = 0; i < self_len; i++) { // only check alphanumeric characters
+ for (size_t i = 0; i < self_len; i++) { // only check alphanumeric characters
if (unichar_isalpha(*self_data++)) {
contains_alpha = true;
if (!f(*(self_data - 1))) { // -1 because we already incremented above
@@ -1806,7 +1815,7 @@ STATIC mp_obj_t str_islower(mp_obj_t self_in) {
}
#if MICROPY_CPYTHON_COMPAT
-// These methods are superfluous in the presense of str() and bytes()
+// These methods are superfluous in the presence of str() and bytes()
// constructors.
// TODO: should accept kwargs too
STATIC mp_obj_t bytes_decode(size_t n_args, const mp_obj_t *args) {
@@ -1935,7 +1944,7 @@ STATIC const mp_rom_map_elem_t str8_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(str8_locals_dict, str8_locals_dict_table);
#if !MICROPY_PY_BUILTINS_STR_UNICODE
-STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str);
+STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf);
const mp_obj_type_t mp_type_str = {
{ &mp_type_type },
@@ -2012,7 +2021,7 @@ mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr) {
return MP_OBJ_FROM_PTR(o);
}
-mp_obj_t mp_obj_new_str(const char* data, mp_uint_t len, bool make_qstr_if_not_already) {
+mp_obj_t mp_obj_new_str(const char* data, size_t len, bool make_qstr_if_not_already) {
if (make_qstr_if_not_already) {
// use existing, or make a new qstr
return MP_OBJ_NEW_QSTR(qstr_from_strn(data, len));
@@ -2033,7 +2042,7 @@ mp_obj_t mp_obj_str_intern(mp_obj_t str) {
return MP_OBJ_NEW_QSTR(qstr_from_strn((const char*)data, len));
}
-mp_obj_t mp_obj_new_bytes(const byte* data, mp_uint_t len) {
+mp_obj_t mp_obj_new_bytes(const byte* data, size_t len) {
return mp_obj_new_str_of_type(&mp_type_bytes, data, len);
}
@@ -2060,9 +2069,10 @@ STATIC void bad_implicit_conversion(mp_obj_t self_in) {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
mp_raise_TypeError("can't convert to str implicitly");
} else {
- mp_raise_TypeError_varg(
- "can't convert '%s' object to str implicitly",
- mp_obj_get_type_str(self_in));
+ const qstr src_name = mp_obj_get_type(self_in)->name;
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
+ "can't convert '%q' object to %q implicitly",
+ src_name, src_name == MP_QSTR_str ? MP_QSTR_bytes : MP_QSTR_str));
}
}
@@ -2091,7 +2101,7 @@ const char *mp_obj_str_get_str(mp_obj_t self_in) {
}
}
-const char *mp_obj_str_get_data(mp_obj_t self_in, mp_uint_t *len) {
+const char *mp_obj_str_get_data(mp_obj_t self_in, size_t *len) {
if (MP_OBJ_IS_STR_OR_BYTES(self_in)) {
GET_STR_DATA_LEN(self_in, s, l);
*len = l;
@@ -2119,12 +2129,12 @@ typedef struct _mp_obj_str8_it_t {
mp_obj_base_t base;
mp_fun_1_t iternext;
mp_obj_t str;
- mp_uint_t cur;
+ size_t cur;
} mp_obj_str8_it_t;
#if !MICROPY_PY_BUILTINS_STR_UNICODE
STATIC mp_obj_t str_it_iternext(mp_obj_t self_in) {
- mp_obj_str8_it_t *self = self_in;
+ mp_obj_str8_it_t *self = MP_OBJ_TO_PTR(self_in);
GET_STR_DATA_LEN(self->str, str, len);
if (self->cur < len) {
mp_obj_t o_out = mp_obj_new_str((const char*)str + self->cur, 1, true);
@@ -2135,13 +2145,14 @@ STATIC mp_obj_t str_it_iternext(mp_obj_t self_in) {
}
}
-STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str) {
- mp_obj_str8_it_t *o = m_new_obj(mp_obj_str8_it_t);
+STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf) {
+ assert(sizeof(mp_obj_str8_it_t) <= sizeof(mp_obj_iter_buf_t));
+ mp_obj_str8_it_t *o = (mp_obj_str8_it_t*)iter_buf;
o->base.type = &mp_type_polymorph_iter;
o->iternext = str_it_iternext;
o->str = str;
o->cur = 0;
- return o;
+ return MP_OBJ_FROM_PTR(o);
}
#endif
@@ -2157,8 +2168,9 @@ STATIC mp_obj_t bytes_it_iternext(mp_obj_t self_in) {
}
}
-mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str) {
- mp_obj_str8_it_t *o = m_new_obj(mp_obj_str8_it_t);
+mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf) {
+ assert(sizeof(mp_obj_str8_it_t) <= sizeof(mp_obj_iter_buf_t));
+ mp_obj_str8_it_t *o = (mp_obj_str8_it_t*)iter_buf;
o->base.type = &mp_type_polymorph_iter;
o->iternext = bytes_it_iternext;
o->str = str;