Skip to content

Commit 0b7e29c

Browse files
committed
Factor out quoted string print function for reuse (mp_str_print_quoted()).
1 parent 8e991e0 commit 0b7e29c

2 files changed

Lines changed: 36 additions & 31 deletions

File tree

py/obj.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ uint mp_obj_str_get_len(mp_obj_t self_in);
291291
qstr mp_obj_str_get_qstr(mp_obj_t self_in); // use this if you will anyway convert the string to a qstr
292292
const char *mp_obj_str_get_str(mp_obj_t self_in); // use this only if you need the string to be null terminated
293293
const byte *mp_obj_str_get_data(mp_obj_t self_in, uint *len);
294+
void mp_str_print_quoted(void (*print)(void *env, const char *fmt, ...), void *env, const byte *str_data, uint str_len);
294295

295296
// bytes
296297
extern const mp_obj_type_t bytes_type;

py/objstr.c

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -34,45 +34,49 @@ static mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str);
3434
/******************************************************************************/
3535
/* str */
3636

37-
void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
37+
void mp_str_print_quoted(void (*print)(void *env, const char *fmt, ...), void *env, const byte *str_data, uint str_len) {
38+
// this escapes characters, but it will be very slow to print (calling print many times)
39+
bool has_single_quote = false;
40+
bool has_double_quote = false;
41+
for (const byte *s = str_data, *top = str_data + str_len; (!has_single_quote || !has_double_quote) && s < top; s++) {
42+
if (*s == '\'') {
43+
has_single_quote = true;
44+
} else if (*s == '"') {
45+
has_double_quote = true;
46+
}
47+
}
48+
int quote_char = '\'';
49+
if (has_single_quote && !has_double_quote) {
50+
quote_char = '"';
51+
}
52+
print(env, "%c", quote_char);
53+
for (const byte *s = str_data, *top = str_data + str_len; s < top; s++) {
54+
if (*s == quote_char) {
55+
print(env, "\\%c", quote_char);
56+
} else if (*s == '\\') {
57+
print(env, "\\\\");
58+
} else if (32 <= *s && *s <= 126) {
59+
print(env, "%c", *s);
60+
} else if (*s == '\n') {
61+
print(env, "\\n");
62+
// TODO add more escape codes here if we want to match CPython
63+
} else {
64+
print(env, "\\x%02x", *s);
65+
}
66+
}
67+
print(env, "%c", quote_char);
68+
}
69+
70+
static void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
3871
GET_STR_DATA_LEN(self_in, str_data, str_len);
3972
bool is_bytes = MP_OBJ_IS_TYPE(self_in, &bytes_type);
4073
if (kind == PRINT_STR && !is_bytes) {
4174
print(env, "%.*s", str_len, str_data);
4275
} else {
43-
// this escapes characters, but it will be very slow to print (calling print many times)
44-
bool has_single_quote = false;
45-
bool has_double_quote = false;
46-
for (const byte *s = str_data, *top = str_data + str_len; (!has_single_quote || !has_double_quote) && s < top; s++) {
47-
if (*s == '\'') {
48-
has_single_quote = true;
49-
} else if (*s == '"') {
50-
has_double_quote = true;
51-
}
52-
}
5376
if (is_bytes) {
5477
print(env, "b");
5578
}
56-
int quote_char = '\'';
57-
if (has_single_quote && !has_double_quote) {
58-
quote_char = '"';
59-
}
60-
print(env, "%c", quote_char);
61-
for (const byte *s = str_data, *top = str_data + str_len; s < top; s++) {
62-
if (*s == quote_char) {
63-
print(env, "\\%c", quote_char);
64-
} else if (*s == '\\') {
65-
print(env, "\\\\");
66-
} else if (32 <= *s && *s <= 126) {
67-
print(env, "%c", *s);
68-
} else if (*s == '\n') {
69-
print(env, "\\n");
70-
// TODO add more escape codes here if we want to match CPython
71-
} else {
72-
print(env, "\\x%02x", *s);
73-
}
74-
}
75-
print(env, "%c", quote_char);
79+
mp_str_print_quoted(print, env, str_data, str_len);
7680
}
7781
}
7882

0 commit comments

Comments
 (0)