/********************************************************************
 * COPYRIGHT:
 * Copyright (C) 2001 IBM, Inc.   All Rights Reserved.
 *
 ********************************************************************/
/********************************************************************************
*
* File CALLCOLL.C
*
* Modification History:
*        Name                     Description
*     Andy Heninger             First Version
*
*********************************************************************************
*/

//
//  This program tests string collation and sort key generation performance.
//      Three APIs can be teste: ICU C , Unix strcoll, strxfrm and Windows LCMapString
//      A file of names is required as input, one per line.  It must be in utf-8 or utf-16 format,
//      and include a byte order mark.  Either LE or BE format is OK.
//

const char gUsageString[] =
 "usage:  collperf options...\n"
    "-help                      Display this message.\n"
    "-file file_name            utf-16 format file of names.\n"
    "-locale name               ICU locale to use.  Default is en_US\n"
    "-rules file_name           Collation rules file (overrides locale)\n"
    "-langid 0x1234             Windows Language ID number.  Default to value for -locale option\n"
    "                              see http://msdn.microsoft.com/library/psdk/winbase/nls_8xo3.htm\n"
    "-win                       Run test using Windows native services.  (ICU is default)\n"
    "-unix                      Run test using Unix strxfrm, strcoll services.\n"
    "-uselen                    Use API with string lengths.  Default is null-terminated strings\n"
    "-usekeys                   Run tests using sortkeys rather than strcoll\n"
    "-strcmp                    Run tests using u_strcmp rather than strcoll\n"
    "-strcmpCPO                 Run tests using u_strcmpCodePointOrder rather than strcoll\n"
    "-loop nnnn                 Loopcount for test.  Adjust for reasonable total running time.\n"
    "-iloop n                   Inner Loop Count.  Default = 1.  Number of calls to function\n"
    "                               under test at each call point.  For measuring test overhead.\n"
    "-terse                     Terse numbers-only output.  Intended for use by scripts.\n"
    "-french                    French accent ordering\n"
    "-frenchoff                 No French accent ordering (for use with French locales.)\n"
    "-norm                      Normalizing mode on\n"
    "-shifted                   Shifted mode\n"
    "-lower                     Lower case first\n"
    "-upper                     Upper case first\n"
    "-case                      Enable separate case level\n"
    "-level n                   Sort level, 1 to 5, for Primary, Secndary, Tertiary, Quaternary, Identical\n"
    "-keyhist                   Produce a table sort key size vs. string length\n"
    "-binsearch                 Binary Search timing test\n"
    "-keygen                    Sort Key Generation timing test\n"
    "-qsort                     Quicksort timing test\n"
    "-iter                      Iteration Performance Test\n"
    "-dump                      Display strings, sort keys and CEs.\n"
    ;



#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <locale.h>
#include <errno.h>

#include <unicode/utypes.h>
#include <unicode/ucol.h>
#include <unicode/uloc.h>
#include <unicode/ustring.h>
#include <unicode/ures.h>
#include <unicode/uchar.h>
#include <unicode/ucnv.h>
#include <unicode/utf8.h>

#ifdef WIN32
#include <windows.h>
#else
//
//  Stubs for Windows API functions when building on UNIXes.
//
typedef int DWORD;
inline int CompareStringW(DWORD, DWORD, UChar *, int, UChar *, int) {return 0;};
#include <sys/time.h>
unsigned long timeGetTime() {
    struct timeval t;
    gettimeofday(&t, 0);
    unsigned long val = t.tv_sec * 1000;  // Let it overflow.  Who cares.
    val += t.tv_usec / 1000;
    return val;
};
inline int LCMapStringW(DWORD, DWORD, UChar *, int, UChar *, int) {return 0;};
const int LCMAP_SORTKEY = 0;
#define MAKELCID(a,b) 0
const int SORT_DEFAULT = 0;
#endif



//
//  Command line option variables
//     These global variables are set according to the options specified
//     on the command line by the user.
char * opt_fName      = 0;
char * opt_locale     = "en_US";
int    opt_langid     = 0;         // Defaults to value corresponding to opt_locale.
char * opt_rules      = 0;
UBool  opt_help       = FALSE;
int    opt_loopCount  = 1;
int    opt_iLoopCount = 1;
UBool  opt_terse      = FALSE;
UBool  opt_qsort      = FALSE;
UBool  opt_binsearch  = FALSE;
UBool  opt_icu        = TRUE;
UBool  opt_win        = FALSE;      // Run with Windows native functions.
UBool  opt_unix       = FALSE;      // Run with UNIX strcoll, strxfrm functions.
UBool  opt_uselen     = FALSE;
UBool  opt_usekeys    = FALSE;
UBool  opt_strcmp     = FALSE;
UBool  opt_strcmpCPO  = FALSE;
UBool  opt_norm       = FALSE;
UBool  opt_keygen     = FALSE;
UBool  opt_french     = FALSE;
UBool  opt_frenchoff  = FALSE;
UBool  opt_shifted    = FALSE;
UBool  opt_lower      = FALSE;
UBool  opt_upper      = FALSE;
UBool  opt_case       = FALSE;
int    opt_level      = 0;
UBool  opt_keyhist    = FALSE;
UBool  opt_itertest   = FALSE;
UBool  opt_dump       = FALSE;



//
//   Definitions for the command line options
//
struct OptSpec {
    const char *name;
    enum {FLAG, NUM, STRING} type;
    void *pVar;
};

OptSpec opts[] = {
    {"-file",        OptSpec::STRING, &opt_fName},
    {"-locale",      OptSpec::STRING, &opt_locale},
    {"-langid",      OptSpec::NUM,    &opt_langid},
    {"-rules",       OptSpec::STRING, &opt_rules},
    {"-qsort",       OptSpec::FLAG,   &opt_qsort},
    {"-binsearch",   OptSpec::FLAG,   &opt_binsearch},
    {"-iter",        OptSpec::FLAG,   &opt_itertest},
    {"-win",         OptSpec::FLAG,   &opt_win},
    {"-unix",        OptSpec::FLAG,   &opt_unix},
    {"-uselen",      OptSpec::FLAG,   &opt_uselen},
    {"-usekeys",     OptSpec::FLAG,   &opt_usekeys},
    {"-strcmp",      OptSpec::FLAG,   &opt_strcmp},
    {"-strcmpCPO",   OptSpec::FLAG,   &opt_strcmpCPO},
    {"-norm",        OptSpec::FLAG,   &opt_norm},
    {"-french",      OptSpec::FLAG,   &opt_french},
    {"-frenchoff",   OptSpec::FLAG,   &opt_frenchoff},
    {"-shifted",     OptSpec::FLAG,   &opt_shifted},
    {"-lower",       OptSpec::FLAG,   &opt_lower},
    {"-upper",       OptSpec::FLAG,   &opt_upper},
    {"-case",        OptSpec::FLAG,   &opt_case},
    {"-level",       OptSpec::NUM,    &opt_level},
    {"-keyhist",     OptSpec::FLAG,   &opt_keyhist},
    {"-keygen",      OptSpec::FLAG,   &opt_keygen},
    {"-loop",        OptSpec::NUM,    &opt_loopCount},
    {"-iloop",       OptSpec::NUM,    &opt_iLoopCount},
    {"-terse",       OptSpec::FLAG,   &opt_terse},
    {"-dump",        OptSpec::FLAG,   &opt_dump},
    {"-help",        OptSpec::FLAG,   &opt_help},
    {"-?",           OptSpec::FLAG,   &opt_help},
    {0, OptSpec::FLAG, 0}
};


