/*
**********************************************************************
*   Copyright (C) 2002, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   Date        Name        Description
*   10/11/02    aliu        Creation.
**********************************************************************
*/

#include <stdio.h>
#include <stdlib.h>
#include "unicode/utypes.h"
#include "unicode/putil.h"
#include "cmemory.h"
#include "cstring.h"
#include "filestrm.h"
#include "unewdata.h"
#include "uoptions.h"
#include "uprops.h"
#include "propname.h"
#include "uassert.h"

// TODO: Clean up and comment this code.

//----------------------------------------------------------------------
// BEGIN DATA
// 
// This is the raw data to be output.  We define the data structure,
// then include a machine-generated header that contains the actual
// data.

#include "unicode/uchar.h"
#include "unicode/uscript.h"

class AliasName {
public:
    const char* str;
    int32_t     index;

    AliasName(const char* str, int32_t index);

    int compare(const AliasName& other) const;

    UBool operator==(const AliasName& other) const {
        return compare(other) == 0;
    }

    UBool operator!=(const AliasName& other) const {
        return compare(other) != 0;
    }
};

AliasName::AliasName(const char* _str,
               int32_t _index) :
    str(_str),
    index(_index)
{
}

int AliasName::compare(const AliasName& other) const {
    return uprv_comparePropertyNames(str, other.str);
}

class Alias {
public:
    int32_t     enumValue;
    int32_t     nameGroupIndex;

    Alias(int32_t enumValue,
             int32_t nameGroupIndex);

    int32_t getUniqueNames(int32_t* nameGroupIndices) const;
};

Alias::Alias(int32_t anEnumValue,
                   int32_t aNameGroupIndex) :
    enumValue(anEnumValue),
    nameGroupIndex(aNameGroupIndex)
{
}

class Property : public Alias {
public:
    int32_t         valueCount;
    const Alias* valueList;

    Property(int32_t enumValue,
                       int32_t nameGroupIndex,
                       int32_t valueCount,
                       const Alias* valueList);
};

Property::Property(int32_t _enumValue,
                                       int32_t _nameGroupIndex,
                                       int32_t _valueCount,
                                       const Alias* _valueList) :
    Alias(_enumValue, _nameGroupIndex),
    valueCount(_valueCount),
    valueList(_valueList)
{
}

// *** Include the data header ***
#include "data.h"

/* return a list of unique names, not including "", for this property
 * @param stringIndices array of at least MAX_NAMES_PER_GROUP
 * elements, will be filled with indices into STRING_TABLE
 * @return number of indices, >= 1
 */
int32_t Alias::getUniqueNames(int32_t* stringIndices) const {
    int32_t count = 0;
    int32_t i = nameGroupIndex;
    UBool done = FALSE;
    while (!done) {
        int32_t j = NAME_GROUP[i++];
        if (j < 0) {
            done = TRUE;
            j = -j;
        }
        if (j == 0) continue; // omit "" entries
        UBool dupe = FALSE;
        for (int32_t k=0; k<count; ++k) {
            if (stringIndices[k] == j) {
                dupe = TRUE;
                break;
            }
            // also do a string check for things like "age|Age"
            if (STRING_TABLE[stringIndices[k]] == STRING_TABLE[j]) {
                //printf("Found dupe %s|%s\n",
                //       STRING_TABLE[stringIndices[k]].str,
                //       STRING_TABLE[j].str);
                dupe = TRUE;
                break;
            }
        }
        if (dupe) continue; // omit duplicates
        stringIndices[count++] = j;
    }
    return count;
}

// END DATA
//----------------------------------------------------------------------

#define MALLOC(type, count) \
  (type*) uprv_malloc(sizeof(type) * count)

void die(const char* msg) {
    fprintf(stderr, "Error: %s\n", msg);
    exit(1);
}

//----------------------------------------------------------------------

/**
 * A list of Alias objects.
 */
class AliasList {
public:
    virtual const Alias& operator[](int32_t i) const = 0;
    virtual int32_t count() const = 0;
};

/**
 * A single array.
 */
class AliasArrayList : public AliasList {
    const Alias* a;
    int32_t n;
public:
    AliasArrayList(const Alias* _a, int32_t _n) {
        a = _a;
        n = _n;
    }
    virtual const Alias& operator[](int32_t i) const {
        return a[i];
    }
    virtual int32_t count() const {
        return n;
    }
};

/**
 * A single array.
 */
class PropertyArrayList : public AliasList {
    const Property* a;
    int32_t n;
public:
    PropertyArrayList(const Property* _a, int32_t _n) {
        a = _a;
        n = _n;
    }
    virtual const Alias& operator[](int32_t i) const {
        return a[i];
    }
    virtual int32_t count() const {
        return n;
    }
};

//----------------------------------------------------------------------

/**
 * An element in a name index.  It maps a name (given by index) into
 * an enum value.
 */
class NameToEnumEntry {
public:
    int32_t nameIndex;
    int32_t enumValue;
    NameToEnumEntry(int32_t a, int32_t b) { nameIndex=a; enumValue=b; }
};

