#!/usr/bin/env python
# Copyright (c) 2010 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import csv
import os.path
import string
import sys

ENTITY = 0
VALUE = 1

def convert_entity_to_cpp_name(entity):
    postfix = "EntityName"
    if entity[-1] == ";":
        return "%sSemicolon%s" % (entity[:-1], postfix)
    return "%s%s" % (entity, postfix)


def convert_entity_to_uchar_array(entity):
    return "{'%s'}" % "', '".join(entity)


def convert_value_to_int(value):
    assert(value[0] == "U")
    assert(value[1] == "+")
    return "0x" + value[2:]


def offset_table_entry(offset):
    return "    &staticEntityTable[%s]," % offset


program_name = os.path.basename(__file__)
if len(sys.argv) < 4 or sys.argv[1] != "-o":
    # Python 3, change to: print("Usage: %s -o OUTPUT_FILE INPUT_FILE" % program_name, file=sys.stderr)
    sys.stderr.write("Usage: %s -o OUTPUT_FILE INPUT_FILE\n" % program_name)
    exit(1)

output_path = sys.argv[2]
input_path = sys.argv[3]

html_entity_names_file = open(input_path)
entries = list(csv.reader(html_entity_names_file))
html_entity_names_file.close()

entries.sort(key = lambda entry: entry[ENTITY])
entity_count = len(entries)

output_file = open(output_path, "w")

output_file.write("""/*
 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

// THIS FILE IS GENERATED BY WebCore/html/parser/create-html-entity-table
// DO NOT EDIT (unless you are a ninja)!

#include "config.h"
#include "HTMLEntityTable.h"

namespace WebCore {

namespace {
""")

for entry in entries:
    output_file.write("const UChar %sEntityName[] = %s;" % (
        convert_entity_to_cpp_name(entry[ENTITY]),
        convert_entity_to_uchar_array(entry[ENTITY])))

output_file.write("""
HTMLEntityTableEntry staticEntityTable[%s] = {""" % entity_count)

index = {}
offset = 0
for entry in entries:
    letter = entry[ENTITY][0]
    if not index.get(letter):
        index[letter] = offset
    output_file.write('    { %sEntityName, %s, %s },' % (
        convert_entity_to_cpp_name(entry[ENTITY]),
        len(entry[ENTITY]),
        convert_value_to_int(entry[VALUE])))
    offset += 1

output_file.write("""};
""")

output_file.write("const HTMLEntityTableEntry* uppercaseOffset[] = {")
for letter in string.ascii_uppercase:
    output_file.write(offset_table_entry(index[letter]))
output_file.write(offset_table_entry(index['a']))
output_file.write("""};

const HTMLEntityTableEntry* lowercaseOffset[] = {""")
for letter in string.ascii_lowercase:
    output_file.write(offset_table_entry(index[letter]))
output_file.write(offset_table_entry(entity_count))
output_file.write("""};

}

const HTMLEntityTableEntry* HTMLEntityTable::firstEntryStartingWith(UChar c)
{
    if (c >= 'A' && c <= 'Z')
        return uppercaseOffset[c - 'A'];
    if (c >= 'a' && c <= 'z')
        return lowercaseOffset[c - 'a'];
    return 0;
}

const HTMLEntityTableEntry* HTMLEntityTable::lastEntryStartingWith(UChar c)
{
    if (c >= 'A' && c <= 'Z')
        return uppercaseOffset[c - 'A' + 1] - 1;
    if (c >= 'a' && c <= 'z')
        return lowercaseOffset[c - 'a' + 1] - 1;
    return 0;
}

const HTMLEntityTableEntry* HTMLEntityTable::firstEntry()
{
    return &staticEntityTable[0];
}

const HTMLEntityTableEntry* HTMLEntityTable::lastEntry()
{
    return &staticEntityTable[%s - 1];
}

}
""" % entity_count)