//---------------------------------------------------------------------------
//
//  Global variables pointing to and describing the test file
//
//---------------------------------------------------------------------------

//
//   struct Line
//
//      Each line from the source file (containing a name, presumably) gets
//      one of these structs.
//
struct  Line {
    UChar     *name;
    int        len;
    char      *winSortKey;
    char      *icuSortKey;
    char      *unixSortKey;
    char      *unixName;
};



Line          *gFileLines;           // Ptr to array of Line structs, one per line in the file.
int            gNumFileLines;
UCollator     *gCol;
DWORD          gWinLCID;

Line          **gSortedLines;
Line          **gRandomLines;
int            gCount;



//---------------------------------------------------------------------------
//
//  ProcessOptions()    Function to read the command line options.
//
//---------------------------------------------------------------------------
UBool ProcessOptions(int argc, const char **argv, OptSpec opts[])
{
    int         i;
    int         argNum;
    const char  *pArgName;
    OptSpec    *pOpt;

    for (argNum=1; argNum<argc; argNum++) {
        pArgName = argv[argNum];
        for (pOpt = opts;  pOpt->name != 0; pOpt++) {
            if (strcmp(pOpt->name, pArgName) == 0) {
                switch (pOpt->type) {
                case OptSpec::FLAG:
                    *(UBool *)(pOpt->pVar) = TRUE;
                    break;
                case OptSpec::STRING:
                    argNum ++;
                    if (argNum >= argc) {
                        fprintf(stderr, "value expected for \"%s\" option.\n", pOpt->name);
                        return FALSE;
                    }
                    *(const char **)(pOpt->pVar)  = argv[argNum];
                    break;
                case OptSpec::NUM:
                    argNum ++;
                    if (argNum >= argc) {
                        fprintf(stderr, "value expected for \"%s\" option.\n", pOpt->name);
                        return FALSE;
                    }
                    char *endp;
                    i = strtol(argv[argNum], &endp, 0);
                    if (endp == argv[argNum]) {
                        fprintf(stderr, "integer value expected for \"%s\" option.\n", pOpt->name);
                        return FALSE;
                    }
                    *(int *)(pOpt->pVar) = i;
                }
                break;
            }
        }
        if (pOpt->name == 0)
        {
            fprintf(stderr, "Unrecognized option \"%s\"\n", pArgName);
            return FALSE;
        }
    }
return TRUE;
}

//---------------------------------------------------------------------------------------
//
//   Comparison functions for use by qsort.
//
//       Six flavors, ICU or Windows, SortKey or String Compare, Strings with length
//           or null terminated.
//
//---------------------------------------------------------------------------------------
int ICUstrcmpK(const void *a, const void *b) {
    gCount++;
    int t = strcmp((*(Line **)a)->icuSortKey, (*(Line **)b)->icuSortKey);
    return t;
}


int ICUstrcmpL(const void *a, const void *b) {
    gCount++;
    UCollationResult t;
    t = ucol_strcoll(gCol, (*(Line **)a)->name, (*(Line **)a)->len, (*(Line **)b)->name, (*(Line **)b)->len);
    if (t == UCOL_LESS) return -1;
    if (t == UCOL_GREATER) return +1;
    return 0;
}


int ICUstrcmp(const void *a, const void *b) {
    gCount++;
    UCollationResult t;
    t = ucol_strcoll(gCol, (*(Line **)a)->name, -1, (*(Line **)b)->name, -1);
    if (t == UCOL_LESS) return -1;
    if (t == UCOL_GREATER) return +1;
    return 0;
}


int Winstrcmp(const void *a, const void *b) {
    gCount++;
    int t;
    t = CompareStringW(gWinLCID, 0, (*(Line **)a)->name, -1, (*(Line **)b)->name, -1);
    return t-2;
}


int UNIXstrcmp(const void *a, const void *b) {
    gCount++;
    int t;
    t = strcoll((*(Line **)a)->unixName, (*(Line **)b)->unixName);
    return t;
}


int WinstrcmpL(const void *a, const void *b) {
    gCount++;
    int t;
    t = CompareStringW(gWinLCID, 0, (*(Line **)a)->name, (*(Line **)a)->len, (*(Line **)b)->name, (*(Line **)b)->len);
    return t-2;
}


int WinstrcmpK(const void *a, const void *b) {
    gCount++;
    int t = strcmp((*(Line **)a)->winSortKey, (*(Line **)b)->winSortKey);
    return t;
}


//---------------------------------------------------------------------------------------
//
//   Function for sorting the names (lines) into a random order.
//      Order is based on a hash of the  ICU Sort key for the lines
//      The randomized order is used as input for the sorting timing tests.
//
//---------------------------------------------------------------------------------------
int ICURandomCmp(const void *a, const void *b) {
    char  *ask = (*(Line **)a)->icuSortKey;
    char  *bsk = (*(Line **)b)->icuSortKey;
    int   aVal = 0;
    int   bVal = 0;
    int   retVal;
    while (*ask != 0) {
        aVal += aVal*37 + *ask++;
    }
    while (*bsk != 0) {
        bVal += bVal*37 + *bsk++;
    }
    retVal = -1;
    if (aVal == bVal) {
        retVal = 0;
    }
    else if (aVal > bVal) {
        retVal = 1;
    }
    return retVal;
}

