1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*******************************************************************************
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*   Copyright (C) 1998-2008, International Business Machines
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*   Corporation and others.  All Rights Reserved.
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*******************************************************************************
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* File parse.c
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* Modification History:
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*   Date          Name          Description
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*   05/26/99     stephen       Creation.
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*   02/25/00     weiv          Overhaul to write udata
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*   5/10/01      Ram           removed ustdio dependency
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*   06/10/2001  Dominic Ludlam <dom@recoil.org> Rewritten
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*******************************************************************************
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*/
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "ucol_imp.h"
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "parse.h"
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "errmsg.h"
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "uhash.h"
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "cmemory.h"
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "cstring.h"
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "uinvchar.h"
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "read.h"
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "ustr.h"
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "reslist.h"
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "rbt_pars.h"
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "unicode/ustring.h"
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "unicode/putil.h"
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdio.h>
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* Number of tokens to read ahead of the current stream position */
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define MAX_LOOKAHEAD   3
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define CR               0x000D
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define LF               0x000A
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define SPACE            0x0020
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TAB              0x0009
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define ESCAPE           0x005C
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define HASH             0x0023
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define QUOTE            0x0027
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define ZERO             0x0030
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define STARTCOMMAND     0x005B
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define ENDCOMMAND       0x005D
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define OPENSQBRACKET    0x005B
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define CLOSESQBRACKET   0x005D
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef struct SResource *
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottParseResourceFunction(char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status);
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct Lookahead
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott     enum   ETokenType type;
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott     struct UString    value;
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott     struct UString    comment;
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott     uint32_t          line;
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* keep in sync with token defines in read.h */
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst char *tokenNames[TOK_TOKEN_COUNT] =
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott     "string",             /* A string token, such as "MonthNames" */
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott     "'{'",                 /* An opening brace character */
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott     "'}'",                 /* A closing brace character */
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott     "','",                 /* A comma */
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott     "':'",                 /* A colon */
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott     "<end of file>",     /* End of the file has been reached successfully */
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott     "<end of line>"
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* Just to store "TRUE" */
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic const UChar trueValue[] = {0x0054, 0x0052, 0x0055, 0x0045, 0x0000};
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct Lookahead  lookahead[MAX_LOOKAHEAD + 1];
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic uint32_t          lookaheadPosition;
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic UCHARBUF         *buffer;
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SRBRoot *bundle;
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic const char     *inputdir;
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic uint32_t        inputdirLength;
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic const char     *outputdir;
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic uint32_t        outputdirLength;
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic UBool gMakeBinaryCollation = TRUE;
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic UBool gOmitCollationRules  = FALSE;
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *parseResource(char *tag, const struct UString *comment, UErrorCode *status);
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* The nature of the lookahead buffer:
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   There are MAX_LOOKAHEAD + 1 slots, used as a circular buffer.  This provides
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   MAX_LOOKAHEAD lookahead tokens and a slot for the current token and value.
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   When getToken is called, the current pointer is moved to the next slot and the
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   old slot is filled with the next token from the reader by calling getNextToken.
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   The token values are stored in the slot, which means that token values don't
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   survive a call to getToken, ie.
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   UString *value;
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   getToken(&value, NULL, status);
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   getToken(NULL,   NULL, status);       bad - value is now a different string
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*/
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottinitLookahead(UCHARBUF *buf, UErrorCode *status)
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    static uint32_t initTypeStrings = 0;
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t i;
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (!initTypeStrings)
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        initTypeStrings = 1;
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    lookaheadPosition   = 0;
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    buffer              = buf;
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    resetLineNumber();
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    for (i = 0; i < MAX_LOOKAHEAD; i++)
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        lookahead[i].type = getNextToken(buffer, &lookahead[i].value, &lookahead[i].line, &lookahead[i].comment, status);
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (U_FAILURE(*status))
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return;
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *status = U_ZERO_ERROR;
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottcleanupLookahead()
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t i;
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    for (i = 0; i < MAX_LOOKAHEAD; i++)
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        ustr_deinit(&lookahead[i].value);
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        ustr_deinit(&lookahead[i].comment);
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic enum ETokenType
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottgetToken(struct UString **tokenValue, struct UString* comment, uint32_t *linenumber, UErrorCode *status)
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    enum ETokenType result;
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t          i;
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result = lookahead[lookaheadPosition].type;
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (tokenValue != NULL)
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *tokenValue = &lookahead[lookaheadPosition].value;
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (linenumber != NULL)
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *linenumber = lookahead[lookaheadPosition].line;
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (comment != NULL)
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        ustr_cpy(comment, &(lookahead[lookaheadPosition].comment), status);
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    i = (lookaheadPosition + MAX_LOOKAHEAD) % (MAX_LOOKAHEAD + 1);
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    lookaheadPosition = (lookaheadPosition + 1) % (MAX_LOOKAHEAD + 1);
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ustr_setlen(&lookahead[i].comment, 0, status);
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ustr_setlen(&lookahead[i].value, 0, status);
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    lookahead[i].type = getNextToken(buffer, &lookahead[i].value, &lookahead[i].line, &lookahead[i].comment, status);
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* printf("getToken, returning %s\n", tokenNames[result]); */
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result;
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic enum ETokenType
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottpeekToken(uint32_t lookaheadCount, struct UString **tokenValue, uint32_t *linenumber, struct UString *comment, UErrorCode *status)
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t i = (lookaheadPosition + lookaheadCount) % (MAX_LOOKAHEAD + 1);
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return TOK_ERROR;
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (lookaheadCount >= MAX_LOOKAHEAD)
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status = U_INTERNAL_PROGRAM_ERROR;
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return TOK_ERROR;
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (tokenValue != NULL)
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *tokenValue = &lookahead[i].value;
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (linenumber != NULL)
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *linenumber = lookahead[i].line;
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(comment != NULL){
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        ustr_cpy(comment, &(lookahead[lookaheadPosition].comment), status);
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return lookahead[i].type;
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottexpect(enum ETokenType expectedToken, struct UString **tokenValue, struct UString *comment, uint32_t *linenumber, UErrorCode *status)
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t        line;
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    enum ETokenType token = getToken(tokenValue, comment, &line, status);
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (linenumber != NULL)
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *linenumber = line;
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return;
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (token != expectedToken)
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status = U_INVALID_FORMAT_ERROR;
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        error(line, "expecting %s, got %s", tokenNames[expectedToken], tokenNames[token]);
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status = U_ZERO_ERROR;
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic char *getInvariantString(uint32_t *line, struct UString *comment, UErrorCode *status)
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString *tokenValue;
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char           *result;
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t        count;
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_STRING, &tokenValue, comment, line, status);
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    count = u_strlen(tokenValue->fChars);
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(!uprv_isInvariantUString(tokenValue->fChars, count)) {
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status = U_INVALID_FORMAT_ERROR;
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        error(*line, "invariant characters required for table keys, binary data, etc.");
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result = uprv_malloc(count+1);
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (result == NULL)
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status = U_MEMORY_ALLOCATION_ERROR;
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    u_UCharsToChars(tokenValue->fChars, result, count+1);
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result;
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseUCARules(char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status)
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource *result = NULL;
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString   *tokenValue;
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    FileStream       *file          = NULL;
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char              filename[256] = { '\0' };
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char              cs[128]       = { '\0' };
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t          line;
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int               len=0;
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UBool quoted = FALSE;
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UCHARBUF *ucbuf=NULL;
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UChar32   c     = 0;
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const char* cp  = NULL;
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UChar *pTarget     = NULL;
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UChar *target      = NULL;
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UChar *targetLimit = NULL;
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int32_t size = 0;
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_STRING, &tokenValue, NULL, &line, status);
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" %s at line %i \n",  (tag == NULL) ? "(null)" : tag, (int)startline);
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* make the filename including the directory */
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (inputdir != NULL)
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        uprv_strcat(filename, inputdir);
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (inputdir[inputdirLength - 1] != U_FILE_SEP_CHAR)
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_strcat(filename, U_FILE_SEP_STRING);
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    u_UCharsToChars(tokenValue->fChars, cs, tokenValue->fLength);
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status);
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_strcat(filename, cs);
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(gOmitCollationRules) {
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return res_none();
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ucbuf = ucbuf_open(filename, &cp, getShowWarning(),FALSE, status);
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status)) {
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        error(line, "An error occured while opening the input file %s\n", filename);
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* We allocate more space than actually required
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    * since the actual size needed for storing UChars
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    * is not known in UTF-8 byte stream
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    */
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    size        = ucbuf_size(ucbuf) + 1;
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    pTarget     = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * size);
341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_memset(pTarget, 0, size*U_SIZEOF_UCHAR);
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    target      = pTarget;
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    targetLimit = pTarget+size;
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* read the rules into the buffer */
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    while (target < targetLimit)
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        c = ucbuf_getc(ucbuf, status);
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if(c == QUOTE) {
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            quoted = (UBool)!quoted;
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* weiv (06/26/2002): adding the following:
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         * - preserving spaces in commands [...]
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         * - # comments until the end of line
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         */
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (c == STARTCOMMAND && !quoted)
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            /* preserve commands
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott             * closing bracket will be handled by the
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott             * append at the end of the loop
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott             */
362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            while(c != ENDCOMMAND) {
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                U_APPEND_CHAR32(c, target,len);
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                c = ucbuf_getc(ucbuf, status);
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else if (c == HASH && !quoted) {
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            /* skip comments */
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            while(c != CR && c != LF) {
370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                c = ucbuf_getc(ucbuf, status);
371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            continue;
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else if (c == ESCAPE)
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            c = unescape(ucbuf, status);
377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (c == U_ERR)
379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                uprv_free(pTarget);
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                T_FileStream_close(file);
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                return NULL;
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else if (!quoted && (c == SPACE || c == TAB || c == CR || c == LF))
386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            /* ignore spaces carriage returns
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            * and line feed unless in the form \uXXXX
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            */
390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            continue;
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* Append UChar * after dissembling if c > 0xffff*/
394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (c != U_EOF)
395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            U_APPEND_CHAR32(c, target,len);
397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            break;
401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* terminate the string */
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(target < targetLimit){
406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *target = 0x0000;
407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result = string_open(bundle, tag, pTarget, (int32_t)(target - pTarget), NULL, status);
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ucbuf_close(ucbuf);
413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_free(pTarget);
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    T_FileStream_close(file);
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result;
417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseTransliterator(char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status)
421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource *result = NULL;
423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString   *tokenValue;
424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    FileStream       *file          = NULL;
425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char              filename[256] = { '\0' };
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char              cs[128]       = { '\0' };
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t          line;
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UCHARBUF *ucbuf=NULL;
429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const char* cp  = NULL;
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UChar *pTarget     = NULL;
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const UChar *pSource     = NULL;
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int32_t size = 0;
433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_STRING, &tokenValue, NULL, &line, status);
435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" %s at line %i \n",  (tag == NULL) ? "(null)" : tag, (int)startline);
438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* make the filename including the directory */
445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (inputdir != NULL)
446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        uprv_strcat(filename, inputdir);
448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (inputdir[inputdirLength - 1] != U_FILE_SEP_CHAR)
450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_strcat(filename, U_FILE_SEP_STRING);
452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    u_UCharsToChars(tokenValue->fChars, cs, tokenValue->fLength);
456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status);
458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_strcat(filename, cs);
464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ucbuf = ucbuf_open(filename, &cp, getShowWarning(),FALSE, status);
467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status)) {
469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        error(line, "An error occured while opening the input file %s\n", filename);
470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* We allocate more space than actually required
474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    * since the actual size needed for storing UChars
475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    * is not known in UTF-8 byte stream
476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    */
477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    pSource = ucbuf_getBuffer(ucbuf, &size, status);
478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    pTarget     = (UChar*) uprv_malloc(U_SIZEOF_UCHAR * (size + 1));
479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_memset(pTarget, 0, size*U_SIZEOF_UCHAR);
480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if !UCONFIG_NO_TRANSLITERATION
482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    size = utrans_stripRules(pSource, size, pTarget, status);
483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else
484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    size = 0;
485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    fprintf(stderr, " Warning: writing empty transliteration data ( UCONFIG_NO_TRANSLITERATION ) \n");
486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result = string_open(bundle, tag, pTarget, size, NULL, status);
488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ucbuf_close(ucbuf);
490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_free(pTarget);
491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    T_FileStream_close(file);
492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result;
494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource* dependencyArray = NULL;
496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseDependency(char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status)
499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource *result = NULL;
501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource *elem = NULL;
502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString   *tokenValue;
503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t          line;
504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char              filename[256] = { '\0' };
505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char              cs[128]       = { '\0' };
506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_STRING, &tokenValue, NULL, &line, status);
508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" %s at line %i \n",  (tag == NULL) ? "(null)" : tag, (int)startline);
511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* make the filename including the directory */
518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (outputdir != NULL)
519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        uprv_strcat(filename, outputdir);
521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (outputdir[outputdirLength - 1] != U_FILE_SEP_CHAR)
523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_strcat(filename, U_FILE_SEP_STRING);
525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    u_UCharsToChars(tokenValue->fChars, cs, tokenValue->fLength);
529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_strcat(filename, cs);
535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(!T_FileStream_file_exists(filename)){
536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if(isStrict()){
537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            error(line, "The dependency file %s does not exist. Please make sure it exists.\n",filename);
538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }else{
539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            warning(line, "The dependency file %s does not exist. Please make sure it exists.\n",filename);
540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(dependencyArray==NULL){
543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        dependencyArray = array_open(bundle, "%%DEPENDENCY", NULL, status);
544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(tag!=NULL){
546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        result = string_open(bundle, tag, tokenValue->fChars, tokenValue->fLength, comment, status);
547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    elem = string_open(bundle, NULL, tokenValue->fChars, tokenValue->fLength, comment, status);
549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    array_add(dependencyArray, elem, status);
551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status);
557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result;
558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseString(char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status)
561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString   *tokenValue;
563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource *result = NULL;
564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*    if (tag != NULL && uprv_strcmp(tag, "%%UCARULES") == 0)
566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return parseUCARules(tag, startline, status);
568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }*/
569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" string %s at line %i \n",  (tag == NULL) ? "(null)" : tag, (int)startline);
571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_STRING, &tokenValue, NULL, NULL, status);
573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_SUCCESS(*status))
575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* create the string now - tokenValue doesn't survive a call to getToken (and therefore
577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        doesn't survive expect either) */
578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        result = string_open(bundle, tag, tokenValue->fChars, tokenValue->fLength, comment, status);
580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if(U_SUCCESS(*status) && result) {
581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status);
582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (U_FAILURE(*status))
584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                res_close(result);
586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                return NULL;
587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result;
592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseAlias(char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status)
596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString   *tokenValue;
598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource *result  = NULL;
599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_STRING, &tokenValue, NULL, NULL, status);
601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" alias %s at line %i \n",  (tag == NULL) ? "(null)" : tag, (int)startline);
604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_SUCCESS(*status))
607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* create the string now - tokenValue doesn't survive a call to getToken (and therefore
609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        doesn't survive expect either) */
610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        result = alias_open(bundle, tag, tokenValue->fChars, tokenValue->fLength, comment, status);
612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status);
614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (U_FAILURE(*status))
616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            res_close(result);
618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result;
623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottaddCollation(struct SResource  *result, uint32_t startline, UErrorCode *status)
627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource  *member = NULL;
629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString    *tokenValue;
630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString     comment;
631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    enum   ETokenType  token;
632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char               subtag[1024];
633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UVersionInfo       version;
634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UBool              override = FALSE;
635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t           line;
636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* '{' . (name resource)* '}' */
637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    version[0]=0; version[1]=0; version[2]=0; version[3]=0;
638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    for (;;)
640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        ustr_init(&comment);
642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        token = getToken(&tokenValue, &comment, &line, status);
643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (token == TOK_CLOSE_BRACE)
645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return result;
647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (token != TOK_STRING)
650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            res_close(result);
652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            *status = U_INVALID_FORMAT_ERROR;
653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (token == TOK_EOF)
655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                error(startline, "unterminated table");
657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            else
659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                error(line, "Unexpected token %s", tokenNames[token]);
661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1);
667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (U_FAILURE(*status))
669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            res_close(result);
671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        member = parseResource(subtag, NULL, status);
675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (U_FAILURE(*status))
677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            res_close(result);
679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (uprv_strcmp(subtag, "Version") == 0)
683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            char     ver[40];
685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            int32_t length = member->u.fString.fLength;
686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (length >= (int32_t) sizeof(ver))
688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                length = (int32_t) sizeof(ver) - 1;
690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            u_UCharsToChars(member->u.fString.fChars, ver, length + 1); /* +1 for copying NULL */
693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            u_versionFromString(version, ver);
694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            table_add(result, member, line, status);
696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else if (uprv_strcmp(subtag, "Override") == 0)
699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            override = FALSE;
701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (u_strncmp(member->u.fString.fChars, trueValue, u_strlen(trueValue)) == 0)
703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                override = TRUE;
705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            table_add(result, member, line, status);
707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else if(uprv_strcmp(subtag, "%%CollationBin")==0)
710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            /* discard duplicate %%CollationBin if any*/
712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else if (uprv_strcmp(subtag, "Sequence") == 0)
714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if UCONFIG_NO_COLLATION
716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            warning(line, "Not building collation elements because of UCONFIG_NO_COLLATION, see uconfig.h");
717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else
718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            /* in order to achieve smaller data files, we can direct genrb */
719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            /* to omit collation rules */
720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if(!gOmitCollationRules) {
721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              /* first we add the "Sequence", so that we always have rules */
722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott              table_add(result, member, line, status);
723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if(gMakeBinaryCollation) {
725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                UErrorCode intStatus = U_ZERO_ERROR;
726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                /* do the collation elements */
728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                int32_t     len   = 0;
729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                uint8_t   *data  = NULL;
730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                UCollator *coll  = NULL;
731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                UParseError parseError;
732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                /* add sequence */
733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                /*table_add(result, member, line, status);*/
734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                coll = ucol_openRules(member->u.fString.fChars, member->u.fString.fLength,
736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    UCOL_OFF, UCOL_DEFAULT_STRENGTH,&parseError, &intStatus);
737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                if (U_SUCCESS(intStatus) && coll != NULL)
739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                {
740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    len = ucol_cloneBinary(coll, NULL, 0, &intStatus);
741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    data = (uint8_t *)uprv_malloc(len);
742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    intStatus = U_ZERO_ERROR;
743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    len = ucol_cloneBinary(coll, data, len, &intStatus);
744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    /*data = ucol_cloneRuleData(coll, &len, &intStatus);*/
745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    /* tailoring rules version */
747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    /* This is wrong! */
748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    /*coll->dataInfo.dataVersion[1] = version[0];*/
749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    /* Copy tailoring version. Builder version already */
750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    /* set in ucol_openRules */
751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    ((UCATableHeader *)data)->version[1] = version[0];
752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    ((UCATableHeader *)data)->version[2] = version[1];
753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    ((UCATableHeader *)data)->version[3] = version[2];
754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    if (U_SUCCESS(intStatus) && data != NULL)
756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    {
757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        member = bin_open(bundle, "%%CollationBin", len, data, NULL, NULL, status);
758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        /*table_add(bundle->fRoot, member, line, status);*/
759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        table_add(result, member, line, status);
760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        uprv_free(data);
761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    }
762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    else
763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    {
764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        warning(line, "could not obtain rules from collator");
765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        if(isStrict()){
766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            *status = U_INVALID_FORMAT_ERROR;
767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            return NULL;
768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        }
769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    }
770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    ucol_close(coll);
772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                }
773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                else
774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                {
775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    warning(line, "%%Collation could not be constructed from CollationElements - check context!");
776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    if(isStrict()){
777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        *status = intStatus;
778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        return NULL;
779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    }
780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                }
781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            } else {
782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                if(isVerbose()) {
783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    printf("Not building Collation binary\n");
784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                }
785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /*member = string_open(bundle, subtag, tokenValue->fChars, tokenValue->fLength, status);*/
790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /*expect(TOK_CLOSE_BRACE, NULL, NULL, status);*/
792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (U_FAILURE(*status))
794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            res_close(result);
796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* not reached */
801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* A compiler warning will appear if all paths don't contain a return statement. */
802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*    *status = U_INTERNAL_PROGRAM_ERROR;
803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return NULL;*/
804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseCollationElements(char *tag, uint32_t startline, UBool newCollation, UErrorCode *status)
808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource  *result = NULL;
810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource  *member = NULL;
811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource  *collationRes = NULL;
812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString    *tokenValue;
813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString     comment;
814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    enum   ETokenType  token;
815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char               subtag[1024], typeKeyword[1024];
816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t           line;
817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result = table_open(bundle, tag, NULL, status);
819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (result == NULL || U_FAILURE(*status))
821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" collation elements %s at line %i \n",  (tag == NULL) ? "(null)" : tag, (int)startline);
826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(!newCollation) {
828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return addCollation(result, startline, status);
829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else {
831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        for(;;) {
832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            ustr_init(&comment);
833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            token = getToken(&tokenValue, &comment, &line, status);
834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (token == TOK_CLOSE_BRACE)
836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                return result;
838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (token != TOK_STRING)
841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                res_close(result);
843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                *status = U_INVALID_FORMAT_ERROR;
844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                if (token == TOK_EOF)
846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                {
847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    error(startline, "unterminated table");
848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                }
849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                else
850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                {
851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    error(line, "Unexpected token %s", tokenNames[token]);
852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                }
853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                return NULL;
855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1);
858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (U_FAILURE(*status))
860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                res_close(result);
862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                return NULL;
863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (uprv_strcmp(subtag, "default") == 0)
866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                member = parseResource(subtag, NULL, status);
868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                if (U_FAILURE(*status))
870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                {
871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    res_close(result);
872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    return NULL;
873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                }
874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                table_add(result, member, line, status);
876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            else
878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                token = peekToken(0, &tokenValue, &line, &comment, status);
880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                /* this probably needs to be refactored or recursively use the parser */
881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                /* first we assume that our collation table won't have the explicit type */
882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                /* then, we cannot handle aliases */
883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                if(token == TOK_OPEN_BRACE) {
884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    token = getToken(&tokenValue, &comment, &line, status);
885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    collationRes = table_open(bundle, subtag, NULL, status);
886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    table_add(result, addCollation(collationRes, startline, status), startline, status);
887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                } else if(token == TOK_COLON) { /* right now, we'll just try to see if we have aliases */
888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    /* we could have a table too */
889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    token = peekToken(1, &tokenValue, &line, &comment, status);
890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    u_UCharsToChars(tokenValue->fChars, typeKeyword, u_strlen(tokenValue->fChars) + 1);
891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    if(uprv_strcmp(typeKeyword, "alias") == 0) {
892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        member = parseResource(subtag, NULL, status);
893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        if (U_FAILURE(*status))
895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        {
896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            res_close(result);
897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                            return NULL;
898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        }
899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        table_add(result, member, line, status);
901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    } else {
902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        res_close(result);
903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        *status = U_INVALID_FORMAT_ERROR;
904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        return NULL;
905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    }
906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                } else {
907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    res_close(result);
908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    *status = U_INVALID_FORMAT_ERROR;
909c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    return NULL;
910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                }
911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            /*member = string_open(bundle, subtag, tokenValue->fChars, tokenValue->fLength, status);*/
914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            /*expect(TOK_CLOSE_BRACE, NULL, NULL, status);*/
916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
917c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (U_FAILURE(*status))
918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                res_close(result);
920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                return NULL;
921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* Necessary, because CollationElements requires the bundle->fRoot member to be present which,
927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   if this weren't special-cased, wouldn't be set until the entire file had been processed. */
928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottrealParseTable(struct SResource *table, char *tag, uint32_t startline, UErrorCode *status)
930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource  *member = NULL;
932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString    *tokenValue=NULL;
933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString    comment;
934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    enum   ETokenType token;
935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char              subtag[1024];
936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t          line;
937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UBool             readToken = FALSE;
938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
939c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* '{' . (name resource)* '}' */
940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" parsing table %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)startline);
942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
943c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    for (;;)
944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
945c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        ustr_init(&comment);
946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        token = getToken(&tokenValue, &comment, &line, status);
947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (token == TOK_CLOSE_BRACE)
949c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (!readToken) {
951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                warning(startline, "Encountered empty table");
952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
953c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return table;
954c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (token != TOK_STRING)
957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            *status = U_INVALID_FORMAT_ERROR;
959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (token == TOK_EOF)
961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                error(startline, "unterminated table");
963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            else
965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                error(line, "unexpected token %s", tokenNames[token]);
967c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
968c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
971c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if(uprv_isInvariantUString(tokenValue->fChars, -1)) {
973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1);
974c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        } else {
975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            *status = U_INVALID_FORMAT_ERROR;
976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            error(line, "invariant characters required for table keys");
977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
978c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
980c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (U_FAILURE(*status))
981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
982c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            error(line, "parse error. Stopped parsing tokens with %s", u_errorName(*status));
983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
984c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
985c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
986c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        member = parseResource(subtag, &comment, status);
987c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (member == NULL || U_FAILURE(*status))
989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            error(line, "parse error. Stopped parsing resource with %s", u_errorName(*status));
991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
992c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
993c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
994c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        table_add(table, member, line, status);
995c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
996c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (U_FAILURE(*status))
997c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
998c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            error(line, "parse error. Stopped parsing table with %s", u_errorName(*status));
999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
1000c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        readToken = TRUE;
1002c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        ustr_deinit(&comment);
1003c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1004c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1005c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* not reached */
1006c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* A compiler warning will appear if all paths don't contain a return statement. */
1007c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*     *status = U_INTERNAL_PROGRAM_ERROR;
1008c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott     return NULL;*/
1009c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1010c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1011c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
1012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseTable(char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status)
1013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
1014c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource *result;
1015c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (tag != NULL && uprv_strcmp(tag, "CollationElements") == 0)
1017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return parseCollationElements(tag, startline, FALSE, status);
1019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (tag != NULL && uprv_strcmp(tag, "collations") == 0)
1021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1022c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return parseCollationElements(tag, startline, TRUE, status);
1023c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1024c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
1025c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" table %s at line %i \n",  (tag == NULL) ? "(null)" : tag, (int)startline);
1026c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1027c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1028c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result = table_open(bundle, tag, comment, status);
1029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (result == NULL || U_FAILURE(*status))
1031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1034c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1035c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return realParseTable(result, tag, startline,  status);
1036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
1039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseArray(char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status)
1040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
1041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource  *result = NULL;
1042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource  *member = NULL;
1043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString    *tokenValue;
1044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString    memberComments;
1045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    enum   ETokenType token;
1046c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UBool             readToken = FALSE;
1047c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1048c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result = array_open(bundle, tag, comment, status);
1049c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1050c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (result == NULL || U_FAILURE(*status))
1051c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1052c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1053c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1054c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
1055c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" array %s at line %i \n",  (tag == NULL) ? "(null)" : tag, (int)startline);
1056c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1057c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1058c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ustr_init(&memberComments);
1059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1060c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* '{' . resource [','] '}' */
1061c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    for (;;)
1062c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1063c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* reset length */
1064c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        ustr_setlen(&memberComments, 0, status);
1065c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1066c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* check for end of array, but don't consume next token unless it really is the end */
1067c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        token = peekToken(0, &tokenValue, NULL, &memberComments, status);
1068c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1069c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1070c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (token == TOK_CLOSE_BRACE)
1071c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1072c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            getToken(NULL, NULL, NULL, status);
1073c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (!readToken) {
1074c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                warning(startline, "Encountered empty array");
1075c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
1076c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            break;
1077c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1078c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1079c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (token == TOK_EOF)
1080c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1081c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            res_close(result);
1082c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            *status = U_INVALID_FORMAT_ERROR;
1083c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            error(startline, "unterminated array");
1084c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
1085c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1086c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1087c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* string arrays are a special case */
1088c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (token == TOK_STRING)
1089c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1090c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            getToken(&tokenValue, &memberComments, NULL, status);
1091c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            member = string_open(bundle, NULL, tokenValue->fChars, tokenValue->fLength, &memberComments, status);
1092c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1093c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else
1094c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1095c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            member = parseResource(NULL, &memberComments, status);
1096c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1097c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1098c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (member == NULL || U_FAILURE(*status))
1099c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            res_close(result);
1101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
1102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        array_add(result, member, status);
1105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (U_FAILURE(*status))
1107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            res_close(result);
1109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
1110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* eat optional comma if present */
1113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        token = peekToken(0, NULL, NULL, NULL, status);
1114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (token == TOK_COMMA)
1116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            getToken(NULL, NULL, NULL, status);
1118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (U_FAILURE(*status))
1121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            res_close(result);
1123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
1124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        readToken = TRUE;
1126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ustr_deinit(&memberComments);
1129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result;
1130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
1133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseIntVector(char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status)
1134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
1135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource  *result = NULL;
1136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    enum   ETokenType  token;
1137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char              *string;
1138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int32_t            value;
1139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UBool              readToken = FALSE;
1140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char              *stopstring;
1141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t           len;
1142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString     memberComments;
1143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result = intvector_open(bundle, tag, comment, status);
1145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (result == NULL || U_FAILURE(*status))
1147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
1152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" vector %s at line %i \n",  (tag == NULL) ? "(null)" : tag, (int)startline);
1153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ustr_init(&memberComments);
1155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* '{' . string [','] '}' */
1156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    for (;;)
1157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        ustr_setlen(&memberComments, 0, status);
1159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* check for end of array, but don't consume next token unless it really is the end */
1161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        token = peekToken(0, NULL, NULL,&memberComments, status);
1162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (token == TOK_CLOSE_BRACE)
1164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            /* it's the end, consume the close brace */
1166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            getToken(NULL, NULL, NULL, status);
1167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (!readToken) {
1168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                warning(startline, "Encountered empty int vector");
1169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
1170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            ustr_deinit(&memberComments);
1171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return result;
1172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        string = getInvariantString(NULL, NULL, status);
1175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (U_FAILURE(*status))
1177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            res_close(result);
1179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
1180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* For handling illegal char in the Intvector */
1183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        value = uprv_strtoul(string, &stopstring, 0);/* make intvector support decimal,hexdigit,octal digit ranging from -2^31-2^32-1*/
1184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        len=(uint32_t)(stopstring-string);
1185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if(len==uprv_strlen(string))
1187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            intvector_add(result, value, status);
1189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_free(string);
1190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            token = peekToken(0, NULL, NULL, NULL, status);
1191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else
1193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_free(string);
1195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            *status=U_INVALID_CHAR_FOUND;
1196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (U_FAILURE(*status))
1199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            res_close(result);
1201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
1202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* the comma is optional (even though it is required to prevent the reader from concatenating
1205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        consecutive entries) so that a missing comma on the last entry isn't an error */
1206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (token == TOK_COMMA)
1207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            getToken(NULL, NULL, NULL, status);
1209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        readToken = TRUE;
1211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* not reached */
1214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* A compiler warning will appear if all paths don't contain a return statement. */
1215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*    intvector_close(result, status);
1216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *status = U_INTERNAL_PROGRAM_ERROR;
1217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return NULL;*/
1218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
1221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseBinary(char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status)
1222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
1223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource *result = NULL;
1224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint8_t          *value;
1225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char             *string;
1226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char              toConv[3] = {'\0', '\0', '\0'};
1227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t          count;
1228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t          i;
1229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t          line;
1230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char             *stopstring;
1231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t          len;
1232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    string = getInvariantString(&line, NULL, status);
1234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (string == NULL || U_FAILURE(*status))
1236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status);
1241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
1243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        uprv_free(string);
1245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
1249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" binary %s at line %i \n",  (tag == NULL) ? "(null)" : tag, (int)startline);
1250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    count = (uint32_t)uprv_strlen(string);
1253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (count > 0){
1254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if((count % 2)==0){
1255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            value = uprv_malloc(sizeof(uint8_t) * count);
1256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (value == NULL)
1258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
1259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                uprv_free(string);
1260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                *status = U_MEMORY_ALLOCATION_ERROR;
1261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                return NULL;
1262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
1263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            for (i = 0; i < count; i += 2)
1265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
1266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                toConv[0] = string[i];
1267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                toConv[1] = string[i + 1];
1268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                value[i >> 1] = (uint8_t) uprv_strtoul(toConv, &stopstring, 16);
1270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                len=(uint32_t)(stopstring-toConv);
1271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                if(len!=uprv_strlen(toConv))
1273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                {
1274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    uprv_free(string);
1275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    *status=U_INVALID_CHAR_FOUND;
1276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    return NULL;
1277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                }
1278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
1279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            result = bin_open(bundle, tag, (i >> 1), value,NULL, comment, status);
1281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_free(value);
1283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else
1285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            *status = U_INVALID_CHAR_FOUND;
1287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_free(string);
1288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            error(line, "Encountered invalid binary string");
1289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
1290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else
1293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        result = bin_open(bundle, tag, 0, NULL, "",comment,status);
1295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        warning(startline, "Encountered empty binary tag");
1296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_free(string);
1298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result;
1300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
1303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseInteger(char *tag, uint32_t startline, const struct UString *comment, UErrorCode *status)
1304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
1305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource *result = NULL;
1306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int32_t           value;
1307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char             *string;
1308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char             *stopstring;
1309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t          len;
1310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    string = getInvariantString(NULL, NULL, status);
1312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (string == NULL || U_FAILURE(*status))
1314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status);
1319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
1321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        uprv_free(string);
1323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
1327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" integer %s at line %i \n",  (tag == NULL) ? "(null)" : tag, (int)startline);
1328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (uprv_strlen(string) <= 0)
1331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        warning(startline, "Encountered empty integer. Default value is 0.");
1333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* Allow integer support for hexdecimal, octal digit and decimal*/
1336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* and handle illegal char in the integer*/
1337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    value = uprv_strtoul(string, &stopstring, 0);
1338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    len=(uint32_t)(stopstring-string);
1339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(len==uprv_strlen(string))
1340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        result = int_open(bundle, tag, value, comment, status);
1342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else
1344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status=U_INVALID_CHAR_FOUND;
1346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_free(string);
1348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result;
1350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
1353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseImport(char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status)
1354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
1355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource *result;
1356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    FileStream       *file;
1357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int32_t           len;
1358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint8_t          *data;
1359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char             *filename;
1360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t          line;
1361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char     *fullname = NULL;
1362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int32_t numRead = 0;
1363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    filename = getInvariantString(&line, NULL, status);
1364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
1366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status);
1371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
1373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        uprv_free(filename);
1375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
1379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" import %s at line %i \n",  (tag == NULL) ? "(null)" : tag, (int)startline);
1380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* Open the input file for reading */
1383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (inputdir == NULL)
1384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if 1
1386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /*
1387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         * Always save file file name, even if there's
1388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         * no input directory specified. MIGHT BREAK SOMETHING
1389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         */
1390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        int32_t filenameLength = uprv_strlen(filename);
1391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        fullname = (char *) uprv_malloc(filenameLength + 1);
1393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        uprv_strcpy(fullname, filename);
1394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
1395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        file = T_FileStream_open(filename, "rb");
1397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else
1399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        int32_t  count     = (int32_t)uprv_strlen(filename);
1402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (inputdir[inputdirLength - 1] != U_FILE_SEP_CHAR)
1404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            fullname = (char *) uprv_malloc(inputdirLength + count + 2);
1406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            /* test for NULL */
1408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if(fullname == NULL)
1409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
1410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                *status = U_MEMORY_ALLOCATION_ERROR;
1411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                return NULL;
1412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
1413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_strcpy(fullname, inputdir);
1415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            fullname[inputdirLength]      = U_FILE_SEP_CHAR;
1417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            fullname[inputdirLength + 1] = '\0';
1418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_strcat(fullname, filename);
1420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else
1422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            fullname = (char *) uprv_malloc(inputdirLength + count + 1);
1424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            /* test for NULL */
1426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if(fullname == NULL)
1427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
1428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                *status = U_MEMORY_ALLOCATION_ERROR;
1429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                return NULL;
1430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
1431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_strcpy(fullname, inputdir);
1433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_strcat(fullname, filename);
1434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        file = T_FileStream_open(fullname, "rb");
1437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (file == NULL)
1441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        error(line, "couldn't open input file %s", filename);
1443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status = U_FILE_ACCESS_ERROR;
1444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    len  = T_FileStream_size(file);
1448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    data = (uint8_t*)uprv_malloc(len * sizeof(uint8_t));
1449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* test for NULL */
1450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(data == NULL)
1451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status = U_MEMORY_ALLOCATION_ERROR;
1453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        T_FileStream_close (file);
1454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    numRead = T_FileStream_read  (file, data, len);
1458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    T_FileStream_close (file);
1459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result = bin_open(bundle, tag, len, data, fullname, comment, status);
1461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_free(data);
1463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_free(filename);
1464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_free(fullname);
1465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result;
1467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
1470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseInclude(char *tag, uint32_t startline, const struct UString* comment, UErrorCode *status)
1471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
1472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct SResource *result;
1473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int32_t           len=0;
1474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char             *filename;
1475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t          line;
1476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UChar *pTarget     = NULL;
1477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UCHARBUF *ucbuf;
1479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char     *fullname = NULL;
1480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int32_t  count     = 0;
1481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const char* cp = NULL;
1482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const UChar* uBuffer = NULL;
1483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    filename = getInvariantString(&line, NULL, status);
1485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    count     = (int32_t)uprv_strlen(filename);
1486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
1488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_CLOSE_BRACE, NULL, NULL, NULL, status);
1493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
1495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        uprv_free(filename);
1497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
1501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" include %s at line %i \n",  (tag == NULL) ? "(null)" : tag, (int)startline);
1502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    fullname = (char *) uprv_malloc(inputdirLength + count + 2);
1505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* test for NULL */
1506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(fullname == NULL)
1507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status = U_MEMORY_ALLOCATION_ERROR;
1509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        uprv_free(filename);
1510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(inputdir!=NULL){
1514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (inputdir[inputdirLength - 1] != U_FILE_SEP_CHAR)
1515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_strcpy(fullname, inputdir);
1518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            fullname[inputdirLength]      = U_FILE_SEP_CHAR;
1520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            fullname[inputdirLength + 1] = '\0';
1521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_strcat(fullname, filename);
1523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else
1525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_strcpy(fullname, inputdir);
1527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_strcat(fullname, filename);
1528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }else{
1530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        uprv_strcpy(fullname,filename);
1531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ucbuf = ucbuf_open(fullname, &cp,getShowWarning(),FALSE,status);
1534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status)) {
1536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        error(line, "couldn't open input file %s\n", filename);
1537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uBuffer = ucbuf_getBuffer(ucbuf,&len,status);
1541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result = string_open(bundle, tag, uBuffer, len, comment, status);
1542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_free(pTarget);
1544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_free(filename);
1546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_free(fullname);
1547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result;
1549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_string,    "string",    6);
1556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_binary,    "binary",    6);
1557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_bin,       "bin",       3);
1558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_table,     "table",     5);
1559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_table_no_fallback,     "table(nofallback)",         17);
1560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_int,       "int",       3);
1561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_integer,   "integer",   7);
1562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_array,     "array",     5);
1563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_alias,     "alias",     5);
1564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_intvector, "intvector", 9);
1565c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_import,    "import",    6);
1566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_include,   "include",   7);
1567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_reserved,  "reserved",  8);
1568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* Various non-standard processing plugins that create one or more special resources. */
1570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_plugin_uca_rules,      "process(uca_rules)",        18);
1571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_plugin_collation,      "process(collation)",        18);
1572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_plugin_transliterator, "process(transliterator)",   23);
1573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_STRING_DECL(k_type_plugin_dependency,     "process(dependency)",       19);
1574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef enum EResourceType
1576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
1577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_UNKNOWN,
1578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_STRING,
1579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_BINARY,
1580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_TABLE,
1581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_TABLE_NO_FALLBACK,
1582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_INTEGER,
1583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_ARRAY,
1584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_ALIAS,
1585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_INTVECTOR,
1586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_IMPORT,
1587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_INCLUDE,
1588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_PROCESS_UCA_RULES,
1589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_PROCESS_COLLATION,
1590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_PROCESS_TRANSLITERATOR,
1591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_PROCESS_DEPENDENCY,
1592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    RT_RESERVED
1593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} EResourceType;
1594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct {
1596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const char *nameChars;   /* only used for debugging */
1597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    const UChar *nameUChars;
1598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ParseResourceFunction *parseFunction;
1599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} gResourceTypes[] = {
1600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"Unknown", NULL, NULL},
1601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"string", k_type_string, parseString},
1602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"binary", k_type_binary, parseBinary},
1603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"table", k_type_table, parseTable},
1604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"table(nofallback)", k_type_table_no_fallback, NULL}, /* parseFunction will never be called */
1605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"integer", k_type_integer, parseInteger},
1606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"array", k_type_array, parseArray},
1607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"alias", k_type_alias, parseAlias},
1608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"intvector", k_type_intvector, parseIntVector},
1609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"import", k_type_import, parseImport},
1610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"include", k_type_include, parseInclude},
1611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"process(uca_rules)", k_type_plugin_uca_rules, parseUCARules},
1612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"process(collation)", k_type_plugin_collation, NULL /* not implemented yet */},
1613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"process(transliterator)", k_type_plugin_transliterator, parseTransliterator},
1614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"process(dependency)", k_type_plugin_dependency, parseDependency},
1615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {"reserved", NULL, NULL}
1616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
1617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid initParser(UBool omitBinaryCollation, UBool omitCollationRules)
1619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
1620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t i;
1621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_string,    "string",    6);
1623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_binary,    "binary",    6);
1624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_bin,       "bin",       3);
1625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_table,     "table",     5);
1626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_table_no_fallback,     "table(nofallback)",         17);
1627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_int,       "int",       3);
1628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_integer,   "integer",   7);
1629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_array,     "array",     5);
1630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_alias,     "alias",     5);
1631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_intvector, "intvector", 9);
1632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_import,    "import",    6);
1633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_reserved,  "reserved",  8);
1634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_include,   "include",   7);
1635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_plugin_uca_rules,      "process(uca_rules)",        18);
1637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_plugin_collation,      "process(collation)",        18);
1638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_plugin_transliterator, "process(transliterator)",   23);
1639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    U_STRING_INIT(k_type_plugin_dependency,     "process(dependency)",       19);
1640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    for (i = 0; i < MAX_LOOKAHEAD + 1; i++)
1642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        ustr_init(&lookahead[i].value);
1644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    gMakeBinaryCollation = !omitBinaryCollation;
1646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    gOmitCollationRules = omitCollationRules;
1647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic U_INLINE UBool isTable(enum EResourceType type) {
1650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return (UBool)(type==RT_TABLE || type==RT_TABLE_NO_FALLBACK);
1651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic enum EResourceType
1654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseResourceType(UErrorCode *status)
1655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
1656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString        *tokenValue;
1657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString        comment;
1658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    enum   EResourceType  result = RT_UNKNOWN;
1659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t              line=0;
1660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ustr_init(&comment);
1661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_STRING, &tokenValue, &comment, &line, status);
1662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
1664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return RT_UNKNOWN;
1666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *status = U_ZERO_ERROR;
1669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* Search for normal types */
1671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    result=RT_UNKNOWN;
1672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    while (++result < RT_RESERVED) {
1673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (u_strcmp(tokenValue->fChars, gResourceTypes[result].nameUChars) == 0) {
1674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            break;
1675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* Now search for the aliases */
1678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (u_strcmp(tokenValue->fChars, k_type_int) == 0) {
1679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        result = RT_INTEGER;
1680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else if (u_strcmp(tokenValue->fChars, k_type_bin) == 0) {
1682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        result = RT_BINARY;
1683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else if (result == RT_RESERVED) {
1685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        char tokenBuffer[1024];
1686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        u_austrncpy(tokenBuffer, tokenValue->fChars, sizeof(tokenBuffer));
1687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        tokenBuffer[sizeof(tokenBuffer) - 1] = 0;
1688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status = U_INVALID_FORMAT_ERROR;
1689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        error(line, "unknown resource type '%s'", tokenBuffer);
1690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return result;
1693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* parse a non-top-level resource */
1696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SResource *
1697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottparseResource(char *tag, const struct UString *comment, UErrorCode *status)
1698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
1699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    enum   ETokenType      token;
1700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    enum   EResourceType  resType = RT_UNKNOWN;
1701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ParseResourceFunction *parseFunction = NULL;
1702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString        *tokenValue;
1703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t                 startline;
1704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t                 line;
1705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    token = getToken(&tokenValue, NULL, &startline, status);
1707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(isVerbose()){
1709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        printf(" resource %s at line %i \n",  (tag == NULL) ? "(null)" : tag, (int)startline);
1710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* name . [ ':' type ] '{' resource '}' */
1713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* This function parses from the colon onwards.  If the colon is present, parse the
1714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    type then try to parse a resource of that type.  If there is no explicit type,
1715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    work it out using the lookahead tokens. */
1716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    switch (token)
1717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case TOK_EOF:
1719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status = U_INVALID_FORMAT_ERROR;
1720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        error(startline, "Unexpected EOF encountered");
1721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case TOK_ERROR:
1724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status = U_INVALID_FORMAT_ERROR;
1725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case TOK_COLON:
1728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        resType = parseResourceType(status);
1729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        expect(TOK_OPEN_BRACE, &tokenValue, NULL, &startline, status);
1730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (U_FAILURE(*status))
1732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
1734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        break;
1737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    case TOK_OPEN_BRACE:
1739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        break;
1740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    default:
1742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status = U_INVALID_FORMAT_ERROR;
1743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        error(startline, "syntax error while reading a resource, expected '{' or ':'");
1744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (resType == RT_UNKNOWN)
1748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* No explicit type, so try to work it out.  At this point, we've read the first '{'.
1750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        We could have any of the following:
1751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        { {         => array (nested)
1752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        { :/}       => array
1753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        { string ,  => string array
1754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        { string {  => table
1756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        { string :/{    => table
1758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        { string }      => string
1759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        */
1760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        token = peekToken(0, NULL, &line, NULL,status);
1762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (U_FAILURE(*status))
1764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
1766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (token == TOK_OPEN_BRACE || token == TOK_COLON ||token ==TOK_CLOSE_BRACE )
1769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            resType = RT_ARRAY;
1771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else if (token == TOK_STRING)
1773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            token = peekToken(1, NULL, &line, NULL, status);
1775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (U_FAILURE(*status))
1777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
1778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                return NULL;
1779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
1780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            switch (token)
1782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            {
1783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            case TOK_COMMA:         resType = RT_ARRAY;  break;
1784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            case TOK_OPEN_BRACE:    resType = RT_TABLE;  break;
1785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            case TOK_CLOSE_BRACE:   resType = RT_STRING; break;
1786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            case TOK_COLON:         resType = RT_TABLE;  break;
1787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            default:
1788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                *status = U_INVALID_FORMAT_ERROR;
1789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                error(line, "Unexpected token after string, expected ',', '{' or '}'");
1790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                return NULL;
1791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
1792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else
1794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            *status = U_INVALID_FORMAT_ERROR;
1796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            error(line, "Unexpected token after '{'");
1797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
1798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* printf("Type guessed as %s\n", resourceNames[resType]); */
1801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    } else if(resType == RT_TABLE_NO_FALLBACK) {
1802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status = U_INVALID_FORMAT_ERROR;
1803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        error(startline, "error: %s resource type not valid except on top bundle level", gResourceTypes[resType].nameChars);
1804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* We should now know what we need to parse next, so call the appropriate parser
1808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    function and return. */
1809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    parseFunction = gResourceTypes[resType].parseFunction;
1810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (parseFunction != NULL) {
1811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return parseFunction(tag, startline, comment, status);
1812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else {
1814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status = U_INTERNAL_PROGRAM_ERROR;
1815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        error(startline, "internal error: %s resource type found and not handled", gResourceTypes[resType].nameChars);
1816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return NULL;
1819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* parse the top-level resource */
1822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct SRBRoot *
1823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottparse(UCHARBUF *buf, const char *inputDir, const char *outputDir, UErrorCode *status)
1824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
1825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString    *tokenValue;
1826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    struct UString    comment;
1827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uint32_t           line;
1828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    enum EResourceType bundleType;
1829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    enum ETokenType    token;
1830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    initLookahead(buf, status);
1832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    inputdir       = inputDir;
1834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    inputdirLength = (inputdir != NULL) ? (uint32_t)uprv_strlen(inputdir) : 0;
1835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    outputdir       = outputDir;
1836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    outputdirLength = (outputdir != NULL) ? (uint32_t)uprv_strlen(outputdir) : 0;
1837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ustr_init(&comment);
1839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    expect(TOK_STRING, &tokenValue, &comment, NULL, status);
1840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bundle = bundle_open(&comment, status);
1842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (bundle == NULL || U_FAILURE(*status))
1844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bundle_setlocale(bundle, tokenValue->fChars, status);
1850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* The following code is to make Empty bundle work no matter with :table specifer or not */
1851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    token = getToken(NULL, NULL, &line, status);
1852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(token==TOK_COLON) {
1853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *status=U_ZERO_ERROR;
1854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        bundleType=parseResourceType(status);
1855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if(isTable(bundleType))
1857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            expect(TOK_OPEN_BRACE, NULL, NULL, &line, status);
1859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else
1861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            *status=U_PARSE_ERROR;
1863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            error(line, "parse error. Stopped parsing with %s", u_errorName(*status));
1864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else
1867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* not a colon */
1869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if(token==TOK_OPEN_BRACE)
1870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            *status=U_ZERO_ERROR;
1872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            bundleType=RT_TABLE;
1873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else
1875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
1876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            /* neither colon nor open brace */
1877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            *status=U_PARSE_ERROR;
1878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            bundleType=RT_UNKNOWN;
1879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            error(line, "parse error, did not find open-brace '{' or colon ':', stopped with %s", u_errorName(*status));
1880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
1884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        bundle_close(bundle, status);
1886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(bundleType==RT_TABLE_NO_FALLBACK) {
1890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /*
1891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         * Parse a top-level table with the table(nofallback) declaration.
1892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         * This is the same as a regular table, but also sets the
1893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         * URES_ATT_NO_FALLBACK flag in indexes[URES_INDEX_ATTRIBUTES] .
1894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott         */
1895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        bundle->noFallback=TRUE;
1896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* top-level tables need not handle special table names like "collations" */
1898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    realParseTable(bundle->fRoot, NULL, line, status);
1899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if(dependencyArray!=NULL){
1901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        table_add(bundle->fRoot, dependencyArray, 0, status);
1902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        dependencyArray = NULL;
1903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(*status))
1905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        bundle_close(bundle, status);
1907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        res_close(dependencyArray);
1908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return NULL;
1909c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (getToken(NULL, NULL, &line, status) != TOK_EOF)
1912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
1913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        warning(line, "extraneous text after resource bundle (perhaps unmatched braces)");
1914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if(isStrict()){
1915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            *status = U_INVALID_FORMAT_ERROR;
1916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return NULL;
1917c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
1918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
1919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    cleanupLookahead();
1921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ustr_deinit(&comment);
1922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return bundle;
1923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
1924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1925