Skip to content

Commit be84297

Browse files
committed
Merge pull request adafruit#123 from xbe/master
Implement str.strip
2 parents f09e903 + 7b0f39f commit be84297

2 files changed

Lines changed: 61 additions & 0 deletions

File tree

py/mpqstrraw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,5 @@ Q(append)
6565
Q(pop)
6666
Q(sort)
6767
Q(join)
68+
Q(strip)
6869
Q(format)

py/objstr.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,64 @@ mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
147147
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "?str.join expecting a list of str's"));
148148
}
149149

150+
static bool chr_in_str(const char* const str, const size_t str_len, const char c) {
151+
for (size_t i = 0; i < str_len; i++) {
152+
if (str[i] == c) {
153+
return true;
154+
}
155+
}
156+
return false;
157+
}
158+
159+
mp_obj_t str_strip(int n_args, const mp_obj_t *args) {
160+
assert(1 <= n_args && n_args <= 2);
161+
assert(MP_OBJ_IS_TYPE(args[0], &str_type));
162+
const char *chars_to_del;
163+
static const char whitespace[] = " \t\n\r\v\f";
164+
165+
if (n_args == 1) {
166+
chars_to_del = whitespace;
167+
} else {
168+
assert(MP_OBJ_IS_TYPE(args[1], &str_type));
169+
mp_obj_str_t *chars_to_del_obj = args[1];
170+
chars_to_del = qstr_str(chars_to_del_obj->qstr);
171+
}
172+
173+
const size_t chars_to_del_len = strlen(chars_to_del);
174+
mp_obj_str_t *self = args[0];
175+
const char *orig_str = qstr_str(self->qstr);
176+
const size_t orig_str_len = strlen(orig_str);
177+
178+
size_t first_good_char_pos = 0;
179+
bool first_good_char_pos_set = false;
180+
size_t last_good_char_pos = 0;
181+
for (size_t i = 0; i < orig_str_len; i++) {
182+
if (!chr_in_str(chars_to_del, chars_to_del_len, orig_str[i])) {
183+
last_good_char_pos = i;
184+
if (!first_good_char_pos_set) {
185+
first_good_char_pos = i;
186+
first_good_char_pos_set = true;
187+
}
188+
}
189+
}
190+
191+
if (first_good_char_pos == 0 && last_good_char_pos == 0) {
192+
//string is all whitespace, return '\0'
193+
char *empty = m_new(char, 1);
194+
empty[0] = '\0';
195+
return mp_obj_new_str(qstr_from_str_take(empty, 1));
196+
}
197+
198+
assert(last_good_char_pos >= first_good_char_pos);
199+
//+1 to accomodate the last character
200+
size_t stripped_len = last_good_char_pos - first_good_char_pos + 1;
201+
//+1 to accomodate '\0'
202+
char *stripped_str = m_new(char, stripped_len + 1);
203+
strncpy(stripped_str, orig_str + first_good_char_pos, stripped_len);
204+
stripped_str[stripped_len] = '\0';
205+
return mp_obj_new_str(qstr_from_str_take(stripped_str, stripped_len + 1));
206+
}
207+
150208
void vstr_printf_wrapper(void *env, const char *fmt, ...) {
151209
va_list args;
152210
va_start(args, fmt);
@@ -182,10 +240,12 @@ mp_obj_t str_format(int n_args, const mp_obj_t *args) {
182240
}
183241

184242
static MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join);
243+
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj, 1, 2, str_strip);
185244
static MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, str_format);
186245

187246
static const mp_method_t str_type_methods[] = {
188247
{ "join", &str_join_obj },
248+
{ "strip", &str_strip_obj },
189249
{ "format", &str_format_obj },
190250
{ NULL, NULL }, // end-of-list sentinel
191251
};

0 commit comments

Comments
 (0)