//---------------------------------------------------------------------------------------
//
//   doKeyGen()     Key Generation Timing Test
//
//---------------------------------------------------------------------------------------
void doKeyGen()
{
    int  line;
    int  loops;
    int  iLoop;
    int  t;
    int  len=-1;

    // Adjust loop count to compensate for file size.   Should be order n
    double dLoopCount = double(opt_loopCount) * (1000. /  double(gNumFileLines));
    int adj_loopCount = int(dLoopCount);
    if (adj_loopCount < 1) adj_loopCount = 1;


    unsigned long startTime = timeGetTime();

    if (opt_win) {
        for (loops=0; loops<adj_loopCount; loops++) {
            for (line=0; line < gNumFileLines; line++) {
                if (opt_uselen) {
                    len = gFileLines[line].len;
                }
                for (iLoop=0; iLoop < opt_iLoopCount; iLoop++) {
                    t=LCMapStringW(gWinLCID, LCMAP_SORTKEY,
                        gFileLines[line].name, len,
                        (unsigned short *)gFileLines[line].winSortKey, 5000);    // TODO  something with length.
                }
            }
        }
    }
    else if (opt_icu)
    {
        for (loops=0; loops<adj_loopCount; loops++) {
            for (line=0; line < gNumFileLines; line++) {
                if (opt_uselen) {
                    len = gFileLines[line].len;
                }
                for (iLoop=0; iLoop < opt_iLoopCount; iLoop++) {
                    t = ucol_getSortKey(gCol, gFileLines[line].name, len, (unsigned char *)gFileLines[line].icuSortKey, 5000);
                }
            }
        }
    }
    else if (opt_unix)
    {
        for (loops=0; loops<adj_loopCount; loops++) {
            for (line=0; line < gNumFileLines; line++) {
                for (iLoop=0; iLoop < opt_iLoopCount; iLoop++) {
                t = strxfrm(gFileLines[line].unixSortKey, gFileLines[line].unixName, 5000);
                }
            }
        }
    }

    unsigned long elapsedTime = timeGetTime() - startTime;
    int ns = (int)(float(1000000) * (float)elapsedTime / (float)(adj_loopCount*gNumFileLines));

    if (opt_terse == FALSE) {
        printf("Sort Key Generation:  total # of keys = %d\n", loops*gNumFileLines);
        printf("Sort Key Generation:  time per key = %d ns\n", ns);
    }
    else {
        printf("%d,  ", ns);
    }

    int   totalKeyLen = 0;
    int   totalChars  = 0;
    for (line=0; line<gNumFileLines; line++) {
        totalChars += u_strlen(gFileLines[line].name);
        if (opt_win) {
            totalKeyLen += strlen(gFileLines[line].winSortKey);
        }
        else if (opt_icu) {
            totalKeyLen += strlen(gFileLines[line].icuSortKey);
        }
        else if (opt_unix) {
            totalKeyLen += strlen(gFileLines[line].unixSortKey);
        }

    }
    if (opt_terse == FALSE) {
        printf("Key Length / character = %f\n", (float)totalKeyLen / (float)totalChars);
    } else {
        printf("%f, ", (float)totalKeyLen / (float)totalChars);
    }
}



//---------------------------------------------------------------------------------------
//
//    doBinarySearch()    Binary Search timing test.  Each name from the list
//                        is looked up in the full sorted list of names.
//
//---------------------------------------------------------------------------------------
void doBinarySearch()
{

    gCount = 0;
    int  line;
    int  loops;
    int  iLoop;
    unsigned long elapsedTime;

    // Adjust loop count to compensate for file size.   Should be order n (lookups) * log n  (compares/lookup)
    // Accurate timings do not depend on this being perfect.  The correction is just to try to
    //   get total running times of about the right order, so the that user doesn't need to
    //   manually adjust the loop count for every different file size.
    double dLoopCount = double(opt_loopCount) * 3000. / (log10(gNumFileLines) * double(gNumFileLines));
    if (opt_usekeys) dLoopCount *= 5;
    int adj_loopCount = int(dLoopCount);
    if (adj_loopCount < 1) adj_loopCount = 1;


    for (;;) {  // not really a loop, just allows "break" to work, to simplify
                //   inadvertantly running more than one test through here.
        if (opt_strcmp || opt_strcmpCPO) 
        {
            unsigned long startTime = timeGetTime();
            typedef int32_t (*PF)(const UChar *, const UChar *);
            PF pf = u_strcmp;
            if (opt_strcmpCPO) {pf = u_strcmpCodePointOrder;}
            if (opt_strcmp && opt_win) {pf = (PF)wcscmp;}   // Damn the difference between int32_t and int
                                                            //   which forces the use of a cast here.
            
            int r;
            for (loops=0; loops<adj_loopCount; loops++) {
                
                for (line=0; line < gNumFileLines; line++) {
                    int hi      = gNumFileLines-1;
                    int lo      = 0;
                    int  guess = -1;
                    for (;;) {
                        int newGuess = (hi + lo) / 2;
                        if (newGuess == guess)
                            break;
                        guess = newGuess;
                        for (iLoop=0; iLoop < opt_iLoopCount; iLoop++) {
                            r = (*pf)((gSortedLines[line])->name, (gSortedLines[guess])->name);
                        }
                        gCount++;
                        if (r== 0)
                            break;
                        if (r < 0)
                            hi = guess;
                        else
                            lo   = guess;
                    }
                }
            }
            elapsedTime = timeGetTime() - startTime;
            break;
        }
        
        
        if (opt_icu)
        {
            unsigned long startTime = timeGetTime();
            UCollationResult  r;
            for (loops=0; loops<adj_loopCount; loops++) {
                
                for (line=0; line < gNumFileLines; line++) {
                    int lineLen  = -1;
                    int guessLen = -1;
                    if (opt_uselen) {
                        lineLen = (gSortedLines[line])->len;
                    }
                    int hi      = gNumFileLines-1;
                    int lo      = 0;
                    int  guess = -1;
                    for (;;) {
                        int newGuess = (hi + lo) / 2;
                        if (newGuess == guess)
                            break;
                        guess = newGuess;
                        int ri;
                        if (opt_usekeys) {
                            for (iLoop=0; iLoop < opt_iLoopCount; iLoop++) {
                                ri = strcmp((gSortedLines[line])->icuSortKey, (gSortedLines[guess])->icuSortKey);
                            }
                            gCount++;
                            r=UCOL_GREATER; if(ri<0) {r=UCOL_LESS;} else if (ri==0) {r=UCOL_EQUAL;}
                        }
                        else
                        {
                            if (opt_uselen) {
                                guessLen = (gSortedLines[guess])->len;
                            }
                            for (iLoop=0; iLoop < opt_iLoopCount; iLoop++) {
                                r = ucol_strcoll(gCol, (gSortedLines[line])->name, lineLen, (gSortedLines[guess])->name, guessLen);
                            }
                            gCount++;
                        }
                        if (r== UCOL_EQUAL)
                            break;
                        if (r == UCOL_LESS)
                            hi = guess;
                        else
                            lo   = guess;
                    }
                }
            }
            elapsedTime = timeGetTime() - startTime;
            break;
        }
        
        if (opt_win)
        {
            unsigned long startTime = timeGetTime();
            int r;
            for (loops=0; loops<adj_loopCount; loops++) {
                
                for (line=0; line < gNumFileLines; line++) {
                    int lineLen  = -1;
                    int guessLen = -1;
                    if (opt_uselen) {
                        lineLen = (gSortedLines[line])->len;
                    }
                    int hi   = gNumFileLines-1;
                    int lo   = 0;
                    int  guess = -1;
                    for (;;) {
                        int newGuess = (hi + lo) / 2;
                        if (newGuess == guess)
                            break;
                        guess = newGuess;
                        if (opt_usekeys) {
                            for (iLoop=0; iLoop < opt_iLoopCount; iLoop++) {
                                r = strcmp((gSortedLines[line])->winSortKey, (gSortedLines[guess])->winSortKey);
                            }
                            gCount++;
                            r+=2;
                        }
                        else
                        {
                            if (opt_uselen) {
                                guessLen = (gSortedLines[guess])->len;
                            }
                            for (iLoop=0; iLoop < opt_iLoopCount; iLoop++) {
                                r = CompareStringW(gWinLCID, 0, (gSortedLines[line])->name, lineLen, (gSortedLines[guess])->name, guessLen);
                            }
                            if (r == 0) {
                                if (opt_terse == FALSE) {
                                    fprintf(stderr, "Error returned from Windows CompareStringW.\n");
                                }
                                exit(-1);
                            }
                            gCount++;
                        }
                        if (r== 2)   //  strings ==
                            break;
                        if (r == 1)  //  line < guess
                            hi = guess;
                        else         //  line > guess
                            lo   = guess;
                    }
                }
            }
            elapsedTime = timeGetTime() - startTime;
            break;
        }
        
        if (opt_unix)
        {
            unsigned long startTime = timeGetTime();
            int r;
            for (loops=0; loops<adj_loopCount; loops++) {
                
                for (line=0; line < gNumFileLines; line++) {
                    int hi   = gNumFileLines-1;
                    int lo   = 0;
                    int  guess = -1;
                    for (;;) {
                        int newGuess = (hi + lo) / 2;
                        if (newGuess == guess)
                            break;
                        guess = newGuess;
                        if (opt_usekeys) {
                            for (iLoop=0; iLoop < opt_iLoopCount; iLoop++) {
                                 r = strcmp((gSortedLines[line])->unixSortKey, (gSortedLines[guess])->unixSortKey);
                            }
                            gCount++;
                        }
                        else
                        {
                            for (iLoop=0; iLoop < opt_iLoopCount; iLoop++) {
                                r = strcoll((gSortedLines[line])->unixName, (gSortedLines[guess])->unixName);
                            }
                            errno = 0;
                            if (errno != 0) {
                                fprintf(stderr, "Error %d returned from strcoll.\n", errno);
                                exit(-1);
                            }
                            gCount++;
                        }
                        if (r == 0)   //  strings ==
                            break;
                        if (r < 0)  //  line < guess
                            hi = guess;
                        else         //  line > guess
                            lo   = guess;
                    }
                }
            }
            elapsedTime = timeGetTime() - startTime;
            break;
        }
        break;
    }

    int ns = (int)(float(1000000) * (float)elapsedTime / (float)gCount);
    if (opt_terse == FALSE) {
        printf("binary search:  total # of string compares = %d\n", gCount);
        printf("binary search:  compares per loop = %d\n", gCount / loops);
        printf("binary search:  time per compare = %d ns\n", ns);
    } else {
        printf("%d, ", ns);
    }

}




