1 /* 2 * Copyright 2009, The Android Open Source Project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 14 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 15 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 16 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 17 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 20 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 21 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 23 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 28 #include <iostream> 29 #include <string> 30 #include <vector> 31 32 static const char gSite[] = "http://www.corp.google.com/eng/doc/emoji/dev.html"; 33 34 using namespace std; 35 36 static int hexchar_to_int(char c) { 37 if (c >= '0' && c <= '9') { 38 return c - '0'; 39 } 40 if (c >= 'A' && c <= 'F') { 41 return 10 + c - 'A'; 42 } 43 if (c >= 'a' && c <= 'f') { 44 return 10 + c - 'a'; 45 } 46 return -1; // unrecognized char for nex 47 } 48 49 /* Tool to build gmoji_pua table, listing all of the pua values for gmoji 50 */ 51 int main (int argc, char * const argv[]) { 52 53 char buffer[10000]; 54 FILE* file = fopen(argv[1], "r"); 55 if (NULL == file) { 56 std::cerr << "Can't open " << argv[1] << " for input. Aborting\n"; 57 std::cout << "\n"; 58 return -1; 59 } 60 61 vector<int> unichars; 62 int lineNo = 0; 63 for (;;) { 64 if (fgets(buffer, sizeof(buffer), file) == 0) { 65 break; 66 } 67 68 int prevPua = 0; 69 int pua = 0; 70 // we just want to eat the first 5 chars 71 for (int i = 0; i < 5; i++) { 72 int value = hexchar_to_int(buffer[i]); 73 if (value < 0) { // bad char for hex 74 std::cerr << "Expected hex char on line " << lineNo 75 << " col " << i << "\n"; 76 return -1; 77 } 78 pua = (pua << 4) | value; 79 } 80 if (pua < 0xFE000 || pua > 0xFEFFF) { 81 std::cerr << "PUA not in expected range " << pua << " line " 82 << lineNo << "\n"; 83 return -1; 84 } 85 if (pua <= prevPua) { 86 std::cerr << "PUA value not in ascending order line " 87 << lineNo << "\n"; 88 return -1; 89 } 90 unichars.push_back(pua); 91 prevPua = pua; 92 lineNo++; 93 } 94 95 // Now output our resulting array to look like a C array 96 const int perLine = 8; 97 const int base = unichars[0]; 98 printf("\n"); 99 printf("// Compressed gmoji table, sorted\n"); 100 printf("// Originally scraped from %s\n", gSite); 101 printf("// Input text file \"%s\"\n", argv[1]); 102 printf("\n"); 103 printf("static const uint16_t gGmojiPUA[] = {\n"); 104 for (int i = 0; i < unichars.size(); i++) { 105 if ((i % perLine) == 0) { // first one 106 printf(" "); 107 } 108 printf("0x%03X", unichars[i] - base); 109 if (i == unichars.size() - 1) { // last one entirely 110 printf("\n"); 111 } 112 else if ((i % perLine) == (perLine - 1)) { // last one on line 113 printf(",\n"); 114 } else { 115 printf(", "); 116 } 117 } 118 printf("};\n"); 119 printf("\n"); 120 printf("#define GMOJI_PUA_MIN 0x%X\n", unichars[0]); 121 printf("#define GMOJI_PUA_MAX 0x%X\n", unichars[unichars.size()-1]); 122 printf("#define GMOJI_PUA_COUNT (sizeof(gGmojiPUA) / sizeof(gGmojiPUA[0]))\n"); 123 printf("// GMOJI_PUA_COUNT should be %d\n", unichars.size()); 124 printf("\n"); 125 126 fclose(file); 127 return 0; 128 } 129