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

Changeset 292

Show
Ignore:
Timestamp:
12/12/09 08:17:20 (15 years ago)
Author:
walter
Message:

bugzilla 3455 Some Unicode characters not allowed in identifiers

Files:

Legend:

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

    r248 r292  
    617617#endif 
    618618        case 'a':   case 'b':   case 'c':   case 'd':   case 'e': 
    619619        case 'f':   case 'g':   case 'h':   case 'i':   case 'j': 
    620620        case 'k':               case 'm':   case 'n':   case 'o': 
    621621#if DMDV2 
    622622        case 'p':   /*case 'q': case 'r':*/ case 's':   case 't': 
    623623#else 
    624624        case 'p':   case 'q': /*case 'r':*/ case 's':   case 't': 
    625625#endif 
    626626        case 'u':   case 'v':   case 'w': /*case 'x':*/ case 'y': 
    627627        case 'z': 
    628628        case 'A':   case 'B':   case 'C':   case 'D':   case 'E': 
    629629        case 'F':   case 'G':   case 'H':   case 'I':   case 'J': 
    630630        case 'K':               case 'M':   case 'N':   case 'O': 
    631631        case 'P':   case 'Q':   case 'R':   case 'S':   case 'T': 
    632632        case 'U':   case 'V':   case 'W':   case 'X':   case 'Y': 
    633633        case 'Z': 
    634634        case '_': 
    635635        case_ident: 
    636636        {   unsigned char c; 
    637         StringValue *sv; 
    638         Identifier *id; 
    639  
    640         do 
     637 
     638        while (1) 
    641639        { 
    642640            c = *++p; 
    643         } while (isidchar(c) || (c & 0x80 && isUniAlpha(decodeUTF()))); 
    644         sv = stringtable.update((char *)t->ptr, p - t->ptr); 
    645         id = (Identifier *) sv->ptrvalue; 
     641            if (isidchar(c)) 
     642            continue; 
     643            else if (c & 0x80) 
     644            {   unsigned char *s = p; 
     645            unsigned u = decodeUTF(); 
     646            if (isUniAlpha(u)) 
     647                continue; 
     648            error("char 0x%04x not allowed in identifier", u); 
     649            p = s; 
     650            } 
     651            break; 
     652        } 
     653 
     654        StringValue *sv = stringtable.update((char *)t->ptr, p - t->ptr); 
     655        Identifier *id = (Identifier *) sv->ptrvalue; 
    646656        if (!id) 
    647657        {   id = new Identifier(sv->lstring.string,TOKidentifier); 
    648658            sv->ptrvalue = id; 
    649659        } 
    650660        t->ident = id; 
    651661        t->value = (enum TOK) id->value; 
    652662        anyToken = 1; 
    653663        if (*t->ptr == '_') // if special identifier token 
    654664        { 
    655665            static char date[11+1]; 
    656666            static char time[8+1]; 
    657667            static char timestamp[24+1]; 
    658668 
    659669            if (!date[0])   // lazy evaluation 
    660670            {   time_t t; 
    661671            char *p; 
    662672 
    663673            ::time(&t); 
    664674            p = ctime(&t); 
    665675            assert(p); 
     
    11601170        if (*p == c2)       \ 
    11611171        {   p++;        \ 
    11621172            t->value = tok2;    \ 
    11631173        }           \ 
    11641174        else            \ 
    11651175            t->value = tok1;    \ 
    11661176        return; 
    11671177 
    11681178        DOUBLE('*', TOKmul, '=', TOKmulass) 
    11691179        DOUBLE('%', TOKmod, '=', TOKmodass) 
    11701180        DOUBLE('^', TOKxor, '=', TOKxorass) 
    11711181 
    11721182#undef DOUBLE 
    11731183 
    11741184        case '#': 
    11751185        p++; 
    11761186        pragma(); 
    11771187        continue; 
    11781188 
    11791189        default: 
    1180         {   unsigned char c = *p; 
     1190        {   unsigned c = *p; 
    11811191 
    11821192        if (c & 0x80) 
    1183         {   unsigned u = decodeUTF(); 
     1193        {   c = decodeUTF(); 
    11841194 
    11851195            // Check for start of unicode identifier 
    1186             if (isUniAlpha(u)) 
     1196            if (isUniAlpha(c)) 
    11871197            goto case_ident; 
    11881198 
    1189             if (u == PS || u == LS) 
     1199            if (c == PS || c == LS) 
    11901200            { 
    11911201            loc.linnum++; 
    11921202            p++; 
    11931203            continue; 
    11941204            } 
    11951205        } 
    1196         if (isprint(c)) 
     1206        if (c < 0x80 && isprint(c)) 
    11971207            error("unsupported char '%c'", c); 
    11981208        else 
    11991209            error("unsupported char 0x%02x", c); 
    12001210        p++; 
    12011211        continue; 
    12021212        } 
    12031213    } 
    12041214    } 
    12051215} 
    12061216 
    12071217/******************************************* 
    12081218 * Parse escape sequence. 
    12091219 */ 
    12101220 
    12111221unsigned Lexer::escapeSequence() 
    12121222{   unsigned c; 
    12131223    int n; 
    12141224    int ndigits; 
    12151225 
    12161226    c = *p; 
     
    14381448        stringbuffer.writeByte(0); 
    14391449        t->ustring = (unsigned char *)mem.malloc(stringbuffer.offset); 
    14401450        memcpy(t->ustring, stringbuffer.data, stringbuffer.offset); 
    14411451        stringPostfix(t); 
    14421452        return TOKstring; 
    14431453 
    14441454        default: 
    14451455        if (c >= '0' && c <= '9') 
    14461456            c -= '0'; 
    14471457        else if (c >= 'a' && c <= 'f') 
    14481458            c -= 'a' - 10; 
    14491459        else if (c >= 'A' && c <= 'F') 
    14501460            c -= 'A' - 10; 
    14511461        else if (c & 0x80) 
    14521462        {   p--; 
    14531463            unsigned u = decodeUTF(); 
    14541464            p++; 
    14551465            if (u == PS || u == LS) 
    14561466            loc.linnum++; 
    14571467            else 
    1458             error("non-hex character \\u%x", u); 
     1468            error("non-hex character \\u%04x", u); 
    14591469        } 
    14601470        else 
    14611471            error("non-hex character '%c'", c); 
    14621472        if (n & 1) 
    14631473        {   v = (v << 4) | c; 
    14641474            stringbuffer.writeByte(v); 
    14651475        } 
    14661476        else 
    14671477            v = c; 
    14681478        n++; 
    14691479        break; 
    14701480    } 
    14711481    } 
    14721482} 
    14731483 
    14741484 
    14751485#if DMDV2 
    14761486/************************************** 
    14771487 * Lex delimited strings: 
    14781488 *  q"(foo(xxx))"   // "foo(xxx)" 
  • trunk/src/lexer.c

    r269 r292  
    630630#endif 
    631631        case 'a':   case 'b':   case 'c':   case 'd':   case 'e': 
    632632        case 'f':   case 'g':   case 'h':   case 'i':   case 'j': 
    633633        case 'k':               case 'm':   case 'n':   case 'o': 
    634634#if DMDV2 
    635635        case 'p':   /*case 'q': case 'r':*/ case 's':   case 't': 
    636636#else 
    637637        case 'p':   case 'q': /*case 'r':*/ case 's':   case 't': 
    638638#endif 
    639639        case 'u':   case 'v':   case 'w': /*case 'x':*/ case 'y': 
    640640        case 'z': 
    641641        case 'A':   case 'B':   case 'C':   case 'D':   case 'E': 
    642642        case 'F':   case 'G':   case 'H':   case 'I':   case 'J': 
    643643        case 'K':               case 'M':   case 'N':   case 'O': 
    644644        case 'P':   case 'Q':   case 'R':   case 'S':   case 'T': 
    645645        case 'U':   case 'V':   case 'W':   case 'X':   case 'Y': 
    646646        case 'Z': 
    647647        case '_': 
    648648        case_ident: 
    649649        {   unsigned char c; 
    650         StringValue *sv; 
    651         Identifier *id; 
    652  
    653         do 
     650 
     651        while (1) 
    654652        { 
    655653            c = *++p; 
    656         } while (isidchar(c) || (c & 0x80 && isUniAlpha(decodeUTF()))); 
    657         sv = stringtable.update((char *)t->ptr, p - t->ptr); 
    658         id = (Identifier *) sv->ptrvalue; 
     654            if (isidchar(c)) 
     655            continue; 
     656            else if (c & 0x80) 
     657            {   unsigned char *s = p; 
     658            unsigned u = decodeUTF(); 
     659            if (isUniAlpha(u)) 
     660                continue; 
     661            error("char 0x%04x not allowed in identifier", u); 
     662            p = s; 
     663            } 
     664            break; 
     665        } 
     666 
     667        StringValue *sv = stringtable.update((char *)t->ptr, p - t->ptr); 
     668        Identifier *id = (Identifier *) sv->ptrvalue; 
    659669        if (!id) 
    660670        {   id = new Identifier(sv->lstring.string,TOKidentifier); 
    661671            sv->ptrvalue = id; 
    662672        } 
    663673        t->ident = id; 
    664674        t->value = (enum TOK) id->value; 
    665675        anyToken = 1; 
    666676        if (*t->ptr == '_') // if special identifier token 
    667677        { 
    668678            static char date[11+1]; 
    669679            static char time[8+1]; 
    670680            static char timestamp[24+1]; 
    671681 
    672682            if (!date[0])   // lazy evaluation 
    673683            {   time_t t; 
    674684            char *p; 
    675685 
    676686            ::time(&t); 
    677687            p = ctime(&t); 
    678688            assert(p); 
     
    11981208        {   p++;        \ 
    11991209            t->value = tok2;    \ 
    12001210        }           \ 
    12011211        else            \ 
    12021212            t->value = tok1;    \ 
    12031213        return; 
    12041214 
    12051215        DOUBLE('*', TOKmul, '=', TOKmulass) 
    12061216        DOUBLE('%', TOKmod, '=', TOKmodass) 
    12071217#if DMDV1 
    12081218        DOUBLE('^', TOKxor, '=', TOKxorass) 
    12091219#endif 
    12101220#undef DOUBLE 
    12111221 
    12121222        case '#': 
    12131223        p++; 
    12141224        pragma(); 
    12151225        continue; 
    12161226 
    12171227        default: 
    1218         {   unsigned char c = *p; 
     1228        {   unsigned c = *p; 
    12191229 
    12201230        if (c & 0x80) 
    1221         {   unsigned u = decodeUTF(); 
     1231        {   c = decodeUTF(); 
    12221232 
    12231233            // Check for start of unicode identifier 
    1224             if (isUniAlpha(u)) 
     1234            if (isUniAlpha(c)) 
    12251235            goto case_ident; 
    12261236 
    1227             if (u == PS || u == LS) 
     1237            if (c == PS || c == LS) 
    12281238            { 
    12291239            loc.linnum++; 
    12301240            p++; 
    12311241            continue; 
    12321242            } 
    12331243        } 
    1234         if (isprint(c)) 
     1244        if (c < 0x80 && isprint(c)) 
    12351245            error("unsupported char '%c'", c); 
    12361246        else 
    12371247            error("unsupported char 0x%02x", c); 
    12381248        p++; 
    12391249        continue; 
    12401250        } 
    12411251    } 
    12421252    } 
    12431253} 
    12441254 
    12451255/******************************************* 
    12461256 * Parse escape sequence. 
    12471257 */ 
    12481258 
    12491259unsigned Lexer::escapeSequence() 
    12501260{   unsigned c = *p; 
    12511261 
    12521262#ifdef TEXTUAL_ASSEMBLY_OUT 
    12531263    return c; 
    12541264#endif 
     
    14791489        stringbuffer.writeByte(0); 
    14801490        t->ustring = (unsigned char *)mem.malloc(stringbuffer.offset); 
    14811491        memcpy(t->ustring, stringbuffer.data, stringbuffer.offset); 
    14821492        stringPostfix(t); 
    14831493        return TOKstring; 
    14841494 
    14851495        default: 
    14861496        if (c >= '0' && c <= '9') 
    14871497            c -= '0'; 
    14881498        else if (c >= 'a' && c <= 'f') 
    14891499            c -= 'a' - 10; 
    14901500        else if (c >= 'A' && c <= 'F') 
    14911501            c -= 'A' - 10; 
    14921502        else if (c & 0x80) 
    14931503        {   p--; 
    14941504            unsigned u = decodeUTF(); 
    14951505            p++; 
    14961506            if (u == PS || u == LS) 
    14971507            loc.linnum++; 
    14981508            else 
    1499             error("non-hex character \\u%x", u); 
     1509            error("non-hex character \\u%04x", u); 
    15001510        } 
    15011511        else 
    15021512            error("non-hex character '%c'", c); 
    15031513        if (n & 1) 
    15041514        {   v = (v << 4) | c; 
    15051515            stringbuffer.writeByte(v); 
    15061516        } 
    15071517        else 
    15081518            v = c; 
    15091519        n++; 
    15101520        break; 
    15111521    } 
    15121522    } 
    15131523} 
    15141524 
    15151525 
    15161526#if DMDV2 
    15171527/************************************** 
    15181528 * Lex delimited strings: 
    15191529 *  q"(foo(xxx))"   // "foo(xxx)" 
  • trunk/src/utf.c

    r189 r292  
    11// utf.c 
    2 // Copyright (c) 2003 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> 
    1414#include <assert.h> 
    1515 
    1616#include "utf.h" 
    1717 
    1818int utf_isValidDchar(dchar_t c) 
    1919{ 
    2020    return c < 0xD800 || 
    2121    (c > 0xDFFF && c <= 0x10FFFF && c != 0xFFFE && c != 0xFFFF); 
    2222} 
    2323 
    2424/******************************************** 
    2525 * Decode a single UTF-8 character sequence. 
    2626 * Returns: 
    2727 *  NULL    success 
    2828 *  !=NULL  error message string 
    2929 */ 
    3030 
    3131const char *utf_decodeChar(unsigned char *s, size_t len, size_t *pidx, dchar_t *presult) 
    3232{ 
    3333    dchar_t V; 
    3434    size_t i = *pidx; 
    3535    unsigned char u = s[i]; 
     36 
     37    //printf("utf_decodeChar(s = %02x, %02x, %02x len = %d)\n", u, s[1], s[2], len); 
    3638 
    3739    assert(i >= 0 && i < len); 
    3840 
    3941    if (u & 0x80) 
    4042    {   unsigned n; 
    4143    unsigned char u2; 
    4244 
    4345    /* The following encodings are valid, except for the 5 and 6 byte 
    4446     * combinations: 
    4547     *  0xxxxxxx 
    4648     *  110xxxxx 10xxxxxx 
    4749     *  1110xxxx 10xxxxxx 10xxxxxx 
    4850     *  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 
    4951     *  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
    5052     *  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
    5153     */ 
    5254    for (n = 1; ; n++) 
    5355    { 
    5456        if (n > 4) 
    5557        goto Lerr;      // only do the first 4 of 6 encodings