//---------------------------------------------------------------------------------------
//
//   doQSort()    The quick sort timing test.  Uses the C library qsort function.
//
//---------------------------------------------------------------------------------------
void doQSort() {
    int i;
    Line **sortBuf = new Line *[gNumFileLines];

    // Adjust loop count to compensate for file size.   QSort should be n log(n)
    double dLoopCount = double(opt_loopCount) * 3000. / (log10(gNumFileLines) * double(gNumFileLines));
    if (opt_usekeys) dLoopCount *= 5;
    int adj_loopCount = int(dLoopCount);
    if (adj_loopCount < 1) adj_loopCount = 1;


    gCount = 0;
    unsigned long startTime = timeGetTime();
    if (opt_win && opt_usekeys) {
        for (i=0; i<opt_loopCount; i++) {
            memcpy(sortBuf, gRandomLines, gNumFileLines * sizeof(Line *));
            qsort(sortBuf, gNumFileLines, sizeof(Line *), WinstrcmpK);
        }
    }

    else if (opt_win && opt_uselen) {
        for (i=0; i<adj_loopCount; i++) {
            memcpy(sortBuf, gRandomLines, gNumFileLines * sizeof(Line *));
            qsort(sortBuf, gNumFileLines, sizeof(Line *), WinstrcmpL);
        }
    }


    else if (opt_win && !opt_uselen) {
        for (i=0; i<adj_loopCount; i++) {
            memcpy(sortBuf, gRandomLines, gNumFileLines * sizeof(Line *));
            qsort(sortBuf, gNumFileLines, sizeof(Line *), Winstrcmp);
        }
    }

    else if (opt_icu && opt_usekeys) {
        for (i=0; i<adj_loopCount; i++) {
            memcpy(sortBuf, gRandomLines, gNumFileLines * sizeof(Line *));
            qsort(sortBuf, gNumFileLines, sizeof(Line *), ICUstrcmpK);
        }
    }

    else if (opt_icu && opt_uselen) {
        for (i=0; i<adj_loopCount; i++) {
            memcpy(sortBuf, gRandomLines, gNumFileLines * sizeof(Line *));
            qsort(sortBuf, gNumFileLines, sizeof(Line *), ICUstrcmpL);
        }
    }


    else if (opt_icu && !opt_uselen) {
        for (i=0; i<adj_loopCount; i++) {
            memcpy(sortBuf, gRandomLines, gNumFileLines * sizeof(Line *));
            qsort(sortBuf, gNumFileLines, sizeof(Line *), ICUstrcmp);
        }
    }

    else if (opt_unix && !opt_usekeys) {
        for (i=0; i<adj_loopCount; i++) {
            memcpy(sortBuf, gRandomLines, gNumFileLines * sizeof(Line *));
            qsort(sortBuf, gNumFileLines, sizeof(Line *), UNIXstrcmp);
        }
    }

    unsigned long elapsedTime = timeGetTime() - startTime;
    int ns = (int)(float(1000000) * (float)elapsedTime / (float)gCount);
    if (opt_terse == FALSE) {
        printf("qsort:  total # of string compares = %d\n", gCount);
        printf("qsort:  time per compare = %d ns\n", ns);
    } else {
        printf("%d, ", ns);
    }
};



//---------------------------------------------------------------------------------------
//
//    doKeyHist()       Output a table of data for
//                        average sort key size vs. string length.
//
//---------------------------------------------------------------------------------------
void doKeyHist() {
    int     i;
    int     maxLen = 0;

    // Find the maximum string length
    for (i=0; i<gNumFileLines; i++) {
        if (gFileLines[i].len > maxLen) maxLen = gFileLines[i].len;
    }

    // Allocate arrays to hold the histogram data
    int *accumulatedLen  = new int[maxLen+1];
    int *numKeysOfSize   = new int[maxLen+1];
    for (i=0; i<=maxLen; i++) {
        accumulatedLen[i] = 0;
        numKeysOfSize[i] = 0;
    }

    // Fill the arrays...
    for (i=0; i<gNumFileLines; i++) {
        int len = gFileLines[i].len;
        accumulatedLen[len] += strlen(gFileLines[i].icuSortKey);
        numKeysOfSize[len] += 1;
    }

    // And write out averages
    printf("String Length,  Avg Key Length,  Avg Key Len per char\n");
    for (i=1; i<=maxLen; i++) {
        if (numKeysOfSize[i] > 0) {
            printf("%d, %f, %f\n", i, (float)accumulatedLen[i] / (float)numKeysOfSize[i],
                (float)accumulatedLen[i] / (float)(numKeysOfSize[i] * i));
        }
    }
}

