1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 41b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert* Copyright (C) 1998-2015, International Business Machines 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 9103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius* File parse.cpp 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification History: 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Date Name Description 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 05/26/99 stephen Creation. 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 02/25/00 weiv Overhaul to write udata 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 5/10/01 Ram removed ustdio dependency 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 06/10/2001 Dominic Ludlam <dom@recoil.org> Rewritten 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 21fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// Safer use of UnicodeString. 22fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#ifndef UNISTR_FROM_CHAR_EXPLICIT 23fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius# define UNISTR_FROM_CHAR_EXPLICIT explicit 24fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif 25fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 26fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// Less important, but still a good idea. 27fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#ifndef UNISTR_FROM_STRING_EXPLICIT 28fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius# define UNISTR_FROM_STRING_EXPLICIT explicit 29fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif 30fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 31c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#include <assert.h> 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "parse.h" 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "errmsg.h" 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uhash.h" 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uinvchar.h" 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "read.h" 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ustr.h" 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "reslist.h" 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "rbt_pars.h" 4227f654740f2a26ad62a5c155af9199af9e69b889claireho#include "genrb.h" 43c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#include "unicode/stringpiece.h" 44c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#include "unicode/unistr.h" 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h" 4627f654740f2a26ad62a5c155af9199af9e69b889claireho#include "unicode/uscript.h" 47fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/utf16.h" 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/putil.h" 49c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#include "charstr.h" 50fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationbuilder.h" 51fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationdata.h" 52fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationdatareader.h" 53fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationdatawriter.h" 54fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationfastlatinbuilder.h" 55fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationinfo.h" 56fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationroot.h" 57fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationruleparser.h" 58fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationtailoring.h" 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h> 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Number of tokens to read ahead of the current stream position */ 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define MAX_LOOKAHEAD 3 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define CR 0x000D 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LF 0x000A 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define SPACE 0x0020 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define TAB 0x0009 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ESCAPE 0x005C 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define HASH 0x0023 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define QUOTE 0x0027 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZERO 0x0030 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define STARTCOMMAND 0x005B 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ENDCOMMAND 0x005D 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define OPENSQBRACKET 0x005B 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define CLOSESQBRACKET 0x005D 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 77c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertusing icu::CharString; 78c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertusing icu::LocalMemory; 79fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliususing icu::LocalPointer; 80c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertusing icu::LocalUCHARBUFPointer; 81c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertusing icu::StringPiece; 82fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliususing icu::UnicodeString; 83fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct Lookahead 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType type; 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString value; 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString comment; 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* keep in sync with token defines in read.h */ 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char *tokenNames[TOK_TOKEN_COUNT] = 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "string", /* A string token, such as "MonthNames" */ 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "'{'", /* An opening brace character */ 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "'}'", /* A closing brace character */ 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "','", /* A comma */ 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "':'", /* A colon */ 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "<end of file>", /* End of the file has been reached successfully */ 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "<end of line>" 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Just to store "TRUE" */ 10654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar trueValue[] = {0x0054, 0x0052, 0x0055, 0x0045, 0x0000}; 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 10827f654740f2a26ad62a5c155af9199af9e69b889clairehotypedef struct { 10927f654740f2a26ad62a5c155af9199af9e69b889claireho struct Lookahead lookahead[MAX_LOOKAHEAD + 1]; 11027f654740f2a26ad62a5c155af9199af9e69b889claireho uint32_t lookaheadPosition; 11127f654740f2a26ad62a5c155af9199af9e69b889claireho UCHARBUF *buffer; 11227f654740f2a26ad62a5c155af9199af9e69b889claireho struct SRBRoot *bundle; 11327f654740f2a26ad62a5c155af9199af9e69b889claireho const char *inputdir; 11427f654740f2a26ad62a5c155af9199af9e69b889claireho uint32_t inputdirLength; 11527f654740f2a26ad62a5c155af9199af9e69b889claireho const char *outputdir; 11627f654740f2a26ad62a5c155af9199af9e69b889claireho uint32_t outputdirLength; 117fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *filename; 118103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool makeBinaryCollation; 11959d709d503bab6e2b61931737e662dd293b40578ccornelius UBool omitCollationRules; 12027f654740f2a26ad62a5c155af9199af9e69b889claireho} ParseState; 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 12227f654740f2a26ad62a5c155af9199af9e69b889clairehotypedef struct SResource * 12327f654740f2a26ad62a5c155af9199af9e69b889clairehoParseResourceFunction(ParseState* state, char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status); 12427f654740f2a26ad62a5c155af9199af9e69b889claireho 12527f654740f2a26ad62a5c155af9199af9e69b889clairehostatic struct SResource *parseResource(ParseState* state, char *tag, const struct UString *comment, UErrorCode *status); 126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* The nature of the lookahead buffer: 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru There are MAX_LOOKAHEAD + 1 slots, used as a circular buffer. This provides 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAX_LOOKAHEAD lookahead tokens and a slot for the current token and value. 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru When getToken is called, the current pointer is moved to the next slot and the 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru old slot is filled with the next token from the reader by calling getNextToken. 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru The token values are stored in the slot, which means that token values don't 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru survive a call to getToken, ie. 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UString *value; 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getToken(&value, NULL, status); 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getToken(NULL, NULL, status); bad - value is now a different string 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 14127f654740f2a26ad62a5c155af9199af9e69b889clairehoinitLookahead(ParseState* state, UCHARBUF *buf, UErrorCode *status) 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static uint32_t initTypeStrings = 0; 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t i; 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!initTypeStrings) 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru initTypeStrings = 1; 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 15127f654740f2a26ad62a5c155af9199af9e69b889claireho state->lookaheadPosition = 0; 15227f654740f2a26ad62a5c155af9199af9e69b889claireho state->buffer = buf; 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru resetLineNumber(); 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < MAX_LOOKAHEAD; i++) 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 15827f654740f2a26ad62a5c155af9199af9e69b889claireho state->lookahead[i].type = getNextToken(state->buffer, &state->lookahead[i].value, &state->lookahead[i].line, &state->lookahead[i].comment, status); 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ZERO_ERROR; 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 168c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void 16927f654740f2a26ad62a5c155af9199af9e69b889clairehocleanupLookahead(ParseState* state) 170c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{ 171c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uint32_t i; 17254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius for (i = 0; i <= MAX_LOOKAHEAD; i++) 173c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { 17427f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_deinit(&state->lookahead[i].value); 17527f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_deinit(&state->lookahead[i].comment); 176c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 177c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 178c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru} 179c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic enum ETokenType 18127f654740f2a26ad62a5c155af9199af9e69b889clairehogetToken(ParseState* state, struct UString **tokenValue, struct UString* comment, uint32_t *linenumber, UErrorCode *status) 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType result; 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t i; 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 18627f654740f2a26ad62a5c155af9199af9e69b889claireho result = state->lookahead[state->lookaheadPosition].type; 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tokenValue != NULL) 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 19027f654740f2a26ad62a5c155af9199af9e69b889claireho *tokenValue = &state->lookahead[state->lookaheadPosition].value; 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (linenumber != NULL) 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 19527f654740f2a26ad62a5c155af9199af9e69b889claireho *linenumber = state->lookahead[state->lookaheadPosition].line; 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (comment != NULL) 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 20027f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_cpy(comment, &(state->lookahead[state->lookaheadPosition].comment), status); 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 20327f654740f2a26ad62a5c155af9199af9e69b889claireho i = (state->lookaheadPosition + MAX_LOOKAHEAD) % (MAX_LOOKAHEAD + 1); 20427f654740f2a26ad62a5c155af9199af9e69b889claireho state->lookaheadPosition = (state->lookaheadPosition + 1) % (MAX_LOOKAHEAD + 1); 20527f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_setlen(&state->lookahead[i].comment, 0, status); 20627f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_setlen(&state->lookahead[i].value, 0, status); 20727f654740f2a26ad62a5c155af9199af9e69b889claireho state->lookahead[i].type = getNextToken(state->buffer, &state->lookahead[i].value, &state->lookahead[i].line, &state->lookahead[i].comment, status); 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* printf("getToken, returning %s\n", tokenNames[result]); */ 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic enum ETokenType 21527f654740f2a26ad62a5c155af9199af9e69b889clairehopeekToken(ParseState* state, uint32_t lookaheadCount, struct UString **tokenValue, uint32_t *linenumber, struct UString *comment, UErrorCode *status) 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 21727f654740f2a26ad62a5c155af9199af9e69b889claireho uint32_t i = (state->lookaheadPosition + lookaheadCount) % (MAX_LOOKAHEAD + 1); 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TOK_ERROR; 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lookaheadCount >= MAX_LOOKAHEAD) 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TOK_ERROR; 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tokenValue != NULL) 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 23227f654740f2a26ad62a5c155af9199af9e69b889claireho *tokenValue = &state->lookahead[i].value; 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (linenumber != NULL) 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 23727f654740f2a26ad62a5c155af9199af9e69b889claireho *linenumber = state->lookahead[i].line; 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(comment != NULL){ 24127f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_cpy(comment, &(state->lookahead[state->lookaheadPosition].comment), status); 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 24427f654740f2a26ad62a5c155af9199af9e69b889claireho return state->lookahead[i].type; 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 24827f654740f2a26ad62a5c155af9199af9e69b889clairehoexpect(ParseState* state, enum ETokenType expectedToken, struct UString **tokenValue, struct UString *comment, uint32_t *linenumber, UErrorCode *status) 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 25227f654740f2a26ad62a5c155af9199af9e69b889claireho enum ETokenType token = getToken(state, tokenValue, comment, &line, status); 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (linenumber != NULL) 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *linenumber = line; 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token != expectedToken) 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "expecting %s, got %s", tokenNames[expectedToken], tokenNames[token]); 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 269c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru else 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ZERO_ERROR; 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 27527f654740f2a26ad62a5c155af9199af9e69b889clairehostatic char *getInvariantString(ParseState* state, uint32_t *line, struct UString *comment, UErrorCode *status) 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *result; 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t count; 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 28127f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_STRING, &tokenValue, comment, line, status); 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count = u_strlen(tokenValue->fChars); 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!uprv_isInvariantUString(tokenValue->fChars, count)) { 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(*line, "invariant characters required for table keys, binary data, etc."); 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 29554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius result = static_cast<char *>(uprv_malloc(count+1)); 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result == NULL) 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, result, count+1); 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 308103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusparseUCARules(ParseState* state, char *tag, uint32_t startline, const struct UString* /*comment*/, UErrorCode *status) 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *result = NULL; 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FileStream *file = NULL; 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char filename[256] = { '\0' }; 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char cs[128] = { '\0' }; 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool quoted = FALSE; 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCHARBUF *ucbuf=NULL; 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar32 c = 0; 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* cp = NULL; 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *pTarget = NULL; 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *target = NULL; 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *targetLimit = NULL; 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t size = 0; 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 32527f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_STRING, &tokenValue, NULL, &line, status); 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* make the filename including the directory */ 33627f654740f2a26ad62a5c155af9199af9e69b889claireho if (state->inputdir != NULL) 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 33827f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strcat(filename, state->inputdir); 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 34027f654740f2a26ad62a5c155af9199af9e69b889claireho if (state->inputdir[state->inputdirLength - 1] != U_FILE_SEP_CHAR) 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(filename, U_FILE_SEP_STRING); 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, cs, tokenValue->fLength); 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 34827f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(filename, cs); 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 35659d709d503bab6e2b61931737e662dd293b40578ccornelius if(state->omitCollationRules) { 357c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return res_none(); 358c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucbuf = ucbuf_open(filename, &cp, getShowWarning(),FALSE, status); 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "An error occured while opening the input file %s\n", filename); 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* We allocate more space than actually required 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * since the actual size needed for storing UChars 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * is not known in UTF-8 byte stream 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size = ucbuf_size(ucbuf) + 1; 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pTarget = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * size); 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memset(pTarget, 0, size*U_SIZEOF_UCHAR); 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru target = pTarget; 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru targetLimit = pTarget+size; 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* read the rules into the buffer */ 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (target < targetLimit) 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = ucbuf_getc(ucbuf, status); 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c == QUOTE) { 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru quoted = (UBool)!quoted; 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* weiv (06/26/2002): adding the following: 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * - preserving spaces in commands [...] 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * - # comments until the end of line 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (c == STARTCOMMAND && !quoted) 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* preserve commands 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * closing bracket will be handled by the 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * append at the end of the loop 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(c != ENDCOMMAND) { 39554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius U_APPEND_CHAR32_ONLY(c, target); 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = ucbuf_getc(ucbuf, status); 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (c == HASH && !quoted) { 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* skip comments */ 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(c != CR && c != LF) { 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = ucbuf_getc(ucbuf, status); 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (c == ESCAPE) 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = unescape(ucbuf, status); 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 410103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (c == (UChar32)U_ERR) 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(pTarget); 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru T_FileStream_close(file); 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (!quoted && (c == SPACE || c == TAB || c == CR || c == LF)) 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* ignore spaces carriage returns 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and line feed unless in the form \uXXXX 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Append UChar * after dissembling if c > 0xffff*/ 426103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (c != (UChar32)U_EOF) 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 42854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius U_APPEND_CHAR32_ONLY(c, target); 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* terminate the string */ 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(target < targetLimit){ 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *target = 0x0000; 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 44127f654740f2a26ad62a5c155af9199af9e69b889claireho result = string_open(state->bundle, tag, pTarget, (int32_t)(target - pTarget), NULL, status); 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucbuf_close(ucbuf); 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(pTarget); 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru T_FileStream_close(file); 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 452103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusparseTransliterator(ParseState* state, char *tag, uint32_t startline, const struct UString* /*comment*/, UErrorCode *status) 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *result = NULL; 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FileStream *file = NULL; 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char filename[256] = { '\0' }; 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char cs[128] = { '\0' }; 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCHARBUF *ucbuf=NULL; 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* cp = NULL; 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *pTarget = NULL; 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *pSource = NULL; 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t size = 0; 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 46627f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_STRING, &tokenValue, NULL, &line, status); 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* make the filename including the directory */ 47727f654740f2a26ad62a5c155af9199af9e69b889claireho if (state->inputdir != NULL) 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 47927f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strcat(filename, state->inputdir); 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 48127f654740f2a26ad62a5c155af9199af9e69b889claireho if (state->inputdir[state->inputdirLength - 1] != U_FILE_SEP_CHAR) 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(filename, U_FILE_SEP_STRING); 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, cs, tokenValue->fLength); 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 48927f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(filename, cs); 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucbuf = ucbuf_open(filename, &cp, getShowWarning(),FALSE, status); 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "An error occured while opening the input file %s\n", filename); 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* We allocate more space than actually required 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * since the actual size needed for storing UChars 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * is not known in UTF-8 byte stream 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pSource = ucbuf_getBuffer(ucbuf, &size, status); 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pTarget = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * (size + 1)); 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memset(pTarget, 0, size*U_SIZEOF_UCHAR); 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_TRANSLITERATION 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size = utrans_stripRules(pSource, size, pTarget, status); 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size = 0; 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, " Warning: writing empty transliteration data ( UCONFIG_NO_TRANSLITERATION ) \n"); 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 51927f654740f2a26ad62a5c155af9199af9e69b889claireho result = string_open(state->bundle, tag, pTarget, size, NULL, status); 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucbuf_close(ucbuf); 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(pTarget); 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru T_FileStream_close(file); 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 527c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertstatic ArrayResource* dependencyArray = NULL; 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 53027f654740f2a26ad62a5c155af9199af9e69b889clairehoparseDependency(ParseState* state, char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status) 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *result = NULL; 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *elem = NULL; 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char filename[256] = { '\0' }; 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char cs[128] = { '\0' }; 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 53927f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_STRING, &tokenValue, NULL, &line, status); 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* make the filename including the directory */ 55027f654740f2a26ad62a5c155af9199af9e69b889claireho if (state->outputdir != NULL) 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 55227f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strcat(filename, state->outputdir); 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 55427f654740f2a26ad62a5c155af9199af9e69b889claireho if (state->outputdir[state->outputdirLength - 1] != U_FILE_SEP_CHAR) 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(filename, U_FILE_SEP_STRING); 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, cs, tokenValue->fLength); 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(filename, cs); 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!T_FileStream_file_exists(filename)){ 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isStrict()){ 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "The dependency file %s does not exist. Please make sure it exists.\n",filename); 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else{ 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(line, "The dependency file %s does not exist. Please make sure it exists.\n",filename); 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(dependencyArray==NULL){ 57527f654740f2a26ad62a5c155af9199af9e69b889claireho dependencyArray = array_open(state->bundle, "%%DEPENDENCY", NULL, status); 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tag!=NULL){ 57827f654740f2a26ad62a5c155af9199af9e69b889claireho result = string_open(state->bundle, tag, tokenValue->fChars, tokenValue->fLength, comment, status); 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 58027f654740f2a26ad62a5c155af9199af9e69b889claireho elem = string_open(state->bundle, NULL, tokenValue->fChars, tokenValue->fLength, comment, status); 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 582c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert dependencyArray->add(elem); 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 58827f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 59227f654740f2a26ad62a5c155af9199af9e69b889clairehoparseString(ParseState* state, char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status) 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *result = NULL; 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* if (tag != NULL && uprv_strcmp(tag, "%%UCARULES") == 0) 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return parseUCARules(tag, startline, status); 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }*/ 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" string %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 60427f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_STRING, &tokenValue, NULL, NULL, status); 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(*status)) 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* create the string now - tokenValue doesn't survive a call to getToken (and therefore 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doesn't survive expect either) */ 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 61127f654740f2a26ad62a5c155af9199af9e69b889claireho result = string_open(state->bundle, tag, tokenValue->fChars, tokenValue->fLength, comment, status); 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_SUCCESS(*status) && result) { 61327f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 615c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (U_FAILURE(*status)) 616c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { 617c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 618c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return NULL; 619c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 62727f654740f2a26ad62a5c155af9199af9e69b889clairehoparseAlias(ParseState* state, char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *result = NULL; 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 63227f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_STRING, &tokenValue, NULL, NULL, status); 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" alias %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(*status)) 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* create the string now - tokenValue doesn't survive a call to getToken (and therefore 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doesn't survive expect either) */ 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 64327f654740f2a26ad62a5c155af9199af9e69b889claireho result = alias_open(state->bundle, tag, tokenValue->fChars, tokenValue->fLength, comment, status); 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 64527f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 649c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 657fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_COLLATION 658fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 659fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusnamespace { 66027f654740f2a26ad62a5c155af9199af9e69b889claireho 66127f654740f2a26ad62a5c155af9199af9e69b889clairehostatic struct SResource* resLookup(struct SResource* res, const char* key){ 662c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (res == res_none() || !res->isTable()) { 66327f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 66427f654740f2a26ad62a5c155af9199af9e69b889claireho } 66527f654740f2a26ad62a5c155af9199af9e69b889claireho 666c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert TableResource *list = static_cast<TableResource *>(res); 667c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert SResource *current = list->fFirst; 66827f654740f2a26ad62a5c155af9199af9e69b889claireho while (current != NULL) { 66927f654740f2a26ad62a5c155af9199af9e69b889claireho if (uprv_strcmp(((list->fRoot->fKeys) + (current->fKey)), key) == 0) { 67027f654740f2a26ad62a5c155af9199af9e69b889claireho return current; 67127f654740f2a26ad62a5c155af9199af9e69b889claireho } 67227f654740f2a26ad62a5c155af9199af9e69b889claireho current = current->fNext; 67327f654740f2a26ad62a5c155af9199af9e69b889claireho } 67427f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 67527f654740f2a26ad62a5c155af9199af9e69b889claireho} 67627f654740f2a26ad62a5c155af9199af9e69b889claireho 677fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusclass GenrbImporter : public icu::CollationRuleParser::Importer { 678fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliuspublic: 679fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius GenrbImporter(const char *in, const char *out) : inputDir(in), outputDir(out) {} 680fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius virtual ~GenrbImporter(); 681f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius virtual void getRules( 682fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *localeID, const char *collationType, 683f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UnicodeString &rules, 684fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *&errorReason, UErrorCode &errorCode); 685fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 686fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusprivate: 687fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *inputDir; 688fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *outputDir; 689fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius}; 690fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 691fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusGenrbImporter::~GenrbImporter() {} 692fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 693f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusvoid 694fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusGenrbImporter::getRules( 695fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *localeID, const char *collationType, 696f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UnicodeString &rules, 697fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *& /*errorReason*/, UErrorCode &errorCode) { 698c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert CharString filename(localeID, errorCode); 699c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert for(int32_t i = 0; i < filename.length(); i++){ 70027f654740f2a26ad62a5c155af9199af9e69b889claireho if(filename[i] == '-'){ 701c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert filename.data()[i] = '_'; 70227f654740f2a26ad62a5c155af9199af9e69b889claireho } 70327f654740f2a26ad62a5c155af9199af9e69b889claireho } 704c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert filename.append(".txt", errorCode); 705fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(errorCode)) { 706f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return; 70727f654740f2a26ad62a5c155af9199af9e69b889claireho } 708c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert CharString inputDirBuf; 709c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert CharString openFileName; 710fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(inputDir == NULL) { 711c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert const char *filenameBegin = uprv_strrchr(filename.data(), U_FILE_SEP_CHAR); 71227f654740f2a26ad62a5c155af9199af9e69b889claireho if (filenameBegin != NULL) { 71327f654740f2a26ad62a5c155af9199af9e69b889claireho /* 71427f654740f2a26ad62a5c155af9199af9e69b889claireho * When a filename ../../../data/root.txt is specified, 71527f654740f2a26ad62a5c155af9199af9e69b889claireho * we presume that the input directory is ../../../data 71627f654740f2a26ad62a5c155af9199af9e69b889claireho * This is very important when the resource file includes 71727f654740f2a26ad62a5c155af9199af9e69b889claireho * another file, like UCARules.txt or thaidict.brk. 71827f654740f2a26ad62a5c155af9199af9e69b889claireho */ 719c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert StringPiece dir = filename.toStringPiece(); 720c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert const char *filenameLimit = filename.data() + filename.length(); 721c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert dir.remove_suffix((int32_t)(filenameLimit - filenameBegin)); 722c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert inputDirBuf.append(dir, errorCode); 723c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert inputDir = inputDirBuf.data(); 72427f654740f2a26ad62a5c155af9199af9e69b889claireho } 72527f654740f2a26ad62a5c155af9199af9e69b889claireho }else{ 726c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert int32_t dirlen = (int32_t)uprv_strlen(inputDir); 72727f654740f2a26ad62a5c155af9199af9e69b889claireho 728c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if((filename[0] != U_FILE_SEP_CHAR) && (inputDir[dirlen-1] !='.')) { 72927f654740f2a26ad62a5c155af9199af9e69b889claireho /* 73027f654740f2a26ad62a5c155af9199af9e69b889claireho * append the input dir to openFileName if the first char in 731c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * filename is not file separator char and the last char input directory is not '.'. 73227f654740f2a26ad62a5c155af9199af9e69b889claireho * This is to support : 73327f654740f2a26ad62a5c155af9199af9e69b889claireho * genrb -s. /home/icu/data 73427f654740f2a26ad62a5c155af9199af9e69b889claireho * genrb -s. icu/data 73527f654740f2a26ad62a5c155af9199af9e69b889claireho * The user cannot mix notations like 73627f654740f2a26ad62a5c155af9199af9e69b889claireho * genrb -s. /icu/data --- the absolute path specified. -s redundant 73727f654740f2a26ad62a5c155af9199af9e69b889claireho * user should use 73827f654740f2a26ad62a5c155af9199af9e69b889claireho * genrb -s. icu/data --- start from CWD and look in icu/data dir 73927f654740f2a26ad62a5c155af9199af9e69b889claireho */ 740c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert openFileName.append(inputDir, dirlen, errorCode); 741c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(inputDir[dirlen-1] != U_FILE_SEP_CHAR) { 742c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert openFileName.append(U_FILE_SEP_CHAR, errorCode); 74327f654740f2a26ad62a5c155af9199af9e69b889claireho } 74427f654740f2a26ad62a5c155af9199af9e69b889claireho } 74527f654740f2a26ad62a5c155af9199af9e69b889claireho } 746c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert openFileName.append(filename, errorCode); 747c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(U_FAILURE(errorCode)) { 748c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return; 749c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 750c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert // printf("GenrbImporter::getRules(%s, %s) reads %s\n", localeID, collationType, openFileName.data()); 751c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert const char* cp = ""; 752c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalUCHARBUFPointer ucbuf( 753c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert ucbuf_open(openFileName.data(), &cp, getShowWarning(), TRUE, &errorCode)); 754fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(errorCode == U_FILE_ACCESS_ERROR) { 755c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert fprintf(stderr, "couldn't open file %s\n", openFileName.data()); 756c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return; 75727f654740f2a26ad62a5c155af9199af9e69b889claireho } 758c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (ucbuf.isNull() || U_FAILURE(errorCode)) { 759c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert fprintf(stderr, "An error occured processing file %s. Error: %s\n", openFileName.data(), u_errorName(errorCode)); 760c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return; 76127f654740f2a26ad62a5c155af9199af9e69b889claireho } 76227f654740f2a26ad62a5c155af9199af9e69b889claireho 76327f654740f2a26ad62a5c155af9199af9e69b889claireho /* Parse the data into an SRBRoot */ 764c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert struct SRBRoot *data = 765c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert parse(ucbuf.getAlias(), inputDir, outputDir, filename.data(), FALSE, FALSE, &errorCode); 766f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_FAILURE(errorCode)) { 767c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return; 768f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 76927f654740f2a26ad62a5c155af9199af9e69b889claireho 770c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert struct SResource *root = data->fRoot; 771c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert struct SResource *collations = resLookup(root, "collations"); 772103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (collations != NULL) { 773c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert struct SResource *collation = resLookup(collations, collationType); 774103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (collation != NULL) { 775c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert struct SResource *sequence = resLookup(collation, "Sequence"); 776c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (sequence != NULL && sequence->isString()) { 777f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // No string pointer aliasing so that we need not hold onto the resource bundle. 778c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert StringResource *sr = static_cast<StringResource *>(sequence); 779c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert rules = sr->fString; 780103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 781103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 782103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 78327f654740f2a26ad62a5c155af9199af9e69b889claireho} 78427f654740f2a26ad62a5c155af9199af9e69b889claireho 785103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Quick-and-dirty escaping function. 786103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Assumes that we are on an ASCII-based platform. 787103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic void 788103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusescape(const UChar *s, char *buffer) { 789103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t length = u_strlen(s); 790103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t i = 0; 791103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (;;) { 792103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar32 c; 793103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_NEXT(s, i, length, c); 794103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (c == 0) { 795103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *buffer = 0; 796103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return; 797103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else if (0x20 <= c && c <= 0x7e) { 798103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // printable ASCII 799103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *buffer++ = (char)c; // assumes ASCII-based platform 800103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 801103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius buffer += sprintf(buffer, "\\u%04X", (int)c); 802103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 803103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 804103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 805103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 806fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} // namespace 807fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 808fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif // !UCONFIG_NO_COLLATION 809fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 810c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertstatic TableResource * 811c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik RoubertaddCollation(ParseState* state, TableResource *result, const char *collationType, 812fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uint32_t startline, UErrorCode *status) 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 814fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // TODO: Use LocalPointer for result, or make caller close it when there is a failure. 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *member = NULL; 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString comment; 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType token; 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char subtag[1024]; 820fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString rules; 821fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UBool haveRules = FALSE; 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UVersionInfo version; 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 824fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* '{' . (name resource)* '}' */ 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru version[0]=0; version[1]=0; version[2]=0; version[3]=0; 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_init(&comment); 83127f654740f2a26ad62a5c155af9199af9e69b889claireho token = getToken(state, &tokenValue, &comment, &line, status); 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_CLOSE_BRACE) 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 835fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token != TOK_STRING) 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 840c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_EOF) 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "unterminated table"); 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "Unexpected token %s", tokenNames[token]); 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 859c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 86327f654740f2a26ad62a5c155af9199af9e69b889claireho member = parseResource(state, subtag, NULL, status); 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 867c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 870fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (result == NULL) 871fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius { 872fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Ignore the parsed resources, continue parsing. 873fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 874c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert else if (uprv_strcmp(subtag, "Version") == 0 && member->isString()) 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 876c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert StringResource *sr = static_cast<StringResource *>(member); 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char ver[40]; 878c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert int32_t length = sr->length(); 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 880c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (length >= UPRV_LENGTHOF(ver)) 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 882c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert length = UPRV_LENGTHOF(ver) - 1; 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 885c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert sr->fString.extract(0, length, ver, UPRV_LENGTHOF(ver), US_INV); 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_versionFromString(version, ver); 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 888c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(member, line, *status); 889fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius member = NULL; 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if(uprv_strcmp(subtag, "%%CollationBin")==0) 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* discard duplicate %%CollationBin if any*/ 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 895c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert else if (uprv_strcmp(subtag, "Sequence") == 0 && member->isString()) 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 897c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert StringResource *sr = static_cast<StringResource *>(member); 898c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert rules = sr->fString; 899fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius haveRules = TRUE; 900fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Defer building the collator until we have seen 901fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // all sub-elements of the collation table, including the Version. 90250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* in order to achieve smaller data files, we can direct genrb */ 90350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* to omit collation rules */ 904fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(!state->omitCollationRules) { 905c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(member, line, *status); 906fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius member = NULL; 90750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 909fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius else // Just copy non-special items. 910fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius { 911c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(member, line, *status); 912fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius member = NULL; 913fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 914fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius res_close(member); // TODO: use LocalPointer 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 917c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 922fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (!haveRules) { return result; } 923fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 924fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if UCONFIG_NO_COLLATION || UCONFIG_NO_FILE_IO 925fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius warning(line, "Not building collation elements because of UCONFIG_NO_COLLATION and/or UCONFIG_NO_FILE_IO, see uconfig.h"); 926fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (void)collationType; 927fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#else 928f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // CLDR ticket #3949, ICU ticket #8082: 929f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Do not build collation binary data for for-import-only "private" collation rule strings. 930f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (uprv_strncmp(collationType, "private-", 8) == 0) { 931f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(isVerbose()) { 932f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius printf("Not building %s~%s collation binary\n", state->filename, collationType); 933f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 934f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return result; 935f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 936f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 937fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(!state->makeBinaryCollation) { 938fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(isVerbose()) { 939fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius printf("Not building %s~%s collation binary\n", state->filename, collationType); 940fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 941fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return result; 942fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 943fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode intStatus = U_ZERO_ERROR; 944fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UParseError parseError; 945fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uprv_memset(&parseError, 0, sizeof(parseError)); 946fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius GenrbImporter importer(state->inputdir, state->outputdir); 947fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const icu::CollationTailoring *base = icu::CollationRoot::getRoot(intStatus); 948fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(intStatus)) { 949fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius error(line, "failed to load root collator (ucadata.icu) - %s", u_errorName(intStatus)); 950fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius res_close(result); 951fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; // TODO: use LocalUResourceBundlePointer for result 952fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 953fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius icu::CollationBuilder builder(base, intStatus); 954fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(uprv_strncmp(collationType, "search", 6) == 0) { 955fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius builder.disableFastLatin(); // build fast-Latin table unless search collator 956fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 957fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalPointer<icu::CollationTailoring> t( 958fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius builder.parseAndBuild(rules, version, &importer, &parseError, intStatus)); 959fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(intStatus)) { 960fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *reason = builder.getErrorReason(); 961fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(reason == NULL) { reason = ""; } 962fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius error(line, "CollationBuilder failed at %s~%s/Sequence rule offset %ld: %s %s", 963fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius state->filename, collationType, 964fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (long)parseError.offset, u_errorName(intStatus), reason); 965fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(parseError.preContext[0] != 0 || parseError.postContext[0] != 0) { 966fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Print pre- and post-context. 967fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius char preBuffer[100], postBuffer[100]; 968fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius escape(parseError.preContext, preBuffer); 969fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius escape(parseError.postContext, postBuffer); 970fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius error(line, " error context: \"...%s\" ! \"%s...\"", preBuffer, postBuffer); 971fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 972c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(isStrict() || t.isNull()) { 973fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *status = intStatus; 974fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius res_close(result); 975fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 976fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 977fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 978fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius icu::LocalMemory<uint8_t> buffer; 979fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t capacity = 100000; 980fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uint8_t *dest = buffer.allocateInsteadAndCopy(capacity); 981fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(dest == NULL) { 982fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fprintf(stderr, "memory allocation (%ld bytes) for file contents failed\n", 983fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (long)capacity); 984fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *status = U_MEMORY_ALLOCATION_ERROR; 985fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius res_close(result); 986fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 987fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 988fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t indexes[icu::CollationDataReader::IX_TOTAL_SIZE + 1]; 989fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t totalSize = icu::CollationDataWriter::writeTailoring( 990fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *t, *t->settings, indexes, dest, capacity, intStatus); 991fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(intStatus == U_BUFFER_OVERFLOW_ERROR) { 992fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius intStatus = U_ZERO_ERROR; 993fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius capacity = totalSize; 994fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius dest = buffer.allocateInsteadAndCopy(capacity); 995fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(dest == NULL) { 996fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fprintf(stderr, "memory allocation (%ld bytes) for file contents failed\n", 997fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (long)capacity); 998fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *status = U_MEMORY_ALLOCATION_ERROR; 999fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius res_close(result); 1000fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 1001fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1002fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius totalSize = icu::CollationDataWriter::writeTailoring( 1003fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *t, *t->settings, indexes, dest, capacity, intStatus); 1004fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1005fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(intStatus)) { 1006fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fprintf(stderr, "CollationDataWriter::writeTailoring() failed: %s\n", 1007fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius u_errorName(intStatus)); 1008fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius res_close(result); 1009fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 1010fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1011fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(isVerbose()) { 1012fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius printf("%s~%s collation tailoring part sizes:\n", state->filename, collationType); 1013fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius icu::CollationInfo::printSizes(totalSize, indexes); 10141b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert if(t->settings->hasReordering()) { 10151b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert printf("%s~%s collation reordering ranges:\n", state->filename, collationType); 10161b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert icu::CollationInfo::printReorderRanges( 10171b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert *t->data, t->settings->reorderCodes, t->settings->reorderCodesLength); 10181b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert } 1019fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1020fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius struct SResource *collationBin = bin_open(state->bundle, "%%CollationBin", totalSize, dest, NULL, NULL, status); 1021c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(collationBin, line, *status); 1022fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(*status)) { 1023fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius res_close(result); 1024fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 1025fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1026fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif 1027fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return result; 1028fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 1029fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1030fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic UBool 1031fc41dc5b8c2370d49e461ba58d6cbe33b20ed002Fredrik RoubertkeepCollationType(const char *type) { // android-changed 1032fc41dc5b8c2370d49e461ba58d6cbe33b20ed002Fredrik Roubert // BEGIN android-added 1033fc41dc5b8c2370d49e461ba58d6cbe33b20ed002Fredrik Roubert if (uprv_strcmp(type, "big5han") == 0) { return FALSE; } 1034fc41dc5b8c2370d49e461ba58d6cbe33b20ed002Fredrik Roubert if (uprv_strcmp(type, "gb2312han") == 0) { return FALSE; } 1035fc41dc5b8c2370d49e461ba58d6cbe33b20ed002Fredrik Roubert // END android-added 1036f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TRUE; 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 104027f654740f2a26ad62a5c155af9199af9e69b889clairehoparseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool newCollation, UErrorCode *status) 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1042c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert TableResource *result = NULL; 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *member = NULL; 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString comment; 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType token; 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char subtag[1024], typeKeyword[1024]; 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 1049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 105027f654740f2a26ad62a5c155af9199af9e69b889claireho result = table_open(state->bundle, tag, NULL, status); 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result == NULL || U_FAILURE(*status)) 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" collation elements %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!newCollation) { 1060fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return addCollation(state, result, "(no type)", startline, status); 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(;;) { 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_init(&comment); 106527f654740f2a26ad62a5c155af9199af9e69b889claireho token = getToken(state, &tokenValue, &comment, &line, status); 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_CLOSE_BRACE) 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token != TOK_STRING) 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1074c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_EOF) 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "unterminated table"); 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "Unexpected token %s", tokenNames[token]); 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1093c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strcmp(subtag, "default") == 0) 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 109927f654740f2a26ad62a5c155af9199af9e69b889claireho member = parseResource(state, subtag, NULL, status); 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1103c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1107c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(member, line, *status); 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 111127f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 0, &tokenValue, &line, &comment, status); 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* this probably needs to be refactored or recursively use the parser */ 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* first we assume that our collation table won't have the explicit type */ 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* then, we cannot handle aliases */ 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(token == TOK_OPEN_BRACE) { 111627f654740f2a26ad62a5c155af9199af9e69b889claireho token = getToken(state, &tokenValue, &comment, &line, status); 1117c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert TableResource *collationRes; 1118fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (keepCollationType(subtag)) { 1119fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius collationRes = table_open(state->bundle, subtag, NULL, status); 1120fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 1121fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius collationRes = NULL; 1122fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1123fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // need to parse the collation data regardless 1124fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius collationRes = addCollation(state, collationRes, subtag, startline, status); 1125fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (collationRes != NULL) { 1126c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(collationRes, startline, *status); 112727f654740f2a26ad62a5c155af9199af9e69b889claireho } 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(token == TOK_COLON) { /* right now, we'll just try to see if we have aliases */ 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we could have a table too */ 113027f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 1, &tokenValue, &line, &comment, status); 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, typeKeyword, u_strlen(tokenValue->fChars) + 1); 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(uprv_strcmp(typeKeyword, "alias") == 0) { 113327f654740f2a26ad62a5c155af9199af9e69b889claireho member = parseResource(state, subtag, NULL, status); 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1136c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1140c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(member, line, *status); 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1142c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1147c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /*member = string_open(bundle, subtag, tokenValue->fChars, tokenValue->fLength, status);*/ 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /*expect(TOK_CLOSE_BRACE, NULL, NULL, status);*/ 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1159c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Necessary, because CollationElements requires the bundle->fRoot member to be present which, 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if this weren't special-cased, wouldn't be set until the entire file had been processed. */ 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 1169c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik RoubertrealParseTable(ParseState* state, TableResource *table, char *tag, uint32_t startline, UErrorCode *status) 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *member = NULL; 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue=NULL; 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString comment; 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType token; 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char subtag[1024]; 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool readToken = FALSE; 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* '{' . (name resource)* '}' */ 1180103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" parsing table %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_init(&comment); 118727f654740f2a26ad62a5c155af9199af9e69b889claireho token = getToken(state, &tokenValue, &comment, &line, status); 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_CLOSE_BRACE) 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!readToken) { 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(startline, "Encountered empty table"); 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return table; 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token != TOK_STRING) 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_EOF) 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "unterminated table"); 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "unexpected token %s", tokenNames[token]); 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(uprv_isInvariantUString(tokenValue->fChars, -1)) { 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "invariant characters required for table keys"); 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1223b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru error(line, "parse error. Stopped parsing tokens with %s", u_errorName(*status)); 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 122727f654740f2a26ad62a5c155af9199af9e69b889claireho member = parseResource(state, subtag, &comment, status); 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (member == NULL || U_FAILURE(*status)) 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1231b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru error(line, "parse error. Stopped parsing resource with %s", u_errorName(*status)); 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1235c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert table->add(member, line, *status); 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1239b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru error(line, "parse error. Stopped parsing table with %s", u_errorName(*status)); 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru readToken = TRUE; 1243c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ustr_deinit(&comment); 1244103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* not reached */ 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* A compiler warning will appear if all paths don't contain a return statement. */ 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* *status = U_INTERNAL_PROGRAM_ERROR; 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL;*/ 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 125327f654740f2a26ad62a5c155af9199af9e69b889clairehoparseTable(ParseState* state, char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tag != NULL && uprv_strcmp(tag, "CollationElements") == 0) 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 125727f654740f2a26ad62a5c155af9199af9e69b889claireho return parseCollationElements(state, tag, startline, FALSE, status); 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tag != NULL && uprv_strcmp(tag, "collations") == 0) 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 126127f654740f2a26ad62a5c155af9199af9e69b889claireho return parseCollationElements(state, tag, startline, TRUE, status); 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" table %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1267c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert TableResource *result = table_open(state->bundle, tag, comment, status); 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result == NULL || U_FAILURE(*status)) 1270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 127327f654740f2a26ad62a5c155af9199af9e69b889claireho return realParseTable(state, result, tag, startline, status); 1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 127727f654740f2a26ad62a5c155af9199af9e69b889clairehoparseArray(ParseState* state, char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *member = NULL; 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString memberComments; 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType token; 1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool readToken = FALSE; 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1285c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert ArrayResource *result = array_open(state->bundle, tag, comment, status); 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result == NULL || U_FAILURE(*status)) 1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" array %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_init(&memberComments); 1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* '{' . resource [','] '}' */ 1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) 1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* reset length */ 1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_setlen(&memberComments, 0, status); 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* check for end of array, but don't consume next token unless it really is the end */ 130427f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 0, &tokenValue, NULL, &memberComments, status); 1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_CLOSE_BRACE) 1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 130927f654740f2a26ad62a5c155af9199af9e69b889claireho getToken(state, NULL, NULL, NULL, status); 1310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!readToken) { 1311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(startline, "Encountered empty array"); 1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_EOF) 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1318c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "unterminated array"); 1321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* string arrays are a special case */ 1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_STRING) 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 132727f654740f2a26ad62a5c155af9199af9e69b889claireho getToken(state, &tokenValue, &memberComments, NULL, status); 132827f654740f2a26ad62a5c155af9199af9e69b889claireho member = string_open(state->bundle, NULL, tokenValue->fChars, tokenValue->fLength, &memberComments, status); 1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 133227f654740f2a26ad62a5c155af9199af9e69b889claireho member = parseResource(state, NULL, &memberComments, status); 1333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (member == NULL || U_FAILURE(*status)) 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1337c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1341c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(member); 1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* eat optional comma if present */ 134427f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 0, NULL, NULL, NULL, status); 1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_COMMA) 1347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 134827f654740f2a26ad62a5c155af9199af9e69b889claireho getToken(state, NULL, NULL, NULL, status); 1349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1353c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru readToken = TRUE; 1357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1359c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ustr_deinit(&memberComments); 1360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 136427f654740f2a26ad62a5c155af9199af9e69b889clairehoparseIntVector(ParseState* state, char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) 1365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType token; 1367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *string; 1368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t value; 1369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool readToken = FALSE; 1370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *stopstring; 1371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t len; 1372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString memberComments; 1373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1374c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert IntVectorResource *result = intvector_open(state->bundle, tag, comment, status); 1375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result == NULL || U_FAILURE(*status)) 1377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" vector %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_init(&memberComments); 1385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* '{' . string [','] '}' */ 1386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) 1387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_setlen(&memberComments, 0, status); 1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* check for end of array, but don't consume next token unless it really is the end */ 139127f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 0, NULL, NULL,&memberComments, status); 1392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_CLOSE_BRACE) 1394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* it's the end, consume the close brace */ 139627f654740f2a26ad62a5c155af9199af9e69b889claireho getToken(state, NULL, NULL, NULL, status); 1397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!readToken) { 1398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(startline, "Encountered empty int vector"); 1399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1400c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ustr_deinit(&memberComments); 1401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 140427f654740f2a26ad62a5c155af9199af9e69b889claireho string = getInvariantString(state, NULL, NULL, status); 1405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1408c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1412c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* For handling illegal char in the Intvector */ 1413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value = uprv_strtoul(string, &stopstring, 0);/* make intvector support decimal,hexdigit,octal digit ranging from -2^31-2^32-1*/ 1414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len=(uint32_t)(stopstring-string); 1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len==uprv_strlen(string)) 1417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1418c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(value, *status); 1419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(string); 142027f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 0, NULL, NULL, NULL, status); 1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(string); 1425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_INVALID_CHAR_FOUND; 1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1430c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* the comma is optional (even though it is required to prevent the reader from concatenating 1435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru consecutive entries) so that a missing comma on the last entry isn't an error */ 1436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_COMMA) 1437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 143827f654740f2a26ad62a5c155af9199af9e69b889claireho getToken(state, NULL, NULL, NULL, status); 1439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru readToken = TRUE; 1441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* not reached */ 1444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* A compiler warning will appear if all paths don't contain a return statement. */ 1445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* intvector_close(result, status); 1446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 1447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL;*/ 1448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 145127f654740f2a26ad62a5c155af9199af9e69b889clairehoparseBinary(ParseState* state, char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) 1452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1453c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert uint32_t line; 1454c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalMemory<char> string(getInvariantString(state, &line, NULL, status)); 1455c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (string.isNull() || U_FAILURE(*status)) 1456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 146027f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 1461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" binary %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1470c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert uint32_t count = (uint32_t)uprv_strlen(string.getAlias()); 1471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (count > 0){ 1472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((count % 2)==0){ 1473c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalMemory<uint8_t> value; 1474c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (value.allocateInsteadAndCopy(count) == NULL) 1475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1480c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert char toConv[3] = {'\0', '\0', '\0'}; 1481c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert for (uint32_t i = 0; i < count; i += 2) 1482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru toConv[0] = string[i]; 1484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru toConv[1] = string[i + 1]; 1485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1486c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert char *stopstring; 1487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value[i >> 1] = (uint8_t) uprv_strtoul(toConv, &stopstring, 16); 1488c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert uint32_t len=(uint32_t)(stopstring-toConv); 1489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1490c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(len!=2) 1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_INVALID_CHAR_FOUND; 1493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1497c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return bin_open(state->bundle, tag, count >> 1, value.getAlias(), NULL, comment, status); 1498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_CHAR_FOUND; 1502c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert error(line, "Encountered invalid binary value (length is odd)"); 1503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1508c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert warning(startline, "Encountered empty binary value"); 1509c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return bin_open(state->bundle, tag, 0, NULL, "", comment, status); 1510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 151427f654740f2a26ad62a5c155af9199af9e69b889clairehoparseInteger(ParseState* state, char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) 1515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *result = NULL; 1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t value; 1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *string; 1519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *stopstring; 1520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t len; 1521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 152227f654740f2a26ad62a5c155af9199af9e69b889claireho string = getInvariantString(state, NULL, NULL, status); 1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (string == NULL || U_FAILURE(*status)) 1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 152927f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 1530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(string); 1534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" integer %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strlen(string) <= 0) 1542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(startline, "Encountered empty integer. Default value is 0."); 1544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1546c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* Allow integer support for hexdecimal, octal digit and decimal*/ 1547c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* and handle illegal char in the integer*/ 1548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value = uprv_strtoul(string, &stopstring, 0); 1549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len=(uint32_t)(stopstring-string); 1550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len==uprv_strlen(string)) 1551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 155227f654740f2a26ad62a5c155af9199af9e69b889claireho result = int_open(state->bundle, tag, value, comment, status); 1553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_INVALID_CHAR_FOUND; 1557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(string); 1559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 156427f654740f2a26ad62a5c155af9199af9e69b889clairehoparseImport(ParseState* state, char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status) 1565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 1567c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalMemory<char> filename(getInvariantString(state, &line, NULL, status)); 1568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 157327f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 1574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" import %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Open the input file for reading */ 1585c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert CharString fullname; 1586c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (state->inputdir != NULL) { 1587c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert fullname.append(state->inputdir, *status); 1588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1589c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert fullname.appendPathPart(filename.getAlias(), *status); 1590c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (U_FAILURE(*status)) { 1591c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return NULL; 1592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1594c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert FileStream *file = T_FileStream_open(fullname.data(), "rb"); 1595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (file == NULL) 1596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1597c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert error(line, "couldn't open input file %s", filename.getAlias()); 1598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_FILE_ACCESS_ERROR; 1599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1602c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert int32_t len = T_FileStream_size(file); 1603c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalMemory<uint8_t> data; 1604c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(data.allocateInsteadAndCopy(len) == NULL) 1605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru T_FileStream_close (file); 1608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1611c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /* int32_t numRead = */ T_FileStream_read(file, data.getAlias(), len); 1612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru T_FileStream_close (file); 1613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1614c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return bin_open(state->bundle, tag, len, data.getAlias(), fullname.data(), comment, status); 1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 161827f654740f2a26ad62a5c155af9199af9e69b889clairehoparseInclude(ParseState* state, char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status) 1619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *result; 1621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t len=0; 1622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *filename; 1623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 1624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *pTarget = NULL; 1625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCHARBUF *ucbuf; 1627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *fullname = NULL; 1628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t count = 0; 1629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* cp = NULL; 1630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar* uBuffer = NULL; 1631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 163227f654740f2a26ad62a5c155af9199af9e69b889claireho filename = getInvariantString(state, &line, NULL, status); 1633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count = (int32_t)uprv_strlen(filename); 1634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 164027f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 1641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(filename); 1645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" include %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 165227f654740f2a26ad62a5c155af9199af9e69b889claireho fullname = (char *) uprv_malloc(state->inputdirLength + count + 2); 1653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* test for NULL */ 1654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fullname == NULL) 1655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(filename); 1658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 166127f654740f2a26ad62a5c155af9199af9e69b889claireho if(state->inputdir!=NULL){ 166227f654740f2a26ad62a5c155af9199af9e69b889claireho if (state->inputdir[state->inputdirLength - 1] != U_FILE_SEP_CHAR) 1663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 166527f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strcpy(fullname, state->inputdir); 1666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 166727f654740f2a26ad62a5c155af9199af9e69b889claireho fullname[state->inputdirLength] = U_FILE_SEP_CHAR; 166827f654740f2a26ad62a5c155af9199af9e69b889claireho fullname[state->inputdirLength + 1] = '\0'; 1669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(fullname, filename); 1671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 167427f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strcpy(fullname, state->inputdir); 1675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(fullname, filename); 1676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else{ 1678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(fullname,filename); 1679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucbuf = ucbuf_open(fullname, &cp,getShowWarning(),FALSE,status); 1682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 1684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "couldn't open input file %s\n", filename); 1685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uBuffer = ucbuf_getBuffer(ucbuf,&len,status); 168927f654740f2a26ad62a5c155af9199af9e69b889claireho result = string_open(state->bundle, tag, uBuffer, len, comment, status); 1690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 169154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius ucbuf_close(ucbuf); 169254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 1693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(pTarget); 1694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(filename); 1696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fullname); 1697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_string, "string", 6); 1706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_binary, "binary", 6); 1707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_bin, "bin", 3); 1708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_table, "table", 5); 1709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_table_no_fallback, "table(nofallback)", 17); 1710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_int, "int", 3); 1711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_integer, "integer", 7); 1712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_array, "array", 5); 1713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_alias, "alias", 5); 1714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_intvector, "intvector", 9); 1715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_import, "import", 6); 1716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_include, "include", 7); 1717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Various non-standard processing plugins that create one or more special resources. */ 1719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_plugin_uca_rules, "process(uca_rules)", 18); 1720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_plugin_collation, "process(collation)", 18); 1721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_plugin_transliterator, "process(transliterator)", 23); 1722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_plugin_dependency, "process(dependency)", 19); 1723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef enum EResourceType 1725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1726fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_UNKNOWN, 1727fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_STRING, 1728fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_BINARY, 1729fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_TABLE, 1730fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_TABLE_NO_FALLBACK, 1731fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_INTEGER, 1732fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_ARRAY, 1733fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_ALIAS, 1734fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_INTVECTOR, 1735fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_IMPORT, 1736fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_INCLUDE, 1737fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_PROCESS_UCA_RULES, 1738fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_PROCESS_COLLATION, 1739fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_PROCESS_TRANSLITERATOR, 1740fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_PROCESS_DEPENDENCY, 1741fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_RESERVED 1742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} EResourceType; 1743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct { 1745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *nameChars; /* only used for debugging */ 1746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *nameUChars; 1747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ParseResourceFunction *parseFunction; 1748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} gResourceTypes[] = { 1749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"Unknown", NULL, NULL}, 1750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"string", k_type_string, parseString}, 1751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"binary", k_type_binary, parseBinary}, 1752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"table", k_type_table, parseTable}, 1753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"table(nofallback)", k_type_table_no_fallback, NULL}, /* parseFunction will never be called */ 1754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"integer", k_type_integer, parseInteger}, 1755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"array", k_type_array, parseArray}, 1756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"alias", k_type_alias, parseAlias}, 1757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"intvector", k_type_intvector, parseIntVector}, 1758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"import", k_type_import, parseImport}, 1759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"include", k_type_include, parseInclude}, 1760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"process(uca_rules)", k_type_plugin_uca_rules, parseUCARules}, 1761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"process(collation)", k_type_plugin_collation, NULL /* not implemented yet */}, 1762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"process(transliterator)", k_type_plugin_transliterator, parseTransliterator}, 1763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"process(dependency)", k_type_plugin_dependency, parseDependency}, 1764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"reserved", NULL, NULL} 1765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 1766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 176759d709d503bab6e2b61931737e662dd293b40578ccorneliusvoid initParser() 1768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_string, "string", 6); 1770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_binary, "binary", 6); 1771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_bin, "bin", 3); 1772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_table, "table", 5); 1773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_table_no_fallback, "table(nofallback)", 17); 1774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_int, "int", 3); 1775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_integer, "integer", 7); 1776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_array, "array", 5); 1777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_alias, "alias", 5); 1778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_intvector, "intvector", 9); 1779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_import, "import", 6); 1780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_include, "include", 7); 1781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_plugin_uca_rules, "process(uca_rules)", 18); 1783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_plugin_collation, "process(collation)", 18); 1784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_plugin_transliterator, "process(transliterator)", 23); 1785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_plugin_dependency, "process(dependency)", 19); 1786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1788103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic inline UBool isTable(enum EResourceType type) { 1789fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return (UBool)(type==RESTYPE_TABLE || type==RESTYPE_TABLE_NO_FALLBACK); 1790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic enum EResourceType 179327f654740f2a26ad62a5c155af9199af9e69b889clairehoparseResourceType(ParseState* state, UErrorCode *status) 1794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 1796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString comment; 1797fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius enum EResourceType result = RESTYPE_UNKNOWN; 1798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line=0; 1799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_init(&comment); 180027f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_STRING, &tokenValue, &comment, &line, status); 1801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1804fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return RESTYPE_UNKNOWN; 1805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ZERO_ERROR; 1808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Search for normal types */ 1810fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result=RESTYPE_UNKNOWN; 1811fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius while ((result=(EResourceType)(result+1)) < RESTYPE_RESERVED) { 1812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (u_strcmp(tokenValue->fChars, gResourceTypes[result].nameUChars) == 0) { 1813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Now search for the aliases */ 1817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (u_strcmp(tokenValue->fChars, k_type_int) == 0) { 1818fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result = RESTYPE_INTEGER; 1819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (u_strcmp(tokenValue->fChars, k_type_bin) == 0) { 1821fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result = RESTYPE_BINARY; 1822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1823fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius else if (result == RESTYPE_RESERVED) { 1824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char tokenBuffer[1024]; 1825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_austrncpy(tokenBuffer, tokenValue->fChars, sizeof(tokenBuffer)); 1826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tokenBuffer[sizeof(tokenBuffer) - 1] = 0; 1827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "unknown resource type '%s'", tokenBuffer); 1829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* parse a non-top-level resource */ 1835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 183627f654740f2a26ad62a5c155af9199af9e69b889clairehoparseResource(ParseState* state, char *tag, const struct UString *comment, UErrorCode *status) 1837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType token; 1839fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius enum EResourceType resType = RESTYPE_UNKNOWN; 1840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ParseResourceFunction *parseFunction = NULL; 1841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 1842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t startline; 1843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 1844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1845103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 184627f654740f2a26ad62a5c155af9199af9e69b889claireho token = getToken(state, &tokenValue, NULL, &startline, status); 1847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" resource %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* name . [ ':' type ] '{' resource '}' */ 1853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* This function parses from the colon onwards. If the colon is present, parse the 1854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type then try to parse a resource of that type. If there is no explicit type, 1855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru work it out using the lookahead tokens. */ 1856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (token) 1857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case TOK_EOF: 1859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "Unexpected EOF encountered"); 1861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case TOK_ERROR: 1864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case TOK_COLON: 186827f654740f2a26ad62a5c155af9199af9e69b889claireho resType = parseResourceType(state, status); 186927f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_OPEN_BRACE, &tokenValue, NULL, &startline, status); 1870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case TOK_OPEN_BRACE: 1879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "syntax error while reading a resource, expected '{' or ':'"); 1884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1887103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1888fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (resType == RESTYPE_UNKNOWN) 1889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* No explicit type, so try to work it out. At this point, we've read the first '{'. 1891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru We could have any of the following: 1892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { { => array (nested) 1893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { :/} => array 1894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { string , => string array 1895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { string { => table 1897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { string :/{ => table 1899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { string } => string 1900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 190227f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 0, NULL, &line, NULL,status); 1903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_OPEN_BRACE || token == TOK_COLON ||token ==TOK_CLOSE_BRACE ) 1910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1911fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resType = RESTYPE_ARRAY; 1912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (token == TOK_STRING) 1914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 191527f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 1, NULL, &line, NULL, status); 1916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (token) 1923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1924fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case TOK_COMMA: resType = RESTYPE_ARRAY; break; 1925fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case TOK_OPEN_BRACE: resType = RESTYPE_TABLE; break; 1926fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case TOK_CLOSE_BRACE: resType = RESTYPE_STRING; break; 1927fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case TOK_COLON: resType = RESTYPE_TABLE; break; 1928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "Unexpected token after string, expected ',', '{' or '}'"); 1931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "Unexpected token after '{'"); 1938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* printf("Type guessed as %s\n", resourceNames[resType]); */ 1942fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if(resType == RESTYPE_TABLE_NO_FALLBACK) { 1943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "error: %s resource type not valid except on top bundle level", gResourceTypes[resType].nameChars); 1945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1948103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* We should now know what we need to parse next, so call the appropriate parser 1950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru function and return. */ 1951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru parseFunction = gResourceTypes[resType].parseFunction; 1952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (parseFunction != NULL) { 195327f654740f2a26ad62a5c155af9199af9e69b889claireho return parseFunction(state, tag, startline, comment, status); 1954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 1956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 1957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "internal error: %s resource type found and not handled", gResourceTypes[resType].nameChars); 1958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* parse the top-level resource */ 1964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct SRBRoot * 1965fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusparse(UCHARBUF *buf, const char *inputDir, const char *outputDir, const char *filename, 196659d709d503bab6e2b61931737e662dd293b40578ccornelius UBool makeBinaryCollation, UBool omitCollationRules, UErrorCode *status) 1967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 1969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString comment; 1970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 1971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum EResourceType bundleType; 1972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType token; 197327f654740f2a26ad62a5c155af9199af9e69b889claireho ParseState state; 197427f654740f2a26ad62a5c155af9199af9e69b889claireho uint32_t i; 1975b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1976103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 197727f654740f2a26ad62a5c155af9199af9e69b889claireho for (i = 0; i < MAX_LOOKAHEAD + 1; i++) 197827f654740f2a26ad62a5c155af9199af9e69b889claireho { 197927f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_init(&state.lookahead[i].value); 198027f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_init(&state.lookahead[i].comment); 198127f654740f2a26ad62a5c155af9199af9e69b889claireho } 1982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 198327f654740f2a26ad62a5c155af9199af9e69b889claireho initLookahead(&state, buf, status); 1984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 198527f654740f2a26ad62a5c155af9199af9e69b889claireho state.inputdir = inputDir; 198627f654740f2a26ad62a5c155af9199af9e69b889claireho state.inputdirLength = (state.inputdir != NULL) ? (uint32_t)uprv_strlen(state.inputdir) : 0; 198727f654740f2a26ad62a5c155af9199af9e69b889claireho state.outputdir = outputDir; 198827f654740f2a26ad62a5c155af9199af9e69b889claireho state.outputdirLength = (state.outputdir != NULL) ? (uint32_t)uprv_strlen(state.outputdir) : 0; 1989fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius state.filename = filename; 1990103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius state.makeBinaryCollation = makeBinaryCollation; 199159d709d503bab6e2b61931737e662dd293b40578ccornelius state.omitCollationRules = omitCollationRules; 1992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_init(&comment); 199427f654740f2a26ad62a5c155af9199af9e69b889claireho expect(&state, TOK_STRING, &tokenValue, &comment, NULL, status); 1995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1996c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert state.bundle = new SRBRoot(&comment, FALSE, *status); 1997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 199827f654740f2a26ad62a5c155af9199af9e69b889claireho if (state.bundle == NULL || U_FAILURE(*status)) 1999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2004c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert state.bundle->setLocale(tokenValue->fChars, *status); 200527f654740f2a26ad62a5c155af9199af9e69b889claireho 2006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* The following code is to make Empty bundle work no matter with :table specifer or not */ 200727f654740f2a26ad62a5c155af9199af9e69b889claireho token = getToken(&state, NULL, NULL, &line, status); 2008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(token==TOK_COLON) { 2009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_ZERO_ERROR; 201027f654740f2a26ad62a5c155af9199af9e69b889claireho bundleType=parseResourceType(&state, status); 2011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isTable(bundleType)) 2013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 201427f654740f2a26ad62a5c155af9199af9e69b889claireho expect(&state, TOK_OPEN_BRACE, NULL, NULL, &line, status); 2015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 2017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_PARSE_ERROR; 2019103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius error(line, "parse error. Stopped parsing with %s", u_errorName(*status)); 2020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 2023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* not a colon */ 2025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(token==TOK_OPEN_BRACE) 2026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_ZERO_ERROR; 2028fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius bundleType=RESTYPE_TABLE; 2029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 2031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* neither colon nor open brace */ 2033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_PARSE_ERROR; 2034fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius bundleType=RESTYPE_UNKNOWN; 2035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "parse error, did not find open-brace '{' or colon ':', stopped with %s", u_errorName(*status)); 2036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 2040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2041c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete state.bundle; 2042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2045fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(bundleType==RESTYPE_TABLE_NO_FALLBACK) { 2046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Parse a top-level table with the table(nofallback) declaration. 2048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is the same as a regular table, but also sets the 2049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * URES_ATT_NO_FALLBACK flag in indexes[URES_INDEX_ATTRIBUTES] . 2050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2051c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert state.bundle->fNoFallback=TRUE; 2052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* top-level tables need not handle special table names like "collations" */ 2054c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert assert(!state.bundle->fIsPoolBundle); 2055c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert assert(state.bundle->fRoot->fType == URES_TABLE); 2056c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert TableResource *rootTable = static_cast<TableResource *>(state.bundle->fRoot); 2057c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert realParseTable(&state, rootTable, NULL, line, status); 2058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(dependencyArray!=NULL){ 2059c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert rootTable->add(dependencyArray, 0, *status); 2060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dependencyArray = NULL; 2061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2062103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(*status)) 2063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2064c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete state.bundle; 2065c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(dependencyArray); 2066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 206927f654740f2a26ad62a5c155af9199af9e69b889claireho if (getToken(&state, NULL, NULL, &line, status) != TOK_EOF) 2070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(line, "extraneous text after resource bundle (perhaps unmatched braces)"); 2072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isStrict()){ 2073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 2074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 207827f654740f2a26ad62a5c155af9199af9e69b889claireho cleanupLookahead(&state); 2079c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ustr_deinit(&comment); 208027f654740f2a26ad62a5c155af9199af9e69b889claireho return state.bundle; 2081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2082