1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*******************************************************************************
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Copyright (C) 1999-2009, International Business Machines
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Corporation and others.  All Rights Reserved.
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*******************************************************************************
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   file name:  gencnval.c
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   encoding:   US-ASCII
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   tab size:   8 (not used)
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   indentation:4
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   created on: 1999nov05
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   created by: Markus W. Scherer
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   This program reads convrtrs.txt and writes a memory-mappable
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   converter name alias table to cnvalias.dat .
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   This program currently writes version 2.1 of the data format. See
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   ucnv_io.c for more details on the format. Note that version 2.1
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   is written in such a way that a 2.0 reader will be able to use it,
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   and a 2.1 reader will be able to read 2.0.
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h"
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/putil.h"
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ucnv.h" /* ucnv_compareNames() */
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucnv_io.h"
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h"
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cstring.h"
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uinvchar.h"
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "filestrm.h"
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uclean.h"
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unewdata.h"
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uoptions.h"
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdio.h>
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdlib.h>
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <ctype.h>
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* TODO: Need to check alias name length is less than UCNV_MAX_CONVERTER_NAME_LENGTH */
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* STRING_STORE_SIZE + TAG_STORE_SIZE <= ((2^16 - 1) * 2)
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) That is the maximum size for the string stores combined
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) because the strings are index at 16-bit boundries by a
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 16-bit index, and there is only one section for the
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) strings.
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define STRING_STORE_SIZE 0x1FBFE   /* 130046 */
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define TAG_STORE_SIZE      0x400   /* 1024 */
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* The combined tag and converter count can affect the number of lists
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) created.  The size of all lists must be less than (2^17 - 1)
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) because the lists are indexed as a 16-bit array with a 16-bit index.
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAX_TAG_COUNT 0x3F      /* 63 */
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAX_CONV_COUNT UCNV_CONVERTER_INDEX_MASK
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAX_ALIAS_COUNT 0xFFFF  /* 65535 */
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* The maximum number of aliases that a standard tag/converter combination can have.
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) At this moment 6/18/2002, IANA has 12 names for ASCII. Don't go below 15 for
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) this value. I don't recommend more than 31 for this value.
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAX_TC_ALIAS_COUNT 0x1F    /* 31 */
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAX_LINE_SIZE 0x7FFF    /* 32767 */
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAX_LIST_SIZE 0xFFFF    /* 65535 */
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DATA_NAME "cnvalias"
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DATA_TYPE "icu" /* ICU alias table */
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define ALL_TAG_STR "ALL"
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define ALL_TAG_NUM 1
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define EMPTY_TAG_NUM 0
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* UDataInfo cf. udata.h */
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UDataInfo dataInfo={
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    sizeof(UDataInfo),
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    0,
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    U_IS_BIG_ENDIAN,
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    U_CHARSET_FAMILY,
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    sizeof(UChar),
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    0,
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {0x43, 0x76, 0x41, 0x6c},     /* dataFormat="CvAl" */
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {3, 0, 1, 0},                 /* formatVersion */
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {1, 4, 2, 0}                  /* dataVersion */
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef struct {
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *store;
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t top;
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t max;
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} StringBlock;
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char stringStore[STRING_STORE_SIZE];
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static StringBlock stringBlock = { stringStore, 0, STRING_STORE_SIZE };
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef struct {
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t    aliasCount;
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t    *aliases;     /* Index into stringStore */
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} AliasList;
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef struct {
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t converter;     /* Index into stringStore */
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t totalAliasCount;    /* Total aliases in this column */
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} Converter;
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static Converter converters[MAX_CONV_COUNT];
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t converterCount=0;
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char tagStore[TAG_STORE_SIZE];
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static StringBlock tagBlock = { tagStore, 0, TAG_STORE_SIZE };
115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef struct {
117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t    tag;        /* Index into tagStore */
118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t    totalAliasCount; /* Total aliases in this row */
119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    AliasList   aliasList[MAX_CONV_COUNT];
120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} Tag;
121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Think of this as a 3D array. It's tagCount by converterCount by aliasCount */
123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static Tag tags[MAX_TAG_COUNT];
124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t tagCount = 0;
125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Used for storing all aliases  */
127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t knownAliases[MAX_ALIAS_COUNT];
128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t knownAliasesCount = 0;
129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*static uint16_t duplicateKnownAliasesCount = 0;*/
130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Used for storing the lists section that point to aliases */
132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t aliasLists[MAX_LIST_SIZE];
133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t aliasListsSize = 0;
134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Were the standard tags declared before the aliases. */
136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UBool standardTagsUsed = FALSE;
137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UBool verbose = FALSE;
138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int lineNum = 1;
139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UConverterAliasOptions tableOptions = {
141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UCNV_IO_STD_NORMALIZED,
142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    1 /* containsCnvOptionInfo */
143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * path to convrtrs.txt
148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const char *path;
150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* prototypes --------------------------------------------------------------- */
152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)parseLine(const char *line);
155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)parseFile(FileStream *in);
158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t
160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)chomp(char *line);
161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)addOfficialTaggedStandards(char *line, int32_t lineLen);
164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t
166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)addAlias(const char *alias, uint16_t standard, uint16_t converter, UBool defaultName);
167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t
169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)addConverter(const char *converter);
170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char *
172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)allocString(StringBlock *block, const char *s, int32_t length);
173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t
175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)addToKnownAliases(const char *alias);
176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int
178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)compareAliases(const void *alias1, const void *alias2);
179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t
181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getTagNumber(const char *tag, uint16_t tagLen);
182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*static void
184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)addTaggedAlias(uint16_t tag, const char *alias, uint16_t converter);*/
185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)writeAliasTable(UNewDataMemory *out);
188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* -------------------------------------------------------------------------- */
190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Presumes that you used allocString() */
192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define GET_ALIAS_STR(index) (stringStore + ((size_t)(index) << 1))
193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define GET_TAG_STR(index) (tagStore + ((size_t)(index) << 1))
194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Presumes that you used allocString() */
196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define GET_ALIAS_NUM(str) ((uint16_t)((str - stringStore) >> 1))
197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define GET_TAG_NUM(str) ((uint16_t)((str - tagStore) >> 1))
198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)enum
200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    HELP1,
202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    HELP2,
203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    VERBOSE,
204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    COPYRIGHT,
205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    DESTDIR,
206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    SOURCEDIR
207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UOption options[]={
210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UOPTION_HELP_H,
211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UOPTION_HELP_QUESTION_MARK,
212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UOPTION_VERBOSE,
213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UOPTION_COPYRIGHT,
214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UOPTION_DESTDIR,
215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UOPTION_SOURCEDIR
216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)extern int
219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)main(int argc, char* argv[]) {
220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char pathBuf[512];
221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    FileStream *in;
222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UNewDataMemory *out;
223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode errorCode=U_ZERO_ERROR;
224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    U_MAIN_INIT_ARGS(argc, argv);
226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* preset then read command line options */
228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    options[DESTDIR].value=options[SOURCEDIR].value=u_getDataDirectory();
229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options);
230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* error handling, printing usage message */
232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(argc<0) {
233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr,
234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "error in command line argument \"%s\"\n",
235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            argv[-argc]);
236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(argc<0 || options[HELP1].doesOccur || options[HELP2].doesOccur) {
238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr,
239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "usage: %s [-options] [convrtrs.txt]\n"
240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "\tread convrtrs.txt and create " U_ICUDATA_NAME "_" DATA_NAME "." DATA_TYPE "\n"
241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "options:\n"
242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "\t-h or -? or --help  this usage text\n"
243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "\t-v or --verbose     prints out extra information about the alias table\n"
244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "\t-c or --copyright   include a copyright notice\n"
245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "\t-d or --destdir     destination directory, followed by the path\n"
246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            "\t-s or --sourcedir   source directory, followed by the path\n",
247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            argv[0]);
248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(options[VERBOSE].doesOccur) {
252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        verbose = TRUE;
253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(argc>=2) {
256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        path=argv[1];
257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        path=options[SOURCEDIR].value;
259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(path!=NULL && *path!=0) {
260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            char *end;
261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uprv_strcpy(pathBuf, path);
263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            end = uprv_strchr(pathBuf, 0);
264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(*(end-1)!=U_FILE_SEP_CHAR) {
265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                *(end++)=U_FILE_SEP_CHAR;
266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uprv_strcpy(end, "convrtrs.txt");
268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            path=pathBuf;
269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            path = "convrtrs.txt";
271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_memset(stringStore, 0, sizeof(stringStore));
275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_memset(tagStore, 0, sizeof(tagStore));
276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_memset(converters, 0, sizeof(converters));
277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_memset(tags, 0, sizeof(tags));
278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_memset(aliasLists, 0, sizeof(aliasLists));
279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_memset(knownAliases, 0, sizeof(aliasLists));
280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    in=T_FileStream_open(path, "r");
283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(in==NULL) {
284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "gencnval: unable to open input file %s\n", path);
285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_FILE_ACCESS_ERROR);
286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    parseFile(in);
288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    T_FileStream_close(in);
289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* create the output file */
291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    out=udata_create(options[DESTDIR].value, DATA_TYPE, DATA_NAME, &dataInfo,
292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     options[COPYRIGHT].doesOccur ? U_COPYRIGHT_STRING : NULL, &errorCode);
293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(errorCode)) {
294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "gencnval: unable to open output file - error %s\n", u_errorName(errorCode));
295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(errorCode);
296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* write the table of aliases based on a tag/converter name combination */
299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    writeAliasTable(out);
300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* finish */
302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_finish(out, &errorCode);
303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(errorCode)) {
304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "gencnval: error finishing output file - %s\n", u_errorName(errorCode));
305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(errorCode);
306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return 0;
309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)parseFile(FileStream *in) {
313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char line[MAX_LINE_SIZE];
314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char lastLine[MAX_LINE_SIZE];
315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t lineSize = 0;
316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t lastLineSize = 0;
317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool validParse = TRUE;
318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    lineNum = 0;
320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Add the empty tag, which is for untagged aliases */
322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    getTagNumber("", 0);
323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    getTagNumber(ALL_TAG_STR, 3);
324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    allocString(&stringBlock, "", 0);
325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* read the list of aliases */
327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (validParse) {
328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        validParse = FALSE;
329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Read non-empty lines that don't start with a space character. */
331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        while (T_FileStream_readLine(in, lastLine, MAX_LINE_SIZE) != NULL) {
332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            lastLineSize = chomp(lastLine);
333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (lineSize == 0 || (lastLineSize > 0 && isspace(*lastLine))) {
334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                uprv_strcpy(line + lineSize, lastLine);
335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                lineSize += lastLineSize;
336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else if (lineSize > 0) {
337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                validParse = TRUE;
338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                break;
339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            lineNum++;
341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (validParse || lineSize > 0) {
344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (isspace(*line)) {
345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fprintf(stderr, "%s:%d: error: cannot start an alias with a space\n", path, lineNum-1);
346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                exit(U_PARSE_ERROR);
347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else if (line[0] == '{') {
348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (!standardTagsUsed && line[lineSize - 1] != '}') {
349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    fprintf(stderr, "%s:%d: error: alias needs to start with a converter name\n", path, lineNum);
350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    exit(U_PARSE_ERROR);
351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                addOfficialTaggedStandards(line, lineSize);
353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                standardTagsUsed = TRUE;
354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (standardTagsUsed) {
356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    parseLine(line);
357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                else {
359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    fprintf(stderr, "%s:%d: error: alias table needs to start a list of standard tags\n", path, lineNum);
360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    exit(U_PARSE_ERROR);
361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /* Was the last line consumed */
364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (lastLineSize > 0) {
365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                uprv_strcpy(line, lastLine);
366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                lineSize = lastLineSize;
367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            else {
369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                lineSize = 0;
370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        lineNum++;
373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* This works almost like the Perl chomp.
377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) It removes the newlines, comments and trailing whitespace (not preceding whitespace).
378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t
380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)chomp(char *line) {
381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *s = line;
382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *lastNonSpace = line;
383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while(*s!=0) {
384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* truncate at a newline or a comment */
385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(*s == '\r' || *s == '\n' || *s == '#') {
386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            *s = 0;
387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (!isspace(*s)) {
390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            lastNonSpace = s;
391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ++s;
393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (lastNonSpace++ > line) {
395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        *lastNonSpace = 0;
396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        s = lastNonSpace;
397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return (int32_t)(s - line);
399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)parseLine(const char *line) {
403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t pos=0, start, limit, length, cnv;
404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *converter, *alias;
405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* skip leading white space */
407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* There is no whitespace at the beginning anymore */
408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*    while(line[pos]!=0 && isspace(line[pos])) {
409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ++pos;
410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* is there nothing on this line? */
414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(line[pos]==0) {
415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* get the converter name */
419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    start=pos;
420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while(line[pos]!=0 && !isspace(line[pos])) {
421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ++pos;
422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    limit=pos;
424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* store the converter name */
426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    length=(uint16_t)(limit-start);
427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    converter=allocString(&stringBlock, line+start, length);
428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* add the converter to the converter table */
430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    cnv=addConverter(converter);
431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* The name itself may be tagged, so let's added it to the aliases list properly */
433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    pos = start;
434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* get all the real aliases */
436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(;;) {
437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* skip white space */
439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        while(line[pos]!=0 && isspace(line[pos])) {
440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ++pos;
441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* is there no more alias name on this line? */
444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(line[pos]==0) {
445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* get an alias name */
449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        start=pos;
450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        while(line[pos]!=0 && line[pos]!='{' && !isspace(line[pos])) {
451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ++pos;
452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        limit=pos;
454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* store the alias name */
456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        length=(uint16_t)(limit-start);
457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (start == 0) {
458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /* add the converter as its own alias to the alias table */
459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            alias = converter;
460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            addAlias(alias, ALL_TAG_NUM, cnv, TRUE);
461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else {
463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            alias=allocString(&stringBlock, line+start, length);
464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            addAlias(alias, ALL_TAG_NUM, cnv, FALSE);
465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        addToKnownAliases(alias);
467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* add the alias/converter pair to the alias table */
469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* addAlias(alias, 0, cnv, FALSE);*/
470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* skip whitespace */
472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        while (line[pos] && isspace(line[pos])) {
473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ++pos;
474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* handle tags if they are present */
477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (line[pos] == '{') {
478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ++pos;
479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            do {
480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                start = pos;
481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                while (line[pos] && line[pos] != '}' && !isspace( line[pos])) {
482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    ++pos;
483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                limit = pos;
485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (start != limit) {
487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    /* add the tag to the tag table */
488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    uint16_t tag = getTagNumber(line + start, (uint16_t)(limit - start));
489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    addAlias(alias, tag, cnv, (UBool)(line[limit-1] == '*'));
490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                while (line[pos] && isspace(line[pos])) {
493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    ++pos;
494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } while (line[pos] && line[pos] != '}');
496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (line[pos] == '}') {
498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                ++pos;
499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fprintf(stderr, "%s:%d: Unterminated tag list\n", path, lineNum);
501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                exit(U_UNMATCHED_BRACES);
502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            addAlias(alias, EMPTY_TAG_NUM, cnv, (UBool)(tags[0].aliasList[cnv].aliasCount == 0));
505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t
510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getTagNumber(const char *tag, uint16_t tagLen) {
511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *atag;
512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t t;
513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool preferredName = ((tagLen > 0) ? (tag[tagLen - 1] == '*') : (FALSE));
514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (tagCount >= MAX_TAG_COUNT) {
516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: too many tags\n", path, lineNum);
517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_BUFFER_OVERFLOW_ERROR);
518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (preferredName) {
521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*        puts(tag);*/
522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        tagLen--;
523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (t = 0; t < tagCount; ++t) {
526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        const char *currTag = GET_TAG_STR(tags[t].tag);
527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (uprv_strlen(currTag) == tagLen && !uprv_strnicmp(currTag, tag, tagLen)) {
528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return t;
529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* we need to add this tag */
533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (tagCount >= MAX_TAG_COUNT) {
534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: error: too many tags\n", path, lineNum);
535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_BUFFER_OVERFLOW_ERROR);
536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* allocate a new entry in the tag table */
539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    atag = allocString(&tagBlock, tag, tagLen);
540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (standardTagsUsed) {
542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: error: Tag \"%s\" is not declared at the beginning of the alias table.\n",
543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            path, lineNum, atag);
544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(1);
545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else if (tagLen > 0 && strcmp(tag, ALL_TAG_STR) != 0) {
547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: warning: Tag \"%s\" was added to the list of standards because it was not declared at beginning of the alias table.\n",
548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            path, lineNum, atag);
549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* add the tag to the tag table */
552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    tags[tagCount].tag = GET_TAG_NUM(atag);
553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* The aliasList should be set to 0's already */
554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return tagCount++;
556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*static void
559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)addTaggedAlias(uint16_t tag, const char *alias, uint16_t converter) {
560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    tags[tag].aliases[converter] = alias;
561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)addOfficialTaggedStandards(char *line, int32_t lineLen) {
566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *atag;
567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *endTagExp;
568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *tag;
569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static const char WHITESPACE[] = " \t";
570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (tagCount > UCNV_NUM_RESERVED_TAGS) {
572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: error: official tags already added\n", path, lineNum);
573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_BUFFER_OVERFLOW_ERROR);
574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    tag = strchr(line, '{');
576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (tag == NULL) {
577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Why were we called? */
578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: error: Missing start of tag group\n", path, lineNum);
579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_PARSE_ERROR);
580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    tag++;
582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    endTagExp = strchr(tag, '}');
583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (endTagExp == NULL) {
584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: error: Missing end of tag group\n", path, lineNum);
585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_PARSE_ERROR);
586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    endTagExp[0] = 0;
588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    tag = strtok(tag, WHITESPACE);
590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (tag != NULL) {
591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*        printf("Adding original tag \"%s\"\n", tag);*/
592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* allocate a new entry in the tag table */
594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        atag = allocString(&tagBlock, tag, -1);
595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* add the tag to the tag table */
597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        tags[tagCount++].tag = (uint16_t)((atag - tagStore) >> 1);
598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* The aliasList should already be set to 0's */
600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Get next tag */
602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        tag = strtok(NULL, WHITESPACE);
603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t
607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)addToKnownAliases(const char *alias) {
608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*    uint32_t idx; */
609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* strict matching */
610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*    for (idx = 0; idx < knownAliasesCount; idx++) {
611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uint16_t num = GET_ALIAS_NUM(alias);
612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (knownAliases[idx] != num
613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            && uprv_strcmp(alias, GET_ALIAS_STR(knownAliases[idx])) == 0)
614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fprintf(stderr, "%s:%d: warning: duplicate alias %s and %s found\n", path,
616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                lineNum, alias, GET_ALIAS_STR(knownAliases[idx]));
617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            duplicateKnownAliasesCount++;
618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (knownAliases[idx] != num
621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            && ucnv_compareNames(alias, GET_ALIAS_STR(knownAliases[idx])) == 0)
622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (verbose) {
624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fprintf(stderr, "%s:%d: information: duplicate alias %s and %s found\n", path,
625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    lineNum, alias, GET_ALIAS_STR(knownAliases[idx]));
626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            duplicateKnownAliasesCount++;
628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (knownAliasesCount >= MAX_ALIAS_COUNT) {
633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: warning: Too many aliases defined for all converters\n",
634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            path, lineNum);
635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_BUFFER_OVERFLOW_ERROR);
636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* TODO: We could try to unlist exact duplicates. */
638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return knownAliases[knownAliasesCount++] = GET_ALIAS_NUM(alias);
639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)@param standard When standard is 0, then it's the "empty" tag.
643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t
645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)addAlias(const char *alias, uint16_t standard, uint16_t converter, UBool defaultName) {
646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t idx, idx2;
647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool dupFound = FALSE;
648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool startEmptyWithoutDefault = FALSE;
649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    AliasList *aliasList;
650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(standard>=MAX_TAG_COUNT) {
652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: error: too many standard tags\n", path, lineNum);
653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_BUFFER_OVERFLOW_ERROR);
654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(converter>=MAX_CONV_COUNT) {
656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: error: too many converter names\n", path, lineNum);
657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_BUFFER_OVERFLOW_ERROR);
658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    aliasList = &tags[standard].aliasList[converter];
660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (strchr(alias, '}')) {
662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: error: unmatched } found\n", path,
663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            lineNum);
664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(aliasList->aliasCount + 1 >= MAX_TC_ALIAS_COUNT) {
667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: error: too many aliases for alias %s and converter %s\n", path,
668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            lineNum, alias, GET_ALIAS_STR(converters[converter].converter));
669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_BUFFER_OVERFLOW_ERROR);
670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Show this warning only once. All aliases are added to the "ALL" tag. */
673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (standard == ALL_TAG_NUM && GET_ALIAS_STR(converters[converter].converter) != alias) {
674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Normally these option values are parsed at runtime, and they can
675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           be discarded when the alias is a default converter. Options should
676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           only be on a converter and not an alias. */
677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (uprv_strchr(alias, UCNV_OPTION_SEP_CHAR) != 0)
678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fprintf(stderr, "warning(line %d): alias %s contains a \""UCNV_OPTION_SEP_STRING"\". Options are parsed at run-time and do not need to be in the alias table.\n",
680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                lineNum, alias);
681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (uprv_strchr(alias, UCNV_VALUE_SEP_CHAR) != 0)
683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fprintf(stderr, "warning(line %d): alias %s contains an \""UCNV_VALUE_SEP_STRING"\". Options are parsed at run-time and do not need to be in the alias table.\n",
685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                lineNum, alias);
686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (standard != ALL_TAG_NUM) {
690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Check for duplicate aliases for this tag on all converters */
691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (idx = 0; idx < converterCount; idx++) {
692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            for (idx2 = 0; idx2 < tags[standard].aliasList[idx].aliasCount; idx2++) {
693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                uint16_t aliasNum = tags[standard].aliasList[idx].aliases[idx2];
694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (aliasNum
695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    && ucnv_compareNames(alias, GET_ALIAS_STR(aliasNum)) == 0)
696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                {
697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (idx == converter) {
698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        /*
699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         * (alias, standard) duplicates are harmless if they map to the same converter.
700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         * Only print a warning in verbose mode, or if the alias is a precise duplicate,
701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         * not just a lenient-match duplicate.
702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         */
703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        if (verbose || 0 == uprv_strcmp(alias, GET_ALIAS_STR(aliasNum))) {
704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            fprintf(stderr, "%s:%d: warning: duplicate aliases %s and %s found for standard %s and converter %s\n", path,
705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                lineNum, alias, GET_ALIAS_STR(aliasNum),
706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                GET_TAG_STR(tags[standard].tag),
707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                GET_ALIAS_STR(converters[converter].converter));
708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        }
709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    } else {
710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        fprintf(stderr, "%s:%d: warning: duplicate aliases %s and %s found for standard tag %s between converter %s and converter %s\n", path,
711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            lineNum, alias, GET_ALIAS_STR(aliasNum),
712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            GET_TAG_STR(tags[standard].tag),
713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            GET_ALIAS_STR(converters[converter].converter),
714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            GET_ALIAS_STR(converters[idx].converter));
715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    dupFound = TRUE;
717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    break;
718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Check for duplicate default aliases for this converter on all tags */
723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* It's okay to have multiple standards prefer the same name */
724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*        if (verbose && !dupFound) {
725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            for (idx = 0; idx < tagCount; idx++) {
726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (tags[idx].aliasList[converter].aliases) {
727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    uint16_t aliasNum = tags[idx].aliasList[converter].aliases[0];
728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (aliasNum
729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        && ucnv_compareNames(alias, GET_ALIAS_STR(aliasNum)) == 0)
730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    {
731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        fprintf(stderr, "%s:%d: warning: duplicate alias %s found for converter %s and standard tag %s\n", path,
732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            lineNum, alias, GET_ALIAS_STR(converters[converter].converter), GET_TAG_STR(tags[standard].tag));
733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }*/
738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (aliasList->aliasCount <= 0) {
741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        aliasList->aliasCount++;
742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        startEmptyWithoutDefault = TRUE;
743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    aliasList->aliases = (uint16_t *)uprv_realloc(aliasList->aliases, (aliasList->aliasCount + 1) * sizeof(aliasList->aliases[0]));
745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (startEmptyWithoutDefault) {
746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        aliasList->aliases[0] = 0;
747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (defaultName) {
749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (aliasList->aliases[0] != 0) {
750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fprintf(stderr, "%s:%d: error: Alias %s and %s cannot both be the default alias for standard tag %s and converter %s\n", path,
751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                lineNum,
752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                alias,
753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                GET_ALIAS_STR(aliasList->aliases[0]),
754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                GET_TAG_STR(tags[standard].tag),
755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                GET_ALIAS_STR(converters[converter].converter));
756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            exit(U_PARSE_ERROR);
757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        aliasList->aliases[0] = GET_ALIAS_NUM(alias);
759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        aliasList->aliases[aliasList->aliasCount++] = GET_ALIAS_NUM(alias);
761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*    aliasList->converter = converter;*/
763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    converters[converter].totalAliasCount++; /* One more to the column */
765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    tags[standard].totalAliasCount++; /* One more to the row */
766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return aliasList->aliasCount;
768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint16_t
771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)addConverter(const char *converter) {
772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t idx;
773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(converterCount>=MAX_CONV_COUNT) {
774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: error: too many converters\n", path, lineNum);
775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_BUFFER_OVERFLOW_ERROR);
776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (idx = 0; idx < converterCount; idx++) {
779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (ucnv_compareNames(converter, GET_ALIAS_STR(converters[idx].converter)) == 0) {
780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fprintf(stderr, "%s:%d: error: duplicate converter %s found!\n", path, lineNum, converter);
781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            exit(U_PARSE_ERROR);
782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    converters[converterCount].converter = GET_ALIAS_NUM(converter);
787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    converters[converterCount].totalAliasCount = 0;
788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return converterCount++;
790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* resolve this alias based on the prioritization of the standard tags. */
793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)resolveAliasToConverter(uint16_t alias, uint16_t *tagNum, uint16_t *converterNum) {
795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t idx, idx2, idx3;
796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (idx = UCNV_NUM_RESERVED_TAGS; idx < tagCount; idx++) {
798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (idx2 = 0; idx2 < converterCount; idx2++) {
799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            for (idx3 = 0; idx3 < tags[idx].aliasList[idx2].aliasCount; idx3++) {
800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                uint16_t aliasNum = tags[idx].aliasList[idx2].aliases[idx3];
801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (aliasNum == alias) {
802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    *tagNum = idx;
803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    *converterNum = idx2;
804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    return;
805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Do the leftovers last, just in case */
810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* There is no need to do the ALL tag */
811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    idx = 0;
812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (idx2 = 0; idx2 < converterCount; idx2++) {
813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (idx3 = 0; idx3 < tags[idx].aliasList[idx2].aliasCount; idx3++) {
814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uint16_t aliasNum = tags[idx].aliasList[idx2].aliases[idx3];
815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (aliasNum == alias) {
816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                *tagNum = idx;
817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                *converterNum = idx2;
818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return;
819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    *tagNum = UINT16_MAX;
823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    *converterNum = UINT16_MAX;
824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fprintf(stderr, "%s: warning: alias %s not found\n",
825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        path,
826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        GET_ALIAS_STR(alias));
827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return;
828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* The knownAliases should be sorted before calling this function */
831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static uint32_t
832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)resolveAliases(uint16_t *uniqueAliasArr, uint16_t *uniqueAliasToConverterArr, uint16_t aliasOffset) {
833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t uniqueAliasIdx = 0;
834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t idx;
835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t currTagNum, oldTagNum;
836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t currConvNum, oldConvNum;
837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const char *lastName;
838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    resolveAliasToConverter(knownAliases[0], &oldTagNum, &currConvNum);
840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uniqueAliasToConverterArr[uniqueAliasIdx] = currConvNum;
841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    oldConvNum = currConvNum;
842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uniqueAliasArr[uniqueAliasIdx] = knownAliases[0] + aliasOffset;
843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uniqueAliasIdx++;
844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    lastName = GET_ALIAS_STR(knownAliases[0]);
845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (idx = 1; idx < knownAliasesCount; idx++) {
847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        resolveAliasToConverter(knownAliases[idx], &currTagNum, &currConvNum);
848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (ucnv_compareNames(lastName, GET_ALIAS_STR(knownAliases[idx])) == 0) {
849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /* duplicate found */
850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ((currTagNum < oldTagNum && currTagNum >= UCNV_NUM_RESERVED_TAGS)
851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                || oldTagNum == 0) {
852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                oldTagNum = currTagNum;
853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                uniqueAliasToConverterArr[uniqueAliasIdx - 1] = currConvNum;
854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                uniqueAliasArr[uniqueAliasIdx - 1] = knownAliases[idx] + aliasOffset;
855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (verbose) {
856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    printf("using %s instead of %s -> %s",
857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        GET_ALIAS_STR(knownAliases[idx]),
858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        lastName,
859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        GET_ALIAS_STR(converters[currConvNum].converter));
860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (oldConvNum != currConvNum) {
861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        printf(" (alias conflict)");
862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    puts("");
864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            else {
867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                /* else ignore it */
868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (verbose) {
869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    printf("folding %s into %s -> %s",
870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        GET_ALIAS_STR(knownAliases[idx]),
871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        lastName,
872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        GET_ALIAS_STR(converters[oldConvNum].converter));
873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (oldConvNum != currConvNum) {
874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        printf(" (alias conflict)");
875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    puts("");
877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (oldConvNum != currConvNum) {
880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                uniqueAliasToConverterArr[uniqueAliasIdx - 1] |= UCNV_AMBIGUOUS_ALIAS_MAP_BIT;
881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else {
884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uniqueAliasToConverterArr[uniqueAliasIdx] = currConvNum;
885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            oldConvNum = currConvNum;
886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uniqueAliasArr[uniqueAliasIdx] = knownAliases[idx] + aliasOffset;
887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uniqueAliasIdx++;
888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            lastName = GET_ALIAS_STR(knownAliases[idx]);
889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            oldTagNum = currTagNum;
890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            /*printf("%s -> %s\n", GET_ALIAS_STR(knownAliases[idx]), GET_ALIAS_STR(converters[currConvNum].converter));*/
891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (uprv_strchr(GET_ALIAS_STR(converters[currConvNum].converter), UCNV_OPTION_SEP_CHAR) != NULL) {
893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uniqueAliasToConverterArr[uniqueAliasIdx-1] |= UCNV_CONTAINS_OPTION_BIT;
894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return uniqueAliasIdx;
897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)createOneAliasList(uint16_t *aliasArrLists, uint32_t tag, uint32_t converter, uint16_t offset) {
901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t aliasNum;
902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    AliasList *aliasList = &tags[tag].aliasList[converter];
903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (aliasList->aliasCount == 0) {
905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        aliasArrLists[tag*converterCount + converter] = 0;
906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else {
908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        aliasLists[aliasListsSize++] = aliasList->aliasCount;
909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* write into the array area a 1's based index. */
911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        aliasArrLists[tag*converterCount + converter] = aliasListsSize;
912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*        printf("tag %s converter %s\n",
914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            GET_TAG_STR(tags[tag].tag),
915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            GET_ALIAS_STR(converters[converter].converter));*/
916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (aliasNum = 0; aliasNum < aliasList->aliasCount; aliasNum++) {
917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            uint16_t value;
918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*            printf("   %s\n",
919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                GET_ALIAS_STR(aliasList->aliases[aliasNum]));*/
920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (aliasList->aliases[aliasNum]) {
921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                value = aliasList->aliases[aliasNum] + offset;
922f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
923f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                value = 0;
924f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (tag != 0) { /* Only show the warning when it's not the leftover tag. */
925f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    fprintf(stderr, "%s: warning: tag %s does not have a default alias for %s\n",
926f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            path,
927f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            GET_TAG_STR(tags[tag].tag),
928f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            GET_ALIAS_STR(converters[converter].converter));
929f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
930f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
931f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            aliasLists[aliasListsSize++] = value;
932f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (aliasListsSize >= MAX_LIST_SIZE) {
933f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fprintf(stderr, "%s: error: Too many alias lists\n", path);
934f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                exit(U_BUFFER_OVERFLOW_ERROR);
935f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
936f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
937f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
938f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
939f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
940f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
941f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
942f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)createNormalizedAliasStrings(char *normalizedStrings, const char *origStringBlock, int32_t stringBlockLength) {
943f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t currStrLen;
944f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_memcpy(normalizedStrings, origStringBlock, stringBlockLength);
945f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while ((currStrLen = (int32_t)uprv_strlen(origStringBlock)) < stringBlockLength) {
946f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t currStrSize = currStrLen + 1;
947f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (currStrLen > 0) {
948f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t normStrLen;
949f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ucnv_io_stripForCompare(normalizedStrings, origStringBlock);
950f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            normStrLen = uprv_strlen(normalizedStrings);
951f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (normStrLen > 0) {
952f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                uprv_memset(normalizedStrings + normStrLen, 0, currStrSize - normStrLen);
953f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
954f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
955f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        stringBlockLength -= currStrSize;
956f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        normalizedStrings += currStrSize;
957f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        origStringBlock += currStrSize;
958f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
959f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
960f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
961f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void
962f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)writeAliasTable(UNewDataMemory *out) {
963f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t i, j;
964f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t uniqueAliasesSize;
965f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t aliasOffset = (uint16_t)(tagBlock.top/sizeof(uint16_t));
966f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t *aliasArrLists = (uint16_t *)uprv_malloc(tagCount * converterCount * sizeof(uint16_t));
967f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t *uniqueAliases = (uint16_t *)uprv_malloc(knownAliasesCount * sizeof(uint16_t));
968f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint16_t *uniqueAliasesToConverter = (uint16_t *)uprv_malloc(knownAliasesCount * sizeof(uint16_t));
969f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
970f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    qsort(knownAliases, knownAliasesCount, sizeof(knownAliases[0]), compareAliases);
971f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uniqueAliasesSize = resolveAliases(uniqueAliases, uniqueAliasesToConverter, aliasOffset);
972f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
973f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Array index starts at 1. aliasLists[0] is the size of the lists section. */
974f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    aliasListsSize = 0;
975f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
976f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* write the offsets of all the aliases lists in a 2D array, and create the lists. */
977f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (i = 0; i < tagCount; ++i) {
978f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (j = 0; j < converterCount; ++j) {
979f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            createOneAliasList(aliasArrLists, i, j, aliasOffset);
980f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
981f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
982f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
983f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Write the size of the TOC */
984f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (tableOptions.stringNormalizationType == UCNV_IO_UNNORMALIZED) {
985f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        udata_write32(out, 8);
986f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
987f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else {
988f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        udata_write32(out, 9);
989f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
990f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
991f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Write the sizes of each section */
992f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* All sizes are the number of uint16_t units, not bytes */
993f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_write32(out, converterCount);
994f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_write32(out, tagCount);
995f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_write32(out, uniqueAliasesSize);  /* list of aliases */
996f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_write32(out, uniqueAliasesSize);  /* The preresolved form of mapping an untagged the alias to a converter */
997f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_write32(out, tagCount * converterCount);
998f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_write32(out, aliasListsSize + 1);
999f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_write32(out, sizeof(tableOptions) / sizeof(uint16_t));
1000f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_write32(out, (tagBlock.top + stringBlock.top) / sizeof(uint16_t));
1001f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (tableOptions.stringNormalizationType != UCNV_IO_UNNORMALIZED) {
1002f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        udata_write32(out, (tagBlock.top + stringBlock.top) / sizeof(uint16_t));
1003f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1004f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1005f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* write the table of converters */
1006f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Think of this as the column headers */
1007f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=0; i<converterCount; ++i) {
1008f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        udata_write16(out, (uint16_t)(converters[i].converter + aliasOffset));
1009f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1010f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1011f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* write the table of tags */
1012f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Think of this as the row headers */
1013f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=UCNV_NUM_RESERVED_TAGS; i<tagCount; ++i) {
1014f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        udata_write16(out, tags[i].tag);
1015f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1016f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* The empty tag is considered the leftover list, and put that at the end of the priority list. */
1017f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_write16(out, tags[EMPTY_TAG_NUM].tag);
1018f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_write16(out, tags[ALL_TAG_NUM].tag);
1019f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1020f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Write the unique list of aliases */
1021f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_writeBlock(out, uniqueAliases, uniqueAliasesSize * sizeof(uint16_t));
1022f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1023f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Write the unique list of aliases */
1024f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_writeBlock(out, uniqueAliasesToConverter, uniqueAliasesSize * sizeof(uint16_t));
1025f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1026f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Write the array to the lists */
1027f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_writeBlock(out, (const void *)(aliasArrLists + (2*converterCount)), (((tagCount - 2) * converterCount) * sizeof(uint16_t)));
1028f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Now write the leftover part of the array for the EMPTY and ALL lists */
1029f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_writeBlock(out, (const void *)aliasArrLists, (2 * converterCount * sizeof(uint16_t)));
1030f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1031f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Offset the next array to make the index start at 1. */
1032f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_write16(out, 0xDEAD);
1033f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1034f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Write the lists */
1035f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_writeBlock(out, (const void *)aliasLists, aliasListsSize * sizeof(uint16_t));
1036f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1037f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Write any options for the alias table. */
1038f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_writeBlock(out, (const void *)&tableOptions, sizeof(tableOptions));
1039f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1040f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* write the tags strings */
1041f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_writeString(out, tagBlock.store, tagBlock.top);
1042f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1043f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* write the aliases strings */
1044f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    udata_writeString(out, stringBlock.store, stringBlock.top);
1045f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1046f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* write the normalized aliases strings */
1047f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (tableOptions.stringNormalizationType != UCNV_IO_UNNORMALIZED) {
1048f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        char *normalizedStrings = (char *)uprv_malloc(tagBlock.top + stringBlock.top);
1049f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        createNormalizedAliasStrings(normalizedStrings, tagBlock.store, tagBlock.top);
1050f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        createNormalizedAliasStrings(normalizedStrings + tagBlock.top, stringBlock.store, stringBlock.top);
1051f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1052f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Write out the complete normalized array. */
1053f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        udata_writeString(out, normalizedStrings, tagBlock.top + stringBlock.top);
1054f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free(normalizedStrings);
1055f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1056f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1057f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_free(aliasArrLists);
1058f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_free(uniqueAliases);
1059f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1060f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1061f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static char *
1062f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)allocString(StringBlock *block, const char *s, int32_t length) {
1063f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t top;
1064f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *p;
1065f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1066f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(length<0) {
1067f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        length=(int32_t)uprv_strlen(s);
1068f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1069f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1070f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*
1071f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * add 1 for the terminating NUL
1072f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * and round up (+1 &~1)
1073f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     * to keep the addresses on a 16-bit boundary
1074f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)     */
1075f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    top=block->top + (uint32_t)((length + 1 + 1) & ~1);
1076f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1077f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(top >= block->max) {
1078f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: error: out of memory\n", path, lineNum);
1079f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_MEMORY_ALLOCATION_ERROR);
1080f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1081f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1082f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* get the pointer and copy the string */
1083f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    p = block->store + block->top;
1084f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uprv_memcpy(p, s, length);
1085f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    p[length] = 0; /* NUL-terminate it */
1086f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if((length & 1) == 0) {
1087f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        p[length + 1] = 0; /* set the padding byte */
1088f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1089f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1090f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* check for invariant characters now that we have a NUL-terminated string for easy output */
1091f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(!uprv_isInvariantString(p, length)) {
1092f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fprintf(stderr, "%s:%d: error: the name %s contains not just invariant characters\n", path, lineNum, p);
1093f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        exit(U_INVALID_TABLE_FORMAT);
1094f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1095f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1096f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    block->top = top;
1097f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return p;
1098f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1099f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int
1101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)compareAliases(const void *alias1, const void *alias2) {
1102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* Names like IBM850 and ibm-850 need to be sorted together */
1103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int result = ucnv_compareNames(GET_ALIAS_STR(*(uint16_t*)alias1), GET_ALIAS_STR(*(uint16_t*)alias2));
1104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (!result) {
1105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* Sort the shortest first */
1106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return (int)uprv_strlen(GET_ALIAS_STR(*(uint16_t*)alias1)) - (int)uprv_strlen(GET_ALIAS_STR(*(uint16_t*)alias2));
1107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return result;
1109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
1112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Hey, Emacs, please set the following:
1113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
1114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Local Variables:
1115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * indent-tabs-mode: nil
1116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * End:
1117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *
1118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
1119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1120