//---------------------------------------------------------------------------------------
//
//    doForwardIterTest(UBool)       Forward iteration test
//                                   argument null-terminated string used
//
//---------------------------------------------------------------------------------------
void doForwardIterTest(UBool haslen) {
    int count = 0;
    
    UErrorCode error = U_ZERO_ERROR;
    printf("\n\nPerforming forward iteration performance test with ");

    if (haslen) {
        printf("non-null terminated data -----------\n");
    }
    else {
        printf("null terminated data -----------\n");
    }
    printf("performance test on strings from file -----------\n");

    UChar dummytext[] = {0, 0};
    UCollationElements *iter = ucol_openElements(gCol, NULL, 0, &error);
    ucol_setText(iter, dummytext, 1, &error);
    
    gCount = 0;
    unsigned long startTime = timeGetTime();
    while (count < opt_loopCount) {
        int linecount = 0;
        while (linecount < gNumFileLines) {
            UChar *str = gFileLines[linecount].name;
            int strlen = haslen?gFileLines[linecount].len:-1;
            ucol_setText(iter, str, strlen, &error);
            while (ucol_next(iter, &error) != UCOL_NULLORDER) {
                gCount++;
            }

            linecount ++;
        }
        count ++;
    }
    unsigned long elapsedTime = timeGetTime() - startTime;
    printf("elapsedTime %d\n", elapsedTime);

    // empty loop recalculation
    count = 0;
    startTime = timeGetTime();
    while (count < opt_loopCount) {
        int linecount = 0;
        while (linecount < gNumFileLines) {
            UChar *str = gFileLines[linecount].name;
            int strlen = haslen?gFileLines[linecount].len:-1;
            ucol_setText(iter, str, strlen, &error);
            linecount ++;
        }
        count ++;
    }
    elapsedTime -= (timeGetTime() - startTime);
    printf("elapsedTime %d\n", elapsedTime);

    ucol_closeElements(iter);

    int ns = (int)(float(1000000) * (float)elapsedTime / (float)gCount);
    printf("Total number of strings compared %d in %d loops\n", gNumFileLines,
                                                                opt_loopCount);
    printf("Average time per ucol_next() nano seconds %d\n", ns);

    printf("performance test on skipped-5 concatenated strings from file -----------\n");

    UChar *str;
    int    strlen = 0;
    // appending all the strings
    int linecount = 0;
    while (linecount < gNumFileLines) {
        strlen += haslen?gFileLines[linecount].len:
                                      u_strlen(gFileLines[linecount].name);
        linecount ++;
    }
    str = (UChar *)malloc(sizeof(UChar) * strlen);
    int strindex = 0;
    linecount = 0;
    while (strindex < strlen) {
        int len = 0;
        len += haslen?gFileLines[linecount].len:
                                      u_strlen(gFileLines[linecount].name);
        memcpy(str + strindex, gFileLines[linecount].name, 
               sizeof(UChar) * len);
        strindex += len;
        linecount ++;
    }

    printf("Total size of strings %d\n", strlen);

    gCount = 0;
    count  = 0;

    if (!haslen) {
        strlen = -1;
    }
    iter = ucol_openElements(gCol, str, strlen, &error);
    if (!haslen) {
        strlen = u_strlen(str);
    }
    strlen -= 5; // any left over characters are not iterated,
                 // this is to ensure the backwards and forwards iterators
                 // gets the same position
    startTime = timeGetTime();
    while (count < opt_loopCount) {
        int count5 = 5;
        strindex = 0;
        ucol_setOffset(iter, strindex, &error);
        while (TRUE) {
            if (ucol_next(iter, &error) == UCOL_NULLORDER) {
                break;
            }
            gCount++;
            count5 --;
            if (count5 == 0) {
                strindex += 10;
                if (strindex > strlen) {
                    break;
                }
                ucol_setOffset(iter, strindex, &error);
                count5 = 5;
            }
        }
        count ++;
    }

    elapsedTime = timeGetTime() - startTime;
    printf("elapsedTime %d\n", elapsedTime);
    
    // empty loop recalculation
    int tempgCount = 0;
    count = 0;
    startTime = timeGetTime();
    while (count < opt_loopCount) {
        int count5 = 5;
        strindex = 0;
        ucol_setOffset(iter, strindex, &error);
        while (TRUE) {
            tempgCount ++;
            count5 --;
            if (count5 == 0) {
                strindex += 10;
                if (strindex > strlen) {
                    break;
                }
                ucol_setOffset(iter, strindex, &error);
                count5 = 5;
            }
        }
        count ++;
    }
    elapsedTime -= (timeGetTime() - startTime);
    printf("elapsedTime %d\n", elapsedTime);

    ucol_closeElements(iter);

    printf("gCount %d\n", gCount);
    ns = (int)(float(1000000) * (float)elapsedTime / (float)gCount);
    printf("Average time per ucol_next() nano seconds %d\n", ns);
}

