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