mirror of
https://github.com/taigrr/arduinolibs
synced 2025-01-18 04:33:12 -08:00
Move non-cryptography code to a separate repository
This commit is contained in:
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Southern Storm Software, Pty Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int value;
|
||||
printf("static const uint8_t flipBits[256] PROGMEM = {\n");
|
||||
for (value = 0; value < 256; ++value) {
|
||||
int flipped =
|
||||
((value & 0x01) << 7) | ((value & 0x02) << 5) |
|
||||
((value & 0x04) << 3) | ((value & 0x08) << 1) |
|
||||
((value & 0x10) >> 1) | ((value & 0x20) >> 3) |
|
||||
((value & 0x40) >> 5) | ((value & 0x80) >> 7);
|
||||
if ((value % 12) == 0)
|
||||
printf(" ");
|
||||
else
|
||||
printf(" ");
|
||||
if (value != 255)
|
||||
printf("0x%02X,", flipped);
|
||||
else
|
||||
printf("0x%02X", flipped);
|
||||
if ((value % 12) == 11)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n};\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,304 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Southern Storm Software, Pty Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// Generates the keymap state machine table for the Terminal class.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include "../libraries/Terminal/USBKeysExtra.h"
|
||||
|
||||
typedef struct {
|
||||
const char *sequence;
|
||||
int code;
|
||||
} EscKey;
|
||||
static EscKey const escKeys[] = {
|
||||
// Based on the key sequence tables from:
|
||||
// http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-PC-Style-Function-Keys
|
||||
// http://aperiodic.net/phil/archives/Geekery/term-function-keys.html
|
||||
// Also some miscellaneous codes from other sources like the Linux console.
|
||||
|
||||
// Cursor control keys.
|
||||
{"[A", KEY_UP_ARROW},
|
||||
{"OA", KEY_UP_ARROW},
|
||||
{"A", KEY_UP_ARROW},
|
||||
{"[B", KEY_DOWN_ARROW},
|
||||
{"OB", KEY_DOWN_ARROW},
|
||||
{"B", KEY_DOWN_ARROW},
|
||||
{"[C", KEY_RIGHT_ARROW},
|
||||
{"OC", KEY_RIGHT_ARROW},
|
||||
{"C", KEY_RIGHT_ARROW},
|
||||
{"[D", KEY_LEFT_ARROW},
|
||||
{"OD", KEY_LEFT_ARROW},
|
||||
{"D", KEY_LEFT_ARROW},
|
||||
{"[H", KEY_HOME},
|
||||
{"OH", KEY_HOME},
|
||||
{"[1~", KEY_HOME},
|
||||
{"[F", KEY_END},
|
||||
{"OF", KEY_END},
|
||||
{"[4~", KEY_END},
|
||||
{"[2~", KEY_INSERT},
|
||||
{"[3~", KEY_DELETE},
|
||||
{"[5~", KEY_PAGE_UP},
|
||||
{"[6~", KEY_PAGE_DOWN},
|
||||
|
||||
// Numeric keypad. Mostly mapped back to ASCII.
|
||||
{"O ", ' '},
|
||||
{"? ", ' '},
|
||||
{"OI", KEY_TAB},
|
||||
{"?I", KEY_TAB},
|
||||
{"OM", KEY_RETURN},
|
||||
{"?M", KEY_RETURN},
|
||||
{"Oj", '*'},
|
||||
{"?j", '*'},
|
||||
{"Ok", '+'},
|
||||
{"?k", '+'},
|
||||
{"Ol", ','},
|
||||
{"?l", ','},
|
||||
{"Om", '-'},
|
||||
{"?m", '-'},
|
||||
{"On", '.'},
|
||||
{"?n", '.'},
|
||||
{"Oo", '/'},
|
||||
{"?o", '/'},
|
||||
{"Op", '0'},
|
||||
{"?p", '0'},
|
||||
{"Oq", '1'},
|
||||
{"?q", '1'},
|
||||
{"Or", '2'},
|
||||
{"?r", '2'},
|
||||
{"Os", '3'},
|
||||
{"?s", '3'},
|
||||
{"Ot", '4'},
|
||||
{"?t", '4'},
|
||||
{"Ou", '5'},
|
||||
{"?u", '5'},
|
||||
{"Ov", '6'},
|
||||
{"?v", '6'},
|
||||
{"Ow", '7'},
|
||||
{"?w", '7'},
|
||||
{"Ox", '8'},
|
||||
{"?x", '8'},
|
||||
{"Oy", '9'},
|
||||
{"?y", '9'},
|
||||
{"OX", '='},
|
||||
{"?X", '='},
|
||||
|
||||
// Function keys.
|
||||
{"[11~", KEY_F1},
|
||||
{"P", KEY_F1},
|
||||
{"OP", KEY_F1},
|
||||
{"[[A", KEY_F1},
|
||||
{"[12~", KEY_F2},
|
||||
{"Q", KEY_F2},
|
||||
{"OQ", KEY_F2},
|
||||
{"[[B", KEY_F2},
|
||||
{"[13~", KEY_F3},
|
||||
{"R", KEY_F3},
|
||||
{"OR", KEY_F3},
|
||||
{"[[C", KEY_F3},
|
||||
{"[14~", KEY_F4},
|
||||
{"S", KEY_F4},
|
||||
{"OS", KEY_F4},
|
||||
{"[[D", KEY_F4},
|
||||
{"[15~", KEY_F5},
|
||||
{"[[E", KEY_F5},
|
||||
{"[17~", KEY_F6},
|
||||
{"[18~", KEY_F7},
|
||||
{"[19~", KEY_F8},
|
||||
{"[20~", KEY_F9},
|
||||
{"[21~", KEY_F10},
|
||||
{"[23~", KEY_F11},
|
||||
{"[24~", KEY_F12},
|
||||
{"[25~", KEY_F13},
|
||||
{"[11;2~", KEY_F13},
|
||||
{"O2P", KEY_F13},
|
||||
{"[26~", KEY_F14},
|
||||
{"[12;2~", KEY_F14},
|
||||
{"O2Q", KEY_F14},
|
||||
{"[28~", KEY_F15},
|
||||
{"[13;2~", KEY_F15},
|
||||
{"O2R", KEY_F15},
|
||||
{"[29~", KEY_F16},
|
||||
{"[14;2~", KEY_F16},
|
||||
{"O2S", KEY_F16},
|
||||
{"[31~", KEY_F17},
|
||||
{"[15;2~", KEY_F17},
|
||||
{"[32~", KEY_F18},
|
||||
{"[17;2~", KEY_F18},
|
||||
{"[33~", KEY_F19},
|
||||
{"[18;2~", KEY_F19},
|
||||
{"[34~", KEY_F20},
|
||||
{"[19;2~", KEY_F20},
|
||||
{"[20;2~", KEY_F21},
|
||||
{"[23$", KEY_F21},
|
||||
{"[21;2~", KEY_F22},
|
||||
{"[24$", KEY_F22},
|
||||
{"[23;2~", KEY_F23},
|
||||
{"[11^", KEY_F23},
|
||||
{"[24;2~", KEY_F24},
|
||||
{"[12^", KEY_F24},
|
||||
|
||||
// Other keys.
|
||||
{"[Z", KEY_BACK_TAB},
|
||||
{"OZ", KEY_BACK_TAB},
|
||||
{"[P", KEY_PAUSE},
|
||||
{"[G", KEY_NUMPAD_5},
|
||||
};
|
||||
#define numEscKeys (sizeof(escKeys) / sizeof(escKeys[0]))
|
||||
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
explicit Node(Node *parent = 0);
|
||||
~Node();
|
||||
|
||||
void add(const char *str, int code);
|
||||
void dumpRules(std::vector<uint8_t> *vec);
|
||||
|
||||
int ch;
|
||||
int code;
|
||||
int offset;
|
||||
Node *firstChild;
|
||||
Node *lastChild;
|
||||
Node *nextChild;
|
||||
};
|
||||
|
||||
Node::Node(Node *parent)
|
||||
: ch(0)
|
||||
, code(-1)
|
||||
, offset(0)
|
||||
, firstChild(0)
|
||||
, lastChild(0)
|
||||
, nextChild(0)
|
||||
{
|
||||
if (parent) {
|
||||
if (parent->lastChild)
|
||||
parent->lastChild->nextChild = this;
|
||||
else
|
||||
parent->firstChild = this;
|
||||
parent->lastChild = this;
|
||||
}
|
||||
}
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
Node *child = firstChild;
|
||||
Node *next;
|
||||
while (child != 0) {
|
||||
next = child->nextChild;
|
||||
delete child;
|
||||
child = next;
|
||||
}
|
||||
}
|
||||
|
||||
void Node::add(const char *str, int code)
|
||||
{
|
||||
int ch = str[0] & 0xFF;
|
||||
Node *child = firstChild;
|
||||
while (child != 0) {
|
||||
if (child->ch == ch)
|
||||
break;
|
||||
child = child->nextChild;
|
||||
}
|
||||
if (!child) {
|
||||
child = new Node(this);
|
||||
child->ch = ch;
|
||||
}
|
||||
if (str[1] == '\0') {
|
||||
// Leaf node at the end of a string.
|
||||
child->code = code;
|
||||
} else {
|
||||
// Interior node with more children.
|
||||
child->add(str + 1, code);
|
||||
}
|
||||
}
|
||||
|
||||
void Node::dumpRules(std::vector<uint8_t> *vec)
|
||||
{
|
||||
Node *child;
|
||||
|
||||
// First pass: Output the recognizers for this level.
|
||||
offset = vec->size();
|
||||
child = firstChild;
|
||||
while (child != 0) {
|
||||
if (child->firstChild) {
|
||||
// Interior nodes need 3 bytes for the character and offset.
|
||||
vec->push_back((uint8_t)(child->ch | 0x80));
|
||||
vec->push_back(0);
|
||||
vec->push_back(0);
|
||||
} else {
|
||||
// Leaf nodes need 2 bytes for the character and code.
|
||||
vec->push_back((uint8_t)(child->ch));
|
||||
vec->push_back((uint8_t)(child->code));
|
||||
if (child->code > 255)
|
||||
printf("Code 0x%X exceeds 255 - need to change table format\n", child->code);
|
||||
}
|
||||
child = child->nextChild;
|
||||
}
|
||||
vec->push_back(0); // Terminate this level.
|
||||
|
||||
// Second pass: Output the recognizers for the child levels.
|
||||
child = firstChild;
|
||||
while (child != 0) {
|
||||
if (child->firstChild)
|
||||
child->dumpRules(vec);
|
||||
child = child->nextChild;
|
||||
}
|
||||
|
||||
// Third pass: Back-patch the links to the child recognizers.
|
||||
int posn = offset;
|
||||
child = firstChild;
|
||||
while (child != 0) {
|
||||
if (child->firstChild) {
|
||||
int value = child->offset;
|
||||
(*vec)[posn + 1] = (uint8_t)value;
|
||||
(*vec)[posn + 2] = (uint8_t)(value >> 8);
|
||||
posn += 3;
|
||||
} else {
|
||||
posn += 2;
|
||||
}
|
||||
child = child->nextChild;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Node *root = new Node();
|
||||
for (unsigned index = 0; index < numEscKeys; ++index)
|
||||
root->add(escKeys[index].sequence, escKeys[index].code);
|
||||
std::vector<uint8_t> vec;
|
||||
root->dumpRules(&vec);
|
||||
printf("static uint8_t const keymap[%d] PROGMEM = {\n", (int)vec.size());
|
||||
for (unsigned index = 0; index < vec.size(); ++index) {
|
||||
if ((index % 12) == 0)
|
||||
printf(" ");
|
||||
printf("0x%02X", (int)(vec[index]));
|
||||
if ((index % 12) == 11)
|
||||
printf(",\n");
|
||||
else
|
||||
printf(", ");
|
||||
}
|
||||
printf("};\n");
|
||||
delete root;
|
||||
return 0;
|
||||
}
|
||||
107
gen/genlookup.c
107
gen/genlookup.c
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Southern Storm Software, Pty Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// Utility for generating the button mapping table in LCD.cpp.
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define LCD_BUTTON_NONE 0
|
||||
#define LCD_BUTTON_LEFT 1
|
||||
#define LCD_BUTTON_RIGHT 2
|
||||
#define LCD_BUTTON_UP 3
|
||||
#define LCD_BUTTON_DOWN 4
|
||||
#define LCD_BUTTON_SELECT 5
|
||||
|
||||
#define LCD_BUTTON_VALUE_GAP 10
|
||||
#define LCD_BUTTON_RIGHT_VALUE 0
|
||||
#define LCD_BUTTON_UP_VALUE 145
|
||||
#define LCD_BUTTON_DOWN_VALUE 329
|
||||
#define LCD_BUTTON_LEFT_VALUE 505
|
||||
#define LCD_BUTTON_SELECT_VALUE 741
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char rawTest[1024];
|
||||
int value, value2, value3, bits;
|
||||
char button;
|
||||
|
||||
// Determine the actual values for each of the 1024 inputs.
|
||||
for (value = 0; value < 1024; ++value) {
|
||||
if (value < (LCD_BUTTON_RIGHT_VALUE + LCD_BUTTON_VALUE_GAP))
|
||||
button = LCD_BUTTON_RIGHT;
|
||||
else if (value >= (LCD_BUTTON_UP_VALUE - LCD_BUTTON_VALUE_GAP) &&
|
||||
value <= (LCD_BUTTON_UP_VALUE + LCD_BUTTON_VALUE_GAP))
|
||||
button = LCD_BUTTON_UP;
|
||||
else if (value >= (LCD_BUTTON_DOWN_VALUE - LCD_BUTTON_VALUE_GAP) &&
|
||||
value <= (LCD_BUTTON_DOWN_VALUE + LCD_BUTTON_VALUE_GAP))
|
||||
button = LCD_BUTTON_DOWN;
|
||||
else if (value >= (LCD_BUTTON_LEFT_VALUE - LCD_BUTTON_VALUE_GAP) &&
|
||||
value <= (LCD_BUTTON_LEFT_VALUE + LCD_BUTTON_VALUE_GAP))
|
||||
button = LCD_BUTTON_LEFT;
|
||||
else if (value >= (LCD_BUTTON_SELECT_VALUE - LCD_BUTTON_VALUE_GAP) &&
|
||||
value <= (LCD_BUTTON_SELECT_VALUE + LCD_BUTTON_VALUE_GAP))
|
||||
button = LCD_BUTTON_SELECT;
|
||||
else
|
||||
button = LCD_BUTTON_NONE;
|
||||
rawTest[value] = button;
|
||||
}
|
||||
|
||||
// Dump the accuracy of different bit truncations.
|
||||
for (bits = 4; bits < 10; ++bits) {
|
||||
int count = 0;
|
||||
for (value = 0; value < 1024; ++value) {
|
||||
value2 = value & (((1 << bits) - 1) << (10 - bits));
|
||||
if (rawTest[value] == rawTest[value2])
|
||||
++count;
|
||||
}
|
||||
printf("bits = %d, accuracy = %g%%\n", bits, 100.0 * count / 1024.0);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Dump the button mapping table for the selected bit count.
|
||||
bits = 5;
|
||||
printf("static uint8_t const buttonMappings[] PROGMEM = {\n");
|
||||
for (value2 = 0; value2 < (1 << bits); ++value2) {
|
||||
value = value2 << (10 - bits);
|
||||
value3 = value + (1 << (10 - bits)) - 1;
|
||||
button = 0;
|
||||
while (!button && value <= value3) {
|
||||
button = rawTest[value];
|
||||
++value;
|
||||
}
|
||||
if ((value2 & 0x0F) != 0)
|
||||
printf(", ");
|
||||
else
|
||||
printf(" ");
|
||||
printf("%d", button);
|
||||
if ((value2 & 0x0F) == 0x0F) {
|
||||
if (value2 < ((1 << bits - 1)))
|
||||
printf(",\n");
|
||||
else
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("};\n");
|
||||
printf("#define mapButton(value) (pgm_read_byte(&(buttonMappings[(value) >> %d])))\n", 10 - bits);
|
||||
|
||||
return 0;
|
||||
}
|
||||
235
gen/genwcwidth.c
235
gen/genwcwidth.c
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Southern Storm Software, Pty Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// Generates the Terminal::isWideCharacter() function from the data at:
|
||||
// http://www.unicode.org/Public/UCD/latest/ucd/EastAsianWidth.txt
|
||||
// http://www.unicode.org/reports/tr11/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_UNICODE 0x10FFFF
|
||||
#define NUM_UNICODE (MAX_UNICODE + 1)
|
||||
|
||||
static unsigned char *masks;
|
||||
|
||||
static void mark_range(long code1, long code2)
|
||||
{
|
||||
while (code1 <= code2) {
|
||||
if (code1 > MAX_UNICODE)
|
||||
break;
|
||||
masks[code1 / 8] |= (1 << (code1 % 8));
|
||||
++code1;
|
||||
}
|
||||
}
|
||||
|
||||
static void unmark_range(long code1, long code2)
|
||||
{
|
||||
while (code1 <= code2) {
|
||||
if (code1 > MAX_UNICODE)
|
||||
break;
|
||||
masks[code1 / 8] &= ~(1 << (code1 % 8));
|
||||
++code1;
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_ranges(void)
|
||||
{
|
||||
long code;
|
||||
int index, sum;
|
||||
unsigned char *prevptr = 0;
|
||||
unsigned char *ptr;
|
||||
int dotdot = 0;
|
||||
for (code = 0; code <= MAX_UNICODE; code += 0x100) {
|
||||
ptr = masks + (code / 8);
|
||||
sum = 0;
|
||||
for (index = 0; index < 32; ++index)
|
||||
sum += ptr[index];
|
||||
if (sum == 0 || sum == (0xFF * 32)) {
|
||||
if (prevptr && !memcmp(ptr, prevptr, 32)) {
|
||||
if (!dotdot) {
|
||||
dotdot = 1;
|
||||
printf("..\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
dotdot = 0;
|
||||
printf("%06lX: ", code);
|
||||
for (index = 0; index < 32; ++index)
|
||||
printf("%02X", ptr[index]);
|
||||
printf("\n");
|
||||
prevptr = ptr;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void print_lookup_table(const char *name, long first, long last)
|
||||
{
|
||||
long index, size;
|
||||
unsigned char *ptr = masks + first / 8;
|
||||
size = (last - first + 1) / 8;
|
||||
printf(" static unsigned char const %s[%ld] PROGMEM = {\n", name, size);
|
||||
for (index = 0; index < size; ++index) {
|
||||
if ((index % 8) == 0)
|
||||
printf(" ");
|
||||
printf("0x%02X", ptr[index]);
|
||||
if (index < (size - 1)) {
|
||||
if ((index % 8) == 7)
|
||||
printf(",\n");
|
||||
else
|
||||
printf(", ");
|
||||
} else {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf(" };\n");
|
||||
}
|
||||
|
||||
static void recognizer(void)
|
||||
{
|
||||
long code;
|
||||
int first = 1;
|
||||
|
||||
printf("bool Terminal::isWideCharacter(long code)\n{\n");
|
||||
printf(" // This function was automatically generated by genwcwidth.c\n");
|
||||
print_lookup_table("range3000", 0x3000, 0x30FF);
|
||||
print_lookup_table("rangeFE00", 0xFE00, 0xFFFF);
|
||||
printf(" unsigned c;\n");
|
||||
|
||||
// Bail out early for Latin character sets.
|
||||
printf(" if (code < 0x2300) {\n");
|
||||
printf(" return false;\n");
|
||||
|
||||
// Densely populated ranges.
|
||||
printf(" } else if (code >= 0x3000 && code <= 0x30FF) {\n");
|
||||
printf(" c = (unsigned)(code - 0x3000);\n");
|
||||
printf(" return (pgm_read_byte(range3000 + (c / 8)) & (1 << (c %% 8))) != 0;\n");
|
||||
printf(" } else if (code >= 0xFE00 && code <= 0xFFFF) {\n");
|
||||
printf(" c = (unsigned)(code - 0xFE00);\n");
|
||||
printf(" return (pgm_read_byte(rangeFE00 + (c / 8)) & (1 << (c %% 8))) != 0;\n");
|
||||
|
||||
// Deal with the main wide character ranges.
|
||||
printf(" } else if (code >= 0x3400 && code <= 0x4DBF) {\n");
|
||||
printf(" return true;\n");
|
||||
printf(" } else if (code >= 0x4E00 && code <= 0x9FFF) {\n");
|
||||
printf(" return true;\n");
|
||||
printf(" } else if (code >= 0xF900 && code <= 0xFAFF) {\n");
|
||||
printf(" return true;\n");
|
||||
printf(" } else if (code >= 0x20000 && code <= 0x2FFFD) {\n");
|
||||
printf(" return true;\n");
|
||||
printf(" } else if (code >= 0x30000 && code <= 0x3FFFD) {\n");
|
||||
printf(" return true;\n");
|
||||
printf(" } else if (");
|
||||
|
||||
// Deal with the left-overs.
|
||||
unmark_range(0x3000, 0x30FF);
|
||||
unmark_range(0xFE00, 0xFFFF);
|
||||
for (code = 0; code <= MAX_UNICODE; ++code) {
|
||||
if (masks[code / 8] & (1 << (code % 8))) {
|
||||
if (!first)
|
||||
printf(" ||\n ");
|
||||
else
|
||||
first = 0;
|
||||
printf("code == 0x%04lX", code);
|
||||
}
|
||||
}
|
||||
printf(") {\n");
|
||||
printf(" return true;\n");
|
||||
printf(" }\n");
|
||||
|
||||
printf(" return false;\n");
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *file;
|
||||
char buffer[BUFSIZ];
|
||||
|
||||
// Allocate memory for the "is this a wide character?" mask array.
|
||||
masks = calloc(NUM_UNICODE / 8, sizeof(unsigned char));
|
||||
if (!masks) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Load the contents of "EastAsianWidth.txt".
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s EastAsianWidth.txt\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if ((file = fopen(argv[1], "r")) == NULL) {
|
||||
perror(argv[1]);
|
||||
return 1;
|
||||
}
|
||||
while (fgets(buffer, sizeof(buffer), file)) {
|
||||
if ((buffer[0] >= '0' && buffer[0] <= '9') ||
|
||||
(buffer[0] >= 'A' && buffer[0] <= 'F')) {
|
||||
long code1 = 0;
|
||||
long code2 = 0;
|
||||
char *endptr = NULL;
|
||||
code1 = strtol(buffer, &endptr, 16);
|
||||
if (endptr[0] == '.' && endptr[1] == '.') {
|
||||
endptr += 2;
|
||||
code2 = strtol(buffer, &endptr, 16);
|
||||
} else {
|
||||
code2 = code1;
|
||||
}
|
||||
if (endptr[0] == ';') {
|
||||
// Recognise 'W' and 'F' as wide characters. It is possible
|
||||
// that 'A' (ambiguous) characters may also be wide but only
|
||||
// in East Asian contexts, which we assume we're not for now.
|
||||
if (endptr[1] == 'W' || endptr[1] == 'F') {
|
||||
mark_range(code1, code2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
// Some special ranges that are implicitly all-wide even if the
|
||||
// code points aren't currently allocated by the Unicode standard.
|
||||
mark_range(0x3400, 0x4DBF);
|
||||
mark_range(0x4E00, 0x9FFF);
|
||||
mark_range(0xF900, 0xFAFF);
|
||||
mark_range(0x20000, 0x2FFFD);
|
||||
mark_range(0x30000, 0x3FFFD);
|
||||
|
||||
// Dump the ranges.
|
||||
dump_ranges();
|
||||
|
||||
// Unmark the special ranges to make it easier to find the left-overs.
|
||||
unmark_range(0x3400, 0x4DBF);
|
||||
unmark_range(0x4E00, 0x9FFF);
|
||||
unmark_range(0xF900, 0xFAFF);
|
||||
unmark_range(0x20000, 0x2FFFD);
|
||||
unmark_range(0x30000, 0x3FFFD);
|
||||
|
||||
// Create the recognition tree.
|
||||
recognizer();
|
||||
|
||||
// Clean up and exit.
|
||||
free(masks);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user