//---------------------------------------------------------------------------------------
//
//    doBackwardIterTest(UBool)      Backwards iteration test
//                                   argument null-terminated string used
//
//---------------------------------------------------------------------------------------
void doBackwardIterTest(UBool haslen) {
    int count = 0;
    UErrorCode error = U_ZERO_ERROR;
    printf("\n\nPerforming backward iteration performance test with ");

    if (haslen) {
        printf("non-null terminated data -----------\n");
    }
    else {
        printf("null terminated data -----------\n");
    }
    
    printf("performance test on strings from file -----------\n");

    UCollationElements *iter = ucol_openElements(gCol, NULL, 0, &error);
    UChar dummytext[] = {0, 0};
    ucol_setText(iter, dummytext, 1, &error);

    gCount = 0;
    unsigned long startTime = timeGetTime();
    while (count < opt_loopCount) {
        int linecount = 0;
        while (linecount < gNumFileLines) {
            UChar *str = gFileLines[linecount].name;
            int strlen = haslen?gFileLines[linecount].len:-1;
            ucol_setText(iter, str, strlen, &error);
            while (ucol_previous(iter, &error) != UCOL_NULLORDER) {
                gCount ++;
            }

            linecount ++;
        }
        count ++;
    }
    unsigned long elapsedTime = timeGetTime() - startTime;

    printf("elapsedTime %d\n", elapsedTime);

    // empty loop recalculation
    count = 0;
    startTime = timeGetTime();
    while (count < opt_loopCount) {
        int linecount = 0;
        while (linecount < gNumFileLines) {
            UChar *str = gFileLines[linecount].name;
            int strlen = haslen?gFileLines[linecount].len:-1;
            ucol_setText(iter, str, strlen, &error);
            linecount ++;
        }
        count ++;
    }
    elapsedTime -= (timeGetTime() - startTime);

    printf("elapsedTime %d\n", elapsedTime);
    ucol_closeElements(iter);

    int ns = (int)(float(1000000) * (float)elapsedTime / (float)gCount);
    printf("Total number of strings compared %d in %d loops\n", gNumFileLines,
                                                                opt_loopCount);
    printf("Average time per ucol_previous() nano seconds %d\n", ns);

    printf("performance test on skipped-5 concatenated strings from file -----------\n");

    UChar *str;
    int    strlen = 0;
    // appending all the strings
    int linecount = 0;
    while (linecount < gNumFileLines) {
        strlen += haslen?gFileLines[linecount].len:
                                      u_strlen(gFileLines[linecount].name);
        linecount ++;
    }
    str = (UChar *)malloc(sizeof(UChar) * strlen);
    int strindex = 0;
    linecount = 0;
    while (strindex < strlen) {
        int len = 0;
        len += haslen?gFileLines[linecount].len:
                                      u_strlen(gFileLines[linecount].name);
        memcpy(str + strindex, gFileLines[linecount].name, 
               sizeof(UChar) * len);
        strindex += len;
        linecount ++;
    }

    printf("Total size of strings %d\n", strlen);

    gCount = 0;
    count  = 0;

    if (!haslen) {
        strlen = -1;
    }

    iter = ucol_openElements(gCol, str, strlen, &error);
    if (!haslen) {
        strlen = u_strlen(str);
    }

    startTime = timeGetTime();
    while (count < opt_loopCount) {
        int count5 = 5;
        strindex = 5;
        ucol_setOffset(iter, strindex, &error);
        while (TRUE) {
            if (ucol_previous(iter, &error) == UCOL_NULLORDER) {
                break;
            }
             gCount ++;
             count5 --;
             if (count5 == 0) {
                 strindex += 10;
                 if (strindex > strlen) {
                    break;
                 }
                 ucol_setOffset(iter, strindex, &error);
                 count5 = 5;
             }
        }
        count ++;
    }

    elapsedTime = timeGetTime() - startTime;
    printf("elapsedTime %d\n", elapsedTime);
    
    // empty loop recalculation
    count = 0;
    int tempgCount = 0;
    startTime = timeGetTime();
    while (count < opt_loopCount) {
        int count5 = 5;
        strindex = 5;
        ucol_setOffset(iter, strindex, &error);
        while (TRUE) {
             tempgCount ++;
             count5 --;
             if (count5 == 0) {
                 strindex += 10;
                 if (strindex > strlen) {
                    break;
                 }
                 ucol_setOffset(iter, strindex, &error);
                 count5 = 5;
             }
        }
        count ++;
    }
    elapsedTime -= (timeGetTime() - startTime);
    printf("elapsedTime %d\n", elapsedTime);
    ucol_closeElements(iter);

    printf("gCount %d\n", gCount);
    ns = (int)(float(1000000) * (float)elapsedTime / (float)gCount);
    printf("Average time per ucol_previous() nano seconds %d\n", ns);
}

//---------------------------------------------------------------------------------------
//
//    doIterTest()       Iteration test
//
//---------------------------------------------------------------------------------------
void doIterTest() {
    doForwardIterTest(opt_uselen);
    doBackwardIterTest(opt_uselen);
}


//----------------------------------------------------------------------------------------
//
//   UnixConvert   -- Convert the lines of the file to the encoding for UNIX
//                    Since it appears that Unicode support is going in the general
//                    direction of the use of UTF-8 locales, that is the approach
//                    that is used here.
//
//----------------------------------------------------------------------------------------
void  UnixConvert() {
    int    line;

    UConverter   *cvrtr;    // An ICU code page converter.
    UErrorCode    status = U_ZERO_ERROR;


    cvrtr = ucnv_open("utf-8", &status);    // we are just doing UTF-8 locales for now.
    if (U_FAILURE(status)) {
        fprintf(stderr, "ICU Converter open failed.: %d\n", &status);
        exit(-1);
    }

    for (line=0; line < gNumFileLines; line++) {
        int sizeNeeded = ucnv_fromUChars(cvrtr,
                                         0,            // ptr to target buffer.
                                         0,            // length of target buffer.
                                         gFileLines[line].name,
                                         -1,           //  source is null terminated
                                         &status);
        if (status != U_BUFFER_OVERFLOW_ERROR && status != U_ZERO_ERROR) {
            fprintf(stderr, "Conversion from Unicode, something is wrong.\n");
            exit(-1);
        }
        status = U_ZERO_ERROR;
        gFileLines[line].unixName = new char[sizeNeeded+1];
        sizeNeeded = ucnv_fromUChars(cvrtr,
                                         gFileLines[line].unixName, // ptr to target buffer.
                                         sizeNeeded+1, // length of target buffer.
                                         gFileLines[line].name,
                                         -1,           //  source is null terminated
                                         &status);
        if (U_FAILURE(status)) {
            fprintf(stderr, "ICU Conversion Failed.: %d\n", status);
            exit(-1);
        }
        gFileLines[line].unixName[sizeNeeded] = 0;
    };
    ucnv_close(cvrtr);
}


//----------------------------------------------------------------------------------------
//
//  class UCharFile   Class to hide all the gorp to read a file in
//                    and produce a stream of UChars.
//
//----------------------------------------------------------------------------------------
class UCharFile {
public:
    UCharFile(const char *fileName);
    ~UCharFile();
    UChar   get();
    UBool   eof() {return fEof;};
    UBool   error() {return fError;};
    
private:
    UCharFile (const UCharFile &other) {};                         // No copy constructor.
    UCharFile & operator = (const UCharFile &other) {return *this;};   // No assignment op

    FILE         *fFile;
    const char   *fName;
    UBool        fEof;
    UBool        fError;
    UChar        fPending2ndSurrogate;
    
    enum {UTF16LE, UTF16BE, UTF8} fEncoding;
};

UCharFile::UCharFile(const char * fileName) {
    fEof                 = FALSE;
    fError               = FALSE;
    fName                = fileName;
    fFile                = fopen(fName, "rb");
    fPending2ndSurrogate = 0;
    if (fFile == NULL) {
        fprintf(stderr, "Can not open file \"%s\"\n", opt_fName);
        fError = TRUE;
        return;
    }
    //
    //  Look for the byte order mark at the start of the file.
    //
    int BOMC1, BOMC2, BOMC3;
    BOMC1 = fgetc(fFile);
    BOMC2 = fgetc(fFile);

    if (BOMC1 == 0xff && BOMC2 == 0xfe) {
        fEncoding = UTF16LE; }
    else if (BOMC1 == 0xfe && BOMC2 == 0xff) {
        fEncoding = UTF16BE; }
    else if (BOMC1 == 0xEF && BOMC2 == 0xBB && (BOMC3 = fgetc(fFile)) == 0xBF ) {
        fEncoding = UTF8; }
    else
    {
        fprintf(stderr, "collperf:  file \"%s\" encoding must be UTF-8 or UTF-16, and "
            "must include a BOM.\n", fileName);
        fError = true;
        return;
    }
}


UCharFile::~UCharFile() {
    fclose(fFile);
}



