Skip to content

Commit

Permalink
String#upper, String#lower, set locale on startup
Browse files Browse the repository at this point in the history
  • Loading branch information
Charlie Somerville committed Oct 20, 2012
1 parent 06b3f99 commit 918f49f
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 0 deletions.
6 changes: 6 additions & 0 deletions inc/slash/string.h
Expand Up @@ -57,6 +57,12 @@ sl_string_encode(sl_vm_t* vm, SLVAL self, char* encoding);
SLVAL
sl_string_encode2(sl_vm_t* vm, SLVAL self, SLVAL encoding);

SLVAL
sl_string_upper(sl_vm_t* vm, SLVAL self);

SLVAL
sl_string_lower(sl_vm_t* vm, SLVAL self);

int
sl_string_byte_offset_for_index(sl_vm_t* vm, SLVAL str, int index);

Expand Down
45 changes: 45 additions & 0 deletions src/string.c
Expand Up @@ -3,6 +3,7 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <slash/string.h>
#include <slash/value.h>
#include <slash/vm.h>
Expand Down Expand Up @@ -666,6 +667,48 @@ sl_string_replace(sl_vm_t* vm, SLVAL self, SLVAL search, SLVAL replace)
}
}

SLVAL
sl_string_upper(sl_vm_t* vm, SLVAL selfv)
{
sl_string_t* self = get_string(vm, selfv);
sl_string_t* retn = get_string(vm, sl_allocate(vm, vm->lib.String));
memcpy(retn, self, sizeof(sl_string_t));
retn->buff = sl_alloc_buffer(vm->arena, retn->buff_len);

size_t len = self->buff_len;
uint8_t* buff = self->buff;
size_t out_offset = 0;

while(len) {
uint32_t c = sl_utf8_each_char(vm, &buff, &len);
uint32_t upper_c = toupper(c);
out_offset += sl_utf32_char_to_utf8(vm, upper_c, retn->buff + out_offset);
}

return sl_make_ptr((sl_object_t*)retn);
}

SLVAL
sl_string_lower(sl_vm_t* vm, SLVAL selfv)
{
sl_string_t* self = get_string(vm, selfv);
sl_string_t* retn = get_string(vm, sl_allocate(vm, vm->lib.String));
memcpy(retn, self, sizeof(sl_string_t));
retn->buff = sl_alloc_buffer(vm->arena, retn->buff_len);

size_t len = self->buff_len;
uint8_t* buff = self->buff;
size_t out_offset = 0;

while(len) {
uint32_t c = sl_utf8_each_char(vm, &buff, &len);
uint32_t lower_c = tolower(c);
out_offset += sl_utf32_char_to_utf8(vm, lower_c, retn->buff + out_offset);
}

return sl_make_ptr((sl_object_t*)retn);
}

void
sl_init_string(sl_vm_t* vm)
{
Expand All @@ -691,4 +734,6 @@ sl_init_string(sl_vm_t* vm)
sl_define_method(vm, vm->lib.String, "format", -1, sl_string_format);
sl_define_method(vm, vm->lib.String, "encode", 1, sl_string_encode2);
sl_define_method(vm, vm->lib.String, "replace", 2, sl_string_replace);
sl_define_method(vm, vm->lib.String, "upper", 0, sl_string_upper);
sl_define_method(vm, vm->lib.String, "lower", 0, sl_string_lower);
}
7 changes: 7 additions & 0 deletions src/vm.c
@@ -1,4 +1,5 @@
#include <stdlib.h>
#include <locale.h>
#include <time.h>
#include <slash/lib/rand.h>
#include <slash/value.h>
Expand All @@ -24,6 +25,12 @@ sl_static_init()
}
sl_statically_initialized = 1;
sl_static_init_exts();

if(getenv("LANG")) {
setlocale(LC_ALL, getenv("LANG"));
} else {
setlocale(LC_ALL, "en_US.UTF-8");
}
}

#define LIB(lib) void sl_init_##lib(sl_vm_t*)
Expand Down
10 changes: 10 additions & 0 deletions test/core/string.sl
Expand Up @@ -132,4 +132,14 @@ class StringTest extends Test {
def test_replace_regexp_lambda {
assert_equal("A:B::C", "A1B2C".replace(%r{\d}, \x { ":" * x[0].to_i }));
}
def test_lower {
assert_equal("abcdef", "AbCdEf".lower);
assert_equal("åéîøü", "ÅÉÎØÜ".lower);
}
def test_upper {
assert_equal("ABCDEF", "AbCdEf".upper);
assert_equal("ÅÉÎØÜ", "åéîøü".upper);
}
}.register;

0 comments on commit 918f49f

Please sign in to comment.