Skip to content

Commit fe8fb91

Browse files
committed
py: remove depedence on strcat and stpcpy.
This fixes Issue adafruit#29, and means the core is no longer dependent on string functions, except strlen.
1 parent bbabfb4 commit fe8fb91

2 files changed

Lines changed: 40 additions & 13 deletions

File tree

py/compile.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,13 +1182,18 @@ void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q1, qstr *q2) {
11821182
len += strlen(qstr_str(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
11831183
}
11841184
char *str = m_new(char, len + 1);
1185+
char *str_dest = str;
11851186
str[0] = 0;
11861187
for (int i = 0; i < n; i++) {
11871188
if (i > 0) {
1188-
strcat(str, ".");
1189+
*str_dest++ = '.';
11891190
}
1190-
strcat(str, qstr_str(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1191+
const char *str_src = qstr_str(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1192+
size_t str_src_len = strlen(str_src);
1193+
memcpy(str_dest, str_src, str_src_len);
1194+
str_dest += str_src_len;
11911195
}
1196+
*str_dest = '\0';
11921197
*q2 = qstr_from_str_take(str, len + 1);
11931198
EMIT(import_name, *q2);
11941199
if (is_as) {
@@ -2124,13 +2129,16 @@ void compile_atom_string(compiler_t *comp, mp_parse_node_struct_t *pns) {
21242129

21252130
// allocate memory for concatenated string/bytes
21262131
char *cat_str = m_new(char, n_bytes + 1);
2127-
cat_str[0] = '\0';
21282132

21292133
// concatenate string/bytes
2134+
char *s_dest = cat_str;
21302135
for (int i = 0; i < n; i++) {
2131-
const char *str = qstr_str(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
2132-
strcat(cat_str, str);
2136+
const char *s = qstr_str(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
2137+
size_t s_len = strlen(s);
2138+
memcpy(s_dest, s, s_len);
2139+
s_dest += s_len;
21332140
}
2141+
*s_dest = '\0';
21342142

21352143
EMIT(load_const_str, qstr_from_str_take(cat_str, n_bytes + 1), string_kind == MP_PARSE_NODE_BYTES);
21362144
}

py/objstr.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,13 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
3636
if (MP_OBJ_IS_TYPE(rhs_in, &str_type)) {
3737
// add 2 strings
3838
const char *rhs_str = qstr_str(((mp_obj_str_t*)rhs_in)->qstr);
39-
int alloc_len = strlen(lhs_str) + strlen(rhs_str) + 1;
39+
size_t lhs_len = strlen(lhs_str);
40+
size_t rhs_len = strlen(rhs_str);
41+
int alloc_len = lhs_len + rhs_len + 1;
4042
char *val = m_new(char, alloc_len);
41-
stpcpy(stpcpy(val, lhs_str), rhs_str);
43+
memcpy(val, lhs_str, lhs_len);
44+
memcpy(val + lhs_len, rhs_str, rhs_len);
45+
val[lhs_len + rhs_len] = '\0';
4246
return mp_obj_new_str(qstr_from_str_take(val, alloc_len));
4347
}
4448
break;
@@ -50,9 +54,12 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
5054
mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
5155
assert(MP_OBJ_IS_TYPE(self_in, &str_type));
5256
mp_obj_str_t *self = self_in;
53-
int required_len = strlen(qstr_str(self->qstr));
5457

55-
// process arg, count required chars
58+
// get separation string
59+
const char *sep_str = qstr_str(self->qstr);
60+
size_t sep_len = strlen(sep_str);
61+
62+
// process args
5663
uint seq_len;
5764
mp_obj_t *seq_items;
5865
if (MP_OBJ_IS_TYPE(arg, &tuple_type)) {
@@ -62,23 +69,35 @@ mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
6269
} else {
6370
goto bad_arg;
6471
}
72+
73+
// count required length
74+
int required_len = 0;
6575
for (int i = 0; i < seq_len; i++) {
6676
if (!MP_OBJ_IS_TYPE(seq_items[i], &str_type)) {
6777
goto bad_arg;
6878
}
79+
if (i > 0) {
80+
required_len += sep_len;
81+
}
6982
required_len += strlen(qstr_str(mp_obj_str_get(seq_items[i])));
7083
}
7184

7285
// make joined string
7386
char *joined_str = m_new(char, required_len + 1);
74-
joined_str[0] = 0;
87+
char *s_dest = joined_str;
7588
for (int i = 0; i < seq_len; i++) {
76-
const char *s2 = qstr_str(mp_obj_str_get(seq_items[i]));
7789
if (i > 0) {
78-
strcat(joined_str, qstr_str(self->qstr));
90+
memcpy(s_dest, sep_str, sep_len);
91+
s_dest += sep_len;
7992
}
80-
strcat(joined_str, s2);
93+
const char *s2 = qstr_str(mp_obj_str_get(seq_items[i]));
94+
size_t s2_len = strlen(s2);
95+
memcpy(s_dest, s2, s2_len);
96+
s_dest += s2_len;
8197
}
98+
*s_dest = '\0';
99+
100+
// return joined string
82101
return mp_obj_new_str(qstr_from_str_take(joined_str, required_len + 1));
83102

84103
bad_arg:

0 commit comments

Comments
 (0)