Skip to content

Commit 6913521

Browse files
committed
objstr: Implement .lower() and .upper().
1 parent 1b82e9a commit 6913521

5 files changed

Lines changed: 53 additions & 1 deletion

File tree

py/misc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ bool unichar_isalpha(unichar c);
9696
bool unichar_isprint(unichar c);
9797
bool unichar_isdigit(unichar c);
9898
bool unichar_isxdigit(unichar c);
99+
unichar unichar_tolower(unichar c);
100+
unichar unichar_toupper(unichar c);
99101

100102
/** variable string *********************************************/
101103

py/objstr.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,6 +1365,32 @@ STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg) {
13651365
return str_partitioner(self_in, arg, -1);
13661366
}
13671367

1368+
enum { CASE_UPPER, CASE_LOWER };
1369+
1370+
// Supposedly not too critical operations, so optimize for code size
1371+
STATIC mp_obj_t str_caseconv(int op, mp_obj_t self_in) {
1372+
GET_STR_DATA_LEN(self_in, self_data, self_len);
1373+
byte *data;
1374+
mp_obj_t s = mp_obj_str_builder_start(mp_obj_get_type(self_in), self_len, &data);
1375+
for (int i = 0; i < self_len; i++) {
1376+
if (op == CASE_UPPER) {
1377+
*data++ = unichar_toupper(*self_data++);
1378+
} else {
1379+
*data++ = unichar_tolower(*self_data++);
1380+
}
1381+
}
1382+
*data = 0;
1383+
return mp_obj_str_builder_end(s);
1384+
}
1385+
1386+
STATIC mp_obj_t str_lower(mp_obj_t self_in) {
1387+
return str_caseconv(CASE_LOWER, self_in);
1388+
}
1389+
1390+
STATIC mp_obj_t str_upper(mp_obj_t self_in) {
1391+
return str_caseconv(CASE_UPPER, self_in);
1392+
}
1393+
13681394
#if MICROPY_CPYTHON_COMPAT
13691395
// These methods are superfluous in the presense of str() and bytes()
13701396
// constructors.
@@ -1428,6 +1454,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj, 3, 4, str_replace);
14281454
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj, 2, 4, str_count);
14291455
STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_partition_obj, str_partition);
14301456
STATIC MP_DEFINE_CONST_FUN_OBJ_2(str_rpartition_obj, str_rpartition);
1457+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(str_lower_obj, str_lower);
1458+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(str_upper_obj, str_upper);
14311459

14321460
STATIC const mp_map_elem_t str_locals_dict_table[] = {
14331461
#if MICROPY_CPYTHON_COMPAT
@@ -1449,6 +1477,8 @@ STATIC const mp_map_elem_t str_locals_dict_table[] = {
14491477
{ MP_OBJ_NEW_QSTR(MP_QSTR_count), (mp_obj_t)&str_count_obj },
14501478
{ MP_OBJ_NEW_QSTR(MP_QSTR_partition), (mp_obj_t)&str_partition_obj },
14511479
{ MP_OBJ_NEW_QSTR(MP_QSTR_rpartition), (mp_obj_t)&str_rpartition_obj },
1480+
{ MP_OBJ_NEW_QSTR(MP_QSTR_lower), (mp_obj_t)&str_lower_obj },
1481+
{ MP_OBJ_NEW_QSTR(MP_QSTR_upper), (mp_obj_t)&str_upper_obj },
14521482
};
14531483

14541484
STATIC MP_DEFINE_CONST_DICT(str_locals_dict, str_locals_dict_table);

py/qstrdefs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ Q(startswith)
239239
Q(replace)
240240
Q(partition)
241241
Q(rpartition)
242+
Q(lower)
243+
Q(upper)
242244
Q(iterable)
243245
Q(start)
244246

py/unicode.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ bool unichar_isxdigit(unichar c) {
9797
bool char_is_alpha_or_digit(unichar c) {
9898
return c < 128 && (attr[c] & (FL_ALPHA | FL_DIGIT)) != 0;
9999
}
100+
*/
100101

101102
bool char_is_upper(unichar c) {
102103
return c < 128 && (attr[c] & FL_UPPER) != 0;
@@ -105,4 +106,17 @@ bool char_is_upper(unichar c) {
105106
bool char_is_lower(unichar c) {
106107
return c < 128 && (attr[c] & FL_LOWER) != 0;
107108
}
108-
*/
109+
110+
unichar unichar_tolower(unichar c) {
111+
if (char_is_upper(c)) {
112+
return c + 0x20;
113+
}
114+
return c;
115+
}
116+
117+
unichar unichar_toupper(unichar c) {
118+
if (char_is_lower(c)) {
119+
return c - 0x20;
120+
}
121+
return c;
122+
}

tests/basics/string_upperlow.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
print("".lower())
2+
print(" t\tn\nr\rv\vf\f".upper())
3+
print(" T E S T".lower())
4+
print("*@a1b2cabc_[]/\\".upper())

0 commit comments

Comments
 (0)