16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 2011-2013, International Business Machines 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Corporation and others. All Rights Reserved. 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* file name: ppucd.cpp 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* encoding: US-ASCII 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* tab size: 8 (not used) 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* indentation:4 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created on: 2011dec11 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created by: Markus W. Scherer 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uchar.h" 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "charstr.h" 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cstring.h" 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ppucd.h" 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h" 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uparse.h" 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <stdio.h> 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <string.h> 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPropertyNames::~PropertyNames() {} 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPropertyNames::getPropertyEnum(const char *name) const { 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return u_getPropertyEnum(name); 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPropertyNames::getPropertyValueEnum(int32_t property, const char *name) const { 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return u_getPropertyValueEnum((UProperty)property, name); 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUniProps::UniProps() 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org : start(U_SENTINEL), end(U_SENTINEL), 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bmg(U_SENTINEL), bpb(U_SENTINEL), 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org scf(U_SENTINEL), slc(U_SENTINEL), stc(U_SENTINEL), suc(U_SENTINEL), 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org digitValue(-1), numericValue(NULL), 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org name(NULL), nameAlias(NULL) { 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org memset(binProps, 0, sizeof(binProps)); 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org memset(intProps, 0, sizeof(intProps)); 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org memset(age, 0, 4); 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUniProps::~UniProps() {} 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst int32_t PreparsedUCD::kNumLineBuffers; 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPreparsedUCD::PreparsedUCD(const char *filename, UErrorCode &errorCode) 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org : icuPnames(new PropertyNames()), pnames(icuPnames), 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org file(NULL), 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org defaultLineIndex(-1), blockLineIndex(-1), lineIndex(0), 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lineNumber(0), 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lineType(NO_LINE), 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fieldLimit(NULL), lineLimit(NULL) { 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(errorCode)) { return; } 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(filename==NULL || *filename==0 || (*filename=='-' && filename[1]==0)) { 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filename=NULL; 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org file=stdin; 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org file=fopen(filename, "r"); 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(file==NULL) { 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org perror("error opening preparsed UCD"); 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, "error opening preparsed UCD file %s\n", filename ? filename : "\"no file name given\""); 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_FILE_ACCESS_ERROR; 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org memset(ucdVersion, 0, 4); 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lines[0][0]=0; 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPreparsedUCD::~PreparsedUCD() { 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(file!=stdin) { 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fclose(file); 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete icuPnames; 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Same order as the LineType values. 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char *lineTypeStrings[]={ 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "ucd", 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "property", 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "binary", 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "value", 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "defaults", 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "block", 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "cp", 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "algnamesrange" 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPreparsedUCD::LineType 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPreparsedUCD::readLine(UErrorCode &errorCode) { 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(errorCode)) { return NO_LINE; } 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Select the next available line buffer. 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(!isLineBufferAvailable(lineIndex)) { 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++lineIndex; 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (lineIndex == kNumLineBuffers) { 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lineIndex = 0; 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *line=lines[lineIndex]; 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *line=0; 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lineLimit=fieldLimit=line; 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lineType=NO_LINE; 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *result=fgets(line, sizeof(lines[0]), file); 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(result==NULL) { 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(ferror(file)) { 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org perror("error reading preparsed UCD"); 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, "error reading preparsed UCD before line %ld\n", (long)lineNumber); 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_FILE_ACCESS_ERROR; 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NO_LINE; 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++lineNumber; 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*line=='#') { 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fieldLimit=strchr(line, 0); 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return lineType=EMPTY_LINE; 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Remove trailing /r/n. 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char c; 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *limit=strchr(line, 0); 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(line<limit && ((c=*(limit-1))=='\n' || c=='\r')) { --limit; } 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Remove trailing white space. 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(line<limit && ((c=*(limit-1))==' ' || c=='\t')) { --limit; } 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *limit=0; 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lineLimit=limit; 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(line==limit) { 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fieldLimit=limit; 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return lineType=EMPTY_LINE; 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Split by ';'. 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *semi=line; 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while((semi=strchr(semi, ';'))!=NULL) { *semi++=0; } 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fieldLimit=strchr(line, 0); 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Determine the line type. 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t type; 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(type=EMPTY_LINE+1;; ++type) { 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(type==LINE_TYPE_COUNT) { 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: unknown line type (first field) '%s' on line %ld\n", 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org line, (long)lineNumber); 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NO_LINE; 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(0==strcmp(line, lineTypeStrings[type])) { 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lineType=(LineType)type; 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(lineType==UNICODE_VERSION_LINE && fieldLimit<lineLimit) { 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_versionFromString(ucdVersion, fieldLimit+1); 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return lineType; 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst char * 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPreparsedUCD::firstField() { 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *field=lines[lineIndex]; 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fieldLimit=strchr(field, 0); 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return field; 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst char * 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPreparsedUCD::nextField() { 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(fieldLimit==lineLimit) { return NULL; } 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *field=fieldLimit+1; 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fieldLimit=strchr(field, 0); 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return field; 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UniProps * 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPreparsedUCD::getProps(UnicodeSet &newValues, UErrorCode &errorCode) { 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(errorCode)) { return NULL; } 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newValues.clear(); 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!lineHasPropertyValues()) { 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_ILLEGAL_ARGUMENT_ERROR; 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org firstField(); 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *field=nextField(); 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(field==NULL) { 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No range field after the type. 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: missing default/block/cp range field " 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "(no second field) on line %ld\n", 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (long)lineNumber); 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 start, end; 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!parseCodePointRange(field, start, end, errorCode)) { return NULL; } 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UniProps *props; 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(lineType) { 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case DEFAULTS_LINE: 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(defaultLineIndex>=0) { 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: second line with default properties on line %ld\n", 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (long)lineNumber); 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(start!=0 || end!=0x10ffff) { 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: default range must be 0..10FFFF, not '%s' on line %ld\n", 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org field, (long)lineNumber); 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props=&defaultProps; 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org defaultLineIndex=lineIndex; 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case BLOCK_LINE: 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org blockProps=defaultProps; // Block inherits default properties. 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props=&blockProps; 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org blockLineIndex=lineIndex; 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case CP_LINE: 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(blockProps.start<=start && end<=blockProps.end) { 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Code point range fully inside the last block inherits the block properties. 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cpProps=blockProps; 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(start>blockProps.end || end<blockProps.start) { 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Code point range fully outside the last block inherits the default properties. 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cpProps=defaultProps; 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Code point range partially overlapping with the last block is illegal. 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: cp range %s on line %ld only " 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "partially overlaps with block range %04lX..%04lX\n", 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org field, (long)lineNumber, (long)blockProps.start, (long)blockProps.end); 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props=&cpProps; 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Will not occur because of the range check above. 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_ILLEGAL_ARGUMENT_ERROR; 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props->start=start; 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props->end=end; 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while((field=nextField())!=NULL) { 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!parseProperty(*props, field, newValues, errorCode)) { return NULL; } 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return props; 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const struct { 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *name; 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t prop; 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} ppucdProperties[]={ 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { "Name_Alias", PPUCD_NAME_ALIAS }, 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { "Conditional_Case_Mappings", PPUCD_CONDITIONAL_CASE_MAPPINGS }, 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { "Turkic_Case_Folding", PPUCD_TURKIC_CASE_FOLDING } 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Returns TRUE for "ok to continue parsing fields". 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPreparsedUCD::parseProperty(UniProps &props, const char *field, UnicodeSet &newValues, 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode &errorCode) { 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org CharString pBuffer; 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *p=field; 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *v=strchr(p, '='); 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int binaryValue; 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*p=='-') { 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(v!=NULL) { 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: mix of binary-property-no and " 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "enum-property syntax '%s' on line %ld\n", 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org field, (long)lineNumber); 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org binaryValue=0; 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++p; 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(v==NULL) { 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org binaryValue=1; 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org binaryValue=-1; 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Copy out the property name rather than modifying the field (writing a NUL). 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pBuffer.append(p, (int32_t)(v-p), errorCode); 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p=pBuffer.data(); 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++v; 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t prop=pnames->getPropertyEnum(p); 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(prop<0) { 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(int32_t i=0;; ++i) { 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i==LENGTHOF(ppucdProperties)) { 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Ignore unknown property names. 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(0==uprv_stricmp(p, ppucdProperties[i].name)) { 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prop=ppucdProperties[i].prop; 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(prop>=0); 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(prop<UCHAR_BINARY_LIMIT) { 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(binaryValue>=0) { 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.binProps[prop]=(UBool)binaryValue; 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No binary value for a binary property. 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: enum-property syntax '%s' " 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "for binary property on line %ld\n", 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org field, (long)lineNumber); 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(binaryValue>=0) { 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Binary value for a non-binary property. 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: binary-property syntax '%s' " 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "for non-binary property on line %ld\n", 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org field, (long)lineNumber); 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (prop < UCHAR_INT_START) { 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: prop value is invalid: '%d' for line %ld\n", 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prop, (long)lineNumber); 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(prop<UCHAR_INT_LIMIT) { 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t value=pnames->getPropertyValueEnum(prop, v); 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(value==UCHAR_INVALID_CODE && prop==UCHAR_CANONICAL_COMBINING_CLASS) { 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // TODO: Make getPropertyValueEnum(UCHAR_CANONICAL_COMBINING_CLASS, v) work. 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *end; 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unsigned long ccc=uprv_strtoul(v, &end, 10); 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(v<end && *end==0 && ccc<=254) { 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value=(int32_t)ccc; 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(value==UCHAR_INVALID_CODE) { 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: '%s' is not a valid value on line %ld\n", 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org field, (long)lineNumber); 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.intProps[prop-UCHAR_INT_START]=value; 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(*v=='<') { 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Do not parse default values like <code point>, just set null values. 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(prop) { 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_BIDI_MIRRORING_GLYPH: 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.bmg=U_SENTINEL; 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_BIDI_PAIRED_BRACKET: 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.bpb=U_SENTINEL; 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_SIMPLE_CASE_FOLDING: 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.scf=U_SENTINEL; 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_SIMPLE_LOWERCASE_MAPPING: 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.slc=U_SENTINEL; 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_SIMPLE_TITLECASE_MAPPING: 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.stc=U_SENTINEL; 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_SIMPLE_UPPERCASE_MAPPING: 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.suc=U_SENTINEL; 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_CASE_FOLDING: 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.cf.remove(); 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_LOWERCASE_MAPPING: 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.lc.remove(); 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_TITLECASE_MAPPING: 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.tc.remove(); 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_UPPERCASE_MAPPING: 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.uc.remove(); 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_SCRIPT_EXTENSIONS: 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.scx.clear(); 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: '%s' is not a valid default value on line %ld\n", 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org field, (long)lineNumber); 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char c; 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(prop) { 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_NUMERIC_VALUE: 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.numericValue=v; 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c=*v; 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if('0'<=c && c<='9' && v[1]==0) { 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.digitValue=c-'0'; 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.digitValue=-1; 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_NAME: 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.name=v; 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_AGE: 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_versionFromString(props.age, v); // Writes 0.0.0.0 if v is not numeric. 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_BIDI_MIRRORING_GLYPH: 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.bmg=parseCodePoint(v, errorCode); 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_BIDI_PAIRED_BRACKET: 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.bpb=parseCodePoint(v, errorCode); 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_SIMPLE_CASE_FOLDING: 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.scf=parseCodePoint(v, errorCode); 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_SIMPLE_LOWERCASE_MAPPING: 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.slc=parseCodePoint(v, errorCode); 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_SIMPLE_TITLECASE_MAPPING: 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.stc=parseCodePoint(v, errorCode); 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_SIMPLE_UPPERCASE_MAPPING: 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.suc=parseCodePoint(v, errorCode); 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_CASE_FOLDING: 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org parseString(v, props.cf, errorCode); 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_LOWERCASE_MAPPING: 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org parseString(v, props.lc, errorCode); 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_TITLECASE_MAPPING: 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org parseString(v, props.tc, errorCode); 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_UPPERCASE_MAPPING: 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org parseString(v, props.uc, errorCode); 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case PPUCD_NAME_ALIAS: 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org props.nameAlias=v; 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case PPUCD_CONDITIONAL_CASE_MAPPINGS: 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case PPUCD_TURKIC_CASE_FOLDING: 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No need to parse their values: They are hardcoded in the runtime library. 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UCHAR_SCRIPT_EXTENSIONS: 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org parseScriptExtensions(v, props.scx, errorCode); 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Ignore unhandled properties. 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_SUCCESS(errorCode)) { 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newValues.add((UChar32)prop); 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPreparsedUCD::getRangeForAlgNames(UChar32 &start, UChar32 &end, UErrorCode &errorCode) { 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(errorCode)) { return FALSE; } 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(lineType!=ALG_NAMES_RANGE_LINE) { 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_ILLEGAL_ARGUMENT_ERROR; 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org firstField(); 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *field=nextField(); 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(field==NULL) { 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No range field after the type. 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: missing algnamesrange range field " 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "(no second field) on line %ld\n", 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (long)lineNumber); 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return parseCodePointRange(field, start, end, errorCode); 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUChar32 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPreparsedUCD::parseCodePoint(const char *s, UErrorCode &errorCode) { 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *end; 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t value=(uint32_t)uprv_strtoul(s, &end, 16); 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(end<=s || *end!=0 || value>=0x110000) { 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: '%s' is not a valid code point on line %ld\n", 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s, (long)lineNumber); 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return U_SENTINEL; 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (UChar32)value; 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPreparsedUCD::parseCodePointRange(const char *s, UChar32 &start, UChar32 &end, UErrorCode &errorCode) { 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t st, e; 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_parseCodePointRange(s, &st, &e, &errorCode); 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(errorCode)) { 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: '%s' is not a valid code point range on line %ld\n", 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s, (long)lineNumber); 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=(UChar32)st; 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org end=(UChar32)e; 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPreparsedUCD::parseString(const char *s, UnicodeString &uni, UErrorCode &errorCode) { 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *buffer=uni.getBuffer(-1); 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length=u_parseString(s, buffer, uni.getCapacity(), NULL, &errorCode); 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(errorCode==U_BUFFER_OVERFLOW_ERROR) { 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_ZERO_ERROR; 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uni.releaseBuffer(0); 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org buffer=uni.getBuffer(length); 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=u_parseString(s, buffer, uni.getCapacity(), NULL, &errorCode); 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uni.releaseBuffer(length); 5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(errorCode)) { 5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: '%s' is not a valid Unicode string on line %ld\n", 5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s, (long)lineNumber); 5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgPreparsedUCD::parseScriptExtensions(const char *s, UnicodeSet &scx, UErrorCode &errorCode) { 5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(errorCode)) { return; } 5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org scx.clear(); 5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org CharString scString; 5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;) { 5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *scs; 5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *scLimit=strchr(s, ' '); 5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(scLimit!=NULL) { 5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org scs=scString.clear().append(s, (int32_t)(scLimit-s), errorCode).data(); 5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(errorCode)) { return; } 5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org scs=s; 5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t script=pnames->getPropertyValueEnum(UCHAR_SCRIPT, scs); 5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(script==UCHAR_INVALID_CODE) { 5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: '%s' is not a valid script code on line %ld\n", 5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org scs, (long)lineNumber); 5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(scx.contains(script)) { 5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, 5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org "error in preparsed UCD: scx has duplicate '%s' codes on line %ld\n", 5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org scs, (long)lineNumber); 5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org scx.add(script); 5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(scLimit!=NULL) { 5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s=scLimit+1; 5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(scx.isEmpty()) { 5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, "error in preparsed UCD: empty scx= on line %ld\n", (long)lineNumber); 5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode=U_PARSE_ERROR; 5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END 577