// Sort function for NameToEnumEntry (sort by name index)
U_CAPI int compareNameToEnumEntry(const void* e1, const void* e2) {
    return ((NameToEnumEntry*)e1)->nameIndex - ((NameToEnumEntry*)e2)->nameIndex;
}

//----------------------------------------------------------------------

/**
 * An element in an enum index.  It maps an enum into a name group entry
 * (given by index).
 */
class EnumToNameGroupEntry {
public:
    int32_t enumValue;
    int32_t nameGroupIndex;
    EnumToNameGroupEntry(int32_t a, int32_t b) { enumValue=a; nameGroupIndex=b; }
    
    // are enumValues contiguous for count entries starting with this one?
    // ***!!!*** we assume we are in an array and look at neighbors ***!!!***
    UBool isContiguous(int32_t count) const {
        const EnumToNameGroupEntry* p = this;
        for (int32_t i=1; i<count; ++i) {
            if (p[i].enumValue != (this->enumValue + i)) {
                return FALSE;
            }
        }
        return TRUE;
    }
};

// Sort function for EnumToNameGroupEntry (sort by name index)
U_CAPI int compareEnumToNameGroupEntry(const void* e1, const void* e2) {
    return ((EnumToNameGroupEntry*)e1)->enumValue - ((EnumToNameGroupEntry*)e2)->enumValue;
}

//----------------------------------------------------------------------

/**
 * An element in the map from enumerated property enums to value maps.
 */
class EnumToValueEntry {
public:
    int32_t enumValue;
    EnumToNameGroupEntry* enumToName;
    int32_t enumToName_count;
    NameToEnumEntry* nameToEnum;
    int32_t nameToEnum_count;

    // are enumValues contiguous for count entries starting with this one?
    // ***!!!*** we assume we are in an array and look at neighbors ***!!!***
    UBool isContiguous(int32_t count) const {
        const EnumToValueEntry* p = this;
        for (int32_t i=1; i<count; ++i) {
            if (p[i].enumValue != (this->enumValue + i)) {
                return FALSE;
            }
        }
        return TRUE;
    }
};

// Sort function for EnumToValueEntry (sort by enum)
U_CAPI int compareEnumToValueEntry(const void* e1, const void* e2) {
    return ((EnumToValueEntry*)e1)->enumValue - ((EnumToValueEntry*)e2)->enumValue;
}

//----------------------------------------------------------------------
// BEGIN Builder

#define IS_VALID_OFFSET(x) (((x)>=0)&&((x)<=MAX_OFFSET))

class Builder {
    // header:
    PropertyAliases header;

    // 0:
    NonContiguousEnumToOffset* enumToName;
    int32_t enumToName_size;
    Offset enumToName_offset;

    // 1: (deleted)

    // 2:
    NameToEnum* nameToEnum;
    int32_t nameToEnum_size;
    Offset nameToEnum_offset;

    // 3:
    NonContiguousEnumToOffset* enumToValue;
    int32_t enumToValue_size;
    Offset enumToValue_offset;

    // 4:
    ValueMap* valueMap;
    int32_t valueMap_size;
    int32_t valueMap_count;
    Offset valueMap_offset;

    // for any i, one of valueEnumToName[i] or valueNCEnumToName[i] is
    // NULL and one is not.  valueEnumToName_size[i] is the size of
    // the non-NULL one.  i=0..valueMapCount-1
    // 5a:
    EnumToOffset** valueEnumToName;
    // 5b:
    NonContiguousEnumToOffset** valueNCEnumToName;
    int32_t* valueEnumToName_size;
    Offset* valueEnumToName_offset;
    // 6:
    // arrays of valueMap_count pointers, sizes, & offsets
    NameToEnum** valueNameToEnum;
    int32_t* valueNameToEnum_size;
    Offset* valueNameToEnum_offset;

    // 98:
    Offset* nameGroupPool;
    int32_t nameGroupPool_count;
    int32_t nameGroupPool_size;
    Offset nameGroupPool_offset;

    // 99:
    char* stringPool;
    int32_t stringPool_count;
    int32_t stringPool_size;
    Offset stringPool_offset;
    Offset* stringPool_offsetArray; // relative to stringPool

    int32_t total_size; // size of everything

    int32_t debug;

public:

    Builder(int32_t debugLevel);
    ~Builder();

    void buildTopLevelProperties(const NameToEnumEntry* propName,
                                 int32_t propNameCount,
                                 const EnumToNameGroupEntry* propEnum,
                                 int32_t propEnumCount);

    void buildValues(const EnumToValueEntry* e2v,
                     int32_t count);

    void buildStringPool(const AliasName* propertyNames,
                         int32_t propertyNameCount,
                         const int32_t* nameGroupIndices,
                         int32_t nameGroupIndicesCount);

    void fixup();

    int8_t* createData(int32_t& length) const;

private:

