164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// Copyright (C) 2016 and later: Unicode, Inc. and others. 264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 61b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert* Copyright (C) 1998-2015, International Business Machines 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius* File parse.cpp 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification History: 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Date Name Description 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 05/26/99 stephen Creation. 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 02/25/00 weiv Overhaul to write udata 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 5/10/01 Ram removed ustdio dependency 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 06/10/2001 Dominic Ludlam <dom@recoil.org> Rewritten 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 23fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// Safer use of UnicodeString. 24fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#ifndef UNISTR_FROM_CHAR_EXPLICIT 25fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius# define UNISTR_FROM_CHAR_EXPLICIT explicit 26fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif 27fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 28fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// Less important, but still a good idea. 29fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#ifndef UNISTR_FROM_STRING_EXPLICIT 30fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius# define UNISTR_FROM_STRING_EXPLICIT explicit 31fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif 32fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 33c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#include <assert.h> 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "parse.h" 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "errmsg.h" 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uhash.h" 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uinvchar.h" 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "read.h" 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ustr.h" 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "reslist.h" 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "rbt_pars.h" 4427f654740f2a26ad62a5c155af9199af9e69b889claireho#include "genrb.h" 45c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#include "unicode/stringpiece.h" 46c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#include "unicode/unistr.h" 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h" 4827f654740f2a26ad62a5c155af9199af9e69b889claireho#include "unicode/uscript.h" 49fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/utf16.h" 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/putil.h" 51c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#include "charstr.h" 52fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationbuilder.h" 53fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationdata.h" 54fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationdatareader.h" 55fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationdatawriter.h" 56fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationfastlatinbuilder.h" 57fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationinfo.h" 58fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationroot.h" 59fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationruleparser.h" 60fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collationtailoring.h" 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h> 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Number of tokens to read ahead of the current stream position */ 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define MAX_LOOKAHEAD 3 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define CR 0x000D 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LF 0x000A 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define SPACE 0x0020 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define TAB 0x0009 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ESCAPE 0x005C 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define HASH 0x0023 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define QUOTE 0x0027 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ZERO 0x0030 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define STARTCOMMAND 0x005B 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ENDCOMMAND 0x005D 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define OPENSQBRACKET 0x005B 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define CLOSESQBRACKET 0x005D 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 79c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertusing icu::CharString; 80c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertusing icu::LocalMemory; 81fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliususing icu::LocalPointer; 82c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertusing icu::LocalUCHARBUFPointer; 83c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertusing icu::StringPiece; 84fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliususing icu::UnicodeString; 85fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct Lookahead 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType type; 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString value; 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString comment; 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* keep in sync with token defines in read.h */ 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char *tokenNames[TOK_TOKEN_COUNT] = 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "string", /* A string token, such as "MonthNames" */ 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "'{'", /* An opening brace character */ 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "'}'", /* A closing brace character */ 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "','", /* A comma */ 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "':'", /* A colon */ 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "<end of file>", /* End of the file has been reached successfully */ 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "<end of line>" 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Just to store "TRUE" */ 10854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar trueValue[] = {0x0054, 0x0052, 0x0055, 0x0045, 0x0000}; 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 11027f654740f2a26ad62a5c155af9199af9e69b889clairehotypedef struct { 11127f654740f2a26ad62a5c155af9199af9e69b889claireho struct Lookahead lookahead[MAX_LOOKAHEAD + 1]; 11227f654740f2a26ad62a5c155af9199af9e69b889claireho uint32_t lookaheadPosition; 11327f654740f2a26ad62a5c155af9199af9e69b889claireho UCHARBUF *buffer; 11427f654740f2a26ad62a5c155af9199af9e69b889claireho struct SRBRoot *bundle; 11527f654740f2a26ad62a5c155af9199af9e69b889claireho const char *inputdir; 11627f654740f2a26ad62a5c155af9199af9e69b889claireho uint32_t inputdirLength; 11727f654740f2a26ad62a5c155af9199af9e69b889claireho const char *outputdir; 11827f654740f2a26ad62a5c155af9199af9e69b889claireho uint32_t outputdirLength; 119fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *filename; 120103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool makeBinaryCollation; 12159d709d503bab6e2b61931737e662dd293b40578ccornelius UBool omitCollationRules; 12227f654740f2a26ad62a5c155af9199af9e69b889claireho} ParseState; 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 12427f654740f2a26ad62a5c155af9199af9e69b889clairehotypedef struct SResource * 12527f654740f2a26ad62a5c155af9199af9e69b889clairehoParseResourceFunction(ParseState* state, char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status); 12627f654740f2a26ad62a5c155af9199af9e69b889claireho 12727f654740f2a26ad62a5c155af9199af9e69b889clairehostatic struct SResource *parseResource(ParseState* state, char *tag, const struct UString *comment, UErrorCode *status); 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* The nature of the lookahead buffer: 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru There are MAX_LOOKAHEAD + 1 slots, used as a circular buffer. This provides 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MAX_LOOKAHEAD lookahead tokens and a slot for the current token and value. 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru When getToken is called, the current pointer is moved to the next slot and the 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru old slot is filled with the next token from the reader by calling getNextToken. 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru The token values are stored in the slot, which means that token values don't 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru survive a call to getToken, ie. 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UString *value; 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getToken(&value, NULL, status); 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getToken(NULL, NULL, status); bad - value is now a different string 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 14327f654740f2a26ad62a5c155af9199af9e69b889clairehoinitLookahead(ParseState* state, UCHARBUF *buf, UErrorCode *status) 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static uint32_t initTypeStrings = 0; 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t i; 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!initTypeStrings) 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru initTypeStrings = 1; 151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 15327f654740f2a26ad62a5c155af9199af9e69b889claireho state->lookaheadPosition = 0; 15427f654740f2a26ad62a5c155af9199af9e69b889claireho state->buffer = buf; 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru resetLineNumber(); 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i = 0; i < MAX_LOOKAHEAD; i++) 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 16027f654740f2a26ad62a5c155af9199af9e69b889claireho state->lookahead[i].type = getNextToken(state->buffer, &state->lookahead[i].value, &state->lookahead[i].line, &state->lookahead[i].comment, status); 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ZERO_ERROR; 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 170c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void 17127f654740f2a26ad62a5c155af9199af9e69b889clairehocleanupLookahead(ParseState* state) 172c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{ 173c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uint32_t i; 17454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius for (i = 0; i <= MAX_LOOKAHEAD; i++) 175c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { 17627f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_deinit(&state->lookahead[i].value); 17727f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_deinit(&state->lookahead[i].comment); 178c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 179c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 180c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru} 181c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic enum ETokenType 18327f654740f2a26ad62a5c155af9199af9e69b889clairehogetToken(ParseState* state, struct UString **tokenValue, struct UString* comment, uint32_t *linenumber, UErrorCode *status) 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType result; 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t i; 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 18827f654740f2a26ad62a5c155af9199af9e69b889claireho result = state->lookahead[state->lookaheadPosition].type; 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tokenValue != NULL) 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 19227f654740f2a26ad62a5c155af9199af9e69b889claireho *tokenValue = &state->lookahead[state->lookaheadPosition].value; 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (linenumber != NULL) 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 19727f654740f2a26ad62a5c155af9199af9e69b889claireho *linenumber = state->lookahead[state->lookaheadPosition].line; 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (comment != NULL) 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 20227f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_cpy(comment, &(state->lookahead[state->lookaheadPosition].comment), status); 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 20527f654740f2a26ad62a5c155af9199af9e69b889claireho i = (state->lookaheadPosition + MAX_LOOKAHEAD) % (MAX_LOOKAHEAD + 1); 20627f654740f2a26ad62a5c155af9199af9e69b889claireho state->lookaheadPosition = (state->lookaheadPosition + 1) % (MAX_LOOKAHEAD + 1); 20727f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_setlen(&state->lookahead[i].comment, 0, status); 20827f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_setlen(&state->lookahead[i].value, 0, status); 20927f654740f2a26ad62a5c155af9199af9e69b889claireho state->lookahead[i].type = getNextToken(state->buffer, &state->lookahead[i].value, &state->lookahead[i].line, &state->lookahead[i].comment, status); 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* printf("getToken, returning %s\n", tokenNames[result]); */ 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic enum ETokenType 21727f654740f2a26ad62a5c155af9199af9e69b889clairehopeekToken(ParseState* state, uint32_t lookaheadCount, struct UString **tokenValue, uint32_t *linenumber, struct UString *comment, UErrorCode *status) 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 21927f654740f2a26ad62a5c155af9199af9e69b889claireho uint32_t i = (state->lookaheadPosition + lookaheadCount) % (MAX_LOOKAHEAD + 1); 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TOK_ERROR; 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lookaheadCount >= MAX_LOOKAHEAD) 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TOK_ERROR; 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tokenValue != NULL) 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 23427f654740f2a26ad62a5c155af9199af9e69b889claireho *tokenValue = &state->lookahead[i].value; 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (linenumber != NULL) 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 23927f654740f2a26ad62a5c155af9199af9e69b889claireho *linenumber = state->lookahead[i].line; 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(comment != NULL){ 24327f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_cpy(comment, &(state->lookahead[state->lookaheadPosition].comment), status); 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 24627f654740f2a26ad62a5c155af9199af9e69b889claireho return state->lookahead[i].type; 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 25027f654740f2a26ad62a5c155af9199af9e69b889clairehoexpect(ParseState* state, enum ETokenType expectedToken, struct UString **tokenValue, struct UString *comment, uint32_t *linenumber, UErrorCode *status) 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 25427f654740f2a26ad62a5c155af9199af9e69b889claireho enum ETokenType token = getToken(state, tokenValue, comment, &line, status); 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (linenumber != NULL) 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *linenumber = line; 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token != expectedToken) 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "expecting %s, got %s", tokenNames[expectedToken], tokenNames[token]); 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 271c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru else 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ZERO_ERROR; 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 27727f654740f2a26ad62a5c155af9199af9e69b889clairehostatic char *getInvariantString(ParseState* state, uint32_t *line, struct UString *comment, UErrorCode *status) 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *result; 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t count; 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 28327f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_STRING, &tokenValue, comment, line, status); 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count = u_strlen(tokenValue->fChars); 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!uprv_isInvariantUString(tokenValue->fChars, count)) { 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(*line, "invariant characters required for table keys, binary data, etc."); 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 29754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius result = static_cast<char *>(uprv_malloc(count+1)); 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result == NULL) 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, result, count+1); 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 310103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusparseUCARules(ParseState* state, char *tag, uint32_t startline, const struct UString* /*comment*/, UErrorCode *status) 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *result = NULL; 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FileStream *file = NULL; 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char filename[256] = { '\0' }; 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char cs[128] = { '\0' }; 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool quoted = FALSE; 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCHARBUF *ucbuf=NULL; 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar32 c = 0; 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* cp = NULL; 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *pTarget = NULL; 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *target = NULL; 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *targetLimit = NULL; 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t size = 0; 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 32727f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_STRING, &tokenValue, NULL, &line, status); 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* make the filename including the directory */ 33827f654740f2a26ad62a5c155af9199af9e69b889claireho if (state->inputdir != NULL) 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 34027f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strcat(filename, state->inputdir); 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 34227f654740f2a26ad62a5c155af9199af9e69b889claireho if (state->inputdir[state->inputdirLength - 1] != U_FILE_SEP_CHAR) 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(filename, U_FILE_SEP_STRING); 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, cs, tokenValue->fLength); 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 35027f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(filename, cs); 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 35859d709d503bab6e2b61931737e662dd293b40578ccornelius if(state->omitCollationRules) { 359c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return res_none(); 360c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucbuf = ucbuf_open(filename, &cp, getShowWarning(),FALSE, status); 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "An error occured while opening the input file %s\n", filename); 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* We allocate more space than actually required 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * since the actual size needed for storing UChars 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * is not known in UTF-8 byte stream 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size = ucbuf_size(ucbuf) + 1; 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pTarget = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * size); 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memset(pTarget, 0, size*U_SIZEOF_UCHAR); 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru target = pTarget; 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru targetLimit = pTarget+size; 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* read the rules into the buffer */ 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (target < targetLimit) 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = ucbuf_getc(ucbuf, status); 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c == QUOTE) { 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru quoted = (UBool)!quoted; 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* weiv (06/26/2002): adding the following: 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * - preserving spaces in commands [...] 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * - # comments until the end of line 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (c == STARTCOMMAND && !quoted) 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* preserve commands 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * closing bracket will be handled by the 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * append at the end of the loop 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(c != ENDCOMMAND) { 39754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius U_APPEND_CHAR32_ONLY(c, target); 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = ucbuf_getc(ucbuf, status); 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (c == HASH && !quoted) { 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* skip comments */ 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(c != CR && c != LF) { 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = ucbuf_getc(ucbuf, status); 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (c == ESCAPE) 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = unescape(ucbuf, status); 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 412103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (c == (UChar32)U_ERR) 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(pTarget); 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru T_FileStream_close(file); 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (!quoted && (c == SPACE || c == TAB || c == CR || c == LF)) 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* ignore spaces carriage returns 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and line feed unless in the form \uXXXX 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Append UChar * after dissembling if c > 0xffff*/ 428103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (c != (UChar32)U_EOF) 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 43054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius U_APPEND_CHAR32_ONLY(c, target); 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* terminate the string */ 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(target < targetLimit){ 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *target = 0x0000; 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 44327f654740f2a26ad62a5c155af9199af9e69b889claireho result = string_open(state->bundle, tag, pTarget, (int32_t)(target - pTarget), NULL, status); 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucbuf_close(ucbuf); 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(pTarget); 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru T_FileStream_close(file); 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 454103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusparseTransliterator(ParseState* state, char *tag, uint32_t startline, const struct UString* /*comment*/, UErrorCode *status) 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *result = NULL; 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FileStream *file = NULL; 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char filename[256] = { '\0' }; 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char cs[128] = { '\0' }; 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCHARBUF *ucbuf=NULL; 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* cp = NULL; 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *pTarget = NULL; 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *pSource = NULL; 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t size = 0; 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 46827f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_STRING, &tokenValue, NULL, &line, status); 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* make the filename including the directory */ 47927f654740f2a26ad62a5c155af9199af9e69b889claireho if (state->inputdir != NULL) 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 48127f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strcat(filename, state->inputdir); 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 48327f654740f2a26ad62a5c155af9199af9e69b889claireho if (state->inputdir[state->inputdirLength - 1] != U_FILE_SEP_CHAR) 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(filename, U_FILE_SEP_STRING); 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, cs, tokenValue->fLength); 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 49127f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(filename, cs); 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucbuf = ucbuf_open(filename, &cp, getShowWarning(),FALSE, status); 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "An error occured while opening the input file %s\n", filename); 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* We allocate more space than actually required 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * since the actual size needed for storing UChars 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * is not known in UTF-8 byte stream 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pSource = ucbuf_getBuffer(ucbuf, &size, status); 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pTarget = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * (size + 1)); 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memset(pTarget, 0, size*U_SIZEOF_UCHAR); 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_TRANSLITERATION 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size = utrans_stripRules(pSource, size, pTarget, status); 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size = 0; 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, " Warning: writing empty transliteration data ( UCONFIG_NO_TRANSLITERATION ) \n"); 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 52127f654740f2a26ad62a5c155af9199af9e69b889claireho result = string_open(state->bundle, tag, pTarget, size, NULL, status); 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucbuf_close(ucbuf); 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(pTarget); 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru T_FileStream_close(file); 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 529c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertstatic ArrayResource* dependencyArray = NULL; 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 53227f654740f2a26ad62a5c155af9199af9e69b889clairehoparseDependency(ParseState* state, char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status) 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *result = NULL; 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *elem = NULL; 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char filename[256] = { '\0' }; 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char cs[128] = { '\0' }; 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 54127f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_STRING, &tokenValue, NULL, &line, status); 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* make the filename including the directory */ 55227f654740f2a26ad62a5c155af9199af9e69b889claireho if (state->outputdir != NULL) 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 55427f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strcat(filename, state->outputdir); 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 55627f654740f2a26ad62a5c155af9199af9e69b889claireho if (state->outputdir[state->outputdirLength - 1] != U_FILE_SEP_CHAR) 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(filename, U_FILE_SEP_STRING); 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, cs, tokenValue->fLength); 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(filename, cs); 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!T_FileStream_file_exists(filename)){ 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isStrict()){ 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "The dependency file %s does not exist. Please make sure it exists.\n",filename); 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else{ 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(line, "The dependency file %s does not exist. Please make sure it exists.\n",filename); 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(dependencyArray==NULL){ 57727f654740f2a26ad62a5c155af9199af9e69b889claireho dependencyArray = array_open(state->bundle, "%%DEPENDENCY", NULL, status); 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tag!=NULL){ 58027f654740f2a26ad62a5c155af9199af9e69b889claireho result = string_open(state->bundle, tag, tokenValue->fChars, tokenValue->fLength, comment, status); 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 58227f654740f2a26ad62a5c155af9199af9e69b889claireho elem = string_open(state->bundle, NULL, tokenValue->fChars, tokenValue->fLength, comment, status); 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 584c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert dependencyArray->add(elem); 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 59027f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 59427f654740f2a26ad62a5c155af9199af9e69b889clairehoparseString(ParseState* state, char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status) 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *result = NULL; 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* if (tag != NULL && uprv_strcmp(tag, "%%UCARULES") == 0) 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return parseUCARules(tag, startline, status); 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }*/ 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" string %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 60627f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_STRING, &tokenValue, NULL, NULL, status); 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(*status)) 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* create the string now - tokenValue doesn't survive a call to getToken (and therefore 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doesn't survive expect either) */ 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 61327f654740f2a26ad62a5c155af9199af9e69b889claireho result = string_open(state->bundle, tag, tokenValue->fChars, tokenValue->fLength, comment, status); 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_SUCCESS(*status) && result) { 61527f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 617c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (U_FAILURE(*status)) 618c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru { 619c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 620c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return NULL; 621c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 62927f654740f2a26ad62a5c155af9199af9e69b889clairehoparseAlias(ParseState* state, char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *result = NULL; 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 63427f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_STRING, &tokenValue, NULL, NULL, status); 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" alias %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(*status)) 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* create the string now - tokenValue doesn't survive a call to getToken (and therefore 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doesn't survive expect either) */ 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 64527f654740f2a26ad62a5c155af9199af9e69b889claireho result = alias_open(state->bundle, tag, tokenValue->fChars, tokenValue->fLength, comment, status); 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 64727f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 651c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 659fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_COLLATION 660fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 661fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusnamespace { 66227f654740f2a26ad62a5c155af9199af9e69b889claireho 66327f654740f2a26ad62a5c155af9199af9e69b889clairehostatic struct SResource* resLookup(struct SResource* res, const char* key){ 664c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (res == res_none() || !res->isTable()) { 66527f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 66627f654740f2a26ad62a5c155af9199af9e69b889claireho } 66727f654740f2a26ad62a5c155af9199af9e69b889claireho 668c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert TableResource *list = static_cast<TableResource *>(res); 669c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert SResource *current = list->fFirst; 67027f654740f2a26ad62a5c155af9199af9e69b889claireho while (current != NULL) { 67127f654740f2a26ad62a5c155af9199af9e69b889claireho if (uprv_strcmp(((list->fRoot->fKeys) + (current->fKey)), key) == 0) { 67227f654740f2a26ad62a5c155af9199af9e69b889claireho return current; 67327f654740f2a26ad62a5c155af9199af9e69b889claireho } 67427f654740f2a26ad62a5c155af9199af9e69b889claireho current = current->fNext; 67527f654740f2a26ad62a5c155af9199af9e69b889claireho } 67627f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 67727f654740f2a26ad62a5c155af9199af9e69b889claireho} 67827f654740f2a26ad62a5c155af9199af9e69b889claireho 679fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusclass GenrbImporter : public icu::CollationRuleParser::Importer { 680fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliuspublic: 681fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius GenrbImporter(const char *in, const char *out) : inputDir(in), outputDir(out) {} 682fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius virtual ~GenrbImporter(); 683f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius virtual void getRules( 684fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *localeID, const char *collationType, 685f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UnicodeString &rules, 686fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *&errorReason, UErrorCode &errorCode); 687fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 688fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusprivate: 689fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *inputDir; 690fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *outputDir; 691fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius}; 692fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 693fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusGenrbImporter::~GenrbImporter() {} 694fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 695f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusvoid 696fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusGenrbImporter::getRules( 697fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *localeID, const char *collationType, 698f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UnicodeString &rules, 699fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *& /*errorReason*/, UErrorCode &errorCode) { 700c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert CharString filename(localeID, errorCode); 701c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert for(int32_t i = 0; i < filename.length(); i++){ 70227f654740f2a26ad62a5c155af9199af9e69b889claireho if(filename[i] == '-'){ 703c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert filename.data()[i] = '_'; 70427f654740f2a26ad62a5c155af9199af9e69b889claireho } 70527f654740f2a26ad62a5c155af9199af9e69b889claireho } 706c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert filename.append(".txt", errorCode); 707fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(errorCode)) { 708f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return; 70927f654740f2a26ad62a5c155af9199af9e69b889claireho } 710c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert CharString inputDirBuf; 711c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert CharString openFileName; 712fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(inputDir == NULL) { 713c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert const char *filenameBegin = uprv_strrchr(filename.data(), U_FILE_SEP_CHAR); 71427f654740f2a26ad62a5c155af9199af9e69b889claireho if (filenameBegin != NULL) { 71527f654740f2a26ad62a5c155af9199af9e69b889claireho /* 71627f654740f2a26ad62a5c155af9199af9e69b889claireho * When a filename ../../../data/root.txt is specified, 71727f654740f2a26ad62a5c155af9199af9e69b889claireho * we presume that the input directory is ../../../data 71827f654740f2a26ad62a5c155af9199af9e69b889claireho * This is very important when the resource file includes 71927f654740f2a26ad62a5c155af9199af9e69b889claireho * another file, like UCARules.txt or thaidict.brk. 72027f654740f2a26ad62a5c155af9199af9e69b889claireho */ 721c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert StringPiece dir = filename.toStringPiece(); 722c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert const char *filenameLimit = filename.data() + filename.length(); 723c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert dir.remove_suffix((int32_t)(filenameLimit - filenameBegin)); 724c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert inputDirBuf.append(dir, errorCode); 725c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert inputDir = inputDirBuf.data(); 72627f654740f2a26ad62a5c155af9199af9e69b889claireho } 72727f654740f2a26ad62a5c155af9199af9e69b889claireho }else{ 728c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert int32_t dirlen = (int32_t)uprv_strlen(inputDir); 72927f654740f2a26ad62a5c155af9199af9e69b889claireho 730c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if((filename[0] != U_FILE_SEP_CHAR) && (inputDir[dirlen-1] !='.')) { 73127f654740f2a26ad62a5c155af9199af9e69b889claireho /* 73227f654740f2a26ad62a5c155af9199af9e69b889claireho * append the input dir to openFileName if the first char in 733c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * filename is not file separator char and the last char input directory is not '.'. 73427f654740f2a26ad62a5c155af9199af9e69b889claireho * This is to support : 73527f654740f2a26ad62a5c155af9199af9e69b889claireho * genrb -s. /home/icu/data 73627f654740f2a26ad62a5c155af9199af9e69b889claireho * genrb -s. icu/data 73727f654740f2a26ad62a5c155af9199af9e69b889claireho * The user cannot mix notations like 73827f654740f2a26ad62a5c155af9199af9e69b889claireho * genrb -s. /icu/data --- the absolute path specified. -s redundant 73927f654740f2a26ad62a5c155af9199af9e69b889claireho * user should use 74027f654740f2a26ad62a5c155af9199af9e69b889claireho * genrb -s. icu/data --- start from CWD and look in icu/data dir 74127f654740f2a26ad62a5c155af9199af9e69b889claireho */ 742c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert openFileName.append(inputDir, dirlen, errorCode); 743c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(inputDir[dirlen-1] != U_FILE_SEP_CHAR) { 744c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert openFileName.append(U_FILE_SEP_CHAR, errorCode); 74527f654740f2a26ad62a5c155af9199af9e69b889claireho } 74627f654740f2a26ad62a5c155af9199af9e69b889claireho } 74727f654740f2a26ad62a5c155af9199af9e69b889claireho } 748c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert openFileName.append(filename, errorCode); 749c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(U_FAILURE(errorCode)) { 750c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return; 751c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 752c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert // printf("GenrbImporter::getRules(%s, %s) reads %s\n", localeID, collationType, openFileName.data()); 753c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert const char* cp = ""; 754c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalUCHARBUFPointer ucbuf( 755c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert ucbuf_open(openFileName.data(), &cp, getShowWarning(), TRUE, &errorCode)); 756fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(errorCode == U_FILE_ACCESS_ERROR) { 757c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert fprintf(stderr, "couldn't open file %s\n", openFileName.data()); 758c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return; 75927f654740f2a26ad62a5c155af9199af9e69b889claireho } 760c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (ucbuf.isNull() || U_FAILURE(errorCode)) { 761c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert fprintf(stderr, "An error occured processing file %s. Error: %s\n", openFileName.data(), u_errorName(errorCode)); 762c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return; 76327f654740f2a26ad62a5c155af9199af9e69b889claireho } 76427f654740f2a26ad62a5c155af9199af9e69b889claireho 76527f654740f2a26ad62a5c155af9199af9e69b889claireho /* Parse the data into an SRBRoot */ 766c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert struct SRBRoot *data = 767c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert parse(ucbuf.getAlias(), inputDir, outputDir, filename.data(), FALSE, FALSE, &errorCode); 768f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (U_FAILURE(errorCode)) { 769c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return; 770f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 77127f654740f2a26ad62a5c155af9199af9e69b889claireho 772c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert struct SResource *root = data->fRoot; 773c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert struct SResource *collations = resLookup(root, "collations"); 774103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (collations != NULL) { 775c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert struct SResource *collation = resLookup(collations, collationType); 776103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (collation != NULL) { 777c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert struct SResource *sequence = resLookup(collation, "Sequence"); 778c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (sequence != NULL && sequence->isString()) { 779f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // No string pointer aliasing so that we need not hold onto the resource bundle. 780c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert StringResource *sr = static_cast<StringResource *>(sequence); 781c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert rules = sr->fString; 782103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 783103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 784103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 78527f654740f2a26ad62a5c155af9199af9e69b889claireho} 78627f654740f2a26ad62a5c155af9199af9e69b889claireho 787103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Quick-and-dirty escaping function. 788103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Assumes that we are on an ASCII-based platform. 789103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic void 790103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusescape(const UChar *s, char *buffer) { 791103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t length = u_strlen(s); 792103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t i = 0; 793103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (;;) { 794103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar32 c; 795103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_NEXT(s, i, length, c); 796103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (c == 0) { 797103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *buffer = 0; 798103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return; 799103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else if (0x20 <= c && c <= 0x7e) { 800103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // printable ASCII 801103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *buffer++ = (char)c; // assumes ASCII-based platform 802103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 803103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius buffer += sprintf(buffer, "\\u%04X", (int)c); 804103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 805103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 806103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 807103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 808fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} // namespace 809fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 810fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif // !UCONFIG_NO_COLLATION 811fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 812c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertstatic TableResource * 813c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik RoubertaddCollation(ParseState* state, TableResource *result, const char *collationType, 814fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uint32_t startline, UErrorCode *status) 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 816fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // TODO: Use LocalPointer for result, or make caller close it when there is a failure. 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *member = NULL; 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString comment; 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType token; 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char subtag[1024]; 822fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString rules; 823fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UBool haveRules = FALSE; 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UVersionInfo version; 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 826fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* '{' . (name resource)* '}' */ 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru version[0]=0; version[1]=0; version[2]=0; version[3]=0; 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_init(&comment); 83327f654740f2a26ad62a5c155af9199af9e69b889claireho token = getToken(state, &tokenValue, &comment, &line, status); 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_CLOSE_BRACE) 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 837fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token != TOK_STRING) 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 842c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_EOF) 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "unterminated table"); 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "Unexpected token %s", tokenNames[token]); 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 861c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 86527f654740f2a26ad62a5c155af9199af9e69b889claireho member = parseResource(state, subtag, NULL, status); 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 869c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 872fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (result == NULL) 873fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius { 874fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Ignore the parsed resources, continue parsing. 875fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 876c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert else if (uprv_strcmp(subtag, "Version") == 0 && member->isString()) 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 878c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert StringResource *sr = static_cast<StringResource *>(member); 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char ver[40]; 880c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert int32_t length = sr->length(); 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 882c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (length >= UPRV_LENGTHOF(ver)) 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 884c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert length = UPRV_LENGTHOF(ver) - 1; 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 887c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert sr->fString.extract(0, length, ver, UPRV_LENGTHOF(ver), US_INV); 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_versionFromString(version, ver); 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 890c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(member, line, *status); 891fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius member = NULL; 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if(uprv_strcmp(subtag, "%%CollationBin")==0) 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* discard duplicate %%CollationBin if any*/ 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 897c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert else if (uprv_strcmp(subtag, "Sequence") == 0 && member->isString()) 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 899c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert StringResource *sr = static_cast<StringResource *>(member); 900c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert rules = sr->fString; 901fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius haveRules = TRUE; 902fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Defer building the collator until we have seen 903fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // all sub-elements of the collation table, including the Version. 90450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* in order to achieve smaller data files, we can direct genrb */ 90550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* to omit collation rules */ 906fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(!state->omitCollationRules) { 907c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(member, line, *status); 908fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius member = NULL; 90950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 911fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius else // Just copy non-special items. 912fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius { 913c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(member, line, *status); 914fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius member = NULL; 915fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 916fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius res_close(member); // TODO: use LocalPointer 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 919c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 924fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (!haveRules) { return result; } 925fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 926fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if UCONFIG_NO_COLLATION || UCONFIG_NO_FILE_IO 927fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius warning(line, "Not building collation elements because of UCONFIG_NO_COLLATION and/or UCONFIG_NO_FILE_IO, see uconfig.h"); 928fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (void)collationType; 929fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#else 930f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // CLDR ticket #3949, ICU ticket #8082: 931f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Do not build collation binary data for for-import-only "private" collation rule strings. 932f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (uprv_strncmp(collationType, "private-", 8) == 0) { 933f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if(isVerbose()) { 934f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius printf("Not building %s~%s collation binary\n", state->filename, collationType); 935f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 936f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return result; 937f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 938f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 939fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(!state->makeBinaryCollation) { 940fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(isVerbose()) { 941fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius printf("Not building %s~%s collation binary\n", state->filename, collationType); 942fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 943fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return result; 944fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 945fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode intStatus = U_ZERO_ERROR; 946fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UParseError parseError; 947fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uprv_memset(&parseError, 0, sizeof(parseError)); 948fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius GenrbImporter importer(state->inputdir, state->outputdir); 949fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const icu::CollationTailoring *base = icu::CollationRoot::getRoot(intStatus); 950fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(intStatus)) { 951fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius error(line, "failed to load root collator (ucadata.icu) - %s", u_errorName(intStatus)); 952fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius res_close(result); 953fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; // TODO: use LocalUResourceBundlePointer for result 954fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 955fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius icu::CollationBuilder builder(base, intStatus); 956fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(uprv_strncmp(collationType, "search", 6) == 0) { 957fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius builder.disableFastLatin(); // build fast-Latin table unless search collator 958fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 959fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalPointer<icu::CollationTailoring> t( 960fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius builder.parseAndBuild(rules, version, &importer, &parseError, intStatus)); 961fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(intStatus)) { 962fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *reason = builder.getErrorReason(); 963fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(reason == NULL) { reason = ""; } 964fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius error(line, "CollationBuilder failed at %s~%s/Sequence rule offset %ld: %s %s", 965fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius state->filename, collationType, 966fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (long)parseError.offset, u_errorName(intStatus), reason); 967fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(parseError.preContext[0] != 0 || parseError.postContext[0] != 0) { 968fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Print pre- and post-context. 969fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius char preBuffer[100], postBuffer[100]; 970fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius escape(parseError.preContext, preBuffer); 971fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius escape(parseError.postContext, postBuffer); 972fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius error(line, " error context: \"...%s\" ! \"%s...\"", preBuffer, postBuffer); 973fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 974c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(isStrict() || t.isNull()) { 975fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *status = intStatus; 976fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius res_close(result); 977fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 978fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 979fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 980fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius icu::LocalMemory<uint8_t> buffer; 981fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t capacity = 100000; 982fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uint8_t *dest = buffer.allocateInsteadAndCopy(capacity); 983fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(dest == NULL) { 984fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fprintf(stderr, "memory allocation (%ld bytes) for file contents failed\n", 985fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (long)capacity); 986fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *status = U_MEMORY_ALLOCATION_ERROR; 987fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius res_close(result); 988fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 989fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 990fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t indexes[icu::CollationDataReader::IX_TOTAL_SIZE + 1]; 991fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t totalSize = icu::CollationDataWriter::writeTailoring( 992fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *t, *t->settings, indexes, dest, capacity, intStatus); 993fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(intStatus == U_BUFFER_OVERFLOW_ERROR) { 994fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius intStatus = U_ZERO_ERROR; 995fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius capacity = totalSize; 996fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius dest = buffer.allocateInsteadAndCopy(capacity); 997fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(dest == NULL) { 998fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fprintf(stderr, "memory allocation (%ld bytes) for file contents failed\n", 999fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (long)capacity); 1000fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *status = U_MEMORY_ALLOCATION_ERROR; 1001fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius res_close(result); 1002fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 1003fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1004fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius totalSize = icu::CollationDataWriter::writeTailoring( 1005fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *t, *t->settings, indexes, dest, capacity, intStatus); 1006fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1007fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(intStatus)) { 1008fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fprintf(stderr, "CollationDataWriter::writeTailoring() failed: %s\n", 1009fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius u_errorName(intStatus)); 1010fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius res_close(result); 1011fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 1012fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1013fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(isVerbose()) { 1014fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius printf("%s~%s collation tailoring part sizes:\n", state->filename, collationType); 1015fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius icu::CollationInfo::printSizes(totalSize, indexes); 10161b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert if(t->settings->hasReordering()) { 10171b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert printf("%s~%s collation reordering ranges:\n", state->filename, collationType); 10181b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert icu::CollationInfo::printReorderRanges( 10191b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert *t->data, t->settings->reorderCodes, t->settings->reorderCodesLength); 10201b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert } 1021fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1022fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius struct SResource *collationBin = bin_open(state->bundle, "%%CollationBin", totalSize, dest, NULL, NULL, status); 1023c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(collationBin, line, *status); 1024fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(*status)) { 1025fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius res_close(result); 1026fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 1027fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1028fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif 1029fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return result; 1030fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 1031fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1032fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic UBool 1033d9fc98087b091be81a9a50fbff9c0e22855d8dacFredrik RoubertkeepCollationType(const char *type) { // android-changed 1034d9fc98087b091be81a9a50fbff9c0e22855d8dacFredrik Roubert // BEGIN android-added 1035d9fc98087b091be81a9a50fbff9c0e22855d8dacFredrik Roubert if (uprv_strcmp(type, "big5han") == 0) { return FALSE; } 1036d9fc98087b091be81a9a50fbff9c0e22855d8dacFredrik Roubert if (uprv_strcmp(type, "gb2312han") == 0) { return FALSE; } 1037d9fc98087b091be81a9a50fbff9c0e22855d8dacFredrik Roubert // END android-added 1038f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return TRUE; 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 104227f654740f2a26ad62a5c155af9199af9e69b889clairehoparseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool newCollation, UErrorCode *status) 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1044c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert TableResource *result = NULL; 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *member = NULL; 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString comment; 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType token; 1049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char subtag[1024], typeKeyword[1024]; 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 105227f654740f2a26ad62a5c155af9199af9e69b889claireho result = table_open(state->bundle, tag, NULL, status); 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result == NULL || U_FAILURE(*status)) 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" collation elements %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!newCollation) { 1062fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return addCollation(state, result, "(no type)", startline, status); 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(;;) { 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_init(&comment); 106727f654740f2a26ad62a5c155af9199af9e69b889claireho token = getToken(state, &tokenValue, &comment, &line, status); 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_CLOSE_BRACE) 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token != TOK_STRING) 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1076c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_EOF) 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "unterminated table"); 1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "Unexpected token %s", tokenNames[token]); 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1095c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strcmp(subtag, "default") == 0) 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 110127f654740f2a26ad62a5c155af9199af9e69b889claireho member = parseResource(state, subtag, NULL, status); 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1105c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1109c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(member, line, *status); 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 111327f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 0, &tokenValue, &line, &comment, status); 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* this probably needs to be refactored or recursively use the parser */ 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* first we assume that our collation table won't have the explicit type */ 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* then, we cannot handle aliases */ 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(token == TOK_OPEN_BRACE) { 111827f654740f2a26ad62a5c155af9199af9e69b889claireho token = getToken(state, &tokenValue, &comment, &line, status); 1119c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert TableResource *collationRes; 1120fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (keepCollationType(subtag)) { 1121fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius collationRes = table_open(state->bundle, subtag, NULL, status); 1122fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 1123fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius collationRes = NULL; 1124fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1125fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // need to parse the collation data regardless 1126fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius collationRes = addCollation(state, collationRes, subtag, startline, status); 1127fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (collationRes != NULL) { 1128c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(collationRes, startline, *status); 112927f654740f2a26ad62a5c155af9199af9e69b889claireho } 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(token == TOK_COLON) { /* right now, we'll just try to see if we have aliases */ 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we could have a table too */ 113227f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 1, &tokenValue, &line, &comment, status); 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, typeKeyword, u_strlen(tokenValue->fChars) + 1); 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(uprv_strcmp(typeKeyword, "alias") == 0) { 113527f654740f2a26ad62a5c155af9199af9e69b889claireho member = parseResource(state, subtag, NULL, status); 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1138c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1142c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(member, line, *status); 1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1144c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1149c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /*member = string_open(bundle, subtag, tokenValue->fChars, tokenValue->fLength, status);*/ 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /*expect(TOK_CLOSE_BRACE, NULL, NULL, status);*/ 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1161c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Necessary, because CollationElements requires the bundle->fRoot member to be present which, 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if this weren't special-cased, wouldn't be set until the entire file had been processed. */ 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 1171c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik RoubertrealParseTable(ParseState* state, TableResource *table, char *tag, uint32_t startline, UErrorCode *status) 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *member = NULL; 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue=NULL; 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString comment; 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType token; 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char subtag[1024]; 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool readToken = FALSE; 1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* '{' . (name resource)* '}' */ 1182103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" parsing table %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_init(&comment); 118927f654740f2a26ad62a5c155af9199af9e69b889claireho token = getToken(state, &tokenValue, &comment, &line, status); 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_CLOSE_BRACE) 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!readToken) { 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(startline, "Encountered empty table"); 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return table; 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token != TOK_STRING) 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_EOF) 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "unterminated table"); 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "unexpected token %s", tokenNames[token]); 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(uprv_isInvariantUString(tokenValue->fChars, -1)) { 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "invariant characters required for table keys"); 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1225b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru error(line, "parse error. Stopped parsing tokens with %s", u_errorName(*status)); 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 122927f654740f2a26ad62a5c155af9199af9e69b889claireho member = parseResource(state, subtag, &comment, status); 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (member == NULL || U_FAILURE(*status)) 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1233b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru error(line, "parse error. Stopped parsing resource with %s", u_errorName(*status)); 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1237c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert table->add(member, line, *status); 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1241b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru error(line, "parse error. Stopped parsing table with %s", u_errorName(*status)); 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru readToken = TRUE; 1245c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ustr_deinit(&comment); 1246103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* not reached */ 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* A compiler warning will appear if all paths don't contain a return statement. */ 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* *status = U_INTERNAL_PROGRAM_ERROR; 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL;*/ 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 125527f654740f2a26ad62a5c155af9199af9e69b889clairehoparseTable(ParseState* state, char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tag != NULL && uprv_strcmp(tag, "CollationElements") == 0) 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 125927f654740f2a26ad62a5c155af9199af9e69b889claireho return parseCollationElements(state, tag, startline, FALSE, status); 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tag != NULL && uprv_strcmp(tag, "collations") == 0) 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 126327f654740f2a26ad62a5c155af9199af9e69b889claireho return parseCollationElements(state, tag, startline, TRUE, status); 1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" table %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1269c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert TableResource *result = table_open(state->bundle, tag, comment, status); 1270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result == NULL || U_FAILURE(*status)) 1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 127527f654740f2a26ad62a5c155af9199af9e69b889claireho return realParseTable(state, result, tag, startline, status); 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 127927f654740f2a26ad62a5c155af9199af9e69b889clairehoparseArray(ParseState* state, char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *member = NULL; 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString memberComments; 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType token; 1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool readToken = FALSE; 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1287c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert ArrayResource *result = array_open(state->bundle, tag, comment, status); 1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result == NULL || U_FAILURE(*status)) 1290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" array %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_init(&memberComments); 1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* '{' . resource [','] '}' */ 1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) 1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* reset length */ 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_setlen(&memberComments, 0, status); 1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* check for end of array, but don't consume next token unless it really is the end */ 130627f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 0, &tokenValue, NULL, &memberComments, status); 1307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_CLOSE_BRACE) 1310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 131127f654740f2a26ad62a5c155af9199af9e69b889claireho getToken(state, NULL, NULL, NULL, status); 1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!readToken) { 1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(startline, "Encountered empty array"); 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_EOF) 1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1320c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "unterminated array"); 1323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* string arrays are a special case */ 1327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_STRING) 1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 132927f654740f2a26ad62a5c155af9199af9e69b889claireho getToken(state, &tokenValue, &memberComments, NULL, status); 133027f654740f2a26ad62a5c155af9199af9e69b889claireho member = string_open(state->bundle, NULL, tokenValue->fChars, tokenValue->fLength, &memberComments, status); 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 133427f654740f2a26ad62a5c155af9199af9e69b889claireho member = parseResource(state, NULL, &memberComments, status); 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (member == NULL || U_FAILURE(*status)) 1338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1339c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1343c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(member); 1344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* eat optional comma if present */ 134627f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 0, NULL, NULL, NULL, status); 1347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_COMMA) 1349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 135027f654740f2a26ad62a5c155af9199af9e69b889claireho getToken(state, NULL, NULL, NULL, status); 1351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1355c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru readToken = TRUE; 1359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1361c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ustr_deinit(&memberComments); 1362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 136627f654740f2a26ad62a5c155af9199af9e69b889clairehoparseIntVector(ParseState* state, char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) 1367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType token; 1369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *string; 1370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t value; 1371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool readToken = FALSE; 1372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *stopstring; 1373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t len; 1374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString memberComments; 1375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1376c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert IntVectorResource *result = intvector_open(state->bundle, tag, comment, status); 1377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result == NULL || U_FAILURE(*status)) 1379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" vector %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_init(&memberComments); 1387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* '{' . string [','] '}' */ 1388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) 1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_setlen(&memberComments, 0, status); 1391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* check for end of array, but don't consume next token unless it really is the end */ 139327f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 0, NULL, NULL,&memberComments, status); 1394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_CLOSE_BRACE) 1396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* it's the end, consume the close brace */ 139827f654740f2a26ad62a5c155af9199af9e69b889claireho getToken(state, NULL, NULL, NULL, status); 1399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!readToken) { 1400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(startline, "Encountered empty int vector"); 1401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1402c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ustr_deinit(&memberComments); 1403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 140627f654740f2a26ad62a5c155af9199af9e69b889claireho string = getInvariantString(state, NULL, NULL, status); 1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1410c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1414c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* For handling illegal char in the Intvector */ 1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value = uprv_strtoul(string, &stopstring, 0);/* make intvector support decimal,hexdigit,octal digit ranging from -2^31-2^32-1*/ 1416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len=(uint32_t)(stopstring-string); 1417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len==uprv_strlen(string)) 1419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1420c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result->add(value, *status); 1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(string); 142227f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 0, NULL, NULL, NULL, status); 1423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(string); 1427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_INVALID_CHAR_FOUND; 1428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1432c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(result); 1433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* the comma is optional (even though it is required to prevent the reader from concatenating 1437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru consecutive entries) so that a missing comma on the last entry isn't an error */ 1438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_COMMA) 1439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 144027f654740f2a26ad62a5c155af9199af9e69b889claireho getToken(state, NULL, NULL, NULL, status); 1441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru readToken = TRUE; 1443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* not reached */ 1446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* A compiler warning will appear if all paths don't contain a return statement. */ 1447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* intvector_close(result, status); 1448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 1449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL;*/ 1450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 145327f654740f2a26ad62a5c155af9199af9e69b889clairehoparseBinary(ParseState* state, char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) 1454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1455c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert uint32_t line; 1456c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalMemory<char> string(getInvariantString(state, &line, NULL, status)); 1457c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (string.isNull() || U_FAILURE(*status)) 1458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 146227f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 1463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" binary %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1472c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert uint32_t count = (uint32_t)uprv_strlen(string.getAlias()); 1473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (count > 0){ 1474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((count % 2)==0){ 1475c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalMemory<uint8_t> value; 1476c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (value.allocateInsteadAndCopy(count) == NULL) 1477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1482c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert char toConv[3] = {'\0', '\0', '\0'}; 1483c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert for (uint32_t i = 0; i < count; i += 2) 1484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru toConv[0] = string[i]; 1486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru toConv[1] = string[i + 1]; 1487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1488c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert char *stopstring; 1489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value[i >> 1] = (uint8_t) uprv_strtoul(toConv, &stopstring, 16); 1490c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert uint32_t len=(uint32_t)(stopstring-toConv); 1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1492c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(len!=2) 1493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_INVALID_CHAR_FOUND; 1495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1499c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return bin_open(state->bundle, tag, count >> 1, value.getAlias(), NULL, comment, status); 1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_CHAR_FOUND; 1504c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert error(line, "Encountered invalid binary value (length is odd)"); 1505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1510c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert warning(startline, "Encountered empty binary value"); 1511c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return bin_open(state->bundle, tag, 0, NULL, "", comment, status); 1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 151627f654740f2a26ad62a5c155af9199af9e69b889clairehoparseInteger(ParseState* state, char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status) 1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *result = NULL; 1519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t value; 1520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *string; 1521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *stopstring; 1522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t len; 1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 152427f654740f2a26ad62a5c155af9199af9e69b889claireho string = getInvariantString(state, NULL, NULL, status); 1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (string == NULL || U_FAILURE(*status)) 1527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 153127f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 1532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(string); 1536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" integer %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strlen(string) <= 0) 1544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(startline, "Encountered empty integer. Default value is 0."); 1546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1548c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* Allow integer support for hexdecimal, octal digit and decimal*/ 1549c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* and handle illegal char in the integer*/ 1550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value = uprv_strtoul(string, &stopstring, 0); 1551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len=(uint32_t)(stopstring-string); 1552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len==uprv_strlen(string)) 1553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 155427f654740f2a26ad62a5c155af9199af9e69b889claireho result = int_open(state->bundle, tag, value, comment, status); 1555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_INVALID_CHAR_FOUND; 1559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(string); 1561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 156627f654740f2a26ad62a5c155af9199af9e69b889clairehoparseImport(ParseState* state, char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status) 1567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 1569c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalMemory<char> filename(getInvariantString(state, &line, NULL, status)); 1570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 157527f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 1576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" import %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Open the input file for reading */ 1587c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert CharString fullname; 1588c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (state->inputdir != NULL) { 1589c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert fullname.append(state->inputdir, *status); 1590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1591c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert fullname.appendPathPart(filename.getAlias(), *status); 1592c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (U_FAILURE(*status)) { 1593c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return NULL; 1594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1596c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert FileStream *file = T_FileStream_open(fullname.data(), "rb"); 1597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (file == NULL) 1598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1599c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert error(line, "couldn't open input file %s", filename.getAlias()); 1600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_FILE_ACCESS_ERROR; 1601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1604c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert int32_t len = T_FileStream_size(file); 1605c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert LocalMemory<uint8_t> data; 1606c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(data.allocateInsteadAndCopy(len) == NULL) 1607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru T_FileStream_close (file); 1610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1613c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /* int32_t numRead = */ T_FileStream_read(file, data.getAlias(), len); 1614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru T_FileStream_close (file); 1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1616c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return bin_open(state->bundle, tag, len, data.getAlias(), fullname.data(), comment, status); 1617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 162027f654740f2a26ad62a5c155af9199af9e69b889clairehoparseInclude(ParseState* state, char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status) 1621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *result; 1623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t len=0; 1624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *filename; 1625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 1626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *pTarget = NULL; 1627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCHARBUF *ucbuf; 1629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *fullname = NULL; 1630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t count = 0; 1631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* cp = NULL; 1632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar* uBuffer = NULL; 1633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 163427f654740f2a26ad62a5c155af9199af9e69b889claireho filename = getInvariantString(state, &line, NULL, status); 1635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count = (int32_t)uprv_strlen(filename); 1636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 164227f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); 1643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(filename); 1647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" include %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 165427f654740f2a26ad62a5c155af9199af9e69b889claireho fullname = (char *) uprv_malloc(state->inputdirLength + count + 2); 1655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* test for NULL */ 1656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fullname == NULL) 1657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(filename); 1660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 166327f654740f2a26ad62a5c155af9199af9e69b889claireho if(state->inputdir!=NULL){ 166427f654740f2a26ad62a5c155af9199af9e69b889claireho if (state->inputdir[state->inputdirLength - 1] != U_FILE_SEP_CHAR) 1665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 166727f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strcpy(fullname, state->inputdir); 1668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 166927f654740f2a26ad62a5c155af9199af9e69b889claireho fullname[state->inputdirLength] = U_FILE_SEP_CHAR; 167027f654740f2a26ad62a5c155af9199af9e69b889claireho fullname[state->inputdirLength + 1] = '\0'; 1671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(fullname, filename); 1673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 167627f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strcpy(fullname, state->inputdir); 1677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(fullname, filename); 1678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }else{ 1680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(fullname,filename); 1681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucbuf = ucbuf_open(fullname, &cp,getShowWarning(),FALSE,status); 1684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 1686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "couldn't open input file %s\n", filename); 1687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uBuffer = ucbuf_getBuffer(ucbuf,&len,status); 169127f654740f2a26ad62a5c155af9199af9e69b889claireho result = string_open(state->bundle, tag, uBuffer, len, comment, status); 1692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 169354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius ucbuf_close(ucbuf); 169454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 1695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(pTarget); 1696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(filename); 1698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(fullname); 1699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_string, "string", 6); 1708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_binary, "binary", 6); 1709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_bin, "bin", 3); 1710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_table, "table", 5); 1711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_table_no_fallback, "table(nofallback)", 17); 1712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_int, "int", 3); 1713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_integer, "integer", 7); 1714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_array, "array", 5); 1715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_alias, "alias", 5); 1716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_intvector, "intvector", 9); 1717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_import, "import", 6); 1718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_include, "include", 7); 1719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Various non-standard processing plugins that create one or more special resources. */ 1721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_plugin_uca_rules, "process(uca_rules)", 18); 1722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_plugin_collation, "process(collation)", 18); 1723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_plugin_transliterator, "process(transliterator)", 23); 1724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_STRING_DECL(k_type_plugin_dependency, "process(dependency)", 19); 1725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef enum EResourceType 1727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1728fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_UNKNOWN, 1729fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_STRING, 1730fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_BINARY, 1731fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_TABLE, 1732fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_TABLE_NO_FALLBACK, 1733fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_INTEGER, 1734fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_ARRAY, 1735fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_ALIAS, 1736fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_INTVECTOR, 1737fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_IMPORT, 1738fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_INCLUDE, 1739fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_PROCESS_UCA_RULES, 1740fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_PROCESS_COLLATION, 1741fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_PROCESS_TRANSLITERATOR, 1742fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_PROCESS_DEPENDENCY, 1743fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RESTYPE_RESERVED 1744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} EResourceType; 1745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct { 1747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *nameChars; /* only used for debugging */ 1748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *nameUChars; 1749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ParseResourceFunction *parseFunction; 1750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} gResourceTypes[] = { 1751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"Unknown", NULL, NULL}, 1752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"string", k_type_string, parseString}, 1753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"binary", k_type_binary, parseBinary}, 1754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"table", k_type_table, parseTable}, 1755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"table(nofallback)", k_type_table_no_fallback, NULL}, /* parseFunction will never be called */ 1756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"integer", k_type_integer, parseInteger}, 1757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"array", k_type_array, parseArray}, 1758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"alias", k_type_alias, parseAlias}, 1759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"intvector", k_type_intvector, parseIntVector}, 1760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"import", k_type_import, parseImport}, 1761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"include", k_type_include, parseInclude}, 1762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"process(uca_rules)", k_type_plugin_uca_rules, parseUCARules}, 1763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"process(collation)", k_type_plugin_collation, NULL /* not implemented yet */}, 1764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"process(transliterator)", k_type_plugin_transliterator, parseTransliterator}, 1765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"process(dependency)", k_type_plugin_dependency, parseDependency}, 1766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"reserved", NULL, NULL} 1767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 1768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 176959d709d503bab6e2b61931737e662dd293b40578ccorneliusvoid initParser() 1770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_string, "string", 6); 1772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_binary, "binary", 6); 1773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_bin, "bin", 3); 1774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_table, "table", 5); 1775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_table_no_fallback, "table(nofallback)", 17); 1776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_int, "int", 3); 1777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_integer, "integer", 7); 1778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_array, "array", 5); 1779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_alias, "alias", 5); 1780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_intvector, "intvector", 9); 1781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_import, "import", 6); 1782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_include, "include", 7); 1783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_plugin_uca_rules, "process(uca_rules)", 18); 1785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_plugin_collation, "process(collation)", 18); 1786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_plugin_transliterator, "process(transliterator)", 23); 1787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_STRING_INIT(k_type_plugin_dependency, "process(dependency)", 19); 1788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1790103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic inline UBool isTable(enum EResourceType type) { 1791fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return (UBool)(type==RESTYPE_TABLE || type==RESTYPE_TABLE_NO_FALLBACK); 1792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic enum EResourceType 179527f654740f2a26ad62a5c155af9199af9e69b889clairehoparseResourceType(ParseState* state, UErrorCode *status) 1796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 1798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString comment; 1799fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius enum EResourceType result = RESTYPE_UNKNOWN; 1800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line=0; 1801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_init(&comment); 180227f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_STRING, &tokenValue, &comment, &line, status); 1803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1806fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return RESTYPE_UNKNOWN; 1807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ZERO_ERROR; 1810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Search for normal types */ 1812fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result=RESTYPE_UNKNOWN; 1813fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius while ((result=(EResourceType)(result+1)) < RESTYPE_RESERVED) { 1814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (u_strcmp(tokenValue->fChars, gResourceTypes[result].nameUChars) == 0) { 1815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Now search for the aliases */ 1819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (u_strcmp(tokenValue->fChars, k_type_int) == 0) { 1820fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result = RESTYPE_INTEGER; 1821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (u_strcmp(tokenValue->fChars, k_type_bin) == 0) { 1823fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result = RESTYPE_BINARY; 1824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1825fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius else if (result == RESTYPE_RESERVED) { 1826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char tokenBuffer[1024]; 1827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_austrncpy(tokenBuffer, tokenValue->fChars, sizeof(tokenBuffer)); 1828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tokenBuffer[sizeof(tokenBuffer) - 1] = 0; 1829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "unknown resource type '%s'", tokenBuffer); 1831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* parse a non-top-level resource */ 1837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic struct SResource * 183827f654740f2a26ad62a5c155af9199af9e69b889clairehoparseResource(ParseState* state, char *tag, const struct UString *comment, UErrorCode *status) 1839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType token; 1841fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius enum EResourceType resType = RESTYPE_UNKNOWN; 1842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ParseResourceFunction *parseFunction = NULL; 1843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 1844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t startline; 1845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 1846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1847103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 184827f654740f2a26ad62a5c155af9199af9e69b889claireho token = getToken(state, &tokenValue, NULL, &startline, status); 1849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isVerbose()){ 1851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printf(" resource %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline); 1852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* name . [ ':' type ] '{' resource '}' */ 1855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* This function parses from the colon onwards. If the colon is present, parse the 1856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type then try to parse a resource of that type. If there is no explicit type, 1857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru work it out using the lookahead tokens. */ 1858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (token) 1859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case TOK_EOF: 1861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "Unexpected EOF encountered"); 1863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case TOK_ERROR: 1866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case TOK_COLON: 187027f654740f2a26ad62a5c155af9199af9e69b889claireho resType = parseResourceType(state, status); 187127f654740f2a26ad62a5c155af9199af9e69b889claireho expect(state, TOK_OPEN_BRACE, &tokenValue, NULL, &startline, status); 1872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case TOK_OPEN_BRACE: 1881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "syntax error while reading a resource, expected '{' or ':'"); 1886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1889103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1890fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (resType == RESTYPE_UNKNOWN) 1891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* No explicit type, so try to work it out. At this point, we've read the first '{'. 1893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru We could have any of the following: 1894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { { => array (nested) 1895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { :/} => array 1896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { string , => string array 1897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { string { => table 1899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { string :/{ => table 1901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { string } => string 1902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 190427f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 0, NULL, &line, NULL,status); 1905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (token == TOK_OPEN_BRACE || token == TOK_COLON ||token ==TOK_CLOSE_BRACE ) 1912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1913fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius resType = RESTYPE_ARRAY; 1914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (token == TOK_STRING) 1916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 191727f654740f2a26ad62a5c155af9199af9e69b889claireho token = peekToken(state, 1, NULL, &line, NULL, status); 1918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 1920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (token) 1925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1926fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case TOK_COMMA: resType = RESTYPE_ARRAY; break; 1927fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case TOK_OPEN_BRACE: resType = RESTYPE_TABLE; break; 1928fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case TOK_CLOSE_BRACE: resType = RESTYPE_STRING; break; 1929fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case TOK_COLON: resType = RESTYPE_TABLE; break; 1930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "Unexpected token after string, expected ',', '{' or '}'"); 1933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "Unexpected token after '{'"); 1940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* printf("Type guessed as %s\n", resourceNames[resType]); */ 1944fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else if(resType == RESTYPE_TABLE_NO_FALLBACK) { 1945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 1946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "error: %s resource type not valid except on top bundle level", gResourceTypes[resType].nameChars); 1947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1950103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* We should now know what we need to parse next, so call the appropriate parser 1952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru function and return. */ 1953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru parseFunction = gResourceTypes[resType].parseFunction; 1954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (parseFunction != NULL) { 195527f654740f2a26ad62a5c155af9199af9e69b889claireho return parseFunction(state, tag, startline, comment, status); 1956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 1958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 1959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(startline, "internal error: %s resource type found and not handled", gResourceTypes[resType].nameChars); 1960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* parse the top-level resource */ 1966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct SRBRoot * 1967fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusparse(UCHARBUF *buf, const char *inputDir, const char *outputDir, const char *filename, 196859d709d503bab6e2b61931737e662dd293b40578ccornelius UBool makeBinaryCollation, UBool omitCollationRules, UErrorCode *status) 1969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString *tokenValue; 1971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct UString comment; 1972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t line; 1973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum EResourceType bundleType; 1974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum ETokenType token; 197527f654740f2a26ad62a5c155af9199af9e69b889claireho ParseState state; 197627f654740f2a26ad62a5c155af9199af9e69b889claireho uint32_t i; 1977b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1978103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 197927f654740f2a26ad62a5c155af9199af9e69b889claireho for (i = 0; i < MAX_LOOKAHEAD + 1; i++) 198027f654740f2a26ad62a5c155af9199af9e69b889claireho { 198127f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_init(&state.lookahead[i].value); 198227f654740f2a26ad62a5c155af9199af9e69b889claireho ustr_init(&state.lookahead[i].comment); 198327f654740f2a26ad62a5c155af9199af9e69b889claireho } 1984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 198527f654740f2a26ad62a5c155af9199af9e69b889claireho initLookahead(&state, buf, status); 1986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 198727f654740f2a26ad62a5c155af9199af9e69b889claireho state.inputdir = inputDir; 198827f654740f2a26ad62a5c155af9199af9e69b889claireho state.inputdirLength = (state.inputdir != NULL) ? (uint32_t)uprv_strlen(state.inputdir) : 0; 198927f654740f2a26ad62a5c155af9199af9e69b889claireho state.outputdir = outputDir; 199027f654740f2a26ad62a5c155af9199af9e69b889claireho state.outputdirLength = (state.outputdir != NULL) ? (uint32_t)uprv_strlen(state.outputdir) : 0; 1991fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius state.filename = filename; 1992103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius state.makeBinaryCollation = makeBinaryCollation; 199359d709d503bab6e2b61931737e662dd293b40578ccornelius state.omitCollationRules = omitCollationRules; 1994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ustr_init(&comment); 199627f654740f2a26ad62a5c155af9199af9e69b889claireho expect(&state, TOK_STRING, &tokenValue, &comment, NULL, status); 1997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1998c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert state.bundle = new SRBRoot(&comment, FALSE, *status); 1999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 200027f654740f2a26ad62a5c155af9199af9e69b889claireho if (state.bundle == NULL || U_FAILURE(*status)) 2001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2006c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert state.bundle->setLocale(tokenValue->fChars, *status); 200727f654740f2a26ad62a5c155af9199af9e69b889claireho 2008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* The following code is to make Empty bundle work no matter with :table specifer or not */ 200927f654740f2a26ad62a5c155af9199af9e69b889claireho token = getToken(&state, NULL, NULL, &line, status); 2010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(token==TOK_COLON) { 2011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_ZERO_ERROR; 201227f654740f2a26ad62a5c155af9199af9e69b889claireho bundleType=parseResourceType(&state, status); 2013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isTable(bundleType)) 2015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 201627f654740f2a26ad62a5c155af9199af9e69b889claireho expect(&state, TOK_OPEN_BRACE, NULL, NULL, &line, status); 2017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 2019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_PARSE_ERROR; 2021103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius error(line, "parse error. Stopped parsing with %s", u_errorName(*status)); 2022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 2025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* not a colon */ 2027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(token==TOK_OPEN_BRACE) 2028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_ZERO_ERROR; 2030fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius bundleType=RESTYPE_TABLE; 2031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 2033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* neither colon nor open brace */ 2035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status=U_PARSE_ERROR; 2036fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius bundleType=RESTYPE_UNKNOWN; 2037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error(line, "parse error, did not find open-brace '{' or colon ':', stopped with %s", u_errorName(*status)); 2038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) 2042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2043c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete state.bundle; 2044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2047fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(bundleType==RESTYPE_TABLE_NO_FALLBACK) { 2048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 2049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Parse a top-level table with the table(nofallback) declaration. 2050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is the same as a regular table, but also sets the 2051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * URES_ATT_NO_FALLBACK flag in indexes[URES_INDEX_ATTRIBUTES] . 2052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 2053c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert state.bundle->fNoFallback=TRUE; 2054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* top-level tables need not handle special table names like "collations" */ 2056c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert assert(!state.bundle->fIsPoolBundle); 2057c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert assert(state.bundle->fRoot->fType == URES_TABLE); 2058c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert TableResource *rootTable = static_cast<TableResource *>(state.bundle->fRoot); 2059c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert realParseTable(&state, rootTable, NULL, line, status); 2060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(dependencyArray!=NULL){ 2061c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert rootTable->add(dependencyArray, 0, *status); 2062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dependencyArray = NULL; 2063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2064103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(*status)) 2065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2066c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete state.bundle; 2067c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(dependencyArray); 2068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 207127f654740f2a26ad62a5c155af9199af9e69b889claireho if (getToken(&state, NULL, NULL, &line, status) != TOK_EOF) 2072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru warning(line, "extraneous text after resource bundle (perhaps unmatched braces)"); 2074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isStrict()){ 2075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INVALID_FORMAT_ERROR; 2076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 208027f654740f2a26ad62a5c155af9199af9e69b889claireho cleanupLookahead(&state); 2081c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ustr_deinit(&comment); 208227f654740f2a26ad62a5c155af9199af9e69b889claireho return state.bundle; 2083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2084