/*
*Copyright(c)2017, Jeffrey Lee
*Allrightsreserved.
*
 * 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 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 HOLDER 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
  int x11;
  int unicode;
} keysym;

static int cmpfunc(const void *a, const void *b) {
  const keysym *aa = (const keysym *) a;
  const keysym *bb = (const keysym *) b;
  return aa->x11 - bb->x11;
}

int main(int argc,char **argv) {
  keysym *keysyms = NULL;
  int count = 0;
  while (!feof(stdin)) {
    char buf[1024];
    char *line = fgets(buf, sizeof(buf), stdin);
    if (line == NULL) {
      break;
    }
    /* Look for a unicode mapping */
    char *unicode = strstr(line, "U+");
    char *x11 = strstr(line, "0x");
    if (!unicode || !x11 || strncmp(line, "#define", 7)) {
      continue;
    }
    if ((unicode[-3] != '/') || (unicode[-2] != '*')) {
      continue;
    }
    keysyms = realloc(keysyms, sizeof(keysym)*(count+1));
    if (!keysyms) {
      fprintf(stderr, "No memory\n");
      return -1;
    }
    keysyms[count].x11 = strtol(x11, NULL, 16);
    keysyms[count].unicode = strtol(unicode+2, NULL, 16);
    /* Skip codes which are in the full Unicode region */
    if (keysyms[count].x11 >= 0x1000000) {
      continue;
    }
    /* Skip Latin1 */
    if (keysyms[count].x11 < 0x100) {
      continue;
    }
    count++;
  }
  /* Sort the list */
  qsort(keysyms, count, sizeof(keysym), cmpfunc);
  /* Write it out */
  for (int i=0;i<count;i++) {
    keysym *k = &keysyms[i];
    if ((i == 0) || (k[-1].x11 != k->x11)) {
      printf("  { 0x%x, 0x%x },\n", k->x11, k->unicode);
    }
  }
  return 0;
}