    static EnumToOffset* buildEnumToOffset(const EnumToNameGroupEntry* e2ng,
                                           int32_t count,
                                           int32_t& size);
    static NonContiguousEnumToOffset*
        buildNCEnumToNameGroup(const EnumToNameGroupEntry* e2ng,
                               int32_t count,
                               int32_t& size);

    static NonContiguousEnumToOffset*
        buildNCEnumToValue(const EnumToValueEntry* e2v,
                           int32_t count,
                           int32_t& size);

    static NameToEnum* buildNameToEnum(const NameToEnumEntry* nameToEnum,
                                       int32_t count,
                                       int32_t& size);

    Offset stringIndexToOffset(int32_t index, UBool allowNeg=FALSE) const;
    void fixupNameToEnum(NameToEnum* n);
    void fixupEnumToNameGroup(EnumToOffset* e2ng);
    void fixupNCEnumToNameGroup(NonContiguousEnumToOffset* e2ng);

    void computeOffsets();
    void fixupStringPoolOffsets();
    void fixupNameGroupPoolOffsets();
    void fixupMiscellaneousOffsets();

    static int32_t align(int32_t a);
    static void erase(void* p, int32_t size);
};

Builder::Builder(int32_t debugLevel) {
    debug = debugLevel;
    enumToName = 0;
    nameToEnum = 0;
    enumToValue = 0;
    valueMap_count = 0;
    valueMap = 0;
    valueEnumToName = 0;
    valueNCEnumToName = 0;
    valueEnumToName_size = 0;
    valueEnumToName_offset = 0;
    valueNameToEnum = 0;
    valueNameToEnum_size = 0;
    valueNameToEnum_offset = 0;
    nameGroupPool = 0;
    stringPool = 0;
    stringPool_offsetArray = 0;
}

Builder::~Builder() {
    uprv_free(enumToName);
    uprv_free(nameToEnum);
    uprv_free(enumToValue);
    uprv_free(valueMap);
    for (int32_t i=0; i<valueMap_count; ++i) {
        uprv_free(valueEnumToName[i]);
        uprv_free(valueNCEnumToName[i]);
        uprv_free(valueNameToEnum[i]);
    }
    uprv_free(valueEnumToName);
    uprv_free(valueNCEnumToName);
    uprv_free(valueEnumToName_size);
    uprv_free(valueEnumToName_offset);
    uprv_free(valueNameToEnum);
    uprv_free(valueNameToEnum_size);
    uprv_free(valueNameToEnum_offset);
    uprv_free(nameGroupPool);
    uprv_free(stringPool);
    uprv_free(stringPool_offsetArray);
}

int32_t Builder::align(int32_t a) {
    U_ASSERT(a >= 0);
    int32_t k = a % sizeof(int32_t);
    if (k == 0) {
        return a;
    }
    a += sizeof(int32_t) - k;
    return a;
}

void Builder::erase(void* p, int32_t size) {
    U_ASSERT(size >= 0);
    int8_t* q = (int8_t*) p;
    while (size--) {
        *q++ = 0;
    }
}

EnumToOffset* Builder::buildEnumToOffset(const EnumToNameGroupEntry* e2ng,
                                         int32_t count,
                                         int32_t& size) {
    U_ASSERT(e2ng->isContiguous(count));
    size = align(EnumToOffset::getSize(count));
    EnumToOffset* result = (EnumToOffset*) uprv_malloc(size);
    erase(result, size);
    result->enumStart = e2ng->enumValue;
    result->enumLimit = e2ng->enumValue + count;
    Offset* p = result->getOffsetArray();
    for (int32_t i=0; i<count; ++i) {
        // set these to NGI index values
        // fix them up to NGI offset values
        U_ASSERT(IS_VALID_OFFSET(e2ng[i].nameGroupIndex));
        p[i] = (Offset) e2ng[i].nameGroupIndex; // FIXUP later
    }
    return result;
}

NonContiguousEnumToOffset*
Builder::buildNCEnumToNameGroup(const EnumToNameGroupEntry* e2ng,
                                int32_t count,
                                int32_t& size) {
    U_ASSERT(!e2ng->isContiguous(count));
    size = align(NonContiguousEnumToOffset::getSize(count));
    NonContiguousEnumToOffset* nc = (NonContiguousEnumToOffset*) uprv_malloc(size);
    erase(nc, size);
    nc->count = count;
    EnumValue* e = nc->getEnumArray();
    Offset* p = nc->getOffsetArray();
    for (int32_t i=0; i<count; ++i) {
        // set these to NGI index values
        // fix them up to NGI offset values
        e[i] = e2ng[i].enumValue;
        U_ASSERT(IS_VALID_OFFSET(e2ng[i].nameGroupIndex));
        p[i] = (Offset) e2ng[i].nameGroupIndex; // FIXUP later
    }
    return nc;
}

