Skip to content

Commit

Permalink
implement toupper and tolower independently of libc
Browse files Browse the repository at this point in the history
  • Loading branch information
Charlie Somerville committed Oct 20, 2012
1 parent 918f49f commit 7d6b9dd
Show file tree
Hide file tree
Showing 5 changed files with 853 additions and 23 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -10,4 +10,5 @@
local.mk
src/init_exts.c
src/lib/error_page.c
src/CaseFolding-3.2.0.txt
tmp
5 changes: 4 additions & 1 deletion Makefile
Expand Up @@ -12,7 +12,7 @@ OBJS+=src/class.o src/error.o src/method.o src/object.o src/st.o src/string.o \
src/lib/lambda.o src/lib/enumerable.o src/lib/file.o src/init_exts.o \
src/lib/rand.o src/lib/dict.o src/lib/request.o src/lib/response.o \
src/lib/error_page.o src/lib/system.o src/lib/regexp.o src/gc.o \
src/lib/range.o src/vm_exec.o src/compile.o src/lib/time.o
src/lib/range.o src/vm_exec.o src/compile.o src/lib/time.o src/unicode.o

SAPIS=$(shell ls -F sapi | grep "/" | sed -e 's/\///')

Expand All @@ -37,6 +37,9 @@ libslash.a: $(OBJS)

src/lex.o: CFLAGS += -Wno-unused -Wno-unused-parameter -Wno-sign-compare

src/unicode.c: src/CaseFolding-3.2.0.txt scripts/generate-unicode-c.pl
perl scripts/generate-unicode-c.pl

%.o: %.c inc/*.h inc/*/*.h inc/*/*/*.h Makefile local.mk
@echo "cc $<"
@$(CC) -o $@ $(WARNING_CFLAGS) $(CFLAGS) -c $<
Expand Down
51 changes: 35 additions & 16 deletions src/string.c
Expand Up @@ -9,6 +9,7 @@
#include <slash/vm.h>
#include <slash/class.h>
#include <slash/utf8.h>
#include <slash/unicode.h>
#include <slash/lib/array.h>
#include <slash/lib/number.h>
#include <slash/lib/regexp.h>
Expand Down Expand Up @@ -675,14 +676,23 @@ sl_string_upper(sl_vm_t* vm, SLVAL selfv)
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);
if(strcmp(retn->encoding, "UTF-8") == 0) {
size_t len = self->buff_len;
uint8_t* buff = self->buff;
size_t out_offset = 0;
uint32_t upper_c;

while(len) {
uint32_t c = sl_utf8_each_char(vm, &buff, &len);
upper_c = sl_unicode_toupper(c);
out_offset += sl_utf32_char_to_utf8(vm, upper_c, retn->buff + out_offset);
}
} else {
for(size_t i = 0; i < retn->buff_len; i++) {
if(retn->buff[i] >= 'a' && retn->buff[i] <= 'z') {
retn->buff[i] -= 'a' - 'A';
}
}
}

return sl_make_ptr((sl_object_t*)retn);
Expand All @@ -695,15 +705,24 @@ sl_string_lower(sl_vm_t* vm, SLVAL 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);
if(strcmp(retn->encoding, "UTF-8") == 0) {
size_t len = self->buff_len;
uint8_t* buff = self->buff;
size_t out_offset = 0;
uint32_t lower_c;

while(len) {
uint32_t c = sl_utf8_each_char(vm, &buff, &len);
lower_c = sl_unicode_tolower(c);
out_offset += sl_utf32_char_to_utf8(vm, lower_c, retn->buff + out_offset);
}
} else {
for(size_t i = 0; i < retn->buff_len; i++) {
if(retn->buff[i] >= 'A' && retn->buff[i] <= 'Z') {
retn->buff[i] += 'a' - 'A';
}
}
}

return sl_make_ptr((sl_object_t*)retn);
Expand Down

0 comments on commit 7d6b9dd

Please sign in to comment.