2
*******************************************************************************
4
* Copyright (C) 2000-2001, International Business Machines
5
* Corporation and others. All Rights Reserved.
7
*******************************************************************************
8
* file name: genuca.cpp
10
* tab size: 8 (not used)
13
* created at the end of XX century
14
* created by: Vladimir Weinstein
16
* This program reads the Franctional UCA table and generates
17
* internal format for UCA table as well as inverse UCA table.
18
* It then writes binary files containing the data: ucadata.dat
21
* 02/23/2001 grhoten Made it into a tool
22
* 02/23/2001 weiv Moved element & table handling code to i18n
23
* 05/09/2001 weiv Case bits are now in the CEs, not in front
38
UBool VERBOSE = FALSE;
40
int32_t readElement(char **from, char *to, char separator, UErrorCode *status) {
41
if(U_FAILURE(*status)) {
46
while(**from != separator) {
48
*(buffer+i++) = **from;
54
//*to = (char *)malloc(strlen(buffer)+1);
60
uint32_t getSingleCEValue(char *primary, char *secondary, char *tertiary, UErrorCode *status) {
61
if(U_FAILURE(*status)) {
68
char *primend = primary+4;
69
if(strlen(primary) > 4) {
73
char *secend = secondary+2;
74
if(strlen(secondary) > 2) {
78
char *terend = tertiary+2;
79
if(strlen(tertiary) > 2) {
83
uint32_t primvalue = (uint32_t)((*primary!='\0')?strtoul(primary, &primend, 16):0);
84
uint32_t secvalue = (uint32_t)((*secondary!='\0')?strtoul(secondary, &secend, 16):0);
85
uint32_t tervalue = (uint32_t)((*tertiary!='\0')?strtoul(tertiary, &terend, 16):0);
86
if(primvalue <= 0xFF) {
90
value = ((primvalue<<UCOL_PRIMARYORDERSHIFT)&UCOL_PRIMARYORDERMASK)|
91
((secvalue<<UCOL_SECONDARYORDERSHIFT)&UCOL_SECONDARYORDERMASK)|
92
(tervalue&UCOL_TERTIARYORDERMASK);
106
static uint32_t inverseTable[0xFFFF][3];
107
static uint32_t inversePos = 0;
108
static UChar stringContinue[0xFFFF];
109
static uint32_t sContPos = 0;
111
static void addNewInverse(UCAElements *element, UErrorCode *status) {
112
if(U_FAILURE(*status)) {
115
if(VERBOSE && isContinuation(element->CEs[1])) {
116
//fprintf(stdout, "+");
119
inverseTable[inversePos][0] = element->CEs[0];
120
if(element->noOfCEs > 1 && isContinuation(element->CEs[1])) {
121
inverseTable[inversePos][1] = element->CEs[1];
123
inverseTable[inversePos][1] = 0;
125
if(element->cSize < 2) {
126
inverseTable[inversePos][2] = element->cPoints[0];
127
} else { /* add a new store of cruft */
128
inverseTable[inversePos][2] = ((element->cSize+1) << UCOL_INV_SHIFTVALUE) | sContPos;
129
memcpy(stringContinue+sContPos, element->cPoints, element->cSize*sizeof(UChar));
130
sContPos += element->cSize+1;
134
static void insertInverse(UCAElements *element, uint32_t position, UErrorCode *status) {
137
if(U_FAILURE(*status)) {
141
if(VERBOSE && isContinuation(element->CEs[1])) {
142
//fprintf(stdout, "+");
144
if(position <= inversePos) {
145
/*move stuff around */
146
uprv_memcpy(space, inverseTable[position], (inversePos - position+1)*sizeof(inverseTable[0]));
147
uprv_memcpy(inverseTable[position+1], space, (inversePos - position+1)*sizeof(inverseTable[0]));
149
inverseTable[position][0] = element->CEs[0];
150
if(element->noOfCEs > 1 && isContinuation(element->CEs[1])) {
151
inverseTable[position][1] = element->CEs[1];
153
inverseTable[position][1] = 0;
155
if(element->cSize < 2) {
156
inverseTable[position][2] = element->cPoints[0];
157
} else { /* add a new store of cruft */
158
inverseTable[position][2] = ((element->cSize+1) << UCOL_INV_SHIFTVALUE) | sContPos;
159
memcpy(stringContinue+sContPos, element->cPoints, element->cSize*sizeof(UChar));
160
sContPos += element->cSize+1;
165
static void addToExistingInverse(UCAElements *element, uint32_t position, UErrorCode *status) {
167
if(U_FAILURE(*status)) {
171
if((inverseTable[position][2] & UCOL_INV_SIZEMASK) == 0) { /* single element, have to make new extension place and put both guys there */
172
stringContinue[sContPos] = (UChar)inverseTable[position][2];
173
inverseTable[position][2] = ((element->cSize+3) << UCOL_INV_SHIFTVALUE) | sContPos;
175
stringContinue[sContPos++] = 0xFFFF;
176
memcpy(stringContinue+sContPos, element->cPoints, element->cSize*sizeof(UChar));
177
sContPos += element->cSize;
178
stringContinue[sContPos++] = 0xFFFE;
179
} else { /* adding to the already existing continuing table */
180
uint32_t contIndex = inverseTable[position][2] & UCOL_INV_OFFSETMASK;
181
uint32_t contSize = (inverseTable[position][2] & UCOL_INV_SIZEMASK) >> UCOL_INV_SHIFTVALUE;
183
if(contIndex+contSize < sContPos) {
184
/*fprintf(stderr, ".", sContPos, contIndex+contSize);*/
185
memcpy(stringContinue+contIndex+contSize+element->cSize+1, stringContinue+contIndex+contSize, (element->cSize+1)*sizeof(UChar));
188
stringContinue[contIndex+contSize-1] = 0xFFFF;
189
memcpy(stringContinue+contIndex+contSize, element->cPoints, element->cSize*sizeof(UChar));
190
sContPos += element->cSize+1;
191
stringContinue[contIndex+contSize+element->cSize] = 0xFFFE;
193
inverseTable[position][2] = ((contSize+element->cSize+1) << UCOL_INV_SHIFTVALUE) | contIndex;
197
static uint32_t addToInverse(UCAElements *element, UErrorCode *status) {
199
uint32_t position = inversePos;
200
uint32_t saveElement = element->CEs[0];
201
element->CEs[0] &= 0xFFFFFF3F;
202
if(element->noOfCEs == 1) {
205
if(inversePos == 0) {
206
inverseTable[0][0] = inverseTable[0][1] = inverseTable[0][2] = 0;
207
addNewInverse(element, status);
208
} else if(inverseTable[inversePos][0] > element->CEs[0]) {
209
while(inverseTable[--position][0] > element->CEs[0]) {}
210
if(inverseTable[position][0] == element->CEs[0]) {
211
if(isContinuation(element->CEs[1])) {
212
comp = element->CEs[1];
216
if(inverseTable[position][1] > comp) {
217
while(inverseTable[--position][1] > comp) {}
219
if(inverseTable[position][1] == comp) {
220
addToExistingInverse(element, position, status);
222
insertInverse(element, position+1, status);
225
insertInverse(element, position+1, status);
227
} else if(inverseTable[inversePos][0] == element->CEs[0]) {
228
if(element->noOfCEs > 1 && isContinuation(element->CEs[1])) {
229
comp = element->CEs[1];
230
if(inverseTable[position][1] > comp) {
231
while(inverseTable[--position][1] > comp) {}
233
if(inverseTable[position][1] == comp) {
234
addToExistingInverse(element, position, status);
236
insertInverse(element, position+1, status);
239
addToExistingInverse(element, inversePos, status);
242
addNewInverse(element, status);
244
element->CEs[0] = saveElement;
248
static InverseTableHeader *assembleInverseTable(UErrorCode *status)
250
InverseTableHeader *result = NULL;
251
uint32_t headerByteSize = paddedsize(sizeof(InverseTableHeader));
252
uint32_t inverseTableByteSize = (inversePos+2)*sizeof(uint32_t)*3;
253
uint32_t contsByteSize = sContPos * sizeof(UChar);
256
result = (InverseTableHeader *)uprv_malloc(headerByteSize + inverseTableByteSize + contsByteSize);
258
result->byteSize = headerByteSize + inverseTableByteSize + contsByteSize;
261
inverseTable[inversePos][0] = 0xFFFFFFFF;
262
inverseTable[inversePos][1] = 0xFFFFFFFF;
263
inverseTable[inversePos][2] = 0x0000FFFF;
266
for(i = 2; i<inversePos; i++) {
267
if(inverseTable[i-1][0] > inverseTable[i][0]) {
268
fprintf(stderr, "Error at %i: %08X & %08X\n", i, inverseTable[i-1][0], inverseTable[i][0]);
269
} else if(inverseTable[i-1][0] == inverseTable[i][0] && !(inverseTable[i-1][1] < inverseTable[i][1])) {
270
fprintf(stderr, "Continuation error at %i: %08X %08X & %08X %08X\n", i, inverseTable[i-1][0], inverseTable[i-1][1], inverseTable[i][0], inverseTable[i][1]);
274
result->tableSize = inversePos;
275
result->contsSize = sContPos;
277
result->table = headerByteSize;
278
result->conts = headerByteSize + inverseTableByteSize;
280
memcpy((uint8_t *)result + result->table, inverseTable, inverseTableByteSize);
281
memcpy((uint8_t *)result + result->conts, stringContinue, contsByteSize);
284
*status = U_MEMORY_ALLOCATION_ERROR;
292
static void writeOutInverseData(InverseTableHeader *data,
293
const char *outputDir,
294
const char *copyright,
297
UNewDataMemory *pData;
301
pData=udata_create(outputDir, INVC_DATA_TYPE, INVC_DATA_NAME, &invUcaDataInfo,
304
if(U_FAILURE(*status)) {
305
fprintf(stderr, "Error: unable to create data memory, error %d\n", *status);
309
/* write the data to the file */
311
fprintf(stdout, "Writing out inverse UCA table: %s%c%s.%s\n", outputDir, U_FILE_SEP_CHAR,
315
udata_writeBlock(pData, data, data->byteSize);
318
dataLength=udata_finish(pData, status);
319
if(U_FAILURE(*status)) {
320
fprintf(stderr, "Error: error %d writing the output file\n", *status);
327
static int32_t hex2num(char hex) {
328
if(hex>='0' && hex <='9') {
330
} else if(hex>='a' && hex<='f') {
332
} else if(hex>='A' && hex<='F') {
339
UCAElements *readAnElement(FILE *data, UErrorCode *status) {
340
char buffer[2048], primary[100], secondary[100], tertiary[100];
341
UBool detectedContraction;
343
unsigned int theValue;
344
char *pointer = NULL;
345
char *commentStart = NULL;
346
char *startCodePoint = NULL;
347
char *endCodePoint = NULL;
348
char *spacePointer = NULL;
349
char *result = fgets(buffer, 2048, data);
350
if(U_FAILURE(*status)) {
353
*primary = *secondary = *tertiary = '\0';
358
fprintf(stderr, "empty line but no EOF!\n");
359
*status = U_INVALID_FORMAT_ERROR;
363
if(buffer[0] == '#' || buffer[0] == '\n') {
364
return NULL; // just a comment, skip whole line
367
UCAElements *element = ≤ //(UCAElements *)malloc(sizeof(UCAElements));
369
if(buffer[0] == '[') {
370
const char *vt = "[variable top = ";
371
uint32_t vtLen = uprv_strlen(vt);
372
if(uprv_strncmp(buffer, vt, vtLen) == 0) {
373
element->variableTop = TRUE;
374
if(sscanf(buffer+vtLen, "%4x", &theValue) != 1) /* read first code point */
376
fprintf(stderr, " scanf(hex) failed!\n ");
378
element->cPoints[0] = (UChar)theValue;
379
return element; // just a comment, skip whole line
381
*status = U_INVALID_FORMAT_ERROR;
385
element->variableTop = FALSE;
387
startCodePoint = buffer;
388
endCodePoint = strchr(startCodePoint, ';');
390
if(endCodePoint == 0) {
391
fprintf(stderr, "error - line with no code point!\n");
392
*status = U_INVALID_FORMAT_ERROR; /* No code point - could be an error, but probably only an empty line */
398
if(element != NULL) {
399
memset(element, 0, sizeof(*element));
401
*status = U_MEMORY_ALLOCATION_ERROR;
405
element->cPoints = element->uchars;
407
spacePointer = strchr(buffer, ' ');
408
if(sscanf(buffer, "%4x", &theValue) != 1) /* read first code point */
410
fprintf(stderr, " scanf(hex) failed!\n ");
412
element->cPoints[0] = (UChar)theValue;
414
if(spacePointer == 0) {
415
detectedContraction = FALSE;
419
detectedContraction = TRUE;
420
while(spacePointer != NULL) {
421
sscanf(spacePointer+1, "%4x", &theValue);
422
element->cPoints[i++] = (UChar)theValue;
423
spacePointer = strchr(spacePointer+1, ' ');
428
//fprintf(stderr, "Number of codepoints in contraction: %i\n", i);
431
startCodePoint = endCodePoint+1;
433
commentStart = strchr(startCodePoint, '#');
434
if(commentStart == NULL) {
435
commentStart = strlen(startCodePoint) + startCodePoint - 1;
439
uint32_t CEindex = 0;
440
element->noOfCEs = 0;
442
endCodePoint = strchr(startCodePoint, ']');
443
if(endCodePoint == NULL || endCodePoint >= commentStart) {
446
pointer = strchr(startCodePoint, '[');
449
element->sizePrim[i]=readElement(&pointer, primary, ',', status);
450
element->sizeSec[i]=readElement(&pointer, secondary, ',', status);
451
element->sizeTer[i]=readElement(&pointer, tertiary, ']', status);
454
/* I want to get the CEs entered right here, including continuation */
455
element->CEs[CEindex++] = getSingleCEValue(primary, secondary, tertiary, status);
458
while(2*CEi<element->sizePrim[i] || CEi<element->sizeSec[i] || CEi<element->sizeTer[i]) {
459
uint32_t value = UCOL_CONTINUATION_MARKER; /* Continuation marker */
460
if(2*CEi<element->sizePrim[i]) {
461
value |= ((hex2num(*(primary+4*CEi))&0xF)<<28);
462
value |= ((hex2num(*(primary+4*CEi+1))&0xF)<<24);
465
if(2*CEi+1<element->sizePrim[i]) {
466
value |= ((hex2num(*(primary+4*CEi+2))&0xF)<<20);
467
value |= ((hex2num(*(primary+4*CEi+3))&0xF)<<16);
470
if(CEi<element->sizeSec[i]) {
471
value |= ((hex2num(*(secondary+2*CEi))&0xF)<<12);
472
value |= ((hex2num(*(secondary+2*CEi+1))&0xF)<<8);
475
if(CEi<element->sizeTer[i]) {
476
value |= ((hex2num(*(tertiary+2*CEi))&0x3)<<4);
477
value |= (hex2num(*(tertiary+2*CEi+1))&0xF);
482
element->CEs[CEindex++] = value;
485
startCodePoint = endCodePoint+1;
488
element->noOfCEs = CEindex;
490
element->isThai = UCOL_ISTHAIPREVOWEL(element->cPoints[0]);
492
// we don't want any strange stuff after useful data!
493
while(pointer < commentStart) {
494
if(*pointer != ' ') {
495
*status=U_INVALID_FORMAT_ERROR;
501
if(U_FAILURE(*status)) {
502
fprintf(stderr, "problem putting stuff in hash table\n");
503
*status = U_INTERNAL_PROGRAM_ERROR;
511
void writeOutData(UCATableHeader *data,
512
UChar contractions[][3],
513
uint32_t noOfcontractions,
514
const char *outputDir,
515
const char *copyright,
518
if(U_FAILURE(*status)) {
522
uint32_t size = data->size;
524
if(noOfcontractions != 0) {
525
contractions[noOfcontractions][0] = 0;
526
contractions[noOfcontractions][1] = 0;
527
contractions[noOfcontractions][2] = 0;
531
data->contractionUCACombos = size;
532
data->size += paddedsize((noOfcontractions*3*sizeof(UChar)));
535
UNewDataMemory *pData;
539
pData=udata_create(outputDir, UCA_DATA_TYPE, UCA_DATA_NAME, &ucaDataInfo,
542
if(U_FAILURE(*status)) {
543
fprintf(stderr, "Error: unable to create data memory, error %d\n", *status);
547
/* write the data to the file */
549
fprintf(stdout, "Writing out UCA table: %s%c%s.%s\n", outputDir,
554
udata_writeBlock(pData, data, size);
556
if(noOfcontractions != 0) {
557
udata_writeBlock(pData, contractions, noOfcontractions*3*sizeof(UChar));
558
udata_writePadding(pData, paddedsize((noOfcontractions*3*sizeof(UChar))) - noOfcontractions*3*sizeof(uint16_t));
562
dataLength=udata_finish(pData, status);
563
if(U_FAILURE(*status)) {
564
fprintf(stderr, "Error: error %d writing the output file\n", *status);
570
write_uca_table(const char *filename,
571
const char *outputDir,
572
const char *copyright,
575
FILE *data = fopen(filename, "r");
577
UCAElements *element = NULL;
578
UChar variableTopValue = 0;
579
UCATableHeader *myD = (UCATableHeader *)uprv_malloc(sizeof(UCATableHeader));
580
UColOptionSet *opts = (UColOptionSet *)uprv_malloc(sizeof(UColOptionSet));
581
UChar contractionCEs[256][3];
582
uint32_t noOfContractions = 0;
586
fprintf(stderr, "Couldn't open file: %s\n", filename);
590
memset(inverseTable, 0xDA, sizeof(int32_t)*3*0xFFFF);
592
opts->variableTopValue = variableTopValue;
593
opts->strength = UCOL_TERTIARY;
594
opts->frenchCollation = UCOL_OFF;
595
opts->alternateHandling = UCOL_NON_IGNORABLE; /* attribute for handling variable elements*/
596
opts->caseFirst = UCOL_OFF; /* who goes first, lower case or uppercase */
597
opts->caseLevel = UCOL_OFF; /* do we have an extra case level */
598
opts->normalizationMode = UCOL_OFF; /* attribute for normalization */
599
opts->hiraganaQ = UCOL_OFF; /* attribute for JIS X 4061, used only in Japanese */
600
/* populate the version info struct with version info*/
601
myD->version[0] = UCOL_BUILDER_VERSION;
602
/*TODO:The fractional rules version should be taken from FractionalUCA.txt*/
603
myD->version[1] = UCOL_FRACTIONAL_UCA_VERSION;
604
myD->jamoSpecial = FALSE;
606
tempUCATable *t = uprv_uca_initTempTable(myD, opts, NULL, IMPLICIT_TAG, status);
611
*****************************************************************************************
612
* NON_CHARACTER FDD0 - FDEF, FFFE, FFFF, 1FFFE, 1FFFF, 2FFFE, 2FFFF,...e.g. **FFFE, **FFFF
613
******************************************************************************************
625
{0xAC00, 0xD7AF, UCOL_SPECIAL_FLAG | (HANGUL_SYLLABLE_TAG << 24) }, //0 HANGUL_SYLLABLE_TAG,/* AC00-D7AF*/
626
{0xD800, 0xDBFF, UCOL_SPECIAL_FLAG | (LEAD_SURROGATE_TAG << 24) }, //1 LEAD_SURROGATE_TAG, /* D800-DBFF*/
627
{0xDC00, 0xDFFF, UCOL_SPECIAL_FLAG | (TRAIL_SURROGATE_TAG << 24) }, //2 TRAIL_SURROGATE DC00-DFFF
628
{0x3400, 0x4DB5, UCOL_SPECIAL_FLAG | (CJK_IMPLICIT_TAG << 24) }, //3 CJK_IMPLICIT_TAG, /* 0x3400-0x4DB5*/
629
{0x4E00, 0x9FA5, UCOL_SPECIAL_FLAG | (CJK_IMPLICIT_TAG << 24) }, //4 CJK_IMPLICIT_TAG, /* 0x4E00-0x9FA5*/
630
{0xF900, 0xFA2D, UCOL_SPECIAL_FLAG | (CJK_IMPLICIT_TAG << 24) }, //5 CJK_IMPLICIT_TAG, /* 0xF900-0xFA2D*/
631
{0x20000, 0x2A6D6, UCOL_SPECIAL_FLAG | (CJK_IMPLICIT_TAG << 24) }, //6 CJK_IMPLICIT_TAG, /* 0x20000-0x2A6D6*/
632
{0x2F800, 0x2FA1D, UCOL_SPECIAL_FLAG | (CJK_IMPLICIT_TAG << 24) }, //7 CJK_IMPLICIT_TAG, /* 0x2F800-0x2FA1D*/
634
{0xAC00, 0xD7B0, UCOL_SPECIAL_FLAG | (HANGUL_SYLLABLE_TAG << 24) }, //0 HANGUL_SYLLABLE_TAG,/* AC00-D7AF*/
635
{0xD800, 0xDC00, UCOL_SPECIAL_FLAG | (LEAD_SURROGATE_TAG << 24) }, //1 LEAD_SURROGATE_TAG, /* D800-DBFF*/
636
{0xDC00, 0xE000, UCOL_SPECIAL_FLAG | (TRAIL_SURROGATE_TAG << 24) }, //2 TRAIL_SURROGATE DC00-DFFF
637
{0x3400, 0x4DB6, UCOL_SPECIAL_FLAG | (CJK_IMPLICIT_TAG << 24) }, //3 CJK_IMPLICIT_TAG, /* 0x3400-0x4DB5*/
638
{0x4E00, 0x9FA6, UCOL_SPECIAL_FLAG | (CJK_IMPLICIT_TAG << 24) }, //4 CJK_IMPLICIT_TAG, /* 0x4E00-0x9FA5*/
639
{0xF900, 0xFA2E, UCOL_SPECIAL_FLAG | (CJK_IMPLICIT_TAG << 24) }, //5 CJK_IMPLICIT_TAG, /* 0xF900-0xFA2D*/
640
//{0x20000, 0x2A6D7, UCOL_SPECIAL_FLAG | (CJK_IMPLICIT_TAG << 24) }, //6 CJK_IMPLICIT_TAG, /* 0x20000-0x2A6D6*/
641
//{0x2F800, 0x2FA1E, UCOL_SPECIAL_FLAG | (CJK_IMPLICIT_TAG << 24) }, //7 CJK_IMPLICIT_TAG, /* 0x2F800-0x2FA1D*/
645
for(i = 0; i<sizeof(ranges)/sizeof(ranges[0]); i++) {
646
/*ucmpe32_setRange32(t->mapping, ranges[i].start, ranges[i].end, ranges[i].value); */
647
utrie_setRange32(t->mapping, ranges[i].start, ranges[i].end, ranges[i].value, TRUE);
651
int32_t surrogateCount = 0;
653
if(U_FAILURE(*status)) {
654
fprintf(stderr, "Something returned an error %i (%s) while processing line %i of %s. Exiting...\n",
655
*status, u_errorName(*status), line, filename);
659
element = readAnElement(data, status);
661
if(element != NULL) {
662
// we have read the line, now do something sensible with the read data!
663
if(element->variableTop == TRUE && variableTopValue == 0) {
664
t->options->variableTopValue = element->cPoints[0];
667
// if element is a contraction, we want to add it to contractions
668
if(element->cSize > 1) { // this is a contraction
669
if(UTF_IS_LEAD(element->cPoints[0]) && UTF_IS_TRAIL(element->cPoints[1]) && element->cSize == 2) {
672
contractionCEs[noOfContractions][0] = element->cPoints[0];
673
contractionCEs[noOfContractions][1] = element->cPoints[1];
674
if(element->cSize > 2) { // the third one
675
contractionCEs[noOfContractions][2] = element->cPoints[2];
677
contractionCEs[noOfContractions][2] = 0;
683
/* we're first adding to inverse, because addAnElement will reverse the order */
684
/* of code points and stuff... we don't want that to happen */
685
addToInverse(element, status);
686
uprv_uca_addAnElement(t, element, status);
692
fprintf(stdout, "\nLines read: %i\n", line);
693
fprintf(stdout, "Surrogate count: %i\n", surrogateCount);
694
fprintf(stdout, "Raw data breakdown:\n");
695
/*fprintf(stdout, "Compact array stage1 top: %i, stage2 top: %i\n", t->mapping->stage1Top, t->mapping->stage2Top);*/
696
fprintf(stdout, "Number of contractions: %i\n", noOfContractions);
697
fprintf(stdout, "Contraction image size: %i\n", t->image->contractionSize);
698
fprintf(stdout, "Expansions size: %i\n", t->expansions->position);
702
UCATableHeader *myData = uprv_uca_assembleTable(t, status);
705
fprintf(stdout, "Compacted data breakdown:\n");
706
/*fprintf(stdout, "Compact array stage1 top: %i, stage2 top: %i\n", t->mapping->stage1Top, t->mapping->stage2Top);*/
707
fprintf(stdout, "Number of contractions: %i\n", noOfContractions);
708
fprintf(stdout, "Contraction image size: %i\n", t->image->contractionSize);
709
fprintf(stdout, "Expansions size: %i\n", t->expansions->position);
712
writeOutData(myData, contractionCEs, noOfContractions, outputDir, copyright, status);
714
InverseTableHeader *inverse = assembleInverseTable(status);
715
writeOutInverseData(inverse, outputDir, copyright, status);
717
uprv_uca_closeTempTable(t);
729
static UOption options[]={
730
UOPTION_HELP_H, /* 0 Numbers for those who*/
731
UOPTION_HELP_QUESTION_MARK, /* 1 can't count. */
732
UOPTION_COPYRIGHT, /* 2 */
733
UOPTION_VERSION, /* 3 */
734
UOPTION_DESTDIR, /* 4 */
735
UOPTION_SOURCEDIR, /* 5 */
736
UOPTION_VERBOSE, /* 6 */
737
UOPTION_ICUDATADIR /* 7 */
738
/* weiv can't count :))))) */
741
int main(int argc, char* argv[]) {
742
UErrorCode status = U_ZERO_ERROR;
743
const char* destdir = NULL;
744
const char* srcDir = NULL;
746
char *basename = NULL;
747
const char *copyright = NULL;
749
U_MAIN_INIT_ARGS(argc, argv);
751
/* preset then read command line options */
752
options[4].value=u_getDataDirectory();
754
argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options);
756
/* error handling, printing usage message */
759
"error in command line argument \"%s\"\n",
764
if(options[0].doesOccur || options[1].doesOccur) {
766
"usage: %s [-options] file\n"
767
"\tRead in UCA collation text data and write out the binary collation data\n"
769
"\t-h or -? or --help this usage text\n"
770
"\t-V or --version show a version message\n"
771
"\t-c or --copyright include a copyright notice\n"
772
"\t-d or --destdir destination directory, followed by the path\n"
773
"\t-s or --sourcedir source directory, followed by the path\n"
774
"\t-v or --verbose turn on verbose output\n"
775
"\t-i or --icudatadir directory for locating any needed intermediate data files,\n"
776
"\t followed by path, defaults to %s\n",
777
argv[0], u_getDataDirectory());
778
return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
781
if(options[3].doesOccur) {
782
fprintf(stdout, "genuca version %hu.%hu, ICU tool to read UCA text data and create UCA data tables for collation.\n",
783
ucaDataInfo.formatVersion[0], ucaDataInfo.formatVersion[1]);
784
fprintf(stdout, "Copyright (C) 2000-2001, International Business Machines\n");
785
fprintf(stdout, "Corporation and others. All Rights Reserved.\n");
789
/* get the options values */
790
destdir = options[4].value;
791
srcDir = options[5].value;
792
VERBOSE = options[6].doesOccur;
794
if (options[2].doesOccur) {
795
copyright = U_COPYRIGHT_STRING;
798
if (options[7].doesOccur) {
799
u_setDataDirectory(options[7].value);
802
/* prepare the filename beginning with the source dir */
803
uprv_strcpy(filename, srcDir);
804
basename=filename+uprv_strlen(filename);
806
if(basename>filename && *(basename-1)!=U_FILE_SEP_CHAR) {
807
*basename++ = U_FILE_SEP_CHAR;
811
uprv_strcpy(basename, "FractionalUCA.txt");
814
uprv_strcpy(basename, getLongPathname(*argv));
817
return write_uca_table(filename, destdir, copyright, &status);
821
* Hey, Emacs, please set the following:
824
* indent-tabs-mode: nil