Home | History | Annotate | Download | only in emoji
      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