diff --git a/bin/make_ci.pike b/bin/make_ci.pike index a3f0c0ee899d64ffa430b978bad1c7d027d54f77..90393dab9eba39493da1782089c33eeaa1a111fe 100644 --- a/bin/make_ci.pike +++ b/bin/make_ci.pike @@ -1,5 +1,5 @@ /* - * $Id: make_ci.pike,v 1.4 1999/03/20 16:30:55 grubba Exp $ + * $Id: make_ci.pike,v 1.5 2000/07/27 17:46:47 lange Exp $ * * Creates the file case_info.h * @@ -73,7 +73,7 @@ int main(int argc, array(string) argv) write(sprintf("/*\n" " * Created by\n" - " * $Id: make_ci.pike,v 1.4 1999/03/20 16:30:55 grubba Exp $\n" + " * $Id: make_ci.pike,v 1.5 2000/07/27 17:46:47 lange Exp $\n" " * on %s" " *\n" " * Table used for looking up the case of\n" @@ -90,6 +90,11 @@ int main(int argc, array(string) argv) (info[2]<0)?"-":"", (info[2]<0)?-info[2]:info[2])); } + + for (lineno=0; lineno<sizeof(ci); lineno++) + if (ci[lineno][0] > 0xff) + break; + write(sprintf("#define CASE_INFO_SHIFT0_HIGH 0x%04x\n", lineno)); exit(0); } diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 497c25f00c6069baa69004017201a48c26340cb8..064dc2f63d970c147f18a024da514384d72f4519 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.291 2000/07/19 16:48:51 lange Exp $"); +RCSID("$Id: builtin_functions.c,v 1.292 2000/07/27 17:47:29 lange Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -169,7 +169,7 @@ static struct case_info *find_ci(int c) return NULL; if ((ci) && (ci[0].low <= c) && (ci[1].low > c)) { - return ci; + return ci; } while (lo != hi-1) { @@ -186,6 +186,34 @@ static struct case_info *find_ci(int c) return(cache = (struct case_info *)case_info + lo); } +static struct case_info *find_ci_shift0(int c) +{ + static struct case_info *cache = NULL; + struct case_info *ci = cache; + int lo = 0; + int hi = CASE_INFO_SHIFT0_HIGH; + + if ((c < 0) || (c > 0xffff)) + return NULL; + + if ((ci) && (ci[0].low <= c) && (ci[1].low > c)) { + return ci; + } + + while (lo != hi-1) { + int mid = (lo + hi)>>1; + if (case_info[mid].low < c) { + lo = mid; + } else if (case_info[mid].low == c) { + lo = mid; + break; + } else { + hi = mid; + } + } + return(cache = (struct case_info *)case_info + lo); +} + #define DO_LOWER_CASE(C) do {\ int c = C; \ struct case_info *ci = find_ci(c); \ @@ -200,6 +228,20 @@ static struct case_info *find_ci(int c) } \ } while(0) +#define DO_LOWER_CASE_SHIFT0(C) do {\ + int c = C; \ + struct case_info *ci = find_ci_shift0(c); \ + if (ci) { \ + switch(ci->mode) { \ + case CIM_NONE: case CIM_LOWERDELTA: break; \ + case CIM_UPPERDELTA: C = c + ci->data; break; \ + case CIM_CASEBIT: C = c | ci->data; break; \ + case CIM_CASEBITOFF: C = ((c - ci->data) | ci->data) + ci->data; break; \ + default: fatal("lower_case(): Unknown case_info mode: %d\n", ci->mode); \ + } \ + } \ + } while(0) + #define DO_UPPER_CASE(C) do {\ int c = C; \ struct case_info *ci = find_ci(c); \ @@ -214,6 +256,20 @@ static struct case_info *find_ci(int c) } \ } while(0) +#define DO_UPPER_CASE_SHIFT0(C) do {\ + int c = C; \ + struct case_info *ci = find_ci_shift0(c); \ + if (ci) { \ + switch(ci->mode) { \ + case CIM_NONE: case CIM_UPPERDELTA: break; \ + case CIM_LOWERDELTA: C = c - ci->data; break; \ + case CIM_CASEBIT: C = c & ~ci->data; break; \ + case CIM_CASEBITOFF: C = ((c - ci->data)& ~ci->data) + ci->data; break; \ + default: fatal("lower_case(): Unknown case_info mode: %d\n", ci->mode); \ + } \ + } \ + } while(0) + void f_lower_case(INT32 args) { INT32 i; @@ -231,7 +287,7 @@ void f_lower_case(INT32 args) p_wchar0 *str = STR0(ret); while(i--) { - DO_LOWER_CASE(str[i]); + DO_LOWER_CASE_SHIFT0(str[i]); } } else if (orig->size_shift == 1) { p_wchar1 *str = STR1(ret); @@ -271,7 +327,7 @@ void f_upper_case(INT32 args) while(i--) { if(str[i]!=0xff && str[i]!=0xb5) { - DO_UPPER_CASE(str[i]); + DO_UPPER_CASE_SHIFT0(str[i]); } else { widen = 1; } diff --git a/src/dummy_ci.h b/src/dummy_ci.h index 8224dd80c4cd7475faf19e4ad91e276a10570ebe..e96837932fe809f4c6df63575ab992a7c2f5aac9 100644 --- a/src/dummy_ci.h +++ b/src/dummy_ci.h @@ -1,5 +1,5 @@ /* - * $Id: dummy_ci.h,v 1.3 1999/03/20 16:33:34 grubba Exp $ + * $Id: dummy_ci.h,v 1.4 2000/07/27 17:47:03 lange Exp $ * * Fallback case_info file. * Only ISO-8859-1 in this one. @@ -11,6 +11,8 @@ { 0x005b, CIM_NONE, 0x0000, }, { 0x0061, CIM_CASEBIT, 0x0020, }, { 0x007b, CIM_NONE, 0x0000, }, +{ 0x00b5, CIM_LOWERDELTA, -0x02e7, }, +{ 0x00b6, CIM_NONE, 0x0000, }, { 0x00c0, CIM_CASEBIT, 0x0020, }, { 0x00d7, CIM_NONE, 0x0000, }, { 0x00d8, CIM_CASEBIT, 0x0020, }, @@ -20,3 +22,4 @@ { 0x00f8, CIM_CASEBIT, 0x0020, }, { 0x00ff, CIM_LOWERDELTA, -0x0079, }, { 0x0100, CIM_NONE, 0x0000, }, +#define CASE_INFO_SHIFT0_HIGH 0x000f