/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-â
âvi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8                                :viâ
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¡
â Copyright 2020 Justine Alexandra Roberts Tunney                              â
â                                                                              â
â Permission to use, copy, modify, and/or distribute this software for         â
â any purpose with or without fee is hereby granted, provided that the         â
â above copyright notice and this permission notice appear in all copies.      â
â                                                                              â
â THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                â
â WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                â
â WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             â
â AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         â
â DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        â
â PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               â
â TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             â
â PERFORMANCE OF THIS SOFTWARE.                                                â
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ*/
#include "libc/fmt/bing.internal.h"
#include "libc/macros.internal.h"

static const int kCp437i[] = {
    0x000a << 8 | 10,   // \n NEWLINE
    0x000d << 8 | 13,   // \r CARRIAGE RETURN
    0x0022 << 8 | 34,   // " QUOTATION MARK
    0x0027 << 8 | 39,   // ' APOSTROPHE
    0x003f << 8 | 63,   // ? QUESTION MARK
    0x005c << 8 | 92,   // \ REVERSE SOLIDUS
    0x00a0 << 8 | 0,    // Â  NO-BREAK SPACE
    0x00a1 << 8 | 173,  // Â¡ INVERTED EXCLAMATION MARK
    0x00a2 << 8 | 155,  // Â¢ CENT SIGN
    0x00a3 << 8 | 156,  // Â£ POUND SIGN
    0x00a5 << 8 | 157,  // Â¥ YEN SIGN
    0x00a7 << 8 | 21,   // Â§ SECTION SIGN
    0x00aa << 8 | 166,  // Âª FEMININE ORDINAL INDICATOR
    0x00ab << 8 | 174,  // Â« LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
    0x00ac << 8 | 170,  // Â¬ NOT SIGN
    0x00b0 << 8 | 248,  // Â° DEGREE SIGN
    0x00b1 << 8 | 241,  // Â± PLUS-MINUS SIGN
    0x00b2 << 8 | 253,  // Â² SUPERSCRIPT TWO
    0x00b5 << 8 | 230,  // Âµ MICRO SIGN
    0x00b6 << 8 | 20,   // Â¶ PILCROW SIGN
    0x00b7 << 8 | 250,  // Â· MIDDLE DOT
    0x00ba << 8 | 167,  // Âº MASCULINE ORDINAL INDICATOR
    0x00bb << 8 | 175,  // Â» RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
    0x00bc << 8 | 172,  // Â¼ VULGAR FRACTION ONE QUARTER
    0x00bd << 8 | 171,  // Â½ VULGAR FRACTION ONE HALF
    0x00bf << 8 | 168,  // Â¿ INVERTED QUESTION MARK
    0x00c4 << 8 | 142,  // Ã LATIN CAPITAL LETTER A WITH DIAERESIS
    0x00c5 << 8 | 143,  // Ã LATIN CAPITAL LETTER A WITH RING ABOVE
    0x00c6 << 8 | 146,  // Ã LATIN CAPITAL LETTER AE
    0x00c7 << 8 | 128,  // Ã LATIN CAPITAL LETTER C WITH CEDILLA
    0x00c9 << 8 | 144,  // Ã LATIN CAPITAL LETTER E WITH ACUTE
    0x00d1 << 8 | 165,  // Ã LATIN CAPITAL LETTER N WITH TILDE
    0x00d6 << 8 | 153,  // Ã LATIN CAPITAL LETTER O WITH DIAERESIS
    0x00d7 << 8 | 250,  // Ã MULTIPLICATION SIGN
    0x00dc << 8 | 154,  // Ã LATIN CAPITAL LETTER U WITH DIAERESIS
    0x00df << 8 | 225,  // Ã LATIN SMALL LETTER SHARP S
    0x00e0 << 8 | 133,  // Ã  LATIN SMALL LETTER A WITH GRAVE
    0x00e1 << 8 | 160,  // Ã¡ LATIN SMALL LETTER A WITH ACUTE
    0x00e2 << 8 | 131,  // Ã¢ LATIN SMALL LETTER A WITH CIRCUMFLEX
    0x00e4 << 8 | 132,  // Ã¤ LATIN SMALL LETTER A WITH DIAERESIS
    0x00e5 << 8 | 134,  // Ã¥ LATIN SMALL LETTER A WITH RING ABOVE
    0x00e6 << 8 | 145,  // Ã¦ LATIN SMALL LETTER AE
    0x00e7 << 8 | 135,  // Ã§ LATIN SMALL LETTER C WITH CEDILLA
    0x00e8 << 8 | 138,  // Ã¨ LATIN SMALL LETTER E WITH GRAVE
    0x00e9 << 8 | 130,  // Ã© LATIN SMALL LETTER E WITH ACUTE
    0x00ea << 8 | 136,  // Ãª LATIN SMALL LETTER E WITH CIRCUMFLEX
    0x00eb << 8 | 137,  // Ã« LATIN SMALL LETTER E WITH DIAERESIS
    0x00ec << 8 | 141,  // Ã¬ LATIN SMALL LETTER I WITH GRAVE
    0x00ed << 8 | 161,  // Ã­ LATIN SMALL LETTER I WITH ACUTE
    0x00ee << 8 | 140,  // Ã® LATIN SMALL LETTER I WITH CIRCUMFLEX
    0x00ef << 8 | 139,  // Ã¯ LATIN SMALL LETTER I WITH DIAERESIS
    0x00f1 << 8 | 164,  // Ã± LATIN SMALL LETTER N WITH TILDE
    0x00f2 << 8 | 149,  // Ã² LATIN SMALL LETTER O WITH GRAVE
    0x00f3 << 8 | 162,  // Ã³ LATIN SMALL LETTER O WITH ACUTE
    0x00f4 << 8 | 147,  // Ã´ LATIN SMALL LETTER O WITH CIRCUMFLEX
    0x00f6 << 8 | 148,  // Ã¶ LATIN SMALL LETTER O WITH DIAERESIS
    0x00f7 << 8 | 246,  // Ã· DIVISION SIGN
    0x00f9 << 8 | 151,  // Ã¹ LATIN SMALL LETTER U WITH GRAVE
    0x00fa << 8 | 163,  // Ãº LATIN SMALL LETTER U WITH ACUTE
    0x00fb << 8 | 150,  // Ã» LATIN SMALL LETTER U WITH CIRCUMFLEX
    0x00fc << 8 | 129,  // Ã¼ LATIN SMALL LETTER U WITH DIAERESIS
    0x00ff << 8 | 152,  // Ã¿ LATIN SMALL LETTER Y WITH DIAERESIS
    0x017f << 8 | 244,  // Å¿ LATIN SMALL LETTER LONG S
    0x0192 << 8 | 159,  // Æ LATIN SMALL LETTER F WITH HOOK
    0x0393 << 8 | 226,  // Î GREEK CAPITAL LETTER GAMMA
    0x0398 << 8 | 233,  // Î GREEK CAPITAL LETTER THETA
    0x03a0 << 8 | 227,  // Î  GREEK CAPITAL LETTER PI
    0x03a3 << 8 | 228,  // Î£ GREEK CAPITAL LETTER SIGMA
    0x03a6 << 8 | 232,  // Î¦ GREEK CAPITAL LETTER PHI
    0x03a9 << 8 | 234,  // Î© GREEK CAPITAL LETTER OMEGA
    0x03b1 << 8 | 224,  // Î± GREEK SMALL LETTER ALPHA
    0x03b2 << 8 | 225,  // Î² GREEK SMALL LETTER BETA
    0x03b4 << 8 | 235,  // Î´ GREEK SMALL LETTER DELTA
    0x03b5 << 8 | 238,  // Îµ GREEK SMALL LETTER EPSILON
    0x03bb << 8 | 255,  // Î» GREEK SMALL LETTER LAMDA
    0x03bc << 8 | 230,  // Î¼ GREEK SMALL LETTER MU
    0x03c0 << 8 | 227,  // Ï GREEK SMALL LETTER PI
    0x03c3 << 8 | 229,  // Ï GREEK SMALL LETTER SIGMA
    0x03c4 << 8 | 231,  // Ï GREEK SMALL LETTER TAU
    0x03c6 << 8 | 237,  // Ï GREEK SMALL LETTER PHI
    0x03d5 << 8 | 237,  // Ï GREEK PHI SYMBOL
    0x2018 << 8 | 39,   // â LEFT SINGLE QUOTATION MARK
    0x201c << 8 | 34,   // â LEFT DOUBLE QUOTATION MARK
    0x2022 << 8 | 7,    // â¢ BULLET
    0x203c << 8 | 19,   // â¼ DOUBLE EXCLAMATION MARK
    0x2047 << 8 | 63,   // â DOUBLE QUESTION MARK
    0x207f << 8 | 252,  // â¿ SUPERSCRIPT LATIN SMALL LETTER N
    0x20a7 << 8 | 158,  // â§ PESETA SIGN
    0x20ac << 8 | 158,  // â¬ EURO SIGN
    0x2126 << 8 | 234,  // â¦ OHM SIGN
    0x2190 << 8 | 27,   // â LEFTWARDS ARROW
    0x2191 << 8 | 24,   // â UPWARDS ARROW
    0x2192 << 8 | 26,   // â RIGHTWARDS ARROW
    0x2193 << 8 | 25,   // â DOWNWARDS ARROW
    0x2194 << 8 | 29,   // â LEFT RIGHT ARROW
    0x2195 << 8 | 18,   // â UP DOWN ARROW
    0x21a8 << 8 | 23,   // â¨ UP DOWN ARROW WITH BASE
    0x2202 << 8 | 235,  // â PARTIAL DIFFERENTIAL
    0x2205 << 8 | 0,    // â EMPTY SET
    0x2208 << 8 | 238,  // â ELEMENT OF
    0x220a << 8 | 238,  // â SMALL ELEMENT OF
    0x220f << 8 | 227,  // â N-ARY PRODUCT
    0x2211 << 8 | 228,  // â N-ARY SUMMATION
    0x2219 << 8 | 249,  // â BULLET OPERATOR
    0x221a << 8 | 251,  // â SQUARE ROOT
    0x221e << 8 | 236,  // â INFINITY
    0x221f << 8 | 28,   // â RIGHT ANGLE
    0x2229 << 8 | 239,  // â© INTERSECTION
    0x2248 << 8 | 247,  // â ALMOST EQUAL TO
    0x2261 << 8 | 240,  // â¡ IDENTICAL TO
    0x2264 << 8 | 243,  // â¤ LESS-THAN OR EQUAL TO
    0x2265 << 8 | 242,  // â¥ GREATER-THAN OR EQUAL TO
    0x2302 << 8 | 127,  // â HOUSE
    0x2310 << 8 | 169,  // â REVERSED NOT SIGN
    0x2320 << 8 | 244,  // â  TOP HALF INTEGRAL
    0x2321 << 8 | 245,  // â¡ BOTTOM HALF INTEGRAL
    0x2400 << 8 | 0,    // â SYMBOL FOR NULL
    0x2500 << 8 | 196,  // â BOX DRAWS LIGHT HORIZONTAL
    0x2502 << 8 | 179,  // â BOX DRAWS LIGHT VERTICAL
    0x250c << 8 | 218,  // â BOX DRAWS LIGHT DOWN AND RIGHT
    0x2510 << 8 | 191,  // â BOX DRAWS LIGHT DOWN AND LEFT
    0x2514 << 8 | 192,  // â BOX DRAWS LIGHT UP AND RIGHT
    0x2518 << 8 | 217,  // â BOX DRAWS LIGHT UP AND LEFT
    0x251c << 8 | 195,  // â BOX DRAWS LIGHT VERTICAL AND RIGHT
    0x2524 << 8 | 180,  // â¤ BOX DRAWS LIGHT VERTICAL AND LEFT
    0x252c << 8 | 194,  // â¬ BOX DRAWS LIGHT DOWN AND HORIZONTAL
    0x2534 << 8 | 193,  // â´ BOX DRAWS LIGHT UP AND HORIZONTAL
    0x253c << 8 | 197,  // â¼ BOX DRAWS LIGHT VERTICAL AND HORIZONTAL
    0x2550 << 8 | 205,  // â BOX DRAWS DOUBLE HORIZONTAL
    0x2551 << 8 | 186,  // â BOX DRAWS DOUBLE VERTICAL
    0x2552 << 8 | 213,  // â BOX DRAWS DOWN SINGLE AND RIGHT DOUBLE
    0x2553 << 8 | 214,  // â BOX DRAWS DOWN DOUBLE AND RIGHT SINGLE
    0x2554 << 8 | 201,  // â BOX DRAWS DOUBLE DOWN AND RIGHT
    0x2555 << 8 | 184,  // â BOX DRAWS DOWN SINGLE AND LEFT DOUBLE
    0x2556 << 8 | 183,  // â BOX DRAWS DOWN DOUBLE AND LEFT SINGLE
    0x2557 << 8 | 187,  // â BOX DRAWS DOUBLE DOWN AND LEFT
    0x2558 << 8 | 212,  // â BOX DRAWS UP SINGLE AND RIGHT DOUBLE
    0x2559 << 8 | 211,  // â BOX DRAWS UP DOUBLE AND RIGHT SINGLE
    0x255a << 8 | 200,  // â BOX DRAWS DOUBLE UP AND RIGHT
    0x255b << 8 | 190,  // â BOX DRAWS UP SINGLE AND LEFT DOUBLE
    0x255c << 8 | 189,  // â BOX DRAWS UP DOUBLE AND LEFT SINGLE
    0x255d << 8 | 188,  // â BOX DRAWS DOUBLE UP AND LEFT
    0x255e << 8 | 198,  // â BOX DRAWS VERTICAL SINGLE AND RIGHT DOUBLE
    0x255f << 8 | 199,  // â BOX DRAWS VERTICAL DOUBLE AND RIGHT SINGLE
    0x2560 << 8 | 204,  // â  BOX DRAWS DOUBLE VERTICAL AND RIGHT
    0x2561 << 8 | 181,  // â¡ BOX DRAWS VERTICAL SINGLE AND LEFT DOUBLE
    0x2562 << 8 | 182,  // â¢ BOX DRAWS VERTICAL DOUBLE AND LEFT SINGLE
    0x2563 << 8 | 185,  // â£ BOX DRAWS DOUBLE VERTICAL AND LEFT
    0x2564 << 8 | 209,  // â¤ BOX DRAWS DOWN SINGLE AND HORIZONTAL DOUBLE
    0x2565 << 8 | 210,  // â¥ BOX DRAWS DOWN DOUBLE AND HORIZONTAL SINGLE
    0x2566 << 8 | 203,  // â¦ BOX DRAWS DOUBLE DOWN AND HORIZONTAL
    0x2567 << 8 | 207,  // â§ BOX DRAWS UP SINGLE AND HORIZONTAL DOUBLE
    0x2568 << 8 | 208,  // â¨ BOX DRAWS UP DOUBLE AND HORIZONTAL SINGLE
    0x2569 << 8 | 202,  // â© BOX DRAWS DOUBLE UP AND HORIZONTAL
    0x256a << 8 | 216,  // âª BOX DRAWS VERTICAL SINGLE AND HORIZONTAL DOUBLE
    0x256b << 8 | 215,  // â« BOX DRAWS VERTICAL DOUBLE AND HORIZONTAL SINGLE
    0x256c << 8 | 206,  // â¬ BOX DRAWS DOUBLE VERTICAL AND HORIZONTAL
    0x2580 << 8 | 223,  // â UPPER HALF BLOCK
    0x2584 << 8 | 220,  // â LOWER HALF BLOCK
    0x2588 << 8 | 219,  // â FULL BLOCK
    0x258c << 8 | 221,  // â LEFT HALF BLOCK
    0x2590 << 8 | 222,  // â RIGHT HALF BLOCK
    0x2591 << 8 | 176,  // â LIGHT SHADE
    0x2592 << 8 | 177,  // â MEDIUM SHADE
    0x2593 << 8 | 178,  // â DARK SHADE
    0x25a0 << 8 | 254,  // â  BLACK SQUARE
    0x25ac << 8 | 22,   // â¬ BLACK RECTANGLE
    0x25b2 << 8 | 30,   // â² BLACK UP-POINTING TRIANGLE
    0x25ba << 8 | 16,   // âº BLACK RIGHT-POINTING POINTER
    0x25bc << 8 | 31,   // â¼ BLACK DOWN-POINTING TRIANGLE
    0x25c4 << 8 | 17,   // â BLACK LEFT-POINTING POINTER
    0x25cb << 8 | 9,    // â WHITE CIRCLE
    0x25d8 << 8 | 8,    // â INVERSE BULLET
    0x25d9 << 8 | 10,   // â INVERSE WHITE CIRCLE
    0x263a << 8 | 1,    // âº WHITE SMILING FACE
    0x263b << 8 | 2,    // â» BLACK SMILING FACE
    0x263c << 8 | 15,   // â¼ WHITE SUN WITH RAYS
    0x2640 << 8 | 12,   // â FEMALE SIGN
    0x2642 << 8 | 11,   // â MALE SIGN
    0x2660 << 8 | 6,    // â  BLACK SPADE SUIT
    0x2663 << 8 | 5,    // â£ BLACK CLUB SUIT
    0x2665 << 8 | 3,    // â¥ BLACK HEART SUIT
    0x2666 << 8 | 4,    // â¦ BLACK DIAMOND SUIT
    0x266a << 8 | 13,   // âª EIGHTH NOTE
    0x266b << 8 | 14,   // â« BEAMED EIGHTH NOTES
};

/**
 * Turns CP437 unicode glyph into its binary representation.
 *
 * @param c is a unicode character
 * @return byte representation, or -1 if ch wasn't ibm cp437
 * @see bing()
 */
int unbing(int c) {
  int m, l, r;
  if (32 <= c && c < 127) return c;
  l = 0;
  r = ARRAYLEN(kCp437i) - 1;
  while (l <= r) {
    m = (l + r) >> 1;
    if ((kCp437i[m] >> 8) < c) {
      l = m + 1;
    } else if ((kCp437i[m] >> 8) > c) {
      r = m - 1;
    } else {
      return kCp437i[m] & 255;
    }
  }
  return -1;
}