UChar UCharFile::get() {
    UChar   c;
    switch (fEncoding) {
    case UTF16LE:
        {
            int  cL, cH;
            cL = fgetc(fFile);
            cH = fgetc(fFile);
            c  = cL  | (cH << 8);
            if (cH == EOF) {
                c   = 0;
                fEof = TRUE;
            }
            break;
        }
    case UTF16BE:
        {
            int  cL, cH;
            cH = fgetc(fFile);
            cL = fgetc(fFile);
            c  = cL  | (cH << 8);
            if (cL == EOF) {
                c   = 0;
                fEof = TRUE;
            }
            break;
        }
    case UTF8:
        {
            if (fPending2ndSurrogate != 0) {
                c = fPending2ndSurrogate;
                fPending2ndSurrogate = 0;
                break;
            }
            
            int ch = fgetc(fFile);   // Note:  c and ch are separate cause eof test doesn't work on UChar type.
            if (ch == EOF) {
                c = 0;
                fEof = TRUE;
                break;
            }
            
            if (ch <= 0x7f) {
                // It's ascii.  No further utf-8 conversion.
                c = ch;
                break;
            }
            
            // Figure out the lenght of the char and read the rest of the bytes
            //   into a temp array.
            int nBytes;
            if (ch >= 0xF0) {nBytes=4;}
            else if (ch >= 0xE0) {nBytes=3;}
            else if (ch >= 0xC0) {nBytes=2;}
            else {
                fprintf(stderr, "utf-8 encoded file contains corrupt data.\n");
                fError = TRUE;
                return 0;
            }
            
            unsigned char  bytes[10];
            bytes[0] = (unsigned char)ch;
            int i;
            for (i=1; i<nBytes; i++) {
                bytes[i] = fgetc(fFile);
                if (bytes[i] < 0x80 || bytes[i] >= 0xc0) {
                    fprintf(stderr, "utf-8 encoded file contains corrupt data.\n");
                    fError = TRUE;
                    return 0;
                }
            }
            
            // Convert the bytes from the temp array to a Unicode char.
            i = 0;
            uint32_t  cp;
            UTF8_NEXT_CHAR_UNSAFE(bytes, i, cp);
            c = (UChar)cp;
            
            if (cp >= 0x10000) {
                // The code point needs to be broken up into a utf-16 surrogate pair.
                //  Process first half this time through the main loop, and
                //   remember the other half for the next time through.
                UChar utf16Buf[3];
                i = 0;
                UTF16_APPEND_CHAR_UNSAFE(utf16Buf, i, cp);
                fPending2ndSurrogate = utf16Buf[1];
                c = utf16Buf[0];
            }
            break;
        };
    }
    return c;
}

//----------------------------------------------------------------------------------------
//
//   openRulesCollator  - Command line specified a rules file.  Read it in
//                        and open a collator with it.
//
//----------------------------------------------------------------------------------------
UCollator *openRulesCollator() {
    UCharFile f(opt_rules);
    if (f.error()) {
        return 0;
    }

    int  bufLen = 10000;
    UChar *buf = (UChar *)malloc(bufLen * sizeof(UChar));
    int i = 0;

    for(;;) {
        buf[i] = f.get();
        if (f.eof()) {
            break;
        }
        if (f.error()) {
            return 0;
        }
        i++;
        if (i >= bufLen) {
            bufLen += 10000;
            buf = (UChar *)realloc(buf, bufLen);
        }
    }
    buf[i] = 0;

    UErrorCode    status = U_ZERO_ERROR;
    UCollator *coll = ucol_openRules(buf, u_strlen(buf), UCOL_OFF,
                                         UCOL_DEFAULT_STRENGTH, NULL, &status);
    if (U_FAILURE(status)) {
        fprintf(stderr, "ICU ucol_openRules() open failed.: %d\n", status);
        return 0;
    }
    free(buf);
    return coll;
}





