Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 825

Show
Ignore:
Timestamp:
12/28/10 03:26:53 (14 years ago)
Author:
walter
Message:

bugzilla 4389 ICE(constfold.c, expression.c), or wrong code: string~=dchar in CTFE

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmd-1.x/src/constfold.c

    r670 r825  
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <assert.h> 
    1414#include <math.h> 
    1515 
    1616#if __DMC__ 
    1717#include <complex.h> 
    1818#endif 
    1919 
    2020#include "rmem.h" 
    2121#include "root.h" 
    2222#include "port.h" 
    2323 
    2424#include "mtype.h" 
    2525#include "expression.h" 
    2626#include "aggregate.h" 
    2727#include "declaration.h" 
     28#include "utf.h" 
    2829 
    2930#ifdef IN_GCC 
    3031#include "d-gcc-real.h" 
    3132 
    3233/* %% fix? */ 
    3334extern "C" bool real_isnan (const real_t *); 
    3435#endif 
    3536 
    3637static real_t zero;     // work around DMC bug for now 
    3738 
    3839#if __FreeBSD__ 
    3940#define fmodl fmod      // hack for now, fix later 
    4041#endif 
    4142 
    4243#define LOG 0 
    4344 
    4445Expression *expType(Type *type, Expression *e) 
    4546{ 
    4647    if (type != e->type) 
    4748    { 
     
    13041305            e->type = type; 
    13051306        } 
    13061307    } 
    13071308    return e; 
    13081309} 
    13091310 
    13101311/* Also return EXP_CANT_INTERPRET if this fails 
    13111312 */ 
    13121313Expression *Cat(Type *type, Expression *e1, Expression *e2) 
    13131314{   Expression *e = EXP_CANT_INTERPRET; 
    13141315    Loc loc = e1->loc; 
    13151316    Type *t; 
    13161317    Type *t1 = e1->type->toBasetype(); 
    13171318    Type *t2 = e2->type->toBasetype(); 
    13181319 
    13191320    //printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 
    13201321    //printf("\tt1 = %s, t2 = %s, type = %s\n", t1->toChars(), t2->toChars(), type->toChars()); 
    13211322 
    13221323    if (e1->op == TOKnull && (e2->op == TOKint64 || e2->op == TOKstructliteral)) 
    13231324    {   e = e2; 
     1325        t = t1; 
    13241326        goto L2; 
    13251327    } 
    13261328    else if ((e1->op == TOKint64 || e1->op == TOKstructliteral) && e2->op == TOKnull) 
    13271329    {   e = e1; 
     1330        t = t2; 
    13281331     L2: 
    13291332        Type *tn = e->type->toBasetype(); 
    13301333        if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) 
    13311334        { 
    13321335            // Create a StringExp 
    13331336            void *s; 
    13341337            StringExp *es; 
    1335             size_t len = 1; 
    1336             int sz = tn->size(); 
     1338            if (t->nextOf()) 
     1339                t = t->nextOf()->toBasetype(); 
     1340            int sz = t->size(); 
     1341 
    13371342            dinteger_t v = e->toInteger(); 
    13381343 
     1344            size_t len = utf_codeLength(sz, v); 
    13391345            s = mem.malloc((len + 1) * sz); 
    1340             memcpy((unsigned char *)s, &v, sz); 
     1346            utf_encode(sz, s, v); 
    13411347 
    13421348            // Add terminating 0 
    13431349            memset((unsigned char *)s + len * sz, 0, sz); 
    13441350 
    13451351            es = new StringExp(loc, s, len); 
    13461352            es->sz = sz; 
    13471353            es->committed = 1; 
    13481354            e = es; 
    13491355        } 
    13501356        else 
    13511357        {   // Create an ArrayLiteralExp 
    13521358            Expressions *elements = new Expressions(); 
    13531359            elements->push(e); 
    13541360            e = new ArrayLiteralExp(e->loc, elements); 
    13551361        } 
    13561362        e->type = type; 
    13571363        return e; 
    13581364    } 
    13591365    else if (e1->op == TOKstring && e2->op == TOKstring) 
    13601366    { 
     
    13821388        // Add terminating 0 
    13831389        memset((unsigned char *)s + len * sz, 0, sz); 
    13841390 
    13851391        es = new StringExp(loc, s, len); 
    13861392        es->sz = sz; 
    13871393        es->committed = es1->committed | es2->committed; 
    13881394        if (es1->committed) 
    13891395            t = es1->type; 
    13901396        else 
    13911397            t = es2->type; 
    13921398        es->type = type; 
    13931399        e = es; 
    13941400    } 
    13951401    else if (e1->op == TOKstring && e2->op == TOKint64) 
    13961402    { 
    13971403        // Concatenate the strings 
    13981404        void *s; 
    13991405        StringExp *es1 = (StringExp *)e1; 
    14001406        StringExp *es; 
    14011407        Type *t; 
    1402         size_t len = es1->len + 1; 
    14031408        int sz = es1->sz; 
    14041409        dinteger_t v = e2->toInteger(); 
    14051410 
     1411        size_t len = es1->len + utf_codeLength(sz, v); 
    14061412        s = mem.malloc((len + 1) * sz); 
    14071413        memcpy(s, es1->string, es1->len * sz); 
    1408         memcpy((unsigned char *)s + es1->len * sz, &v, sz); 
     1414        utf_encode(sz, (unsigned char *)s + (sz * es1->len), v); 
    14091415 
    14101416        // Add terminating 0 
    14111417        memset((unsigned char *)s + len * sz, 0, sz); 
    14121418 
    14131419        es = new StringExp(loc, s, len); 
    14141420        es->sz = sz; 
    14151421        es->committed = es1->committed; 
    14161422        t = es1->type; 
    14171423        es->type = type; 
    14181424        e = es; 
    14191425    } 
    14201426    else if (e1->op == TOKint64 && e2->op == TOKstring) 
    14211427    { 
    14221428        // Concatenate the strings 
    14231429        void *s; 
    14241430        StringExp *es2 = (StringExp *)e2; 
    14251431        StringExp *es; 
    14261432        Type *t; 
    14271433        size_t len = 1 + es2->len; 
    14281434        int sz = es2->sz; 
     
    14381444        es = new StringExp(loc, s, len); 
    14391445        es->sz = sz; 
    14401446        es->committed = es2->committed; 
    14411447        t = es2->type; 
    14421448        es->type = type; 
    14431449        e = es; 
    14441450    } 
    14451451    else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral && 
    14461452        e1->type->equals(e2->type)) 
    14471453    { 
    14481454        // Concatenate the arrays 
    14491455        ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; 
    14501456        ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; 
    14511457 
    14521458        es1 = new ArrayLiteralExp(es1->loc, (Expressions *)es1->elements->copy()); 
    14531459        es1->elements->insert(es1->elements->dim, es2->elements); 
    14541460        e = es1; 
    14551461 
    14561462        if (type->toBasetype()->ty == Tsarray) 
    14571463        { 
    1458             e->type = new TypeSArray(t1->next, new IntegerExp(loc, es1->elements->dim, Type::tindex)); 
     1464            e->type = new TypeSArray(t1->nextOf(), new IntegerExp(loc, es1->elements->dim, Type::tindex)); 
    14591465            e->type = e->type->semantic(loc, NULL); 
    14601466        } 
    14611467        else 
    14621468            e->type = type; 
    14631469    } 
    14641470    else if (e1->op == TOKarrayliteral && e2->op == TOKnull && 
    14651471        t1->nextOf()->equals(t2->nextOf())) 
    14661472    { 
    14671473        e = e1; 
    14681474        goto L3; 
    14691475    } 
    14701476    else if (e1->op == TOKnull && e2->op == TOKarrayliteral && 
    14711477        t1->nextOf()->equals(t2->nextOf())) 
    14721478    { 
    14731479        e = e2; 
    14741480     L3: 
    14751481        // Concatenate the array with null 
    14761482        ArrayLiteralExp *es = (ArrayLiteralExp *)e; 
    14771483 
    14781484        es = new ArrayLiteralExp(es->loc, (Expressions *)es->elements->copy()); 
  • branches/dmd-1.x/src/utf.c

    r493 r825  
    11// utf.c 
    2 // Copyright (c) 2003-2010 by Digital Mars 
     2// Copyright (c) 2003-2009 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
    55// http://www.digitalmars.com 
    66// License for redistribution is by either the Artistic License 
    77// in artistic.txt, or the GNU General Public License in gnu.txt. 
    88// See the included readme.txt for details. 
    99 
    1010// Description of UTF-8 at: 
    1111// http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    1212 
    1313#include <stdio.h> 
     14#include <string.h> 
    1415#include <assert.h> 
    1516 
    1617#include "utf.h" 
    1718 
    1819int utf_isValidDchar(dchar_t c) 
    1920{ 
    2021    return c < 0xD800 || 
    2122        (c > 0xDFFF && c <= 0x10FFFF && c != 0xFFFE && c != 0xFFFF); 
     23} 
     24 
     25static const unsigned char UTF8stride[256] = 
     26{ 
     27    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
     28    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
     29    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
     30    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
     31    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
     32    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
     33    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
     34    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
     35    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 
     36    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 
     37    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 
     38    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 
     39    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 
     40    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 
     41    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 
     42    4,4,4,4,4,4,4,4,5,5,5,5,6,6,0xFF,0xFF, 
     43}; 
     44 
     45/** 
     46 * stride() returns the length of a UTF-8 sequence starting at index i 
     47 * in string s. 
     48 * Returns: 
     49 *  The number of bytes in the UTF-8 sequence or 
     50 *  0xFF meaning s[i] is not the start of of UTF-8 sequence. 
     51 */ 
     52 
     53unsigned stride(unsigned char* s, size_t i) 
     54{ 
     55    unsigned result = UTF8stride[s[i]]; 
     56    return result; 
    2257} 
    2358 
    2459/******************************************** 
    2560 * Decode a single UTF-8 character sequence. 
    2661 * Returns: 
    2762 *      NULL    success 
    2863 *      !=NULL  error message string 
    2964 */ 
    3065 
    3166const char *utf_decodeChar(unsigned char *s, size_t len, size_t *pidx, dchar_t *presult) 
    3267{ 
    3368    dchar_t V; 
    3469    size_t i = *pidx; 
    3570    unsigned char u = s[i]; 
    3671 
    3772    //printf("utf_decodeChar(s = %02x, %02x, %02x len = %d)\n", u, s[1], s[2], len); 
    3873 
    3974    assert(i >= 0 && i < len); 
    4075 
    4176    if (u & 0x80) 
     
    176211        } 
    177212        else 
    178213            i++; 
    179214    } 
    180215    else 
    181216    { 
    182217        i++; 
    183218    } 
    184219 
    185220    assert(utf_isValidDchar(u)); 
    186221    *pidx = i; 
    187222    *presult = (dchar_t)u; 
    188223    return NULL; 
    189224 
    190225  Lerr: 
    191226    *presult = (dchar_t)s[i]; 
    192227    *pidx = i + 1; 
    193228    return msg; 
    194229} 
    195230 
     231void utf_encodeChar(unsigned char *s, dchar_t c) 
     232{ 
     233    if (c <= 0x7F) 
     234    { 
     235        s[0] = (char) c; 
     236    } 
     237    else if (c <= 0x7FF) 
     238    { 
     239        s[0] = (char)(0xC0 | (c >> 6)); 
     240        s[1] = (char)(0x80 | (c & 0x3F)); 
     241    } 
     242    else if (c <= 0xFFFF) 
     243    { 
     244        s[0] = (char)(0xE0 | (c >> 12)); 
     245        s[1] = (char)(0x80 | ((c >> 6) & 0x3F)); 
     246        s[2] = (char)(0x80 | (c & 0x3F)); 
     247    } 
     248    else if (c <= 0x10FFFF) 
     249    { 
     250        s[0] = (char)(0xF0 | (c >> 18)); 
     251        s[1] = (char)(0x80 | ((c >> 12) & 0x3F)); 
     252        s[2] = (char)(0x80 | ((c >> 6) & 0x3F)); 
     253        s[3] = (char)(0x80 | (c & 0x3F)); 
     254    } 
     255    else 
     256        assert(0); 
     257} 
     258 
     259void utf_encodeWchar(unsigned short *s, dchar_t c) 
     260{ 
     261    if (c <= 0xFFFF) 
     262    { 
     263        s[0] = (wchar_t) c; 
     264    } 
     265    else 
     266    { 
     267        s[0] = (wchar_t) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800); 
     268        s[1] = (wchar_t) (((c - 0x10000) & 0x3FF) + 0xDC00); 
     269    } 
     270} 
     271 
     272 
     273/** 
     274 * Returns the code length of c in the encoding. 
     275 * The code is returned in character count, not in bytes. 
     276 */ 
     277 
     278int utf_codeLengthChar(dchar_t c) 
     279{ 
     280    return 
     281        c <= 0x7F ? 1 
     282        : c <= 0x7FF ? 2 
     283        : c <= 0xFFFF ? 3 
     284        : c <= 0x10FFFF ? 4 
     285        : (assert(false), 6); 
     286} 
     287 
     288int utf_codeLengthWchar(dchar_t c) 
     289{ 
     290    return c <= 0xFFFF ? 1 : 2; 
     291} 
     292 
     293/** 
     294 * Returns the code length of c in the encoding. 
     295 * sz is the encoding: 1 = utf8, 2 = utf16, 4 = utf32. 
     296 * The code is returned in character count, not in bytes. 
     297 */ 
     298int utf_codeLength(int sz, dchar_t c) 
     299{ 
     300    if (sz == 1) 
     301        return utf_codeLengthChar(c); 
     302    if (sz == 2) 
     303        return utf_codeLengthWchar(c); 
     304    assert(sz == 4); 
     305    return 1; 
     306} 
     307 
     308void utf_encode(int sz, void *s, dchar_t c) 
     309{ 
     310    if (sz == 1) 
     311        utf_encodeChar((unsigned char *)s, c); 
     312    else if (sz == 2) 
     313        utf_encodeWchar((unsigned short *)s, c); 
     314    else 
     315    { 
     316        assert(sz == 4); 
     317        memcpy((unsigned char *)s, &c, sz); 
     318    } 
     319} 
     320 
  • branches/dmd-1.x/src/utf.h

    r493 r825  
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#ifndef DMD_UTF_H 
    1212#define DMD_UTF_H 
    1313 
    1414 
    1515typedef unsigned dchar_t; 
    1616 
    1717int utf_isValidDchar(dchar_t c); 
    1818 
    1919const char *utf_decodeChar(unsigned char *s, size_t len, size_t *pidx, dchar_t *presult); 
    2020const char *utf_decodeWchar(unsigned short *s, size_t len, size_t *pidx, dchar_t *presult); 
    2121 
    2222const char *utf_validateString(unsigned char *s, size_t len); 
    2323 
    2424extern int isUniAlpha(dchar_t); 
    2525 
     26void utf_encodeChar(unsigned char *s, dchar_t c); 
     27void utf_encodeWchar(unsigned short *s, dchar_t c); 
     28 
     29int utf_codeLengthChar(dchar_t c); 
     30int utf_codeLengthWchar(dchar_t c); 
     31 
     32int utf_codeLength(int sz, dchar_t c); 
     33void utf_encode(int sz, void *s, dchar_t c); 
     34 
    2635#endif 
  • trunk/src/constfold.c

    r670 r825  
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#include <stdio.h> 
    1212#include <stdlib.h> 
    1313#include <assert.h> 
    1414#include <math.h> 
    1515 
    1616#if __DMC__ 
    1717#include <complex.h> 
    1818#endif 
    1919 
    2020#include "rmem.h" 
    2121#include "root.h" 
    2222#include "port.h" 
    2323 
    2424#include "mtype.h" 
    2525#include "expression.h" 
    2626#include "aggregate.h" 
    2727#include "declaration.h" 
     28#include "utf.h" 
    2829 
    2930#if __FreeBSD__ 
    3031#define fmodl fmod      // hack for now, fix later 
    3132#endif 
    3233 
    3334#define LOG 0 
    3435 
    3536Expression *expType(Type *type, Expression *e) 
    3637{ 
    3738    if (type != e->type) 
    3839    { 
    3940        e = e->copy(); 
    4041        e->type = type; 
    4142    } 
    4243    return e; 
    4344} 
    4445 
    4546/* ================================== isConst() ============================== */ 
    4647 
    4748int Expression::isConst() 
     
    13361337            e->type = type; 
    13371338        } 
    13381339    } 
    13391340    return e; 
    13401341} 
    13411342 
    13421343/* Also return EXP_CANT_INTERPRET if this fails 
    13431344 */ 
    13441345Expression *Cat(Type *type, Expression *e1, Expression *e2) 
    13451346{   Expression *e = EXP_CANT_INTERPRET; 
    13461347    Loc loc = e1->loc; 
    13471348    Type *t; 
    13481349    Type *t1 = e1->type->toBasetype(); 
    13491350    Type *t2 = e2->type->toBasetype(); 
    13501351 
    13511352    //printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 
    13521353    //printf("\tt1 = %s, t2 = %s, type = %s\n", t1->toChars(), t2->toChars(), type->toChars()); 
    13531354 
    13541355    if (e1->op == TOKnull && (e2->op == TOKint64 || e2->op == TOKstructliteral)) 
    13551356    {   e = e2; 
     1357        t = t1; 
    13561358        goto L2; 
    13571359    } 
    13581360    else if ((e1->op == TOKint64 || e1->op == TOKstructliteral) && e2->op == TOKnull) 
    13591361    {   e = e1; 
     1362        t = t2; 
    13601363     L2: 
    13611364        Type *tn = e->type->toBasetype(); 
    13621365        if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) 
    13631366        { 
    13641367            // Create a StringExp 
    13651368            void *s; 
    13661369            StringExp *es; 
    1367             size_t len = 1; 
    1368             int sz = tn->size(); 
     1370            if (t->nextOf()) 
     1371                t = t->nextOf()->toBasetype(); 
     1372            int sz = t->size(); 
     1373 
    13691374            dinteger_t v = e->toInteger(); 
    13701375 
     1376            size_t len = utf_codeLength(sz, v); 
    13711377            s = mem.malloc((len + 1) * sz); 
    1372             memcpy((unsigned char *)s, &v, sz); 
     1378            utf_encode(sz, s, v); 
    13731379 
    13741380            // Add terminating 0 
    13751381            memset((unsigned char *)s + len * sz, 0, sz); 
    13761382 
    13771383            es = new StringExp(loc, s, len); 
    13781384            es->sz = sz; 
    13791385            es->committed = 1; 
    13801386            e = es; 
    13811387        } 
    13821388        else 
    13831389        {   // Create an ArrayLiteralExp 
    13841390            Expressions *elements = new Expressions(); 
    13851391            elements->push(e); 
    13861392            e = new ArrayLiteralExp(e->loc, elements); 
    13871393        } 
    13881394        e->type = type; 
    13891395        return e; 
    13901396    } 
    13911397    else if (e1->op == TOKstring && e2->op == TOKstring) 
    13921398    { 
     
    14421448            dinteger_t v = es2e->toInteger(); 
    14431449            memcpy((unsigned char *)s + (es1->len + i) * sz, &v, sz); 
    14441450        } 
    14451451 
    14461452        // Add terminating 0 
    14471453        memset((unsigned char *)s + len * sz, 0, sz); 
    14481454 
    14491455        StringExp *es = new StringExp(loc, s, len); 
    14501456        es->sz = sz; 
    14511457        es->committed = 0; //es1->committed; 
    14521458        es->type = type; 
    14531459        e = es; 
    14541460    } 
    14551461    else if (e1->op == TOKstring && e2->op == TOKint64) 
    14561462    { 
    14571463        // Concatenate the strings 
    14581464        void *s; 
    14591465        StringExp *es1 = (StringExp *)e1; 
    14601466        StringExp *es; 
    14611467        Type *t; 
    1462         size_t len = es1->len + 1; 
    14631468        int sz = es1->sz; 
    14641469        dinteger_t v = e2->toInteger(); 
    14651470 
     1471        size_t len = es1->len + utf_codeLength(sz, v); 
    14661472        s = mem.malloc((len + 1) * sz); 
    14671473        memcpy(s, es1->string, es1->len * sz); 
    1468         memcpy((unsigned char *)s + es1->len * sz, &v, sz); 
     1474        utf_encode(sz, (unsigned char *)s + (sz * es1->len), v); 
    14691475 
    14701476        // Add terminating 0 
    14711477        memset((unsigned char *)s + len * sz, 0, sz); 
    14721478 
    14731479        es = new StringExp(loc, s, len); 
    14741480        es->sz = sz; 
    14751481        es->committed = es1->committed; 
    14761482        t = es1->type; 
    14771483        es->type = type; 
    14781484        e = es; 
    14791485    } 
    14801486    else if (e1->op == TOKint64 && e2->op == TOKstring) 
    14811487    { 
    14821488        // Concatenate the strings 
    14831489        void *s; 
    14841490        StringExp *es2 = (StringExp *)e2; 
    14851491        StringExp *es; 
    14861492        Type *t; 
    14871493        size_t len = 1 + es2->len; 
    14881494        int sz = es2->sz; 
  • trunk/src/utf.c

    r436 r825  
    11// utf.c 
    22// Copyright (c) 2003-2009 by Digital Mars 
    33// All Rights Reserved 
    44// written by Walter Bright 
    55// http://www.digitalmars.com 
    66// License for redistribution is by either the Artistic License 
    77// in artistic.txt, or the GNU General Public License in gnu.txt. 
    88// See the included readme.txt for details. 
    99 
    1010// Description of UTF-8 at: 
    1111// http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 
    1212 
    1313#include <stdio.h> 
     14#include <string.h> 
    1415#include <assert.h> 
    1516 
    1617#include "utf.h" 
    1718 
    1819int utf_isValidDchar(dchar_t c) 
    1920{ 
    2021    return c < 0xD800 || 
    2122        (c > 0xDFFF && c <= 0x10FFFF && c != 0xFFFE && c != 0xFFFF); 
    2223} 
    2324 
    2425static const unsigned char UTF8stride[256] = 
    2526{ 
    2627    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
    2728    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
    2829    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
    2930    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
    3031    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
    3132    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
    3233    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
    3334    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
     
    210211        } 
    211212        else 
    212213            i++; 
    213214    } 
    214215    else 
    215216    { 
    216217        i++; 
    217218    } 
    218219 
    219220    assert(utf_isValidDchar(u)); 
    220221    *pidx = i; 
    221222    *presult = (dchar_t)u; 
    222223    return NULL; 
    223224 
    224225  Lerr: 
    225226    *presult = (dchar_t)s[i]; 
    226227    *pidx = i + 1; 
    227228    return msg; 
    228229} 
    229230 
     231void utf_encodeChar(unsigned char *s, dchar_t c) 
     232{ 
     233    if (c <= 0x7F) 
     234    { 
     235        s[0] = (char) c; 
     236    } 
     237    else if (c <= 0x7FF) 
     238    { 
     239        s[0] = (char)(0xC0 | (c >> 6)); 
     240        s[1] = (char)(0x80 | (c & 0x3F)); 
     241    } 
     242    else if (c <= 0xFFFF) 
     243    { 
     244        s[0] = (char)(0xE0 | (c >> 12)); 
     245        s[1] = (char)(0x80 | ((c >> 6) & 0x3F)); 
     246        s[2] = (char)(0x80 | (c & 0x3F)); 
     247    } 
     248    else if (c <= 0x10FFFF) 
     249    { 
     250        s[0] = (char)(0xF0 | (c >> 18)); 
     251        s[1] = (char)(0x80 | ((c >> 12) & 0x3F)); 
     252        s[2] = (char)(0x80 | ((c >> 6) & 0x3F)); 
     253        s[3] = (char)(0x80 | (c & 0x3F)); 
     254    } 
     255    else 
     256        assert(0); 
     257} 
     258 
     259void utf_encodeWchar(unsigned short *s, dchar_t c) 
     260{ 
     261    if (c <= 0xFFFF) 
     262    { 
     263        s[0] = (wchar_t) c; 
     264    } 
     265    else 
     266    { 
     267        s[0] = (wchar_t) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800); 
     268        s[1] = (wchar_t) (((c - 0x10000) & 0x3FF) + 0xDC00); 
     269    } 
     270} 
     271 
     272 
     273/** 
     274 * Returns the code length of c in the encoding. 
     275 * The code is returned in character count, not in bytes. 
     276 */ 
     277 
     278int utf_codeLengthChar(dchar_t c) 
     279{ 
     280    return 
     281        c <= 0x7F ? 1 
     282        : c <= 0x7FF ? 2 
     283        : c <= 0xFFFF ? 3 
     284        : c <= 0x10FFFF ? 4 
     285        : (assert(false), 6); 
     286} 
     287 
     288int utf_codeLengthWchar(dchar_t c) 
     289{ 
     290    return c <= 0xFFFF ? 1 : 2; 
     291} 
     292 
     293/** 
     294 * Returns the code length of c in the encoding. 
     295 * sz is the encoding: 1 = utf8, 2 = utf16, 4 = utf32. 
     296 * The code is returned in character count, not in bytes. 
     297 */ 
     298int utf_codeLength(int sz, dchar_t c) 
     299{ 
     300    if (sz == 1) 
     301        return utf_codeLengthChar(c); 
     302    if (sz == 2) 
     303        return utf_codeLengthWchar(c); 
     304    assert(sz == 4); 
     305    return 1; 
     306} 
     307 
     308void utf_encode(int sz, void *s, dchar_t c) 
     309{ 
     310    if (sz == 1) 
     311        utf_encodeChar((unsigned char *)s, c); 
     312    else if (sz == 2) 
     313        utf_encodeWchar((unsigned short *)s, c); 
     314    else 
     315    { 
     316        assert(sz == 4); 
     317        memcpy((unsigned char *)s, &c, sz); 
     318    } 
     319} 
     320 
  • trunk/src/utf.h

    r189 r825  
    11// Compiler implementation of the D programming language 
    22// utf.h 
    3 // Copyright (c) 2003-2008 by Digital Mars 
     3// Copyright (c) 2003-2010 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111#ifndef DMD_UTF_H 
    1212#define DMD_UTF_H 
    1313 
    1414 
    1515typedef unsigned dchar_t; 
    1616 
    1717int utf_isValidDchar(dchar_t c); 
    1818 
    1919const char *utf_decodeChar(unsigned char *s, size_t len, size_t *pidx, dchar_t *presult); 
    2020const char *utf_decodeWchar(unsigned short *s, size_t len, size_t *pidx, dchar_t *presult); 
    2121 
    2222const char *utf_validateString(unsigned char *s, size_t len); 
    2323 
    2424extern int isUniAlpha(dchar_t); 
    2525 
     26void utf_encodeChar(unsigned char *s, dchar_t c); 
     27void utf_encodeWchar(unsigned short *s, dchar_t c); 
     28 
     29int utf_codeLengthChar(dchar_t c); 
     30int utf_codeLengthWchar(dchar_t c); 
     31 
     32int utf_codeLength(int sz, dchar_t c); 
     33void utf_encode(int sz, void *s, dchar_t c); 
     34 
    2635#endif