#include <stdio.h>
#include <stdlib.h>
// conversion tables are based on
// http://w...content-available-to-author-only...e.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP437.TXT
const unsigned short cp437hi_utf16[128] =
{
0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
};
const unsigned long utf16_cp437hi[128] =
{
0xff00a0, 0xad00a1, 0x9b00a2, 0x9c00a3,
0x9d00a5, 0xa600aa, 0xae00ab, 0xaa00ac,
0xf800b0, 0xf100b1, 0xfd00b2, 0xe600b5,
0xfa00b7, 0xa700ba, 0xaf00bb, 0xac00bc,
0xab00bd, 0xa800bf, 0x8e00c4, 0x8f00c5,
0x9200c6, 0x8000c7, 0x9000c9, 0xa500d1,
0x9900d6, 0x9a00dc, 0xe100df, 0x8500e0,
0xa000e1, 0x8300e2, 0x8400e4, 0x8600e5,
0x9100e6, 0x8700e7, 0x8a00e8, 0x8200e9,
0x8800ea, 0x8900eb, 0x8d00ec, 0xa100ed,
0x8c00ee, 0x8b00ef, 0xa400f1, 0x9500f2,
0xa200f3, 0x9300f4, 0x9400f6, 0xf600f7,
0x9700f9, 0xa300fa, 0x9600fb, 0x8100fc,
0x9800ff, 0x9f0192, 0xe20393, 0xe90398,
0xe403a3, 0xe803a6, 0xea03a9, 0xe003b1,
0xeb03b4, 0xee03b5, 0xe303c0, 0xe503c3,
0xe703c4, 0xed03c6, 0xfc207f, 0x9e20a7,
0xf92219, 0xfb221a, 0xec221e, 0xef2229,
0xf72248, 0xf02261, 0xf32264, 0xf22265,
0xa92310, 0xf42320, 0xf52321, 0xc42500,
0xb32502, 0xda250c, 0xbf2510, 0xc02514,
0xd92518, 0xc3251c, 0xb42524, 0xc2252c,
0xc12534, 0xc5253c, 0xcd2550, 0xba2551,
0xd52552, 0xd62553, 0xc92554, 0xb82555,
0xb72556, 0xbb2557, 0xd42558, 0xd32559,
0xc8255a, 0xbe255b, 0xbd255c, 0xbc255d,
0xc6255e, 0xc7255f, 0xcc2560, 0xb52561,
0xb62562, 0xb92563, 0xd12564, 0xd22565,
0xcb2566, 0xcf2567, 0xd02568, 0xca2569,
0xd8256a, 0xd7256b, 0xce256c, 0xdf2580,
0xdc2584, 0xdb2588, 0xdd258c, 0xde2590,
0xb02591, 0xb12592, 0xb22593, 0xfe25a0
};
unsigned short Cp437toUtf16(unsigned char c)
{
if (c < 0x80)
return c;
return cp437hi_utf16[c - 0x80];
}
static int CompareUtf16toCp437(const void* pv1, const void* pv2)
{
const unsigned long *pl1 = pv1, *pl2 = pv2;
unsigned long v1 = *pl1 & 0xFFFF, v2 = *pl2 & 0xFFFF;
if (v1 > v2)
return +1;
if (v1 < v2)
return -1;
return 0;
}
int Utf16toCp437(unsigned long cp)
{
unsigned long* p;
if (cp < 0x80)
return cp;
if (cp > 0xFFFF)
return -1;
utf16_cp437hi,
sizeof(utf16_cp437hi) / sizeof(utf16_cp437hi[0]),
sizeof(utf16_cp437hi[0]),
&CompareUtf16toCp437);
if (p == NULL)
return -1;
return *p >> 16;
}
int main(void)
{
unsigned c;
for (c = 0; c <= 0xFF; c++)
{
unsigned long cp = Cp437toUtf16(c);
int c2 = Utf16toCp437(cp);
printf("0x%02X -> 0x%04lX -> 0x%02X\n", c
, cp
, c2
);
if (c != c2)
{
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCi8vIGNvbnZlcnNpb24gdGFibGVzIGFyZSBiYXNlZCBvbgovLyBodHRwOi8vdy4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4uZS5vcmcvUHVibGljL01BUFBJTkdTL1ZFTkRPUlMvTUlDU0ZUL1BDL0NQNDM3LlRYVAoKY29uc3QgdW5zaWduZWQgc2hvcnQgY3A0MzdoaV91dGYxNlsxMjhdID0KewogIDB4MDBjNywgMHgwMGZjLCAweDAwZTksIDB4MDBlMiwgMHgwMGU0LCAweDAwZTAsIDB4MDBlNSwgMHgwMGU3LAogIDB4MDBlYSwgMHgwMGViLCAweDAwZTgsIDB4MDBlZiwgMHgwMGVlLCAweDAwZWMsIDB4MDBjNCwgMHgwMGM1LAogIDB4MDBjOSwgMHgwMGU2LCAweDAwYzYsIDB4MDBmNCwgMHgwMGY2LCAweDAwZjIsIDB4MDBmYiwgMHgwMGY5LAogIDB4MDBmZiwgMHgwMGQ2LCAweDAwZGMsIDB4MDBhMiwgMHgwMGEzLCAweDAwYTUsIDB4MjBhNywgMHgwMTkyLAogIDB4MDBlMSwgMHgwMGVkLCAweDAwZjMsIDB4MDBmYSwgMHgwMGYxLCAweDAwZDEsIDB4MDBhYSwgMHgwMGJhLAogIDB4MDBiZiwgMHgyMzEwLCAweDAwYWMsIDB4MDBiZCwgMHgwMGJjLCAweDAwYTEsIDB4MDBhYiwgMHgwMGJiLAogIDB4MjU5MSwgMHgyNTkyLCAweDI1OTMsIDB4MjUwMiwgMHgyNTI0LCAweDI1NjEsIDB4MjU2MiwgMHgyNTU2LAogIDB4MjU1NSwgMHgyNTYzLCAweDI1NTEsIDB4MjU1NywgMHgyNTVkLCAweDI1NWMsIDB4MjU1YiwgMHgyNTEwLAogIDB4MjUxNCwgMHgyNTM0LCAweDI1MmMsIDB4MjUxYywgMHgyNTAwLCAweDI1M2MsIDB4MjU1ZSwgMHgyNTVmLAogIDB4MjU1YSwgMHgyNTU0LCAweDI1NjksIDB4MjU2NiwgMHgyNTYwLCAweDI1NTAsIDB4MjU2YywgMHgyNTY3LAogIDB4MjU2OCwgMHgyNTY0LCAweDI1NjUsIDB4MjU1OSwgMHgyNTU4LCAweDI1NTIsIDB4MjU1MywgMHgyNTZiLAogIDB4MjU2YSwgMHgyNTE4LCAweDI1MGMsIDB4MjU4OCwgMHgyNTg0LCAweDI1OGMsIDB4MjU5MCwgMHgyNTgwLAogIDB4MDNiMSwgMHgwMGRmLCAweDAzOTMsIDB4MDNjMCwgMHgwM2EzLCAweDAzYzMsIDB4MDBiNSwgMHgwM2M0LAogIDB4MDNhNiwgMHgwMzk4LCAweDAzYTksIDB4MDNiNCwgMHgyMjFlLCAweDAzYzYsIDB4MDNiNSwgMHgyMjI5LAogIDB4MjI2MSwgMHgwMGIxLCAweDIyNjUsIDB4MjI2NCwgMHgyMzIwLCAweDIzMjEsIDB4MDBmNywgMHgyMjQ4LAogIDB4MDBiMCwgMHgyMjE5LCAweDAwYjcsIDB4MjIxYSwgMHgyMDdmLCAweDAwYjIsIDB4MjVhMCwgMHgwMGEwCn07Cgpjb25zdCB1bnNpZ25lZCBsb25nIHV0ZjE2X2NwNDM3aGlbMTI4XSA9CnsKICAweGZmMDBhMCwgMHhhZDAwYTEsIDB4OWIwMGEyLCAweDljMDBhMywKICAweDlkMDBhNSwgMHhhNjAwYWEsIDB4YWUwMGFiLCAweGFhMDBhYywKICAweGY4MDBiMCwgMHhmMTAwYjEsIDB4ZmQwMGIyLCAweGU2MDBiNSwKICAweGZhMDBiNywgMHhhNzAwYmEsIDB4YWYwMGJiLCAweGFjMDBiYywKICAweGFiMDBiZCwgMHhhODAwYmYsIDB4OGUwMGM0LCAweDhmMDBjNSwKICAweDkyMDBjNiwgMHg4MDAwYzcsIDB4OTAwMGM5LCAweGE1MDBkMSwKICAweDk5MDBkNiwgMHg5YTAwZGMsIDB4ZTEwMGRmLCAweDg1MDBlMCwKICAweGEwMDBlMSwgMHg4MzAwZTIsIDB4ODQwMGU0LCAweDg2MDBlNSwKICAweDkxMDBlNiwgMHg4NzAwZTcsIDB4OGEwMGU4LCAweDgyMDBlOSwKICAweDg4MDBlYSwgMHg4OTAwZWIsIDB4OGQwMGVjLCAweGExMDBlZCwKICAweDhjMDBlZSwgMHg4YjAwZWYsIDB4YTQwMGYxLCAweDk1MDBmMiwKICAweGEyMDBmMywgMHg5MzAwZjQsIDB4OTQwMGY2LCAweGY2MDBmNywKICAweDk3MDBmOSwgMHhhMzAwZmEsIDB4OTYwMGZiLCAweDgxMDBmYywKICAweDk4MDBmZiwgMHg5ZjAxOTIsIDB4ZTIwMzkzLCAweGU5MDM5OCwKICAweGU0MDNhMywgMHhlODAzYTYsIDB4ZWEwM2E5LCAweGUwMDNiMSwKICAweGViMDNiNCwgMHhlZTAzYjUsIDB4ZTMwM2MwLCAweGU1MDNjMywKICAweGU3MDNjNCwgMHhlZDAzYzYsIDB4ZmMyMDdmLCAweDllMjBhNywKICAweGY5MjIxOSwgMHhmYjIyMWEsIDB4ZWMyMjFlLCAweGVmMjIyOSwKICAweGY3MjI0OCwgMHhmMDIyNjEsIDB4ZjMyMjY0LCAweGYyMjI2NSwKICAweGE5MjMxMCwgMHhmNDIzMjAsIDB4ZjUyMzIxLCAweGM0MjUwMCwKICAweGIzMjUwMiwgMHhkYTI1MGMsIDB4YmYyNTEwLCAweGMwMjUxNCwKICAweGQ5MjUxOCwgMHhjMzI1MWMsIDB4YjQyNTI0LCAweGMyMjUyYywKICAweGMxMjUzNCwgMHhjNTI1M2MsIDB4Y2QyNTUwLCAweGJhMjU1MSwKICAweGQ1MjU1MiwgMHhkNjI1NTMsIDB4YzkyNTU0LCAweGI4MjU1NSwKICAweGI3MjU1NiwgMHhiYjI1NTcsIDB4ZDQyNTU4LCAweGQzMjU1OSwKICAweGM4MjU1YSwgMHhiZTI1NWIsIDB4YmQyNTVjLCAweGJjMjU1ZCwKICAweGM2MjU1ZSwgMHhjNzI1NWYsIDB4Y2MyNTYwLCAweGI1MjU2MSwKICAweGI2MjU2MiwgMHhiOTI1NjMsIDB4ZDEyNTY0LCAweGQyMjU2NSwKICAweGNiMjU2NiwgMHhjZjI1NjcsIDB4ZDAyNTY4LCAweGNhMjU2OSwKICAweGQ4MjU2YSwgMHhkNzI1NmIsIDB4Y2UyNTZjLCAweGRmMjU4MCwKICAweGRjMjU4NCwgMHhkYjI1ODgsIDB4ZGQyNThjLCAweGRlMjU5MCwKICAweGIwMjU5MSwgMHhiMTI1OTIsIDB4YjIyNTkzLCAweGZlMjVhMAp9OwoKdW5zaWduZWQgc2hvcnQgQ3A0Mzd0b1V0ZjE2KHVuc2lnbmVkIGNoYXIgYykKewogIGlmIChjIDwgMHg4MCkKICAgIHJldHVybiBjOwogIHJldHVybiBjcDQzN2hpX3V0ZjE2W2MgLSAweDgwXTsKfQoKc3RhdGljIGludCBDb21wYXJlVXRmMTZ0b0NwNDM3KGNvbnN0IHZvaWQqIHB2MSwgY29uc3Qgdm9pZCogcHYyKQp7CiAgY29uc3QgdW5zaWduZWQgbG9uZyAqcGwxID0gcHYxLCAqcGwyID0gcHYyOwogIHVuc2lnbmVkIGxvbmcgdjEgPSAqcGwxICYgMHhGRkZGLCB2MiA9ICpwbDIgJiAweEZGRkY7CgogIGlmICh2MSA+IHYyKQogICAgcmV0dXJuICsxOwoKICBpZiAodjEgPCB2MikKICAgIHJldHVybiAtMTsKCiAgcmV0dXJuIDA7Cn0KCmludCBVdGYxNnRvQ3A0MzcodW5zaWduZWQgbG9uZyBjcCkKewogIHVuc2lnbmVkIGxvbmcqIHA7CgogIGlmIChjcCA8IDB4ODApCiAgICByZXR1cm4gY3A7CgogIGlmIChjcCA+IDB4RkZGRikKICAgIHJldHVybiAtMTsKICAgIAogIHAgPSBic2VhcmNoKCZjcCwKICAgICAgICAgICAgICB1dGYxNl9jcDQzN2hpLAogICAgICAgICAgICAgIHNpemVvZih1dGYxNl9jcDQzN2hpKSAvIHNpemVvZih1dGYxNl9jcDQzN2hpWzBdKSwKICAgICAgICAgICAgICBzaXplb2YodXRmMTZfY3A0MzdoaVswXSksCiAgICAgICAgICAgICAgJkNvbXBhcmVVdGYxNnRvQ3A0MzcpOwoKICBpZiAocCA9PSBOVUxMKQogICAgcmV0dXJuIC0xOwoKICByZXR1cm4gKnAgPj4gMTY7Cn0KCmludCBtYWluKHZvaWQpCnsKICB1bnNpZ25lZCBjOwoKICBmb3IgKGMgPSAwOyBjIDw9IDB4RkY7IGMrKykKICB7CiAgICB1bnNpZ25lZCBsb25nIGNwID0gQ3A0Mzd0b1V0ZjE2KGMpOwogICAgaW50IGMyID0gVXRmMTZ0b0NwNDM3KGNwKTsKCiAgICBwcmludGYoIjB4JTAyWCAtPiAweCUwNGxYIC0+IDB4JTAyWFxuIiwgYywgY3AsIGMyKTsKCiAgICBpZiAoYyAhPSBjMikKICAgIHsKICAgICAgcHV0cygiRmFpbHVyZSEiKTsKICAgICAgcmV0dXJuIEVYSVRfRkFJTFVSRTsKICAgIH0KICB9CgogIHB1dHMoIlN1Y2Nlc3MhIik7CiAgcmV0dXJuIEVYSVRfU1VDQ0VTUzsKfQo=