NonContiguousEnumToOffset*
Builder::buildNCEnumToValue(const EnumToValueEntry* e2v,
                            int32_t count,
                            int32_t& size) {
    U_ASSERT(!e2v->isContiguous(count));
    size = align(NonContiguousEnumToOffset::getSize(count));
    NonContiguousEnumToOffset* result = (NonContiguousEnumToOffset*) uprv_malloc(size);
    erase(result, size);
    result->count = count;
    EnumValue* e = result->getEnumArray();
    for (int32_t i=0; i<count; ++i) {
        e[i] = e2v[i].enumValue;
        // offset must be set later
    }
    return result;
}

/**
 * Given an index into the string pool, return an offset.  computeOffsets()
 * must have been called already.  If allowNegative is true, allow negatives
 * and preserve their sign.
 */
Offset Builder::stringIndexToOffset(int32_t index, UBool allowNegative) const {
    // Index 0 is ""; we turn this into an Offset of zero
    if (index == 0) return 0;
    if (index < 0) {
        if (allowNegative) {
            return -Builder::stringIndexToOffset(-index);
        } else {
            die("Negative string pool index");
        }
    } else {
        if (index >= stringPool_count) {
            die("String pool index too large");
        }
        Offset result = stringPool_offset + stringPool_offsetArray[index];
        U_ASSERT(result >= 0 && result < total_size);
        return result;
    }
    return 0; // never executed; make compiler happy
}

NameToEnum* Builder::buildNameToEnum(const NameToEnumEntry* nameToEnum,
                                     int32_t count,
                                     int32_t& size) {
    size = align(NameToEnum::getSize(count));
    NameToEnum* n2e = (NameToEnum*) uprv_malloc(size);
    erase(n2e, size);
    n2e->count = count;
    Offset* p = n2e->getNameArray();
    EnumValue* e = n2e->getEnumArray();
    for (int32_t i=0; i<count; ++i) {
        // set these to SP index values
        // fix them up to SP offset values
        U_ASSERT(IS_VALID_OFFSET(nameToEnum[i].nameIndex));
        p[i] = (Offset) nameToEnum[i].nameIndex; // FIXUP later
        e[i] = nameToEnum[i].enumValue;
    }
    return n2e;
}


void Builder::buildTopLevelProperties(const NameToEnumEntry* propName,
                                      int32_t propNameCount,
                                      const EnumToNameGroupEntry* propEnum,
                                      int32_t propEnumCount) {
    enumToName = buildNCEnumToNameGroup(propEnum,
                                        propEnumCount,
                                        enumToName_size);
    nameToEnum = buildNameToEnum(propName,
                                 propNameCount,
                                 nameToEnum_size);
}

void Builder::buildValues(const EnumToValueEntry* e2v,
                          int32_t count) {
    int32_t i;
    
    U_ASSERT(!e2v->isContiguous(count));

    valueMap_count = count;

    enumToValue = buildNCEnumToValue(e2v, count,
                                     enumToValue_size);

    valueMap_size = align(count * sizeof(ValueMap));
    valueMap = (ValueMap*) uprv_malloc(valueMap_size);
    erase(valueMap, valueMap_size);

    valueEnumToName = MALLOC(EnumToOffset*, count);
    valueNCEnumToName = MALLOC(NonContiguousEnumToOffset*, count);
    valueEnumToName_size = MALLOC(int32_t, count);
    valueEnumToName_offset = MALLOC(Offset, count);
    valueNameToEnum = MALLOC(NameToEnum*, count);
    valueNameToEnum_size = MALLOC(int32_t, count);
    valueNameToEnum_offset = MALLOC(Offset, count);

    for (i=0; i<count; ++i) {
        UBool isContiguous =
            e2v[i].enumToName->isContiguous(e2v[i].enumToName_count);
        valueEnumToName[i] = 0;
        valueNCEnumToName[i] = 0;
        if (isContiguous) {
            valueEnumToName[i] = buildEnumToOffset(e2v[i].enumToName,
                                                   e2v[i].enumToName_count,
                                                   valueEnumToName_size[i]);
        } else {
            valueNCEnumToName[i] = buildNCEnumToNameGroup(e2v[i].enumToName,
                                                          e2v[i].enumToName_count,
                                                          valueEnumToName_size[i]);
        }
        valueNameToEnum[i] =
            buildNameToEnum(e2v[i].nameToEnum,
                            e2v[i].nameToEnum_count,
                            valueNameToEnum_size[i]);
    }
}

