/*
* Copyright 2009, The Android Open Source Project
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COMPUTER, 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.
*/
#include <iostream>
#include <string>
#include <vector>
static const char gSite[] = "http://www.corp.google.com/eng/doc/emoji/dev.html";
using namespace std;
static int hexchar_to_int(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'A' && c <= 'F') {
return 10 + c - 'A';
}
if (c >= 'a' && c <= 'f') {
return 10 + c - 'a';
}
return -1; // unrecognized char for nex
}
/* Tool to build gmoji_pua table, listing all of the pua values for gmoji
*/
int main (int argc, char * const argv[]) {
char buffer[10000];
FILE* file = fopen(argv[1], "r");
if (NULL == file) {
std::cerr << "Can't open " << argv[1] << " for input. Aborting\n";
std::cout << "\n";
return -1;
}
vector<int> unichars;
int lineNo = 0;
for (;;) {
if (fgets(buffer, sizeof(buffer), file) == 0) {
break;
}
int prevPua = 0;
int pua = 0;
// we just want to eat the first 5 chars
for (int i = 0; i < 5; i++) {
int value = hexchar_to_int(buffer[i]);
if (value < 0) { // bad char for hex
std::cerr << "Expected hex char on line " << lineNo
<< " col " << i << "\n";
return -1;
}
pua = (pua << 4) | value;
}
if (pua < 0xFE000 || pua > 0xFEFFF) {
std::cerr << "PUA not in expected range " << pua << " line "
<< lineNo << "\n";
return -1;
}
if (pua <= prevPua) {
std::cerr << "PUA value not in ascending order line "
<< lineNo << "\n";
return -1;
}
unichars.push_back(pua);
prevPua = pua;
lineNo++;
}
// Now output our resulting array to look like a C array
const int perLine = 8;
const int base = unichars[0];
printf("\n");
printf("// Compressed gmoji table, sorted\n");
printf("// Originally scraped from %s\n", gSite);
printf("// Input text file \"%s\"\n", argv[1]);
printf("\n");
printf("static const uint16_t gGmojiPUA[] = {\n");
for (int i = 0; i < unichars.size(); i++) {
if ((i % perLine) == 0) { // first one
printf(" ");
}
printf("0x%03X", unichars[i] - base);
if (i == unichars.size() - 1) { // last one entirely
printf("\n");
}
else if ((i % perLine) == (perLine - 1)) { // last one on line
printf(",\n");
} else {
printf(", ");
}
}
printf("};\n");
printf("\n");
printf("#define GMOJI_PUA_MIN 0x%X\n", unichars[0]);
printf("#define GMOJI_PUA_MAX 0x%X\n", unichars[unichars.size()-1]);
printf("#define GMOJI_PUA_COUNT (sizeof(gGmojiPUA) / sizeof(gGmojiPUA[0]))\n");
printf("// GMOJI_PUA_COUNT should be %d\n", unichars.size());
printf("\n");
fclose(file);
return 0;
}