Permalink
Browse files

implement toupper and tolower independently of libc

  • Loading branch information...
1 parent 918f49f commit 7d6b9dd8c87ca57e5cf078d13b3f14b8de144bb5 @charliesome charliesome committed Oct 20, 2012
Showing with 853 additions and 23 deletions.
  1. +1 −0 .gitignore
  2. +4 −1 Makefile
  3. +35 −16 src/string.c
  4. +813 −0 src/unicode.c
  5. +0 −6 src/vm.c
View
@@ -10,4 +10,5 @@
local.mk
src/init_exts.c
src/lib/error_page.c
+src/CaseFolding-3.2.0.txt
tmp
View
@@ -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/\///')
@@ -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 $<
View
@@ -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>
@@ -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);
@@ -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);
Oops, something went wrong.

0 comments on commit 7d6b9dd

Please sign in to comment.