void Builder::buildStringPool(const AliasName* propertyNames,
                              int32_t propertyNameCount,
                              const int32_t* nameGroupIndices,
                              int32_t nameGroupIndicesCount) {
    int32_t i;

    nameGroupPool_count = nameGroupIndicesCount;
    nameGroupPool_size = sizeof(Offset) * nameGroupPool_count;
    nameGroupPool = MALLOC(Offset, nameGroupPool_count);

    for (i=0; i<nameGroupPool_count; ++i) {
        // Some indices are negative.
        int32_t a = nameGroupIndices[i];
        if (a < 0) a = -a;
        U_ASSERT(IS_VALID_OFFSET(a));
        nameGroupPool[i] = (Offset) nameGroupIndices[i];
    }

    stringPool_count = propertyNameCount;
    stringPool_size = 0;
    // first string must be "" -- we skip it
    U_ASSERT(*propertyNames[0].str == 0);
    for (i=1 /*sic*/; i<propertyNameCount; ++i) {
        stringPool_size += uprv_strlen(propertyNames[i].str) + 1;
    }
    stringPool = MALLOC(char, stringPool_size);
    stringPool_offsetArray = MALLOC(Offset, stringPool_count);
    Offset soFar = 0;
    char* p = stringPool;
    stringPool_offsetArray[0] = -1; // we don't use this entry
    for (i=1 /*sic*/; i<propertyNameCount; ++i) {
        const char* str = propertyNames[i].str;
        int32_t len = uprv_strlen(str);
        uprv_strcpy(p, str);
        p += len;
        *p++ = 0;
        stringPool_offsetArray[i] = soFar;
        soFar += (Offset)(len+1);
    }
    U_ASSERT(soFar == stringPool_size);
    U_ASSERT(p == (stringPool + stringPool_size));
}