//----------------------------------------------------------------------------------------
//
//    Main   --  process command line, read in and pre-process the test file,
//                 call other functions to do the actual tests.
//
//----------------------------------------------------------------------------------------
int main(int argc, const char** argv) {
    if (ProcessOptions(argc, argv, opts) != TRUE || opt_help || opt_fName == 0) {
        printf(gUsageString);
        exit (1);
    }

    // Make sure that we've only got one API selected.
    if (opt_unix || opt_win) opt_icu = FALSE;
    if (opt_unix) opt_win = FALSE;

    //
    //  Set up an ICU collator
    //
    UErrorCode          status = U_ZERO_ERROR;

    if (opt_rules != 0) {
        gCol = openRulesCollator();
        if (gCol == 0) {return -1;}
    }
    else {
        gCol = ucol_open(opt_locale, &status);
        if (U_FAILURE(status)) {
            fprintf(stderr, "Collator creation failed.: %d\n", status);
            return -1;
        }
    }
    if (status==U_USING_DEFAULT_ERROR && opt_terse==FALSE) {
        fprintf(stderr, "Warning, U_USING_DEFAULT_ERROR for %s\n", opt_locale);
    }
    if (status==U_USING_FALLBACK_ERROR && opt_terse==FALSE) {
        fprintf(stderr, "Warning, U_USING_FALLBACK_ERROR for %s\n", opt_locale);
    }

    if (opt_norm) {
        ucol_setAttribute(gCol, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
    }
    if (opt_french && opt_frenchoff) {
        fprintf(stderr, "collperf:  Error, specified both -french and -frenchoff options.");
        exit(-1);
    }
    if (opt_french) {
        ucol_setAttribute(gCol, UCOL_FRENCH_COLLATION, UCOL_ON, &status);
    }
    if (opt_frenchoff) {
        ucol_setAttribute(gCol, UCOL_FRENCH_COLLATION, UCOL_OFF, &status);
    }
    if (opt_lower) {
        ucol_setAttribute(gCol, UCOL_CASE_FIRST, UCOL_LOWER_FIRST, &status);
    }
    if (opt_upper) {
        ucol_setAttribute(gCol, UCOL_CASE_FIRST, UCOL_UPPER_FIRST, &status);
    }
    if (opt_case) {
        ucol_setAttribute(gCol, UCOL_CASE_LEVEL, UCOL_ON, &status);
    }
    if (opt_shifted) {
        ucol_setAttribute(gCol, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
    }
    if (opt_level != 0) {
        switch (opt_level) {
        case 1:
            ucol_setAttribute(gCol, UCOL_STRENGTH, UCOL_PRIMARY, &status);
            break;
        case 2:
            ucol_setAttribute(gCol, UCOL_STRENGTH, UCOL_SECONDARY, &status);
            break;
        case 3:
            ucol_setAttribute(gCol, UCOL_STRENGTH, UCOL_TERTIARY, &status);
            break;
        case 4:
            ucol_setAttribute(gCol, UCOL_STRENGTH, UCOL_QUATERNARY, &status);
            break;
        case 5:
            ucol_setAttribute(gCol, UCOL_STRENGTH, UCOL_IDENTICAL, &status);
            break;
        default:
            fprintf(stderr, "-level param must be between 1 and 5\n");
            exit(-1);
        }
    }

    if (U_FAILURE(status)) {
        fprintf(stderr, "Collator attribute setting failed.: %d\n", status);
        return -1;
    }


    //
    //  Set up a Windows LCID
    //
    if (opt_langid != 0) {
        gWinLCID = MAKELCID(opt_langid, SORT_DEFAULT);
    }
    else {
        gWinLCID = uloc_getLCID(opt_locale);
    }


    //
    //  Set the UNIX locale
    //
    if (opt_unix) {
        if (setlocale(LC_ALL, opt_locale) == 0) {
            fprintf(stderr, "setlocale(LC_ALL, %s) failed.\n", opt_locale);
            exit(-1);
        }
    }

    // Read in  the input file.
    //   File assumed to be utf-16.
    //   Lines go onto heap buffers.  Global index array to line starts is created.
    //   Lines themselves are null terminated.
    //

    UCharFile f(opt_fName);
    if (f.error()) {
        exit(-1);
    }

    const int MAXLINES = 40000;
    gFileLines = new Line[MAXLINES];
    UChar buf[1024];
    int   column = 0;

    //  Read the file, split into lines, and save in memory.
    //  Loop runs once per utf-16 value from the input file,
    //    (The number of bytes read from file per loop iteration depends on external encoding.)
    for (;;) {

        UChar c = f.get();
        if (f.error()){
            exit(-1);
        }


        // We now have a good UTF-16 value in c.

        // Watch for CR, LF, EOF; these finish off a line.
        if (c == 0xd) {
            continue;
        }

        if (f.eof() || c == 0x0a || c==0x2028) {  // Unipad inserts 2028 line separators!
            buf[column++] = 0;
            if (column > 1) {
                gFileLines[gNumFileLines].name  = new UChar[column];
                gFileLines[gNumFileLines].len   = column-1;
                memcpy(gFileLines[gNumFileLines].name, buf, column * sizeof(UChar));
                gNumFileLines++;
                column = 0;
                if (gNumFileLines >= MAXLINES) {
                    fprintf(stderr, "File too big.  Max number of lines is %d\n", MAXLINES);
                    exit(-1);
                }

            }
            if (c == 0xa || c == 0x2028)
                continue;
            else
                break;  // EOF
        }
        buf[column++] = c;
        if (column >= 1023)
        {
            static UBool warnFlag = TRUE;
            if (warnFlag) {
                fprintf(stderr, "Warning - file line longer than 1023 chars truncated.\n");
                warnFlag = FALSE;
            }
            column--;
        }
    }

    if (opt_terse == FALSE) {
        printf("file \"%s\", %d lines.\n", opt_fName, gNumFileLines);
    }


    // Convert the lines to the UNIX encoding.
    if (opt_unix) {
        UnixConvert();
    }

    //
    //  Pre-compute ICU sort keys for the lines of the file.
    //
    int line;
    int t;

    for (line=0; line<gNumFileLines; line++) {
         t = ucol_getSortKey(gCol, gFileLines[line].name, -1, (unsigned char *)buf, sizeof(buf));
         gFileLines[line].icuSortKey  = new char[t];

         if (t > sizeof(buf)) {
             t = ucol_getSortKey(gCol, gFileLines[line].name, -1, (unsigned char *)gFileLines[line].icuSortKey , t);
         }
         else
         {
             memcpy(gFileLines[line].icuSortKey, buf, t);
         }
    }



    //
    //  Pre-compute Windows sort keys for the lines of the file.
    //
    for (line=0; line<gNumFileLines; line++) {
         t=LCMapStringW(gWinLCID, LCMAP_SORTKEY, gFileLines[line].name, -1, buf, sizeof(buf));
         gFileLines[line].winSortKey  = new char[t];
         if (t > sizeof(buf)) {
             t = LCMapStringW(gWinLCID, LCMAP_SORTKEY, gFileLines[line].name, -1, (unsigned short *)(gFileLines[line].winSortKey), t);
         }
         else
         {
             memcpy(gFileLines[line].winSortKey, buf, t);
         }
    }

    //
    //  Pre-compute UNIX sort keys for the lines of the file.
    //
    if (opt_unix) {
        for (line=0; line<gNumFileLines; line++) {
            t=strxfrm((char *)buf,  gFileLines[line].unixName,  sizeof(buf));
            gFileLines[line].unixSortKey  = new char[t];
            if (t > sizeof(buf)) {
                t = strxfrm(gFileLines[line].unixSortKey,  gFileLines[line].unixName,  sizeof(buf));
            }
            else
            {
                memcpy(gFileLines[line].unixSortKey, buf, t);
            }
        }
    }


    //
    //  Dump file lines, CEs, Sort Keys if requested.
    //
    if (opt_dump) {
        int  i;
        for (line=0; line<gNumFileLines; line++) {
            for (i=0;;i++) {
                UChar  c = gFileLines[line].name[i];
                if (c == 0)
                    break;
                if (c < 0x20 || c > 0x7e) {
                    printf("\\u%.4x", c);
                }
                else {
                    printf("%c", c);
                }
            }
            printf("\n");

            printf("   CEs: ");
            UCollationElements *CEiter = ucol_openElements(gCol, gFileLines[line].name, -1, &status);
            int32_t ce;
            i = 0;
            for (;;) {
                ce = ucol_next(CEiter, &status);
                if (ce == UCOL_NULLORDER) {
                    break;
                }
                printf(" %.8x", ce);
                if (++i > 8) {
                    printf("\n        ");
                    i = 0;
                }
            }
            printf("\n");
            ucol_closeElements(CEiter);


            printf("   ICU Sort Key: ");
            for (i=0; ; i++) {
                unsigned char c = gFileLines[line].icuSortKey[i];
                printf("%02x ", c);
                if (c == 0) {
                    break;
                }
                if (i > 0 && i % 20 == 0) {
                    printf("\n                 ");
                }
           }
            printf("\n");
        }
    }


    //
    //  Pre-sort the lines.
    //
    int i;
    gSortedLines = new Line *[gNumFileLines];
    for (i=0; i<gNumFileLines; i++) {
        gSortedLines[i] = &gFileLines[i];
    }

    if (opt_win) {
        qsort(gSortedLines, gNumFileLines, sizeof(Line *), Winstrcmp);
    }
    else if (opt_unix) {
        qsort(gSortedLines, gNumFileLines, sizeof(Line *), UNIXstrcmp);
    }
    else   /* ICU */
    {
        qsort(gSortedLines, gNumFileLines, sizeof(Line *), ICUstrcmp);
    }


    //
    //  Make up a randomized order, will be used for sorting tests.
    //
    gRandomLines = new Line *[gNumFileLines];
    for (i=0; i<gNumFileLines; i++) {
        gRandomLines[i] = &gFileLines[i];
    }
    qsort(gRandomLines, gNumFileLines, sizeof(Line *), ICURandomCmp);




    //
    //  We've got the file read into memory.  Go do something with it.
    //

    if (opt_qsort)     doQSort();
    if (opt_binsearch) doBinarySearch();
    if (opt_keygen)    doKeyGen();
    if (opt_keyhist)   doKeyHist();
    if (opt_itertest)  doIterTest();

    return 0;

}
