1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ********************************************************************************
3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius *   Copyright (C) 1998-2012, International Business Machines
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *   Corporation and others.  All Rights Reserved.
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ********************************************************************************
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *  makeconv.c:
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *  tool creating a binary (compressed) representation of the conversion mapping
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *  table (IBM NLTC ucmap format).
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *  05/04/2000    helena     Added fallback mapping into the picture...
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *  06/29/2000  helena      Major rewrite of the callback APIs.
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h>
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/putil.h"
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ucnv_err.h"
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucnv_bld.h"
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucnv_imp.h"
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucnv_cnv.h"
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h"
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h"
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uinvchar.h"
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "filestrm.h"
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "toolutil.h"
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uoptions.h"
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/udata.h"
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unewdata.h"
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uparse.h"
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucm.h"
34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "makeconv.h"
35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "genmbcs.h"
36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
37c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
38c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define DEBUG 0
40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct ConvData {
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UCMFile *ucm;
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    NewConverter *cnvData, *extData;
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UConverterSharedData sharedData;
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UConverterStaticData staticData;
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} ConvData;
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruinitConvData(ConvData *data) {
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_memset(data, 0, sizeof(ConvData));
51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    data->sharedData.structSize=sizeof(UConverterSharedData);
52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    data->staticData.structSize=sizeof(UConverterStaticData);
53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    data->sharedData.staticData=&data->staticData;
54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void
57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucleanupConvData(ConvData *data) {
58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(data!=NULL) {
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(data->cnvData!=NULL) {
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            data->cnvData->close(data->cnvData);
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            data->cnvData=NULL;
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(data->extData!=NULL) {
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            data->extData->close(data->extData);
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            data->extData=NULL;
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ucm_close(data->ucm);
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        data->ucm=NULL;
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * from ucnvstat.c - static prototypes of data-based converters
74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruextern const UConverterStaticData * ucnv_converterStaticData[UCNV_NUMBER_OF_SUPPORTED_CONVERTER_TYPES];
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Global - verbosity
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool VERBOSE = FALSE;
81c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruUBool SMALL = FALSE;
8250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUBool IGNORE_SISO_CHECK = FALSE;
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucreateConverter(ConvData *data, const char* converterName, UErrorCode *pErrorCode);
86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Set up the UNewData and write the converter..
89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void
91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruwriteConverterData(ConvData *data, const char *cnvName, const char *cnvDir, UErrorCode *status);
92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool haveCopyright=TRUE;
94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UDataInfo dataInfo={
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    sizeof(UDataInfo),
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    0,
98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_IS_BIG_ENDIAN,
100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_CHARSET_FAMILY,
101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    sizeof(UChar),
102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    0,
103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {0x63, 0x6e, 0x76, 0x74},     /* dataFormat="cnvt" */
105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {6, 2, 0, 0},                 /* formatVersion */
106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {0, 0, 0, 0}                  /* dataVersion (calculated at runtime) */
107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void
110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruwriteConverterData(ConvData *data, const char *cnvName, const char *cnvDir, UErrorCode *status)
111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UNewDataMemory *mem = NULL;
113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t sz2;
114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t size = 0;
115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t tableType;
116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(U_FAILURE(*status))
118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      {
119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      }
121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    tableType=TABLE_NONE;
123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(data->cnvData!=NULL) {
124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tableType|=TABLE_BASE;
125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(data->extData!=NULL) {
127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tableType|=TABLE_EXT;
128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    mem = udata_create(cnvDir, "cnv", cnvName, &dataInfo, haveCopyright ? U_COPYRIGHT_STRING : NULL, status);
131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(U_FAILURE(*status))
133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      {
134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fprintf(stderr, "Couldn't create the udata %s.%s: %s\n",
135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                cnvName,
136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                "cnv",
137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                u_errorName(*status));
138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      }
140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(VERBOSE)
142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      {
143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        printf("- Opened udata %s.%s\n", cnvName, "cnv");
144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      }
145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* all read only, clean, platform independent data.  Mmmm. :)  */
148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_writeBlock(mem, &data->staticData, sizeof(UConverterStaticData));
149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    size += sizeof(UConverterStaticData); /* Is 4-aligned  - by size */
150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Now, write the table */
151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(tableType&TABLE_BASE) {
152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        size += data->cnvData->write(data->cnvData, &data->staticData, mem, tableType);
153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(tableType&TABLE_EXT) {
155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        size += data->extData->write(data->extData, &data->staticData, mem, tableType);
156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    sz2 = udata_finish(mem, status);
159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(size != sz2)
160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fprintf(stderr, "error: wrote %u bytes to the .cnv file but counted %u bytes\n", (int)sz2, (int)size);
162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *status=U_INTERNAL_PROGRAM_ERROR;
163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(VERBOSE)
165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      printf("- Wrote %u bytes to the udata.\n", (int)sz2);
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
170c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruenum {
171c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    OPT_HELP_H,
172c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    OPT_HELP_QUESTION_MARK,
173c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    OPT_COPYRIGHT,
174c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    OPT_VERSION,
175c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    OPT_DESTDIR,
176c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    OPT_VERBOSE,
177c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    OPT_SMALL,
17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    OPT_IGNORE_SISO_CHECK,
179c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    OPT_COUNT
180c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru};
181c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UOption options[]={
183c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UOPTION_HELP_H,
184c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UOPTION_HELP_QUESTION_MARK,
185c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UOPTION_COPYRIGHT,
186c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UOPTION_VERSION,
187c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UOPTION_DESTDIR,
188c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UOPTION_VERBOSE,
18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    { "small", NULL, NULL, NULL, '\1', UOPT_NO_ARG, 0 },
19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    { "ignore-siso-check", NULL, NULL, NULL, '\1', UOPT_NO_ARG, 0 }
191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint main(int argc, char* argv[])
194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ConvData data;
196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode err = U_ZERO_ERROR, localError;
197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char outFileName[UCNV_MAX_FULL_FILE_NAME_LENGTH];
198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char* destdir, *arg;
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    size_t destdirlen;
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char* dot = NULL, *outBasename;
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char cnvName[UCNV_MAX_FULL_FILE_NAME_LENGTH];
202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char cnvNameWithPkg[UCNV_MAX_FULL_FILE_NAME_LENGTH];
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UVersionInfo icuVersion;
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool printFilename;
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    err = U_ZERO_ERROR;
207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_MAIN_INIT_ARGS(argc, argv);
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Set up the ICU version number */
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    u_getVersion(icuVersion);
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_memcpy(&dataInfo.dataVersion, &icuVersion, sizeof(UVersionInfo));
213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* preset then read command line options */
215c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    options[OPT_DESTDIR].value=u_getDataDirectory();
216c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    argc=u_parseArgs(argc, argv, LENGTHOF(options), options);
217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* error handling, printing usage message */
219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(argc<0) {
220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fprintf(stderr,
221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            "error in command line argument \"%s\"\n",
222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            argv[-argc]);
223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else if(argc<2) {
224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        argc=-1;
225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
226c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if(argc<0 || options[OPT_HELP_H].doesOccur || options[OPT_HELP_QUESTION_MARK].doesOccur) {
227c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        FILE *stdfile=argc<0 ? stderr : stdout;
228c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        fprintf(stdfile,
229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            "usage: %s [-options] files...\n"
230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            "\tread .ucm codepage mapping files and write .cnv files\n"
231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            "options:\n"
232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            "\t-h or -? or --help  this usage text\n"
233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            "\t-V or --version     show a version message\n"
234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            "\t-c or --copyright   include a copyright notice\n"
235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            "\t-d or --destdir     destination directory, followed by the path\n"
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            "\t-v or --verbose     Turn on verbose output\n",
237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            argv[0]);
238c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        fprintf(stdfile,
239c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            "\t      --small       Generate smaller .cnv files. They will be\n"
240c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            "\t                    significantly smaller but may not be compatible with\n"
241c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            "\t                    older versions of ICU and will require heap memory\n"
24250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "\t                    allocation when loaded.\n"
24350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            "\t      --ignore-siso-check         Use SI/SO other than 0xf/0xe.\n");
244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
247c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if(options[OPT_VERSION].doesOccur) {
24854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        printf("makeconv version %u.%u, ICU tool to read .ucm codepage mapping files and write .cnv files\n",
249c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru               dataInfo.formatVersion[0], dataInfo.formatVersion[1]);
250c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        printf("%s\n", U_COPYRIGHT_STRING);
251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        exit(0);
252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* get the options values */
255c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    haveCopyright = options[OPT_COPYRIGHT].doesOccur;
256c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    destdir = options[OPT_DESTDIR].value;
257c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    VERBOSE = options[OPT_VERBOSE].doesOccur;
258c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    SMALL = options[OPT_SMALL].doesOccur;
259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (options[OPT_IGNORE_SISO_CHECK].doesOccur) {
26150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        IGNORE_SISO_CHECK = TRUE;
26250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
26350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (destdir != NULL && *destdir != 0) {
265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strcpy(outFileName, destdir);
266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        destdirlen = uprv_strlen(destdir);
267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        outBasename = outFileName + destdirlen;
268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (*(outBasename - 1) != U_FILE_SEP_CHAR) {
269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *outBasename++ = U_FILE_SEP_CHAR;
270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ++destdirlen;
271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        destdirlen = 0;
274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        outBasename = outFileName;
275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if DEBUG
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      int i;
280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      printf("makeconv: processing %d files...\n", argc - 1);
281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      for(i=1; i<argc; ++i) {
282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        printf("%s ", argv[i]);
283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      }
284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      printf("\n");
285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      fflush(stdout);
286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    err = U_ZERO_ERROR;
290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    printFilename = (UBool) (argc > 2 || VERBOSE);
291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (++argv; --argc; ++argv)
292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        arg = getLongPathname(*argv);
294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
295c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        /* Check for potential buffer overflow */
29654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if(strlen(arg) >= UCNV_MAX_FULL_FILE_NAME_LENGTH)
297c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        {
298c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            fprintf(stderr, "%s\n", u_errorName(U_BUFFER_OVERFLOW_ERROR));
299c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            return U_BUFFER_OVERFLOW_ERROR;
300c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
301c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*produces the right destination path for display*/
303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (destdirlen != 0)
304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            const char *basename;
306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* find the last file sepator */
308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            basename = findBasename(arg);
309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strcpy(outBasename, basename);
310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else
312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strcpy(outFileName, arg);
314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*removes the extension if any is found*/
317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        dot = uprv_strrchr(outBasename, '.');
318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (dot)
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *dot = '\0';
321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* the basename without extension is the converter name */
324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strcpy(cnvName, outBasename);
325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*Adds the target extension*/
327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strcat(outBasename, CONVERTER_FILE_EXTENSION);
328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if DEBUG
330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        printf("makeconv: processing %s  ...\n", arg);
331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fflush(stdout);
332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        localError = U_ZERO_ERROR;
334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        initConvData(&data);
335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        createConverter(&data, arg, &localError);
336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(localError))
338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* if an error is found, print out an error msg and keep going */
340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fprintf(stderr, "Error creating converter for \"%s\" file for \"%s\" (%s)\n", outFileName, arg,
341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                u_errorName(localError));
342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(U_SUCCESS(err)) {
343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                err = localError;
344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else
347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
348c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            /* Insure the static data name matches the  file name */
349c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            /* Changed to ignore directory and only compare base name
350c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru             LDH 1/2/08*/
351c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            char *p;
352c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            p = strrchr(cnvName, U_FILE_SEP_CHAR); /* Find last file separator */
353c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
354c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            if(p == NULL)            /* OK, try alternate */
355c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            {
356c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                p = strrchr(cnvName, U_FILE_ALT_SEP_CHAR);
357c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                if(p == NULL)
358c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                {
359c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    p=cnvName; /* If no separators, no problem */
360c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                }
361c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            }
362c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            else
363c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            {
364c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                p++;   /* If found separtor, don't include it in compare */
365c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            }
366c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            if(uprv_stricmp(p,data.staticData.name))
367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            {
368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                fprintf(stderr, "Warning: %s%s claims to be '%s'\n",
369c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    cnvName,  CONVERTER_FILE_EXTENSION,
370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    data.staticData.name);
371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strcpy((char*)data.staticData.name, cnvName);
374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(!uprv_isInvariantString((char*)data.staticData.name, -1)) {
376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                fprintf(stderr,
377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    "Error: A converter name must contain only invariant characters.\n"
378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    "%s is not a valid converter name.\n",
379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    data.staticData.name);
380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if(U_SUCCESS(err)) {
381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    err = U_INVALID_TABLE_FORMAT;
382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strcpy(cnvNameWithPkg, cnvName);
386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            localError = U_ZERO_ERROR;
388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            writeConverterData(&data, cnvNameWithPkg, destdir, &localError);
389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(U_FAILURE(localError))
391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            {
392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                /* if an error is found, print out an error msg and keep going*/
393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                fprintf(stderr, "Error writing \"%s\" file for \"%s\" (%s)\n", outFileName, arg,
394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    u_errorName(localError));
395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if(U_SUCCESS(err)) {
396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    err = localError;
397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            else if (printFilename)
400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            {
401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                puts(outBasename);
402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fflush(stdout);
405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fflush(stderr);
406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        cleanupConvData(&data);
408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return err;
411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void
414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerugetPlatformAndCCSIDFromName(const char *name, int8_t *pPlatform, int32_t *pCCSID) {
415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if( (name[0]=='i' || name[0]=='I') &&
416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        (name[1]=='b' || name[1]=='B') &&
417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        (name[2]=='m' || name[2]=='M')
418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ) {
419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        name+=3;
420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(*name=='-') {
421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ++name;
422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *pPlatform=UCNV_IBM;
424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *pCCSID=(int32_t)uprv_strtoul(name, NULL, 10);
425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *pPlatform=UCNV_UNKNOWN;
427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *pCCSID=0;
428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void
432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerureadHeader(ConvData *data,
433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           FileStream* convFile,
434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           const char* converterName,
435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           UErrorCode *pErrorCode) {
436b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    char line[1024];
437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char *s, *key, *value;
438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UConverterStaticData *prototype;
439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UConverterStaticData *staticData;
440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(U_FAILURE(*pErrorCode)) {
442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    staticData=&data->staticData;
446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    staticData->platform=UCNV_IBM;
447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    staticData->subCharLen=0;
448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while(T_FileStream_readLine(convFile, line, sizeof(line))) {
450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* basic parsing and handling of state-related items */
451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(ucm_parseHeaderLine(data->ucm, line, &key, &value)) {
452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            continue;
453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* stop at the beginning of the mapping section */
456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(uprv_strcmp(line, "CHARMAP")==0) {
457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* collect the information from the header field, ignore unknown keys */
461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(uprv_strcmp(key, "code_set_name")==0) {
462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(*value!=0) {
463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                uprv_strcpy((char *)staticData->name, value);
464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                getPlatformAndCCSIDFromName(value, &staticData->platform, &staticData->codepage);
465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else if(uprv_strcmp(key, "subchar")==0) {
467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uint8_t bytes[UCNV_EXT_MAX_BYTES];
468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int8_t length;
469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            s=value;
471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            length=ucm_parseBytes(bytes, line, (const char **)&s);
472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(1<=length && length<=4 && *s==0) {
473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                staticData->subCharLen=length;
474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                uprv_memcpy(staticData->subChar, bytes, length);
475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                fprintf(stderr, "error: illegal <subchar> %s\n", value);
477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                *pErrorCode=U_INVALID_TABLE_FORMAT;
478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return;
479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else if(uprv_strcmp(key, "subchar1")==0) {
481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uint8_t bytes[UCNV_EXT_MAX_BYTES];
482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            s=value;
484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(1==ucm_parseBytes(bytes, line, (const char **)&s) && *s==0) {
485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                staticData->subChar1=bytes[0];
486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                fprintf(stderr, "error: illegal <subchar1> %s\n", value);
488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                *pErrorCode=U_INVALID_TABLE_FORMAT;
489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return;
490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* copy values from the UCMFile to the static data */
495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    staticData->maxBytesPerChar=(int8_t)data->ucm->states.maxCharLength;
496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    staticData->minBytesPerChar=(int8_t)data->ucm->states.minCharLength;
497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    staticData->conversionType=data->ucm->states.conversionType;
498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(staticData->conversionType==UCNV_UNSUPPORTED_CONVERTER) {
500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fprintf(stderr, "ucm error: missing conversion type (<uconv_class>)\n");
501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *pErrorCode=U_INVALID_TABLE_FORMAT;
502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*
506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * Now that we know the type, copy any 'default' values from the table.
507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * We need not check the type any further because the parser only
508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * recognizes what we have prototypes for.
509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     *
510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * For delta (extension-only) tables, copy values from the base file
511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * instead, see createConverter().
512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(data->ucm->baseName[0]==0) {
514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        prototype=ucnv_converterStaticData[staticData->conversionType];
515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(prototype!=NULL) {
516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(staticData->name[0]==0) {
517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                uprv_strcpy((char *)staticData->name, prototype->name);
518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(staticData->codepage==0) {
521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                staticData->codepage=prototype->codepage;
522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(staticData->platform==0) {
525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                staticData->platform=prototype->platform;
526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(staticData->minBytesPerChar==0) {
529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                staticData->minBytesPerChar=prototype->minBytesPerChar;
530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(staticData->maxBytesPerChar==0) {
533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                staticData->maxBytesPerChar=prototype->maxBytesPerChar;
534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(staticData->subCharLen==0) {
537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                staticData->subCharLen=prototype->subCharLen;
538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if(prototype->subCharLen>0) {
539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    uprv_memcpy(staticData->subChar, prototype->subChar, prototype->subCharLen);
540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(data->ucm->states.outputType<0) {
546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        data->ucm->states.outputType=(int8_t)data->ucm->states.maxCharLength-1;
547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if( staticData->subChar1!=0 &&
550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            (staticData->minBytesPerChar>1 ||
551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                (staticData->conversionType!=UCNV_MBCS &&
552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 staticData->conversionType!=UCNV_EBCDIC_STATEFUL))
553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ) {
554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fprintf(stderr, "error: <subchar1> defined for a type other than MBCS or EBCDIC_STATEFUL\n");
555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *pErrorCode=U_INVALID_TABLE_FORMAT;
556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* return TRUE if a base table was read, FALSE for an extension table */
560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool
561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerureadFile(ConvData *data, const char* converterName,
562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         UErrorCode *pErrorCode) {
563b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    char line[1024];
564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char *end;
565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    FileStream *convFile;
566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UCMStates *baseStates;
568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool dataIsBase;
569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(U_FAILURE(*pErrorCode)) {
571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return FALSE;
572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    data->ucm=ucm_open();
575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    convFile=T_FileStream_open(converterName, "r");
577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(convFile==NULL) {
578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *pErrorCode=U_FILE_ACCESS_ERROR;
579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return FALSE;
580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    readHeader(data, convFile, converterName, pErrorCode);
583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(U_FAILURE(*pErrorCode)) {
584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return FALSE;
585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(data->ucm->baseName[0]==0) {
588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        dataIsBase=TRUE;
589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        baseStates=&data->ucm->states;
59050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        ucm_processStates(baseStates, IGNORE_SISO_CHECK);
591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        dataIsBase=FALSE;
593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        baseStates=NULL;
594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* read the base table */
597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ucm_readTable(data->ucm, convFile, dataIsBase, baseStates, pErrorCode);
598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(U_FAILURE(*pErrorCode)) {
599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return FALSE;
600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* read an extension table if there is one */
603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while(T_FileStream_readLine(convFile, line, sizeof(line))) {
604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        end=uprv_strchr(line, 0);
605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        while(line<end &&
606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              (*(end-1)=='\n' || *(end-1)=='\r' || *(end-1)==' ' || *(end-1)=='\t')) {
607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            --end;
608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *end=0;
610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(line[0]=='#' || u_skipWhitespace(line)==end) {
612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            continue; /* ignore empty and comment lines */
613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(0==uprv_strcmp(line, "CHARMAP")) {
616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* read the extension table */
617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ucm_readTable(data->ucm, convFile, FALSE, baseStates, pErrorCode);
618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fprintf(stderr, "unexpected text after the base mapping table\n");
620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        break;
622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    T_FileStream_close(convFile);
625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(data->ucm->base->flagsType==UCM_FLAGS_MIXED || data->ucm->ext->flagsType==UCM_FLAGS_MIXED) {
627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fprintf(stderr, "error: some entries have the mapping precision (with '|'), some do not\n");
628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *pErrorCode=U_INVALID_TABLE_FORMAT;
629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return dataIsBase;
632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void
635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucreateConverter(ConvData *data, const char *converterName, UErrorCode *pErrorCode) {
636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ConvData baseData;
637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool dataIsBase;
638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UConverterStaticData *staticData;
640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UCMStates *states, *baseStates;
641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(U_FAILURE(*pErrorCode)) {
643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    initConvData(data);
647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    dataIsBase=readFile(data, converterName, pErrorCode);
649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(U_FAILURE(*pErrorCode)) {
650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    staticData=&data->staticData;
654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    states=&data->ucm->states;
655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(dataIsBase) {
657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*
658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * Build a normal .cnv file with a base table
659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * and an optional extension table.
660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         */
661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        data->cnvData=MBCSOpen(data->ucm);
662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(data->cnvData==NULL) {
663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else if(!data->cnvData->isValid(data->cnvData,
666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            staticData->subChar, staticData->subCharLen)
667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ) {
668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fprintf(stderr, "       the substitution character byte sequence is illegal in this codepage structure!\n");
669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *pErrorCode=U_INVALID_TABLE_FORMAT;
670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else if(staticData->subChar1!=0 &&
672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    !data->cnvData->isValid(data->cnvData, &staticData->subChar1, 1)
673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ) {
674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fprintf(stderr, "       the subchar1 byte is illegal in this codepage structure!\n");
675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *pErrorCode=U_INVALID_TABLE_FORMAT;
676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else if(
678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            data->ucm->ext->mappingsLength>0 &&
679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            !ucm_checkBaseExt(states, data->ucm->base, data->ucm->ext, data->ucm->ext, FALSE)
680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ) {
681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *pErrorCode=U_INVALID_TABLE_FORMAT;
682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else if(data->ucm->base->flagsType&UCM_FLAGS_EXPLICIT) {
683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* sort the table so that it can be turned into UTF-8-friendly data */
684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ucm_sortTable(data->ucm->base);
685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(U_SUCCESS(*pErrorCode)) {
688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(
689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                /* add the base table after ucm_checkBaseExt()! */
690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                !data->cnvData->addTable(data->cnvData, data->ucm->base, &data->staticData)
691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ) {
692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                *pErrorCode=U_INVALID_TABLE_FORMAT;
693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                /*
695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 * addTable() may have requested moving more mappings to the extension table
696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 * if they fit into the base toUnicode table but not into the
697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 * base fromUnicode table.
698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 * (Especially for UTF-8-friendly fromUnicode tables.)
699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 * Such mappings will have the MBCS_FROM_U_EXT_FLAG set, which causes them
700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 * to be excluded from the extension toUnicode data.
701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 * See MBCSOkForBaseFromUnicode() for which mappings do not fit into
702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 * the base fromUnicode table.
703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 */
704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                ucm_moveMappings(data->ucm->base, data->ucm->ext);
705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                ucm_sortTable(data->ucm->ext);
706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if(data->ucm->ext->mappingsLength>0) {
707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    /* prepare the extension table, if there is one */
708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    data->extData=CnvExtOpen(data->ucm);
709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if(data->extData==NULL) {
710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else if(
712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        !data->extData->addTable(data->extData, data->ucm->ext, &data->staticData)
713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    ) {
714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        *pErrorCode=U_INVALID_TABLE_FORMAT;
715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* Build an extension-only .cnv file. */
721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        char baseFilename[500];
722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        char *basename;
723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        initConvData(&baseData);
725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* assemble a path/filename for data->ucm->baseName */
727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strcpy(baseFilename, converterName);
728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        basename=(char *)findBasename(baseFilename);
729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strcpy(basename, data->ucm->baseName);
730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strcat(basename, ".ucm");
731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* read the base table */
733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        dataIsBase=readFile(&baseData, baseFilename, pErrorCode);
734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(U_FAILURE(*pErrorCode)) {
735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return;
736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else if(!dataIsBase) {
737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fprintf(stderr, "error: the <icu:base> file \"%s\" is not a base table file\n", baseFilename);
738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *pErrorCode=U_INVALID_TABLE_FORMAT;
739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* prepare the extension table */
741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            data->extData=CnvExtOpen(data->ucm);
742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(data->extData==NULL) {
743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                /* fill in gaps in extension file header fields */
746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                UCMapping *m, *mLimit;
747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                uint8_t fallbackFlags;
748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                baseStates=&baseData.ucm->states;
750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if(states->conversionType==UCNV_DBCS) {
751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    staticData->minBytesPerChar=(int8_t)(states->minCharLength=2);
752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else if(states->minCharLength==0) {
753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    staticData->minBytesPerChar=(int8_t)(states->minCharLength=baseStates->minCharLength);
754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if(states->maxCharLength<states->minCharLength) {
756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    staticData->maxBytesPerChar=(int8_t)(states->maxCharLength=baseStates->maxCharLength);
757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if(staticData->subCharLen==0) {
760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    uprv_memcpy(staticData->subChar, baseData.staticData.subChar, 4);
761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    staticData->subCharLen=baseData.staticData.subCharLen;
762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                /*
764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 * do not copy subChar1 -
765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 * only use what is explicitly specified
766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 * because it cannot be unset in the extension file header
767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 */
768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                /* get the fallback flags */
770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                fallbackFlags=0;
771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                for(m=baseData.ucm->base->mappings, mLimit=m+baseData.ucm->base->mappingsLength;
772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    m<mLimit && fallbackFlags!=3;
773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    ++m
774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                ) {
775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if(m->f==1) {
776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        fallbackFlags|=1;
777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else if(m->f==3) {
778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        fallbackFlags|=2;
779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if(fallbackFlags&1) {
783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    staticData->hasFromUnicodeFallback=TRUE;
784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if(fallbackFlags&2) {
786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    staticData->hasToUnicodeFallback=TRUE;
787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if(1!=ucm_countChars(baseStates, staticData->subChar, staticData->subCharLen)) {
790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    fprintf(stderr, "       the substitution character byte sequence is illegal in this codepage structure!\n");
791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    *pErrorCode=U_INVALID_TABLE_FORMAT;
792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
79350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                } else if(staticData->subChar1!=0 && 1!=ucm_countChars(baseStates, &staticData->subChar1, 1)) {
794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    fprintf(stderr, "       the subchar1 byte is illegal in this codepage structure!\n");
795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    *pErrorCode=U_INVALID_TABLE_FORMAT;
796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else if(
798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    !ucm_checkValidity(data->ucm->ext, baseStates) ||
799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    !ucm_checkBaseExt(baseStates, baseData.ucm->base, data->ucm->ext, data->ucm->ext, FALSE)
800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                ) {
801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    *pErrorCode=U_INVALID_TABLE_FORMAT;
802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else {
803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if(states->maxCharLength>1) {
804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        /*
805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         * When building a normal .cnv file with a base table
806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         * for an MBCS (not SBCS) table with explicit precision flags,
807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         * the MBCSAddTable() function marks some mappings for moving
808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         * to the extension table.
809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         * They fit into the base toUnicode table but not into the
810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         * base fromUnicode table.
811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         * (Note: We do have explicit precision flags because they are
812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         * required for extension table generation, and
813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         * ucm_checkBaseExt() verified it.)
814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         *
815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         * We do not call MBCSAddTable() here (we probably could)
816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         * so we need to do the analysis before building the extension table.
817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         * We assume that MBCSAddTable() will build a UTF-8-friendly table.
818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         * Redundant mappings in the extension table are ok except they cost some size.
819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         *
820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         * Do this after ucm_checkBaseExt().
821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                         */
822c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                        const MBCSData *mbcsData=MBCSGetDummy();
823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        int32_t needsMove=0;
824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        for(m=baseData.ucm->base->mappings, mLimit=m+baseData.ucm->base->mappingsLength;
825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            m<mLimit;
826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            ++m
827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        ) {
828c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                            if(!MBCSOkForBaseFromUnicode(mbcsData, m->b.bytes, m->bLen, m->u, m->f)) {
829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                m->f|=MBCS_FROM_U_EXT_FLAG;
830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                m->moveFlag=UCM_MOVE_TO_EXT;
831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                ++needsMove;
832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if(needsMove!=0) {
836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            ucm_moveMappings(baseData.ucm->base, data->ucm->ext);
837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            ucm_sortTable(data->ucm->ext);
838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if(!data->extData->addTable(data->extData, data->ucm->ext, &data->staticData)) {
841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        *pErrorCode=U_INVALID_TABLE_FORMAT;
842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        cleanupConvData(&baseData);
848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Hey, Emacs, please set the following:
853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Local Variables:
855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * indent-tabs-mode: nil
856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * End:
857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
859