12e5b6d6dSopenharmony_ci// © 2016 and later: Unicode, Inc. and others.
22e5b6d6dSopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html
32e5b6d6dSopenharmony_ci/*
42e5b6d6dSopenharmony_ci**********************************************************************
52e5b6d6dSopenharmony_ci*   Copyright (C) 2002-2016, International Business Machines
62e5b6d6dSopenharmony_ci*   Corporation and others.  All Rights Reserved.
72e5b6d6dSopenharmony_ci**********************************************************************
82e5b6d6dSopenharmony_ci*
92e5b6d6dSopenharmony_ci* File genbrk.c
102e5b6d6dSopenharmony_ci*/
112e5b6d6dSopenharmony_ci
122e5b6d6dSopenharmony_ci//--------------------------------------------------------------------
132e5b6d6dSopenharmony_ci//
142e5b6d6dSopenharmony_ci//   Tool for generating RuleBasedBreakIterator data files (.brk files).
152e5b6d6dSopenharmony_ci//   .brk files contain the precompiled rules for standard types
162e5b6d6dSopenharmony_ci//   of iterators - word, line, sentence, etc.
172e5b6d6dSopenharmony_ci//
182e5b6d6dSopenharmony_ci//   Usage:  genbrk [options] -r rule-file.txt  -o output-file.brk
192e5b6d6dSopenharmony_ci//
202e5b6d6dSopenharmony_ci//       options:   -v         verbose
212e5b6d6dSopenharmony_ci//                  -? or -h   help
222e5b6d6dSopenharmony_ci//
232e5b6d6dSopenharmony_ci//   The input rule file is a plain text file containing break rules
242e5b6d6dSopenharmony_ci//    in the input format accepted by RuleBasedBreakIterators.  The
252e5b6d6dSopenharmony_ci//    file can be encoded as utf-8, or utf-16 (either endian), or
262e5b6d6dSopenharmony_ci//    in the default code page (platform dependent.).  utf encoded
272e5b6d6dSopenharmony_ci//    files must include a BOM.
282e5b6d6dSopenharmony_ci//
292e5b6d6dSopenharmony_ci//--------------------------------------------------------------------
302e5b6d6dSopenharmony_ci
312e5b6d6dSopenharmony_ci#include "unicode/utypes.h"
322e5b6d6dSopenharmony_ci#include "unicode/ucnv.h"
332e5b6d6dSopenharmony_ci#include "unicode/unistr.h"
342e5b6d6dSopenharmony_ci#include "unicode/rbbi.h"
352e5b6d6dSopenharmony_ci#include "unicode/uclean.h"
362e5b6d6dSopenharmony_ci#include "unicode/udata.h"
372e5b6d6dSopenharmony_ci#include "unicode/putil.h"
382e5b6d6dSopenharmony_ci
392e5b6d6dSopenharmony_ci#include "uoptions.h"
402e5b6d6dSopenharmony_ci#include "unewdata.h"
412e5b6d6dSopenharmony_ci#include "ucmndata.h"
422e5b6d6dSopenharmony_ci#include "rbbidata.h"
432e5b6d6dSopenharmony_ci#include "cmemory.h"
442e5b6d6dSopenharmony_ci
452e5b6d6dSopenharmony_ci#include <stdio.h>
462e5b6d6dSopenharmony_ci#include <stdlib.h>
472e5b6d6dSopenharmony_ci#include <string.h>
482e5b6d6dSopenharmony_ci
492e5b6d6dSopenharmony_ciU_NAMESPACE_USE
502e5b6d6dSopenharmony_ci
512e5b6d6dSopenharmony_cistatic char *progName;
522e5b6d6dSopenharmony_cistatic UOption options[]={
532e5b6d6dSopenharmony_ci    UOPTION_HELP_H,             /* 0 */
542e5b6d6dSopenharmony_ci    UOPTION_HELP_QUESTION_MARK, /* 1 */
552e5b6d6dSopenharmony_ci    UOPTION_VERBOSE,            /* 2 */
562e5b6d6dSopenharmony_ci    { "rules", NULL, NULL, NULL, 'r', UOPT_REQUIRES_ARG, 0 },   /* 3 */
572e5b6d6dSopenharmony_ci    { "out",   NULL, NULL, NULL, 'o', UOPT_REQUIRES_ARG, 0 },   /* 4 */
582e5b6d6dSopenharmony_ci    UOPTION_ICUDATADIR,         /* 5 */
592e5b6d6dSopenharmony_ci    UOPTION_DESTDIR,            /* 6 */
602e5b6d6dSopenharmony_ci    UOPTION_COPYRIGHT,          /* 7 */
612e5b6d6dSopenharmony_ci    UOPTION_QUIET,              /* 8 */
622e5b6d6dSopenharmony_ci};
632e5b6d6dSopenharmony_ci
642e5b6d6dSopenharmony_civoid usageAndDie(int retCode) {
652e5b6d6dSopenharmony_ci        printf("Usage: %s [-v] [-options] -r rule-file -o output-file\n", progName);
662e5b6d6dSopenharmony_ci        printf("\tRead in break iteration rules text and write out the binary data\n"
672e5b6d6dSopenharmony_ci            "options:\n"
682e5b6d6dSopenharmony_ci            "\t-h or -? or --help  this usage text\n"
692e5b6d6dSopenharmony_ci            "\t-V or --version     show a version message\n"
702e5b6d6dSopenharmony_ci            "\t-c or --copyright   include a copyright notice\n"
712e5b6d6dSopenharmony_ci            "\t-v or --verbose     turn on verbose output\n"
722e5b6d6dSopenharmony_ci            "\t-q or --quiet       do not display warnings and progress\n"
732e5b6d6dSopenharmony_ci            "\t-i or --icudatadir  directory for locating any needed intermediate data files,\n"
742e5b6d6dSopenharmony_ci            "\t                    followed by path, defaults to %s\n"
752e5b6d6dSopenharmony_ci            "\t-d or --destdir     destination directory, followed by the path\n",
762e5b6d6dSopenharmony_ci            u_getDataDirectory());
772e5b6d6dSopenharmony_ci        exit (retCode);
782e5b6d6dSopenharmony_ci}
792e5b6d6dSopenharmony_ci
802e5b6d6dSopenharmony_ci
812e5b6d6dSopenharmony_ci#if UCONFIG_NO_BREAK_ITERATION || UCONFIG_NO_FILE_IO
822e5b6d6dSopenharmony_ci
832e5b6d6dSopenharmony_ci/* dummy UDataInfo cf. udata.h */
842e5b6d6dSopenharmony_cistatic UDataInfo dummyDataInfo = {
852e5b6d6dSopenharmony_ci    sizeof(UDataInfo),
862e5b6d6dSopenharmony_ci    0,
872e5b6d6dSopenharmony_ci
882e5b6d6dSopenharmony_ci    U_IS_BIG_ENDIAN,
892e5b6d6dSopenharmony_ci    U_CHARSET_FAMILY,
902e5b6d6dSopenharmony_ci    U_SIZEOF_UCHAR,
912e5b6d6dSopenharmony_ci    0,
922e5b6d6dSopenharmony_ci
932e5b6d6dSopenharmony_ci    { 0, 0, 0, 0 },                 /* dummy dataFormat */
942e5b6d6dSopenharmony_ci    { 0, 0, 0, 0 },                 /* dummy formatVersion */
952e5b6d6dSopenharmony_ci    { 0, 0, 0, 0 }                  /* dummy dataVersion */
962e5b6d6dSopenharmony_ci};
972e5b6d6dSopenharmony_ci
982e5b6d6dSopenharmony_ci#else
992e5b6d6dSopenharmony_ci
1002e5b6d6dSopenharmony_ci//
1012e5b6d6dSopenharmony_ci//  Set up the ICU data header, defined in ucmndata.h
1022e5b6d6dSopenharmony_ci//
1032e5b6d6dSopenharmony_ciDataHeader dh ={
1042e5b6d6dSopenharmony_ci    {sizeof(DataHeader),           // Struct MappedData
1052e5b6d6dSopenharmony_ci        0xda,
1062e5b6d6dSopenharmony_ci        0x27},
1072e5b6d6dSopenharmony_ci
1082e5b6d6dSopenharmony_ci    {                               // struct UDataInfo
1092e5b6d6dSopenharmony_ci        sizeof(UDataInfo),          //     size
1102e5b6d6dSopenharmony_ci        0,                          //     reserved
1112e5b6d6dSopenharmony_ci        U_IS_BIG_ENDIAN,
1122e5b6d6dSopenharmony_ci        U_CHARSET_FAMILY,
1132e5b6d6dSopenharmony_ci        U_SIZEOF_UCHAR,
1142e5b6d6dSopenharmony_ci        0,                          //     reserved
1152e5b6d6dSopenharmony_ci
1162e5b6d6dSopenharmony_ci    { 0x42, 0x72, 0x6b, 0x20 },     //     dataFormat="Brk "
1172e5b6d6dSopenharmony_ci    { 0xff, 0, 0, 0 },              //     formatVersion.  Filled in later with values
1182e5b6d6dSopenharmony_ci                                    //      from the RBBI rule builder.  The  values declared
1192e5b6d6dSopenharmony_ci                                    //      here should never appear in any real RBBI data.
1202e5b6d6dSopenharmony_ci        { 4, 1, 0, 0 }              //   dataVersion (Unicode version)
1212e5b6d6dSopenharmony_ci    }};
1222e5b6d6dSopenharmony_ci
1232e5b6d6dSopenharmony_ci#endif
1242e5b6d6dSopenharmony_ci
1252e5b6d6dSopenharmony_ci//----------------------------------------------------------------------------
1262e5b6d6dSopenharmony_ci//
1272e5b6d6dSopenharmony_ci//  main      for genbrk
1282e5b6d6dSopenharmony_ci//
1292e5b6d6dSopenharmony_ci//----------------------------------------------------------------------------
1302e5b6d6dSopenharmony_ciint  main(int argc, char **argv) {
1312e5b6d6dSopenharmony_ci    UErrorCode  status = U_ZERO_ERROR;
1322e5b6d6dSopenharmony_ci    const char *ruleFileName;
1332e5b6d6dSopenharmony_ci    const char *outFileName;
1342e5b6d6dSopenharmony_ci    const char *outDir = NULL;
1352e5b6d6dSopenharmony_ci    const char *copyright = NULL;
1362e5b6d6dSopenharmony_ci
1372e5b6d6dSopenharmony_ci    //
1382e5b6d6dSopenharmony_ci    // Pick up and check the command line arguments,
1392e5b6d6dSopenharmony_ci    //    using the standard ICU tool utils option handling.
1402e5b6d6dSopenharmony_ci    //
1412e5b6d6dSopenharmony_ci    U_MAIN_INIT_ARGS(argc, argv);
1422e5b6d6dSopenharmony_ci    progName = argv[0];
1432e5b6d6dSopenharmony_ci    argc=u_parseArgs(argc, argv, UPRV_LENGTHOF(options), options);
1442e5b6d6dSopenharmony_ci    if(argc<0) {
1452e5b6d6dSopenharmony_ci        // Unrecognized option
1462e5b6d6dSopenharmony_ci        fprintf(stderr, "error in command line argument \"%s\"\n", argv[-argc]);
1472e5b6d6dSopenharmony_ci        usageAndDie(U_ILLEGAL_ARGUMENT_ERROR);
1482e5b6d6dSopenharmony_ci    }
1492e5b6d6dSopenharmony_ci
1502e5b6d6dSopenharmony_ci    if(options[0].doesOccur || options[1].doesOccur) {
1512e5b6d6dSopenharmony_ci        //  -? or -h for help.
1522e5b6d6dSopenharmony_ci        usageAndDie(0);
1532e5b6d6dSopenharmony_ci    }
1542e5b6d6dSopenharmony_ci
1552e5b6d6dSopenharmony_ci    if (!(options[3].doesOccur && options[4].doesOccur)) {
1562e5b6d6dSopenharmony_ci        fprintf(stderr, "rule file and output file must both be specified.\n");
1572e5b6d6dSopenharmony_ci        usageAndDie(U_ILLEGAL_ARGUMENT_ERROR);
1582e5b6d6dSopenharmony_ci    }
1592e5b6d6dSopenharmony_ci    ruleFileName = options[3].value;
1602e5b6d6dSopenharmony_ci    outFileName  = options[4].value;
1612e5b6d6dSopenharmony_ci
1622e5b6d6dSopenharmony_ci    if (options[5].doesOccur) {
1632e5b6d6dSopenharmony_ci        u_setDataDirectory(options[5].value);
1642e5b6d6dSopenharmony_ci    }
1652e5b6d6dSopenharmony_ci
1662e5b6d6dSopenharmony_ci    status = U_ZERO_ERROR;
1672e5b6d6dSopenharmony_ci
1682e5b6d6dSopenharmony_ci    /* Combine the directory with the file name */
1692e5b6d6dSopenharmony_ci    if(options[6].doesOccur) {
1702e5b6d6dSopenharmony_ci        outDir = options[6].value;
1712e5b6d6dSopenharmony_ci    }
1722e5b6d6dSopenharmony_ci    if (options[7].doesOccur) {
1732e5b6d6dSopenharmony_ci        copyright = U_COPYRIGHT_STRING;
1742e5b6d6dSopenharmony_ci    }
1752e5b6d6dSopenharmony_ci
1762e5b6d6dSopenharmony_ci#if UCONFIG_NO_BREAK_ITERATION || UCONFIG_NO_FILE_IO
1772e5b6d6dSopenharmony_ci
1782e5b6d6dSopenharmony_ci    UNewDataMemory *pData;
1792e5b6d6dSopenharmony_ci    char msg[1024];
1802e5b6d6dSopenharmony_ci
1812e5b6d6dSopenharmony_ci    /* write message with just the name */
1822e5b6d6dSopenharmony_ci    sprintf(msg, "genbrk writes dummy %s because of UCONFIG_NO_BREAK_ITERATION and/or UCONFIG_NO_FILE_IO, see uconfig.h", outFileName);
1832e5b6d6dSopenharmony_ci    fprintf(stderr, "%s\n", msg);
1842e5b6d6dSopenharmony_ci
1852e5b6d6dSopenharmony_ci    /* write the dummy data file */
1862e5b6d6dSopenharmony_ci    pData = udata_create(outDir, NULL, outFileName, &dummyDataInfo, NULL, &status);
1872e5b6d6dSopenharmony_ci    udata_writeBlock(pData, msg, strlen(msg));
1882e5b6d6dSopenharmony_ci    udata_finish(pData, &status);
1892e5b6d6dSopenharmony_ci    return (int)status;
1902e5b6d6dSopenharmony_ci
1912e5b6d6dSopenharmony_ci#else
1922e5b6d6dSopenharmony_ci    /* Initialize ICU */
1932e5b6d6dSopenharmony_ci    u_init(&status);
1942e5b6d6dSopenharmony_ci    if (U_FAILURE(status)) {
1952e5b6d6dSopenharmony_ci        fprintf(stderr, "%s: can not initialize ICU.  status = %s\n",
1962e5b6d6dSopenharmony_ci            argv[0], u_errorName(status));
1972e5b6d6dSopenharmony_ci        exit(1);
1982e5b6d6dSopenharmony_ci    }
1992e5b6d6dSopenharmony_ci    status = U_ZERO_ERROR;
2002e5b6d6dSopenharmony_ci
2012e5b6d6dSopenharmony_ci    //
2022e5b6d6dSopenharmony_ci    //  Read in the rule source file
2032e5b6d6dSopenharmony_ci    //
2042e5b6d6dSopenharmony_ci    long        result;
2052e5b6d6dSopenharmony_ci    long        ruleFileSize;
2062e5b6d6dSopenharmony_ci    FILE        *file;
2072e5b6d6dSopenharmony_ci    char        *ruleBufferC;
2082e5b6d6dSopenharmony_ci
2092e5b6d6dSopenharmony_ci    file = fopen(ruleFileName, "rb");
2102e5b6d6dSopenharmony_ci    if( file == 0 ) {
2112e5b6d6dSopenharmony_ci        fprintf(stderr, "Could not open file \"%s\"\n", ruleFileName);
2122e5b6d6dSopenharmony_ci        exit(-1);
2132e5b6d6dSopenharmony_ci    }
2142e5b6d6dSopenharmony_ci    fseek(file, 0, SEEK_END);
2152e5b6d6dSopenharmony_ci    ruleFileSize = ftell(file);
2162e5b6d6dSopenharmony_ci    fseek(file, 0, SEEK_SET);
2172e5b6d6dSopenharmony_ci    ruleBufferC = new char[ruleFileSize+10];
2182e5b6d6dSopenharmony_ci
2192e5b6d6dSopenharmony_ci    result = (long)fread(ruleBufferC, 1, ruleFileSize, file);
2202e5b6d6dSopenharmony_ci    if (result != ruleFileSize)  {
2212e5b6d6dSopenharmony_ci        fprintf(stderr, "Error reading file \"%s\"\n", ruleFileName);
2222e5b6d6dSopenharmony_ci        exit (-1);
2232e5b6d6dSopenharmony_ci    }
2242e5b6d6dSopenharmony_ci    ruleBufferC[ruleFileSize]=0;
2252e5b6d6dSopenharmony_ci    fclose(file);
2262e5b6d6dSopenharmony_ci
2272e5b6d6dSopenharmony_ci    //
2282e5b6d6dSopenharmony_ci    // Look for a Unicode Signature (BOM) on the rule file
2292e5b6d6dSopenharmony_ci    //
2302e5b6d6dSopenharmony_ci    int32_t        signatureLength;
2312e5b6d6dSopenharmony_ci    const char *   ruleSourceC = ruleBufferC;
2322e5b6d6dSopenharmony_ci    const char*    encoding = ucnv_detectUnicodeSignature(
2332e5b6d6dSopenharmony_ci                           ruleSourceC, ruleFileSize, &signatureLength, &status);
2342e5b6d6dSopenharmony_ci    if (U_FAILURE(status)) {
2352e5b6d6dSopenharmony_ci        exit(status);
2362e5b6d6dSopenharmony_ci    }
2372e5b6d6dSopenharmony_ci    if(encoding!=NULL ){
2382e5b6d6dSopenharmony_ci        ruleSourceC  += signatureLength;
2392e5b6d6dSopenharmony_ci        ruleFileSize -= signatureLength;
2402e5b6d6dSopenharmony_ci    }
2412e5b6d6dSopenharmony_ci
2422e5b6d6dSopenharmony_ci    //
2432e5b6d6dSopenharmony_ci    // Open a converter to take the rule file to UTF-16
2442e5b6d6dSopenharmony_ci    //
2452e5b6d6dSopenharmony_ci    UConverter* conv;
2462e5b6d6dSopenharmony_ci    conv = ucnv_open(encoding, &status);
2472e5b6d6dSopenharmony_ci    if (U_FAILURE(status)) {
2482e5b6d6dSopenharmony_ci        fprintf(stderr, "ucnv_open: ICU Error \"%s\"\n", u_errorName(status));
2492e5b6d6dSopenharmony_ci        exit(status);
2502e5b6d6dSopenharmony_ci    }
2512e5b6d6dSopenharmony_ci
2522e5b6d6dSopenharmony_ci    //
2532e5b6d6dSopenharmony_ci    // Convert the rules to UChar.
2542e5b6d6dSopenharmony_ci    //  Preflight first to determine required buffer size.
2552e5b6d6dSopenharmony_ci    //
2562e5b6d6dSopenharmony_ci    uint32_t destCap = ucnv_toUChars(conv,
2572e5b6d6dSopenharmony_ci                       NULL,           //  dest,
2582e5b6d6dSopenharmony_ci                       0,              //  destCapacity,
2592e5b6d6dSopenharmony_ci                       ruleSourceC,
2602e5b6d6dSopenharmony_ci                       ruleFileSize,
2612e5b6d6dSopenharmony_ci                       &status);
2622e5b6d6dSopenharmony_ci    if (status != U_BUFFER_OVERFLOW_ERROR) {
2632e5b6d6dSopenharmony_ci        fprintf(stderr, "ucnv_toUChars: ICU Error \"%s\"\n", u_errorName(status));
2642e5b6d6dSopenharmony_ci        exit(status);
2652e5b6d6dSopenharmony_ci    }
2662e5b6d6dSopenharmony_ci
2672e5b6d6dSopenharmony_ci    status = U_ZERO_ERROR;
2682e5b6d6dSopenharmony_ci    UChar *ruleSourceU = new UChar[destCap+1];
2692e5b6d6dSopenharmony_ci    ucnv_toUChars(conv,
2702e5b6d6dSopenharmony_ci                  ruleSourceU,     //  dest,
2712e5b6d6dSopenharmony_ci                  destCap+1,
2722e5b6d6dSopenharmony_ci                  ruleSourceC,
2732e5b6d6dSopenharmony_ci                  ruleFileSize,
2742e5b6d6dSopenharmony_ci                  &status);
2752e5b6d6dSopenharmony_ci    if (U_FAILURE(status)) {
2762e5b6d6dSopenharmony_ci        fprintf(stderr, "ucnv_toUChars: ICU Error \"%s\"\n", u_errorName(status));
2772e5b6d6dSopenharmony_ci        exit(status);
2782e5b6d6dSopenharmony_ci    }
2792e5b6d6dSopenharmony_ci    ucnv_close(conv);
2802e5b6d6dSopenharmony_ci
2812e5b6d6dSopenharmony_ci
2822e5b6d6dSopenharmony_ci    //
2832e5b6d6dSopenharmony_ci    //  Put the source rules into a UnicodeString
2842e5b6d6dSopenharmony_ci    //
2852e5b6d6dSopenharmony_ci    UnicodeString ruleSourceS(false, ruleSourceU, destCap);
2862e5b6d6dSopenharmony_ci
2872e5b6d6dSopenharmony_ci    //
2882e5b6d6dSopenharmony_ci    //  Create the break iterator from the rules
2892e5b6d6dSopenharmony_ci    //     This will compile the rules.
2902e5b6d6dSopenharmony_ci    //
2912e5b6d6dSopenharmony_ci    UParseError parseError;
2922e5b6d6dSopenharmony_ci    parseError.line = 0;
2932e5b6d6dSopenharmony_ci    parseError.offset = 0;
2942e5b6d6dSopenharmony_ci    RuleBasedBreakIterator *bi = new RuleBasedBreakIterator(ruleSourceS, parseError, status);
2952e5b6d6dSopenharmony_ci    if (U_FAILURE(status)) {
2962e5b6d6dSopenharmony_ci        fprintf(stderr, "createRuleBasedBreakIterator: ICU Error \"%s\"  at line %d, column %d\n",
2972e5b6d6dSopenharmony_ci                u_errorName(status), (int)parseError.line, (int)parseError.offset);
2982e5b6d6dSopenharmony_ci        exit(status);
2992e5b6d6dSopenharmony_ci    }
3002e5b6d6dSopenharmony_ci
3012e5b6d6dSopenharmony_ci
3022e5b6d6dSopenharmony_ci    //
3032e5b6d6dSopenharmony_ci    //  Get the compiled rule data from the break iterator.
3042e5b6d6dSopenharmony_ci    //
3052e5b6d6dSopenharmony_ci    uint32_t        outDataSize;
3062e5b6d6dSopenharmony_ci    const uint8_t  *outData;
3072e5b6d6dSopenharmony_ci    outData = bi->getBinaryRules(outDataSize);
3082e5b6d6dSopenharmony_ci
3092e5b6d6dSopenharmony_ci    // Copy the data format version numbers from the RBBI data header into the UDataMemory header.
3102e5b6d6dSopenharmony_ci    uprv_memcpy(dh.info.formatVersion, ((RBBIDataHeader *)outData)->fFormatVersion, sizeof(dh.info.formatVersion));
3112e5b6d6dSopenharmony_ci
3122e5b6d6dSopenharmony_ci    //
3132e5b6d6dSopenharmony_ci    //  Create the output file
3142e5b6d6dSopenharmony_ci    //
3152e5b6d6dSopenharmony_ci    size_t bytesWritten;
3162e5b6d6dSopenharmony_ci    UNewDataMemory *pData;
3172e5b6d6dSopenharmony_ci    pData = udata_create(outDir, NULL, outFileName, &(dh.info), copyright, &status);
3182e5b6d6dSopenharmony_ci    if(U_FAILURE(status)) {
3192e5b6d6dSopenharmony_ci        fprintf(stderr, "genbrk: Could not open output file \"%s\", \"%s\"\n",
3202e5b6d6dSopenharmony_ci                         outFileName, u_errorName(status));
3212e5b6d6dSopenharmony_ci        exit(status);
3222e5b6d6dSopenharmony_ci    }
3232e5b6d6dSopenharmony_ci
3242e5b6d6dSopenharmony_ci
3252e5b6d6dSopenharmony_ci    //  Write the data itself.
3262e5b6d6dSopenharmony_ci    udata_writeBlock(pData, outData, outDataSize);
3272e5b6d6dSopenharmony_ci    // finish up
3282e5b6d6dSopenharmony_ci    bytesWritten = udata_finish(pData, &status);
3292e5b6d6dSopenharmony_ci    if(U_FAILURE(status)) {
3302e5b6d6dSopenharmony_ci        fprintf(stderr, "genbrk: error %d writing the output file\n", status);
3312e5b6d6dSopenharmony_ci        exit(status);
3322e5b6d6dSopenharmony_ci    }
3332e5b6d6dSopenharmony_ci
3342e5b6d6dSopenharmony_ci    if (bytesWritten != outDataSize) {
3352e5b6d6dSopenharmony_ci        fprintf(stderr, "Error writing to output file \"%s\"\n", outFileName);
3362e5b6d6dSopenharmony_ci        exit(-1);
3372e5b6d6dSopenharmony_ci    }
3382e5b6d6dSopenharmony_ci
3392e5b6d6dSopenharmony_ci    delete bi;
3402e5b6d6dSopenharmony_ci    delete[] ruleSourceU;
3412e5b6d6dSopenharmony_ci    delete[] ruleBufferC;
3422e5b6d6dSopenharmony_ci    u_cleanup();
3432e5b6d6dSopenharmony_ci
3442e5b6d6dSopenharmony_ci
3452e5b6d6dSopenharmony_ci    if(!options[8].doesOccur) {
3462e5b6d6dSopenharmony_ci        printf("genbrk: tool completed successfully.\n");
3472e5b6d6dSopenharmony_ci    }
3482e5b6d6dSopenharmony_ci    return 0;
3492e5b6d6dSopenharmony_ci
3502e5b6d6dSopenharmony_ci#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
3512e5b6d6dSopenharmony_ci}
3522e5b6d6dSopenharmony_ci
353