void Builder::computeOffsets() {
    int32_t i;
    Offset off = sizeof(header);

    if (debug>0) {
        printf("header   \t offset=%4d  size=%5d\n", 0, off);
    }

    // PropertyAliases must have no v-table and must be
    // padded (if necessary) to the next 32-bit boundary.
    U_ASSERT(offsetof(PropertyAliases, enumToName_offset) == 0);
    U_ASSERT(sizeof(header) % sizeof(int32_t) == 0);

    #define COMPUTE_OFFSET(foo) COMPUTE_OFFSET2(foo,int32_t)

    #define COMPUTE_OFFSET2(foo,type) \
      if (debug>0) printf(#foo "\t offset=%4d  size=%5d\n", off, foo##_size); \
      foo##_offset = off;       \
      U_ASSERT(IS_VALID_OFFSET(off + foo##_size)); \
      U_ASSERT(foo##_offset % sizeof(type) == 0); \
      off = (Offset) (off + foo##_size);

    COMPUTE_OFFSET(enumToName);     // 0:
    COMPUTE_OFFSET(nameToEnum);            // 2:
    COMPUTE_OFFSET(enumToValue);           // 3:
    COMPUTE_OFFSET(valueMap);              // 4:
        
    for (i=0; i<valueMap_count; ++i) {
        if (debug>0) {
            printf(" enumToName[%d]\t offset=%4d  size=%5d\n",
                   i, off, valueEnumToName_size[i]);
        }

        valueEnumToName_offset[i] = off;   // 5:
        U_ASSERT(IS_VALID_OFFSET(off + valueEnumToName_size[i]));
        off = (Offset) (off + valueEnumToName_size[i]);

        if (debug>0) {
            printf(" nameToEnum[%d]\t offset=%4d  size=%5d\n",
                   i, off, valueNameToEnum_size[i]);
        }

        valueNameToEnum_offset[i] = off;   // 6:
        U_ASSERT(IS_VALID_OFFSET(off + valueNameToEnum_size[i]));
        off = (Offset) (off + valueNameToEnum_size[i]);
    }
    
    // These last two chunks have weaker alignment needs
    COMPUTE_OFFSET2(nameGroupPool,Offset); // 98:
    COMPUTE_OFFSET2(stringPool,char);      // 99:

    total_size = off;
    if (debug>0) printf("total                         size=%5d\n\n", total_size);
    U_ASSERT(total_size <= (MAX_OFFSET+1));
}

void Builder::fixupNameToEnum(NameToEnum* n) {
    // Fix the string pool offsets in n
    Offset* p = n->getNameArray();
    for (int32_t i=0; i<n->count; ++i) {
        p[i] = stringIndexToOffset(p[i]);
    }
}

void Builder::fixupStringPoolOffsets() {
    int32_t i;
    
    // 2:
    fixupNameToEnum(nameToEnum);

    // 6:
    for (i=0; i<valueMap_count; ++i) {
        fixupNameToEnum(valueNameToEnum[i]);
    }

    // 98:
    for (i=0; i<nameGroupPool_count; ++i) {
        nameGroupPool[i] = stringIndexToOffset(nameGroupPool[i], TRUE);
    }
}

void Builder::fixupEnumToNameGroup(EnumToOffset* e2ng) {
    EnumValue i;
    int32_t j;
    Offset* p = e2ng->getOffsetArray();
    for (i=e2ng->enumStart, j=0; i<e2ng->enumLimit; ++i, ++j) {
        p[j] = nameGroupPool_offset + sizeof(Offset) * p[j];
    }
}

void Builder::fixupNCEnumToNameGroup(NonContiguousEnumToOffset* e2ng) {
    int32_t i;
    EnumValue* e = e2ng->getEnumArray();
    Offset* p = e2ng->getOffsetArray();
    for (i=0; i<e2ng->count; ++i) {
        p[i] = nameGroupPool_offset + sizeof(Offset) * p[i];
    }    
}

void Builder::fixupNameGroupPoolOffsets() {
    int32_t i;

    // 0:
    fixupNCEnumToNameGroup(enumToName);

    // 1: (deleted)

    // 5:
    for (i=0; i<valueMap_count; ++i) {
        // 5a:
        if (valueEnumToName[i] != 0) {
            fixupEnumToNameGroup(valueEnumToName[i]);
        }
        // 5b:
        if (valueNCEnumToName[i] != 0) {
            fixupNCEnumToNameGroup(valueNCEnumToName[i]);
        }
    }
}

void Builder::fixupMiscellaneousOffsets() {
    int32_t i;

    // header:
    erase(&header, sizeof(header));
    header.enumToName_offset = enumToName_offset;
    header.nameToEnum_offset = nameToEnum_offset;
    header.enumToValue_offset = enumToValue_offset;
    // header meta-info used by Java:
	U_ASSERT(total_size > 0 && total_size < 0x7FFF);
    header.total_size = (int16_t) total_size;
    header.valueMap_offset = valueMap_offset;
    header.valueMap_count = (int16_t) valueMap_count;
    header.nameGroupPool_offset = nameGroupPool_offset;
    header.nameGroupPool_count = (int16_t) nameGroupPool_count;
    header.stringPool_offset = stringPool_offset;
    header.stringPool_count = (int16_t) stringPool_count - 1; // don't include "" entry

	U_ASSERT(valueMap_count <= 0x7FFF);
	U_ASSERT(nameGroupPool_count <= 0x7FFF);
	U_ASSERT(stringPool_count <= 0x7FFF);

    // 3:
    Offset* p = enumToValue->getOffsetArray();
    EnumValue* e = enumToValue->getEnumArray();
    U_ASSERT(valueMap_count == enumToValue->count);
    for (i=0; i<valueMap_count; ++i) {
        p[i] = (Offset)(valueMap_offset + sizeof(ValueMap) * i);
    }

    // 4:
    for (i=0; i<valueMap_count; ++i) {
        ValueMap& v = valueMap[i];
        v.enumToName_offset = v.ncEnumToName_offset = 0;
        if (valueEnumToName[i] != 0) {
            v.enumToName_offset = valueEnumToName_offset[i];
        }
        if (valueNCEnumToName[i] != 0) {
            v.ncEnumToName_offset = valueEnumToName_offset[i];
        }
        v.nameToEnum_offset = valueNameToEnum_offset[i];
    }
}

void Builder::fixup() {
    computeOffsets();
    fixupStringPoolOffsets();
    fixupNameGroupPoolOffsets();
    fixupMiscellaneousOffsets();
}

int8_t* Builder::createData(int32_t& length) const {
    length = total_size;
    int8_t* result = MALLOC(int8_t, length);
    
    int8_t* p = result;
    int8_t* limit = result + length;
    
    #define APPEND2(x, size)   \
      U_ASSERT((p+size)<=limit); \
      uprv_memcpy(p, x, size); \
      p += size

    #define APPEND(x) APPEND2(x, x##_size)

    APPEND2(&header, sizeof(header));
    APPEND(enumToName);
    APPEND(nameToEnum);
    APPEND(enumToValue);
    APPEND(valueMap);
 
    for (int32_t i=0; i<valueMap_count; ++i) {
        U_ASSERT((valueEnumToName[i] != 0 && valueNCEnumToName[i] == 0) ||
               (valueEnumToName[i] == 0 && valueNCEnumToName[i] != 0));
        if (valueEnumToName[i] != 0) {
            APPEND2(valueEnumToName[i], valueEnumToName_size[i]);
        }
        if (valueNCEnumToName[i] != 0) {
            APPEND2(valueNCEnumToName[i], valueEnumToName_size[i]);
        }
        APPEND2(valueNameToEnum[i], valueNameToEnum_size[i]);
    }

    APPEND(nameGroupPool);
    APPEND(stringPool);

    U_ASSERT(p == limit);
    return result;
}

// END Builder
//----------------------------------------------------------------------

/* UDataInfo cf. udata.h */
static UDataInfo dataInfo = {
    sizeof(UDataInfo),
    0,

    U_IS_BIG_ENDIAN,
    U_CHARSET_FAMILY,
    sizeof(UChar),
    0,

    {PNAME_SIG_0, PNAME_SIG_1, PNAME_SIG_2, PNAME_SIG_3},
    {PNAME_FORMAT_VERSION, 0, 0, 0},                 /* formatVersion */
    {VERSION_0, VERSION_1, VERSION_2, VERSION_3} /* Unicode version */
};

// Glue for C<->C++
U_CAPI int compareAliasNames(const void* elem1, const void* elem2) {
    return ((const AliasName*)elem1)->compare(*(const AliasName*)elem2);
}

class genpname {

    // command-line options
    UBool useCopyright;
    UBool verbose;
    int32_t debug;

public:
    int      MMain(int argc, char *argv[]);

private:
    NameToEnumEntry* createNameIndex(const AliasList& list,
                                     int32_t& nameIndexCount);

    EnumToNameGroupEntry* createEnumIndex(const AliasList& list);

    int32_t  writeDataFile(const char *destdir, const Builder&);
};

int main(int argc, char *argv[]) {
    genpname app;
    U_MAIN_INIT_ARGS(argc, argv);
    return app.MMain(argc, argv);
}

static UOption options[]={
    UOPTION_HELP_H,
    UOPTION_HELP_QUESTION_MARK,
    UOPTION_COPYRIGHT,
    UOPTION_DESTDIR,
    UOPTION_VERBOSE,
    UOPTION_DEF("debug", 'D', UOPT_REQUIRES_ARG),
};

NameToEnumEntry* genpname::createNameIndex(const AliasList& list,
                                           int32_t& nameIndexCount) {

    // Build name => enum map

    // This is an n->1 map.  There are typically multiple names
    // mapping to one enum.  The name index is sorted in order of the name,
    // as defined by the uprv_compareAliasNames() function.

    int32_t i, j;
    int32_t count = list.count();
    
    // compute upper limit on number of names in the index
    int32_t nameIndexCapacity = count * MAX_NAMES_PER_GROUP;
    NameToEnumEntry* nameIndex = MALLOC(NameToEnumEntry, nameIndexCapacity);

    nameIndexCount = 0;
    int32_t names[MAX_NAMES_PER_GROUP];
    for (i=0; i<count; ++i) {
        const Alias& p = list[i];
        int32_t n = p.getUniqueNames(names);
        for (j=0; j<n; ++j) {
            U_ASSERT(nameIndexCount < nameIndexCapacity);
            nameIndex[nameIndexCount++] =
                NameToEnumEntry(names[j], p.enumValue);
        }
    }
    qsort((void*) nameIndex, nameIndexCount, sizeof(nameIndex[0]),
          compareNameToEnumEntry);
    if (debug>1) {
        printf("Alias names: %d\n", nameIndexCount);
        for (i=0; i<nameIndexCount; ++i) {
            printf("%s => %d\n",
                   STRING_TABLE[nameIndex[i].nameIndex].str,
                   nameIndex[i].enumValue);
        }
        printf("\n");
    }
    // make sure there are no duplicates.  for a sorted list we need
    // only compare adjacent items.  Alias.getUniqueNames() has
    // already eliminated duplicate names for a single property, which
    // does occur, so we're checking for duplicate names between two
    // properties, which should never occur.
    UBool ok = TRUE;
    for (i=1; i<nameIndexCount; ++i) {
        if (STRING_TABLE[nameIndex[i-1].nameIndex] ==
            STRING_TABLE[nameIndex[i].nameIndex]) {
            printf("Error: Duplicate names in property list: \"%s\", \"%s\"\n",
                   STRING_TABLE[nameIndex[i-1].nameIndex].str,
                   STRING_TABLE[nameIndex[i].nameIndex].str);
            ok = FALSE;
        }
    }
    if (!ok) {
        die("Two or more duplicate names in property list");
    }

    return nameIndex;
}

EnumToNameGroupEntry* genpname::createEnumIndex(const AliasList& list) {

    // Build the enum => name map

    // This is a 1->n map.  Each enum maps to 1 or more names.  To
    // accomplish this the index entry points to an element of the
    // NAME_GROUP array.  This is the short name (which may be empty).
    // From there, subsequent elements of NAME_GROUP are alternate
    // names for this enum, up to and including the first one that is
    // negative (negate for actual index).

    int32_t i, j, k;
    int32_t count = list.count();
    
    EnumToNameGroupEntry* enumIndex = MALLOC(EnumToNameGroupEntry, count);
    for (i=0; i<count; ++i) {
        const Alias& p = list[i];
        enumIndex[i] = EnumToNameGroupEntry(p.enumValue, p.nameGroupIndex);
    }
    qsort((void*) enumIndex, count, sizeof(enumIndex[0]),
          compareEnumToNameGroupEntry);
    if (debug>1) {
        printf("Property enums: %d\n", count);
        for (i=0; i<count; ++i) {
            printf("%d => %d: ",
                   enumIndex[i].enumValue,
                   enumIndex[i].nameGroupIndex);
            UBool done = FALSE;
            for (j=enumIndex[i].nameGroupIndex; !done; ++j) {
                k = NAME_GROUP[j];
                if (k < 0) {
                    k = -k;
                    done = TRUE;
                }
                printf("\"%s\"", STRING_TABLE[k].str);
                if (!done) printf(", ");
            }
            printf("\n");
        }
        printf("\n");
    }
    return enumIndex;
}

int genpname::MMain(int argc, char* argv[]) {

    int32_t i, j;

    /* preset then read command line options */
    options[3].value=u_getDataDirectory();
    argc=u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options);

    /* error handling, printing usage message */
    if (argc<0) {
        fprintf(stderr,
            "error in command line argument \"%s\"\n",
            argv[-argc]);
    }

    debug = options[5].doesOccur ? (*options[5].value - '0') : 0;

    if (argc!=1 || options[0].doesOccur || options[1].doesOccur ||
       debug < 0 || debug > 9) {
        fprintf(stderr,
            "usage: %s [-options]\n"
            "\tcreate " U_ICUDATA_NAME "_" PNAME_DATA_NAME "." PNAME_DATA_TYPE "\n"
            "options:\n"
            "\t-h or -? or --help  this usage text\n"
            "\t-v or --verbose     turn on verbose output\n"
            "\t-c or --copyright   include a copyright notice\n"
            "\t-d or --destdir     destination directory, followed by the path\n"
            "\t-D or --debug 0..9  emit debugging messages (if > 0)\n",
            argv[0]);
        return argc<0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
    }

    /* get the options values */
    useCopyright=options[2].doesOccur;
    verbose = options[4].doesOccur;

    // ------------------------------------------------------------
    // Sort the string table.  This produces the proper sorting
    // using the actual comparison function we will use.
    qsort((void*) STRING_TABLE, STRING_COUNT, sizeof(STRING_TABLE[0]),
          compareAliasNames);
    if (debug>1) {
        printf("String pool: %d\n", STRING_COUNT);
    }
    for (i=0; i<STRING_COUNT; ++i) {
        REMAP[STRING_TABLE[i].index] = i;
        if (debug>1) {
            if (i != 0) printf(", ");
            printf("%s (%d)", STRING_TABLE[i].str, STRING_TABLE[i].index);
        }
    }
    if (debug>1) {
        printf("\n\n");
    }

    // ------------------------------------------------------------
    // Fixup the NAME_GROUP indices so they match the sorted order
    for (i=0; i<NAME_GROUP_COUNT; ++i) {
        // keep negative entries (end markers) negative
        if (NAME_GROUP[i] < 0) {
            NAME_GROUP[i] = -REMAP[-NAME_GROUP[i]];
        } else {
            NAME_GROUP[i] = REMAP[NAME_GROUP[i]];
        }
    }

    // ------------------------------------------------------------
    // Create top-level property indices

    PropertyArrayList props(PROPERTY, PROPERTY_COUNT);
    int32_t propNameCount;
    NameToEnumEntry* propName = createNameIndex(props, propNameCount);
    EnumToNameGroupEntry* propEnum = createEnumIndex(props);

    // ------------------------------------------------------------
    // Create indices for the value list for each enumerated property

    // This will have more entries than we need...
    EnumToValueEntry* enumToValue = MALLOC(EnumToValueEntry, PROPERTY_COUNT);
    int32_t enumToValue_count = 0;
    for (i=0, j=0; i<PROPERTY_COUNT; ++i) {
        if (PROPERTY[i].valueCount == 0) continue;
        AliasArrayList values(PROPERTY[i].valueList,
                              PROPERTY[i].valueCount);
        enumToValue[j].enumValue = PROPERTY[i].enumValue;
        enumToValue[j].enumToName = createEnumIndex(values);
        enumToValue[j].enumToName_count = PROPERTY[i].valueCount;
        enumToValue[j].nameToEnum = createNameIndex(values,
                                                    enumToValue[j].nameToEnum_count);
        ++j;
    }
    enumToValue_count = j;
    qsort((void*) enumToValue, enumToValue_count, sizeof(enumToValue[0]),
          compareEnumToValueEntry);

    // ------------------------------------------------------------
    // Build PropertyAliases layout in memory

    Builder builder(debug);

    builder.buildTopLevelProperties(propName,
                                    propNameCount,
                                    propEnum,
                                    PROPERTY_COUNT);
    
    builder.buildValues(enumToValue,
                        enumToValue_count);

    builder.buildStringPool(STRING_TABLE,
                            STRING_COUNT,
                            NAME_GROUP,
                            NAME_GROUP_COUNT);

    builder.fixup();

    ////////////////////////////////////////////////////////////
    // Write the output file
    ////////////////////////////////////////////////////////////
    int32_t wlen = writeDataFile(options[3].value, builder);
    if (verbose) {
        fprintf(stdout, "Output file: %s.%s, %ld bytes\n",
            U_ICUDATA_NAME "_" PNAME_DATA_NAME, PNAME_DATA_TYPE, (long)wlen);
    }

    return 0; // success
}

int32_t genpname::writeDataFile(const char *destdir, const Builder& builder) {
    int32_t length;
    int8_t* data = builder.createData(length);

    UNewDataMemory *pdata;
    UErrorCode status = U_ZERO_ERROR;

    pdata = udata_create(destdir, PNAME_DATA_TYPE, U_ICUDATA_NAME "_" PNAME_DATA_NAME, &dataInfo,
                         useCopyright ? U_COPYRIGHT_STRING : 0, &status);
    if (U_FAILURE(status)) {
        die("Unable to create data memory");
    }

    udata_writeBlock(pdata, data, length);

    int32_t dataLength = (int32_t) udata_finish(pdata, &status);
    if (U_FAILURE(status)) {
        die("Error writing output file");
    }
    if (dataLength != length) {
        die("Written file doesn't match expected size");
    }

    return dataLength;
}

//eof
