tinymux/utf/buildFiles.cpp

1773 lines
49 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <iconv.h>
#include "ConvertUTF.h"
#include "smutil.h"
const bool mux_isdigit[256] =
{
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
//
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 3
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // F
};
const bool mux_isspace[256] =
{
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
//
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, // 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // F
};
#define mux_isdigit(x) (mux_isdigit[(unsigned char)(x)])
#define mux_isspace(x) (mux_isspace[(unsigned char)(x)])
const char TableATOI[16][10] =
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
{ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
{ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
{ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39},
{ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49},
{ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59},
{ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69},
{ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79},
{ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89},
{ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99}
};
long mux_atol(const char *pString)
{
long sum = 0;
int LeadingCharacter = 0;
// Convert ASCII digits
//
unsigned int c1;
unsigned int c0 = pString[0];
if (!mux_isdigit(c0))
{
while (mux_isspace(pString[0]))
{
pString++;
}
LeadingCharacter = pString[0];
if ( LeadingCharacter == '-'
|| LeadingCharacter == '+')
{
pString++;
}
c0 = pString[0];
if (!mux_isdigit(c0))
{
return 0;
}
}
do
{
c1 = pString[1];
if (mux_isdigit(c1))
{
sum = 100 * sum + TableATOI[c0-'0'][c1-'0'];
pString += 2;
}
else
{
sum = 10 * sum + (c0-'0');
break;
}
} while (mux_isdigit(c0 = pString[0]));
// Interpret sign
//
if (LeadingCharacter == '-')
{
sum = -sum;
}
return sum;
}
// Korean Hangul Constants.
//
const UTF32 SBase = 0xAC00;
const UTF32 LBase = 0x1100;
const UTF32 VBase = 0x1161;
const UTF32 TBase = 0x11A7;
const UTF32 SCount = 11172;
const int LCount = 19;
const int VCount = 21;
const int TCount = 28;
const int NCount = VCount * TCount;
const size_t codepoints = 1114109;
#define CATEGORY_LETTER 0x0001000
#define SUBCATEGORY_UPPER 0x0000001 // Lu
#define SUBCATEGORY_LOWER 0x0000002 // Ll
#define SUBCATEGORY_TITLE 0x0000004 // Lt
#define SUBCATEGORY_LET_MODIFIER 0x0000008 // Lm
#define SUBCATEGORY_LET_OTHER 0x0000010 // Lo
#define CATEGORY_MARK 0x0002000
#define SUBCATEGORY_NONSPACING 0x0000001 // Mn
#define SUBCATEGORY_SPACING_COMBINING 0x0000002 // Mc
#define SUBCATEGORY_SPACING_ENCLOSING 0x0000004 // Me
#define CATEGORY_NUMBER 0x0004000
#define SUBCATEGORY_DECIMAL_DIGIT 0x0000001 // Nd
#define SUBCATEGORY_LETTER 0x0000002 // Nl
#define SUBCATEGORY_NUM_OTHER 0x0000004 // No
#define CATEGORY_PUNCTUATION 0x0008000
#define SUBCATEGORY_CONNECTOR 0x0000001 // Pc
#define SUBCATEGORY_DASH 0x0000002 // Pd
#define SUBCATEGORY_OPEN 0x0000004 // Ps
#define SUBCATEGORY_CLOSE 0x0000008 // Pe
#define SUBCATEGORY_INITIAL_QUOTE 0x0000010 // Pi
#define SUBCATEGORY_FINAL_QUOTE 0x0000020 // Pf
#define SUBCATEGORY_PUNC_OTHER 0x0000040 // Po
#define CATEGORY_SYMBOL 0x0010000
#define SUBCATEGORY_MATH 0x0000001 // Sm
#define SUBCATEGORY_CURRENCY 0x0000002 // Sc
#define SUBCATEGORY_SYM_MODIFIER 0x0000004 // Sk
#define SUBCATEGORY_SYM_OTHER 0x0000008 // So
#define CATEGORY_SEPARATOR 0x0020000
#define SUBCATEGORY_SPACE 0x0000001 // Zs
#define SUBCATEGORY_LINE 0x0000002 // Zl
#define SUBCATEGORY_PARAGRAPH 0x0000004 // Zp
#define CATEGORY_OTHER 0x0040000
#define SUBCATEGORY_CONTROL 0x0000001 // Cc
#define SUBCATEGORY_FORMAT 0x0000002 // Cf
#define SUBCATEGORY_SURROGATE 0x0000004 // Cs
#define SUBCATEGORY_PRIVATE_USE 0x0000008 // Co
#define SUBCATEGORY_NOT_ASSIGNED 0x0000010 // Cn
static struct
{
int cat;
const char *catlet;
} CategoryTable[] =
{
{ CATEGORY_LETTER|SUBCATEGORY_UPPER, "Lu" },
{ CATEGORY_LETTER|SUBCATEGORY_LOWER, "Ll" },
{ CATEGORY_LETTER|SUBCATEGORY_TITLE, "Lt" },
{ CATEGORY_LETTER|SUBCATEGORY_LET_MODIFIER, "Lm" },
{ CATEGORY_LETTER|SUBCATEGORY_LET_OTHER, "Lo" },
{ CATEGORY_MARK|SUBCATEGORY_NONSPACING, "Mn" },
{ CATEGORY_MARK|SUBCATEGORY_SPACING_COMBINING, "Mc" },
{ CATEGORY_MARK|SUBCATEGORY_SPACING_ENCLOSING, "Me" },
{ CATEGORY_NUMBER|SUBCATEGORY_DECIMAL_DIGIT, "Nd" },
{ CATEGORY_NUMBER|SUBCATEGORY_LETTER, "Nl" },
{ CATEGORY_NUMBER|SUBCATEGORY_NUM_OTHER, "No" },
{ CATEGORY_PUNCTUATION|SUBCATEGORY_CONNECTOR, "Pc" },
{ CATEGORY_PUNCTUATION|SUBCATEGORY_DASH, "Pd" },
{ CATEGORY_PUNCTUATION|SUBCATEGORY_OPEN, "Ps" },
{ CATEGORY_PUNCTUATION|SUBCATEGORY_CLOSE, "Pe" },
{ CATEGORY_PUNCTUATION|SUBCATEGORY_INITIAL_QUOTE, "Pi" },
{ CATEGORY_PUNCTUATION|SUBCATEGORY_FINAL_QUOTE, "Pf" },
{ CATEGORY_PUNCTUATION|SUBCATEGORY_PUNC_OTHER, "Po" },
{ CATEGORY_SYMBOL|SUBCATEGORY_MATH, "Sm" },
{ CATEGORY_SYMBOL|SUBCATEGORY_CURRENCY, "Sc" },
{ CATEGORY_SYMBOL|SUBCATEGORY_SYM_MODIFIER, "Sk" },
{ CATEGORY_SYMBOL|SUBCATEGORY_SYM_OTHER, "So" },
{ CATEGORY_SEPARATOR|SUBCATEGORY_SPACE, "Zs" },
{ CATEGORY_SEPARATOR|SUBCATEGORY_LINE, "Zl" },
{ CATEGORY_SEPARATOR|SUBCATEGORY_PARAGRAPH, "Zp" },
{ CATEGORY_OTHER|SUBCATEGORY_CONTROL, "Cc" },
{ CATEGORY_OTHER|SUBCATEGORY_FORMAT, "Cf" },
{ CATEGORY_OTHER|SUBCATEGORY_SURROGATE, "Cs" },
{ CATEGORY_OTHER|SUBCATEGORY_PRIVATE_USE, "Co" },
{ 0, NULL }
};
#define BIDI_LEFT_TO_RIGHT 1
#define BIDI_LEFT_TO_RIGHT_EMBEDDING 2
#define BIDI_LEFT_TO_RIGHT_OVERRIDE 3
#define BIDI_RIGHT_TO_LEFT 4
#define BIDI_RIGHT_TO_LEFT_ARABIC 5
#define BIDI_RIGHT_TO_LEFT_EMBEDDING 6
#define BIDI_RIGHT_TO_LEFT_OVERRIDE 7
#define BIDI_POP_DIRECTIONAL_FORMAT 8
#define BIDI_EUROPEAN_NUMBER 9
#define BIDI_EUROPEAN_NUMBER_SEPARATOR 10
#define BIDI_EUROPEAN_NUMBER_TERMINATOR 11
#define BIDI_ARABIC_NUMBER 12
#define BIDI_COMMON_NUMBER_SEPARATOR 13
#define BIDI_NON_SPACING_MARK 14
#define BIDI_BOUNDARY_NEUTRAL 15
#define BIDI_PARAGRAPH_SEPARATOR 16
#define BIDI_SEGMENT_SEPARATOR 17
#define BIDI_WHITESPACE 18
#define BIDI_OTHER_NEUTRALS 19
static struct
{
int BiDi;
const char *BiDiLet;
} BiDiTable[] =
{
{ BIDI_LEFT_TO_RIGHT, "L" },
{ BIDI_LEFT_TO_RIGHT_EMBEDDING, "LRE" },
{ BIDI_LEFT_TO_RIGHT_OVERRIDE, "LRO" },
{ BIDI_RIGHT_TO_LEFT, "R" },
{ BIDI_RIGHT_TO_LEFT_ARABIC, "AL" },
{ BIDI_RIGHT_TO_LEFT_EMBEDDING, "RLE" },
{ BIDI_RIGHT_TO_LEFT_OVERRIDE, "RLO" },
{ BIDI_POP_DIRECTIONAL_FORMAT, "PDF" },
{ BIDI_EUROPEAN_NUMBER, "EN" },
{ BIDI_EUROPEAN_NUMBER_SEPARATOR, "ES" },
{ BIDI_EUROPEAN_NUMBER_TERMINATOR, "ET" },
{ BIDI_ARABIC_NUMBER, "AN" },
{ BIDI_COMMON_NUMBER_SEPARATOR, "CS" },
{ BIDI_NON_SPACING_MARK, "NSM" },
{ BIDI_BOUNDARY_NEUTRAL, "BN" },
{ BIDI_PARAGRAPH_SEPARATOR, "B" },
{ BIDI_SEGMENT_SEPARATOR, "S" },
{ BIDI_WHITESPACE, "WS" },
{ BIDI_OTHER_NEUTRALS, "ON" },
{ 0, NULL }
};
#define DECOMP_TYPE_NONE 0
#define DECOMP_TYPE_FONT 1
#define DECOMP_TYPE_NOBREAK 2
#define DECOMP_TYPE_INITIAL 3
#define DECOMP_TYPE_MEDIAL 4
#define DECOMP_TYPE_FINAL 5
#define DECOMP_TYPE_ISOLATED 6
#define DECOMP_TYPE_CIRCLE 7
#define DECOMP_TYPE_SUPER 8
#define DECOMP_TYPE_SUB 9
#define DECOMP_TYPE_VERTICAL 10
#define DECOMP_TYPE_WIDE 11
#define DECOMP_TYPE_NARROW 12
#define DECOMP_TYPE_SMALL 13
#define DECOMP_TYPE_SQUARE 14
#define DECOMP_TYPE_FRACTION 15
#define DECOMP_TYPE_COMPAT 16
#define DECOMP_TYPE_ALL 17
static struct
{
int DecompType;
const char *DecompTypeLet;
} DecompTypeTable[] =
{
{ DECOMP_TYPE_FONT, "font" },
{ DECOMP_TYPE_NOBREAK, "noBreak" },
{ DECOMP_TYPE_INITIAL, "initial" },
{ DECOMP_TYPE_MEDIAL, "medial" },
{ DECOMP_TYPE_FINAL, "final" },
{ DECOMP_TYPE_ISOLATED, "isolated" },
{ DECOMP_TYPE_CIRCLE, "circle" },
{ DECOMP_TYPE_SUPER, "super" },
{ DECOMP_TYPE_SUB, "sub" },
{ DECOMP_TYPE_VERTICAL, "vertical" },
{ DECOMP_TYPE_WIDE, "wide" },
{ DECOMP_TYPE_NARROW, "narrow" },
{ DECOMP_TYPE_SMALL, "small" },
{ DECOMP_TYPE_SQUARE, "square" },
{ DECOMP_TYPE_FRACTION, "fraction" },
{ DECOMP_TYPE_COMPAT, "compat" },
{ 0, NULL }
};
#define MAPPING_ASCII 0
#define MAPPING_ISO_8859_1 1
#define MAPPING_ISO_8859_2 2
#define NUM_MAPPINGS 3
static struct
{
const char *pName;
const char *pFilename;
const char *pOutput;
int Type;
} MappingTypeTable[] =
{
{ "ASCII", "cl_ascii.txt", "tr_utf8_ascii_out.txt", MAPPING_ASCII },
{ "ISO-8859-1", "cl_8859_1.txt", "tr_utf8_latin1_out.txt", MAPPING_ISO_8859_1 },
{ "ISO-8859-2", "cl_8859_2.txt", "tr_utf8_latin2_out.txt", MAPPING_ISO_8859_2 },
{ NULL, 0 }
};
class CodePoint
{
public:
CodePoint();
~CodePoint();
bool IsDefined(void) { return m_bDefined; };
void SetDescription(const char *pDescription);
char *GetDescription(void) { return m_pDescription; };
void SetCategory(int category) { m_category = category; };
int GetCategory(void) { return m_category; };
const char *GetCategoryName(void);
void SetCombiningClass(int cc) { m_class = cc; };
int GetCombiningClass(void) { return m_class; };
void SetBiDi(int bidi) { m_bidi = bidi; };
int GetBiDi(void) { return m_bidi; };
const char *GetBiDiName(void);
void SetDecompositionType(int dt) { m_DecompType = dt; };
int GetDecompositionType(void) { return m_DecompType; };
const char *GetDecompositionTypeName(void);
void SetDecompositionMapping(int nPoints, UTF32 pts[]);
int GetDecompositionMapping(UTF32 pts[]);
void SetDecimalDigitValue(int n);
bool GetDecimalDigitValue(int *pn);
void SetDigitValue(int n);
bool GetDigitValue(int *pn);
void SetNumericValue(const char *p);
bool GetNumericValue(char **p);
void SetBidiMirrored(bool b) { m_bBidiMirrored = b; };
bool GetBidiMirrored(void) { return m_bBidiMirrored; };
void SetUnicode1Name(const char *p);
char *GetUnicode1Name(void) { return m_pUnicode1Name; };
void SetISOComment(const char *p);
char *GetISOComment(void) { return m_pISOComment; };
void SetSimpleUppercaseMapping(UTF32 ptUpper) { m_SimpleUppercaseMapping = ptUpper; };
void SetSimpleLowercaseMapping(UTF32 ptLower) { m_SimpleLowercaseMapping = ptLower; };
void SetSimpleTitlecaseMapping(UTF32 ptTitle) { m_SimpleTitlecaseMapping = ptTitle; };
UTF32 GetSimpleUppercaseMapping(void) { return m_SimpleUppercaseMapping; };
UTF32 GetSimpleLowercaseMapping(void) { return m_SimpleLowercaseMapping; };
UTF32 GetSimpleTitlecaseMapping(void) { return m_SimpleTitlecaseMapping; };
void SetProhibited(void) { m_bProhibited = true; };
bool IsProhibited(void) { return m_bProhibited; };
void SetMapping(int m, unsigned char ch) { m_mappings[m].ch = ch; m_mappings[m].bIs = true; };
bool IsMapping(int m, unsigned char &ch) { ch = m_mappings[m].ch; return m_mappings[m].bIs; };
private:
bool m_bDefined;
char *m_pDescription;
int m_category;
int m_class;
int m_bidi;
int m_DecompType;
int m_nDecompMapping;
UTF32 m_aDecompMapping[30];
int m_nDecimalDigitValue;
bool m_bHaveDecimalDigitValue;
int m_nDigitValue;
bool m_bHaveDigitValue;
char *m_pNumericValue;
bool m_bHaveNumericValue;
bool m_bBidiMirrored;
char *m_pUnicode1Name;
char *m_pISOComment;
UTF32 m_SimpleUppercaseMapping;
UTF32 m_SimpleLowercaseMapping;
UTF32 m_SimpleTitlecaseMapping;
bool m_bProhibited;
struct
{
bool bIs;
unsigned char ch;
} m_mappings[NUM_MAPPINGS];
};
void CodePoint::SetDecimalDigitValue(int n)
{
m_nDecimalDigitValue = n;
m_bHaveDecimalDigitValue = true;
}
bool CodePoint::GetDecimalDigitValue(int *pn)
{
*pn = m_nDecimalDigitValue;
return m_bHaveDecimalDigitValue;
}
void CodePoint::SetDigitValue(int n)
{
m_nDigitValue = n;
m_bHaveDigitValue = true;
}
bool CodePoint::GetDigitValue(int *pn)
{
*pn = m_nDigitValue;
return m_bHaveDigitValue;
}
void CodePoint::SetNumericValue(const char *p)
{
size_t n = strlen(p);
m_pNumericValue = new char[n+1];
memcpy(m_pNumericValue, p, n+1);
m_bHaveNumericValue = true;
}
bool CodePoint::GetNumericValue(char **p)
{
*p = m_pNumericValue;
return m_bHaveNumericValue;
}
int CodePoint::GetDecompositionMapping(UTF32 pts[])
{
for (int i = 0; i < m_nDecompMapping; i++)
{
pts[i] = m_aDecompMapping[i];
}
return m_nDecompMapping;
}
void CodePoint::SetDecompositionMapping(int nPoints, UTF32 pts[])
{
m_nDecompMapping = nPoints;
for (int i = 0; i < nPoints; i++)
{
m_aDecompMapping[i] = pts[i];
}
}
CodePoint::CodePoint()
{
m_bDefined = false;
m_pDescription = NULL;
m_category = CATEGORY_OTHER|SUBCATEGORY_NOT_ASSIGNED;
m_class = 0;
m_bidi = BIDI_LEFT_TO_RIGHT; // BUG: The default is not the same for all code point values.
m_DecompType = DECOMP_TYPE_NONE;
m_nDecompMapping = 0;
m_nDecimalDigitValue = 0;
m_bHaveDecimalDigitValue = false;
m_nDigitValue = 0;
m_bHaveDigitValue = false;
m_pNumericValue = NULL;
m_bHaveNumericValue = false;
m_bBidiMirrored = false;
m_pUnicode1Name = NULL;
m_pISOComment = NULL;
m_SimpleUppercaseMapping = UNI_EOF;
m_SimpleLowercaseMapping = UNI_EOF;
m_SimpleTitlecaseMapping = UNI_EOF;
m_bProhibited = false;
for (int i = 0; i < NUM_MAPPINGS; i++)
{
m_mappings[i].bIs = false;
}
}
CodePoint::~CodePoint()
{
if (NULL != m_pDescription)
{
delete [] m_pDescription;
m_pDescription = NULL;
}
m_bDefined = false;
}
void CodePoint::SetDescription(const char *pDescription)
{
if (NULL != m_pDescription)
{
delete [] m_pDescription;
m_pDescription = NULL;
}
size_t n = strlen(pDescription);
m_pDescription = new char[n+1];
memcpy(m_pDescription, pDescription, n+1);
m_bDefined = true;
}
void CodePoint::SetUnicode1Name(const char *p)
{
if (NULL != m_pUnicode1Name)
{
delete [] m_pUnicode1Name;
m_pUnicode1Name = NULL;
}
size_t n = strlen(p);
m_pUnicode1Name = new char[n+1];
memcpy(m_pUnicode1Name, p, n+1);
}
void CodePoint::SetISOComment(const char *p)
{
if (NULL != m_pISOComment)
{
delete [] m_pISOComment;
m_pISOComment = NULL;
}
size_t n = strlen(p);
m_pISOComment = new char[n+1];
memcpy(m_pISOComment, p, n+1);
}
class UniData
{
public:
UniData() {};
~UniData() {};
void LoadUnicodeDataFile(void);
void LoadUnicodeDataLine(UTF32 codepoint, int nFields, char *aFields[]);
void LoadUnicodeHanFile(void);
void LoadMappings(void);
void Prohibit(void);
void SaveMasterFile(void);
void SaveTranslateToUpper(void);
void SaveTranslateToLower(void);
void SaveTranslateToTitle(void);
void SaveTranslateDecimalValue(void);
void SaveMappings();
void SaveClassifyPrivateUse(void);
void SaveDecompositions(void);
void SaveClassifyPrintable(void);
void SaveCombiningClass(void);
void GetDecomposition(UTF32 pt, int dt, int &nPoints, UTF32 pts[]);
private:
CodePoint cp[codepoints+1];
};
UniData *g_UniData = NULL;
void UniData::GetDecomposition(UTF32 pt, int dt, int &nPoints, UTF32 pts[])
{
if (!cp[pt].IsDefined())
{
exit(1);
}
if ( DECOMP_TYPE_NONE != cp[pt].GetDecompositionType()
&& DECOMP_TYPE_ALL != dt
&& dt != cp[pt].GetDecompositionType())
{
pts[nPoints++] = pt;
return;
}
UTF32 pts2[50];
int n = cp[pt].GetDecompositionMapping(pts2);
if (n == 1 && pts2[0] == pt)
{
pts[nPoints++] = pt;
return;
}
for (UTF32 i = 0; i < n; i++)
{
GetDecomposition(pts2[i], dt, nPoints, pts);
}
}
int main(int argc, char *argv[])
{
if (1 != argc)
{
printf("Usage: buildFiles uses UnicodeData.txt\n");
return 0;
}
g_UniData = new UniData;
g_UniData->LoadUnicodeDataFile();
g_UniData->LoadUnicodeHanFile();
g_UniData->LoadMappings();
g_UniData->Prohibit();
g_UniData->SaveMasterFile();
g_UniData->SaveTranslateToUpper();
g_UniData->SaveTranslateToLower();
g_UniData->SaveTranslateToTitle();
g_UniData->SaveTranslateDecimalValue();
g_UniData->SaveMappings();
g_UniData->SaveClassifyPrivateUse();
g_UniData->SaveDecompositions();
g_UniData->SaveClassifyPrintable();
g_UniData->SaveCombiningClass();
return 0;
}
void UniData::LoadUnicodeDataFile(void)
{
FILE *fp = fopen("UnicodeData.txt", "r");
if (NULL != fp)
{
char buffer1[1024];
char buffer2[1024];
while (NULL != ReadLine(fp, buffer1, sizeof(buffer1)))
{
bool bRange = false;
bool bRangeValid = false;
int nFields1, nFields2;
char *aFields1[15], *aFields2[15];
ParseFields(buffer1, 15, nFields1, aFields1);
if ( 2 <= nFields1
&& aFields1[1][0] == '<')
{
size_t n1 = strlen(aFields1[1]);
if ( 9 <= n1
&& strcmp(&aFields1[1][n1-8], ", First>") == 0)
{
bRange = true;
if (NULL != ReadLine(fp, buffer2, sizeof(buffer2)))
{
ParseFields(buffer2, 15, nFields2, aFields2);
if ( 2 <= nFields2
&& aFields2[1][0] == '<')
{
size_t n2 = strlen(aFields2[1]);
if ( 8 <= n2
&& strcmp(&aFields2[1][n2-7], ", Last>") == 0)
{
aFields1[1][n1-8] = '\0';
aFields1[1]++;
aFields2[1][n2-7] = '\0';
aFields2[1]++;
bRangeValid = true;
}
}
}
}
}
if (!bRange)
{
// Single Code Point.
//
UTF32 pt = DecodeCodePoint(aFields1[0]);
LoadUnicodeDataLine(pt, nFields1, aFields1);
}
else if (bRangeValid)
{
// Range of Code Points.
//
bool bMatches = false;
if (nFields1 == nFields2)
{
bMatches = true;
for (int i = 1; i < nFields1; i++)
{
if (strcmp(aFields1[i], aFields2[i]) != 0)
{
bMatches = false;
}
}
}
if (bMatches)
{
//printf("%s - %s\n", aFields1[0], aFields2[0]);
UTF32 pt1 = DecodeCodePoint(aFields1[0]);
UTF32 pt2 = DecodeCodePoint(aFields2[0]);
if (pt1 != SBase)
{
// non-Hangul range.
//
for (UTF32 pt = pt1; pt <= pt2; pt++)
{
LoadUnicodeDataLine(pt, nFields1, aFields1);
}
}
else
{
// Korean Hangul range.
//
for (UTF32 pt = pt1; pt <= pt2; pt++)
{
UTF32 SIndex = pt - SBase;
UTF32 L = LBase + SIndex / NCount;
UTF32 V = VBase + (SIndex % NCount) / TCount;
UTF32 T = TBase + SIndex % TCount;
char Hangul[1024];
if (T == TBase)
{
sprintf(Hangul, "%04X %04X", L, V);
}
else
{
sprintf(Hangul, "%04X %04X %04X", L, V, T);
}
aFields1[5] = Hangul;
LoadUnicodeDataLine(pt, nFields1, aFields1);
}
}
}
else
{
printf("***ERROR: %s in range form does not agree with %s\n", aFields1[0], aFields2[0]);
}
}
else
{
printf("***ERROR: Invalid Range form near %s\n", aFields1[0]);
}
}
fclose(fp);
}
}
void UniData::LoadUnicodeDataLine(UTF32 codepoint, int nFields, char *aFields[])
{
if (codepoint <= codepoints)
{
// Description
//
if (2 <= nFields)
{
cp[codepoint].SetDescription(aFields[1]);
}
// Category
//
if (3 <= nFields)
{
bool bValid = false;
int i = 0;
while (CategoryTable[i].catlet)
{
if (strcmp(aFields[2], CategoryTable[i].catlet) == 0)
{
cp[codepoint].SetCategory(CategoryTable[i].cat);
bValid = true;
break;
}
i++;
}
if (!bValid)
{
printf("***ERROR: Invalid Category %s for U+%04X\n", aFields[2], codepoint);
exit(1);
}
}
// Combining Class.
//
if (4 <= nFields)
{
int cc = mux_atol(aFields[3]);
cp[codepoint].SetCombiningClass(cc);
}
// Bidi algorithm.
//
if (5 <= nFields)
{
bool bValid = false;
int i = 0;
while (BiDiTable[i].BiDiLet)
{
if (strcmp(aFields[4], BiDiTable[i].BiDiLet) == 0)
{
cp[codepoint].SetBiDi(BiDiTable[i].BiDi);
bValid = true;
break;
}
i++;
}
if (!bValid)
{
printf("***ERROR: Invalid BiDi %s for U+%04X\n", aFields[4], codepoint);
exit(1);
}
}
// Decomposition Type and Mapping.
//
if (6 <= nFields)
{
bool bValid = false;
const char *pDecomposition_Mapping = NULL;
const char *pDecomposition_Type = NULL;
if ('<' == aFields[5][0])
{
char *p = strchr(aFields[5]+1, '>');
if (NULL != p)
{
*p++ = '\0';
while (mux_isspace(*p))
{
p++;
}
pDecomposition_Type = aFields[5]+1;
pDecomposition_Mapping = p;
bValid = true;
}
}
else
{
pDecomposition_Type = "";
pDecomposition_Mapping = aFields[5];
bValid = true;
}
if (bValid)
{
if ('\0' != pDecomposition_Type[0])
{
bValid = false;
int i = 0;
while (DecompTypeTable[i].DecompType)
{
if (strcmp(pDecomposition_Type, DecompTypeTable[i].DecompTypeLet) == 0)
{
cp[codepoint].SetDecompositionType(DecompTypeTable[i].DecompType);
bValid = true;
break;
}
i++;
}
}
if (!bValid)
{
printf("***ERROR: Decomposition Type Name not found (%s).\n", pDecomposition_Type);
}
else
{
int nPoints;
const char *aPoints[30];
UTF32 pts[30];
ParsePoints(pDecomposition_Mapping, 30, nPoints, aPoints);
for (int i = 0; i < nPoints; i++)
{
pts[i] = DecodeCodePoint(aPoints[i]);
}
if (0 == nPoints)
{
pts[0] = codepoint;
nPoints = 1;
}
cp[codepoint].SetDecompositionMapping(nPoints, pts);
}
}
else
{
printf("***ERROR: Expression malformed.\n");
}
if (!bValid)
{
printf("***ERROR: Invalid Decomposition Type, '%s', or Mapping, '%s', for U+%04X\n", pDecomposition_Type, pDecomposition_Mapping, codepoint);
exit(1);
}
}
// Decimal Digit Value.
//
if ( 7 <= nFields
&& '\0' != aFields[6][0])
{
int cc = mux_atol(aFields[6]);
cp[codepoint].SetDecimalDigitValue(cc);
}
// Digit Value.
//
if ( 8 <= nFields
&& '\0' != aFields[7][0])
{
int cc = mux_atol(aFields[7]);
cp[codepoint].SetDigitValue(cc);
}
// Numeric Value.
//
if ( 9 <= nFields
&& '\0' != aFields[8][0])
{
cp[codepoint].SetNumericValue(aFields[8]);
}
// Bidi_Mirrored.
//
if ( 10 <= nFields
&& '\0' != aFields[9][0])
{
if ('Y' == aFields[9][0])
{
cp[codepoint].SetBidiMirrored(true);
}
else if ('N' == aFields[9][0])
{
cp[codepoint].SetBidiMirrored(false);
}
else
{
printf("Bidi_Mirrored '%s'.\n", aFields[9]);
exit(1);
}
}
// Unicode_1_Name.
//
if ( 11 <= nFields
&& '\0' != aFields[10][0])
{
cp[codepoint].SetUnicode1Name(aFields[10]);
}
// ISO Comment.
//
if ( 12 <= nFields
&& '\0' != aFields[11][0])
{
cp[codepoint].SetISOComment(aFields[11]);
}
// Simple Uppercase Mapping.
//
if ( 13 <= nFields
&& '\0' != aFields[12][0])
{
UTF32 pt = DecodeCodePoint(aFields[12]);
cp[codepoint].SetSimpleUppercaseMapping(pt);
}
// Simple Lowercase Mapping.
//
if ( 14 <= nFields
&& '\0' != aFields[13][0])
{
UTF32 pt = DecodeCodePoint(aFields[13]);
cp[codepoint].SetSimpleLowercaseMapping(pt);
}
// Simple Titlecase Mapping.
//
if ( 15 <= nFields
&& '\0' != aFields[14][0])
{
UTF32 pt = DecodeCodePoint(aFields[14]);
cp[codepoint].SetSimpleTitlecaseMapping(pt);
}
}
}
void UniData::LoadMappings(void)
{
for (int iMapping = 0; iMapping < NUM_MAPPINGS; iMapping++)
{
iconv_t iconvd = iconv_open(MappingTypeTable[iMapping].pName, "UTF-32LE");
if (((iconv_t)-1) == iconvd)
{
printf("iconv_open() error for %s.\n", MappingTypeTable[iMapping].pName);
exit(1);
}
for (UTF32 pt = 0; pt <= codepoints; pt++)
{
if (cp[pt].IsDefined())
{
UTF32 achIn[10];
size_t nIn = 2*sizeof(UTF32);
char *pIn = (char *)achIn;
unsigned char achOut[10];
size_t nOut = sizeof(achOut);
char *pOut = (char *)achOut;
achIn[0] = pt;
achIn[1] = 0;
size_t cnt = iconv(iconvd, NULL, NULL, NULL, NULL);
cnt = iconv(iconvd, &pIn, &nIn, &pOut, &nOut);
if ( ((size_t)-1) != cnt
&& '\0' != achOut[0]
&& '\0' == achOut[1])
{
cp[pt].SetMapping(MappingTypeTable[iMapping].Type, achOut[0]);
}
}
}
iconv_close(iconvd);
}
}
void UniData::SaveDecompositions()
{
FILE *fp = fopen("Decompositions.txt", "w+");
if (NULL == fp)
{
return;
}
for (UTF32 pt = 0; pt <= codepoints; pt++)
{
if (cp[pt].IsDefined())
{
int nPoints = 0;
UTF32 pts[100];
GetDecomposition(pt, DECOMP_TYPE_NONE, nPoints, pts);
if (nPoints != 1 || pts[0] != pt)
{
fprintf(fp, "%04X;", pt);
for (UTF32 pt2 = 0; pt2 < nPoints; pt2++)
{
if (pt2 != 0)
{
fprintf(fp, " ");
}
fprintf(fp, "%04X", pts[pt2]);
}
fprintf(fp, ";%s\n", cp[pt].GetDescription());
}
}
}
fclose(fp);
}
void UniData::SaveCombiningClass()
{
FILE *fp = fopen("tr_class.txt", "w+");
if (NULL == fp)
{
return;
}
for (UTF32 pt = 0; pt <= codepoints; pt++)
{
if (cp[pt].IsDefined())
{
static const int table[] =
{
0,
1,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
84,
91,
103,
107,
118,
122,
129,
130,
132,
202,
214,
216,
218,
220,
222,
224,
226,
228,
230,
232,
233,
234,
240,
};
int i;
int cc = cp[pt].GetCombiningClass();
for (i = 0; i < sizeof(table)/sizeof(table[0]); i++)
{
if (table[i] == cc)
{
fprintf(fp, "%04X;%u;%s\n", pt, i, cp[pt].GetDescription());
break;
}
}
if (i == sizeof(table)/sizeof(table[0]))
{
fprintf(fp, "Didn't find entry for %u\n", cc);
}
}
}
fclose(fp);
}
void UniData::SaveMappings()
{
for (int iMapping = 0; iMapping < NUM_MAPPINGS; iMapping++)
{
FILE *fp = fopen(MappingTypeTable[iMapping].pOutput, "w+");
if (NULL == fp)
{
return;
}
for (UTF32 pt = 0; pt <= codepoints; pt++)
{
if (cp[pt].IsDefined())
{
int nPoints = 0;
UTF32 pts[100];
GetDecomposition(pt, DECOMP_TYPE_ALL, nPoints, pts);
unsigned char ch;
UTF32 pt2;
int cnt = 0;
for (pt2 = 0; pt2 < nPoints; pt2++)
{
if (cp[pts[pt2]].IsMapping(MappingTypeTable[iMapping].Type, ch))
{
cnt++;
}
}
if ( 1 == cnt
&& cp[pts[0]].IsMapping(MappingTypeTable[iMapping].Type, ch))
{
char *pUnicode1Name = cp[pt].GetUnicode1Name();
fprintf(fp, "%04X;%u;%s;%s\n", pt, ch,
cp[pt].GetDescription(),
(NULL == pUnicode1Name) ? "" : pUnicode1Name);
}
}
}
fclose(fp);
}
}
void UniData::SaveTranslateToUpper(void)
{
FILE *fp = fopen("tr_toupper.txt", "w+");
if (NULL == fp)
{
return;
}
for (UTF32 pt = 0; pt <= codepoints; pt++)
{
if ( cp[pt].IsDefined()
&& !cp[pt].IsProhibited())
{
UTF32 ptUpper = cp[pt].GetSimpleUppercaseMapping();
if ( UNI_EOF != ptUpper
&& cp[ptUpper].IsDefined()
&& !cp[ptUpper].IsProhibited())
{
char *p = cp[pt].GetUnicode1Name();
fprintf(fp, "%04X;%04X;%s;%s\n", pt, ptUpper, cp[pt].GetDescription(), (NULL == p) ? "" : p);
}
}
}
fclose(fp);
}
void UniData::SaveTranslateToLower(void)
{
FILE *fp = fopen("tr_tolower.txt", "w+");
if (NULL == fp)
{
return;
}
for (UTF32 pt = 0; pt <= codepoints; pt++)
{
if ( cp[pt].IsDefined()
&& !cp[pt].IsProhibited())
{
UTF32 ptLower = cp[pt].GetSimpleLowercaseMapping();
if ( UNI_EOF != ptLower
&& cp[ptLower].IsDefined()
&& !cp[ptLower].IsProhibited())
{
char *p = cp[pt].GetUnicode1Name();
fprintf(fp, "%04X;%04X;%s;%s\n", pt, ptLower, cp[pt].GetDescription(), (NULL == p) ? "" : p);
}
}
}
fclose(fp);
}
void UniData::SaveTranslateToTitle(void)
{
FILE *fp = fopen("tr_totitle.txt", "w+");
if (NULL == fp)
{
return;
}
for (UTF32 pt = 0; pt <= codepoints; pt++)
{
if ( cp[pt].IsDefined()
&& !cp[pt].IsProhibited())
{
UTF32 ptTitle = cp[pt].GetSimpleTitlecaseMapping();
if ( UNI_EOF != ptTitle
&& cp[ptTitle].IsDefined()
&& !cp[ptTitle].IsProhibited())
{
char *p = cp[pt].GetUnicode1Name();
fprintf(fp, "%04X;%04X;%s;%s\n", pt, ptTitle, cp[pt].GetDescription(), (NULL == p) ? "" : p);
}
}
}
fclose(fp);
}
void UniData::SaveTranslateDecimalValue(void)
{
FILE *fp = fopen("tr_decimal_value.txt", "w+");
if (NULL == fp)
{
return;
}
for (UTF32 pt = 0; pt <= codepoints; pt++)
{
if ( cp[pt].IsDefined()
&& !cp[pt].IsProhibited())
{
int n;
if (cp[pt].GetDecimalDigitValue(&n))
{
char *p = cp[pt].GetUnicode1Name();
fprintf(fp, "%04X;%u;%s;%s\n", pt, n, cp[pt].GetDescription(), (NULL == p) ? "" : p);
}
}
}
fclose(fp);
}
void UniData::SaveMasterFile(void)
{
FILE *fp = fopen("UnicodeMaster.txt", "w+");
if (NULL == fp)
{
return;
}
for (UTF32 pt = 0; pt <= codepoints; pt++)
{
if (cp[pt].IsDefined())
{
fprintf(fp, "%04X;%s;%s;%u;%s", pt, cp[pt].GetDescription(), cp[pt].GetCategoryName(),
cp[pt].GetCombiningClass(), cp[pt].GetBiDiName());
char DecompBuffer[1024];
DecompBuffer[0] = '\0';
if (cp[pt].GetDecompositionType() != DECOMP_TYPE_NONE)
{
strcat(DecompBuffer, "<");
strcat(DecompBuffer, cp[pt].GetDecompositionTypeName());
strcat(DecompBuffer, ">");
}
UTF32 pts[30];
int nPoints = cp[pt].GetDecompositionMapping(pts);
if (nPoints != 1 || pts[0] != pt)
{
if ('\0' != DecompBuffer[0])
{
strcat(DecompBuffer, " ");
}
for (int i = 0; i < nPoints; i++)
{
if (0 != i)
{
strcat(DecompBuffer, " ");
}
char buf[12];
sprintf(buf, "%04X", pts[i]);
strcat(DecompBuffer, buf);
}
}
fprintf(fp, ";%s", DecompBuffer);
int n;
if (cp[pt].GetDecimalDigitValue(&n))
{
fprintf(fp, ";%u", n);
}
else
{
fprintf(fp, ";");
}
if (cp[pt].GetDigitValue(&n))
{
fprintf(fp, ";%u", n);
}
else
{
fprintf(fp, ";");
}
char *pNumericValue = NULL;
if (cp[pt].GetNumericValue(&pNumericValue))
{
fprintf(fp, ";%s", pNumericValue);
}
else
{
fprintf(fp, ";");
}
if (cp[pt].GetBidiMirrored())
{
fprintf(fp, ";Y");
}
else
{
fprintf(fp, ";N");
}
char *pUnicode1Name = cp[pt].GetUnicode1Name();
if (pUnicode1Name)
{
fprintf(fp, ";%s", pUnicode1Name);
}
else
{
fprintf(fp, ";");
}
char *pISOComment = cp[pt].GetISOComment();
if (pISOComment)
{
fprintf(fp, ";%s", pISOComment);
}
else
{
fprintf(fp, ";");
}
UTF32 ptUpper = cp[pt].GetSimpleUppercaseMapping();
if (UNI_EOF != ptUpper)
{
fprintf(fp, ";%04X", ptUpper);
}
else
{
fprintf(fp, ";");
}
UTF32 ptLower = cp[pt].GetSimpleLowercaseMapping();
if (UNI_EOF != ptLower)
{
fprintf(fp, ";%04X", ptLower);
}
else
{
fprintf(fp, ";");
}
UTF32 ptTitle = cp[pt].GetSimpleTitlecaseMapping();
if (UNI_EOF != ptTitle)
{
fprintf(fp, ";%04X", ptTitle);
}
else
{
fprintf(fp, ";");
}
fprintf(fp, "\n");
}
}
fclose(fp);
}
void UniData::Prohibit(void)
{
for (UTF32 pt = 0; pt <= codepoints; pt++)
{
if (cp[pt].IsDefined())
{
bool bShouldProhibit = false;
if ( 0 != cp[pt].GetCombiningClass()
|| (cp[pt].GetCategory() & CATEGORY_OTHER))
{
bShouldProhibit = true;
}
if (cp[pt].GetCategory() == (CATEGORY_OTHER|SUBCATEGORY_PRIVATE_USE))
{
if ( ( 0xE000 <= pt
&& pt <= 0xE0FF)
|| ( 0xF8D0 <= pt
&& pt <= 0xF8FF))
{
// Tengwar and Klingon
//
bShouldProhibit = false;
}
}
if (bShouldProhibit)
{
cp[pt].SetProhibited();
}
}
}
}
void UniData::SaveClassifyPrintable(void)
{
FILE *fp = fopen("cl_Printable.txt", "w+");
if (NULL == fp)
{
return;
}
for (UTF32 pt = 0; pt <= codepoints; pt++)
{
if ( cp[pt].IsDefined()
&& !cp[pt].IsProhibited())
{
fprintf(fp, "%04X;%s;%s;%u;%s", pt, cp[pt].GetDescription(), cp[pt].GetCategoryName(),
cp[pt].GetCombiningClass(), cp[pt].GetBiDiName());
char DecompBuffer[1024];
DecompBuffer[0] = '\0';
if (cp[pt].GetDecompositionType() != DECOMP_TYPE_NONE)
{
strcat(DecompBuffer, "<");
strcat(DecompBuffer, cp[pt].GetDecompositionTypeName());
strcat(DecompBuffer, ">");
}
UTF32 pts[30];
int nPoints = cp[pt].GetDecompositionMapping(pts);
if (nPoints != 1 || pts[0] != pt)
{
if ('\0' != DecompBuffer[0])
{
strcat(DecompBuffer, " ");
}
for (int i = 0; i < nPoints; i++)
{
if (0 != i)
{
strcat(DecompBuffer, " ");
}
char buf[12];
sprintf(buf, "%04X", pts[i]);
strcat(DecompBuffer, buf);
}
}
fprintf(fp, ";%s", DecompBuffer);
int n;
if (cp[pt].GetDecimalDigitValue(&n))
{
fprintf(fp, ";%u", n);
}
else
{
fprintf(fp, ";");
}
if (cp[pt].GetDigitValue(&n))
{
fprintf(fp, ";%u", n);
}
else
{
fprintf(fp, ";");
}
char *pNumericValue = NULL;
if (cp[pt].GetNumericValue(&pNumericValue))
{
fprintf(fp, ";%s", pNumericValue);
}
else
{
fprintf(fp, ";");
}
if (cp[pt].GetBidiMirrored())
{
fprintf(fp, ";Y");
}
else
{
fprintf(fp, ";N");
}
char *pUnicode1Name = cp[pt].GetUnicode1Name();
if (pUnicode1Name)
{
fprintf(fp, ";%s", pUnicode1Name);
}
else
{
fprintf(fp, ";");
}
char *pISOComment = cp[pt].GetISOComment();
if (pISOComment)
{
fprintf(fp, ";%s", pISOComment);
}
else
{
fprintf(fp, ";");
}
UTF32 ptUpper = cp[pt].GetSimpleUppercaseMapping();
if (UNI_EOF != ptUpper)
{
fprintf(fp, ";%04X", ptUpper);
}
else
{
fprintf(fp, ";");
}
UTF32 ptLower = cp[pt].GetSimpleLowercaseMapping();
if (UNI_EOF != ptLower)
{
fprintf(fp, ";%04X", ptLower);
}
else
{
fprintf(fp, ";");
}
UTF32 ptTitle = cp[pt].GetSimpleTitlecaseMapping();
if (UNI_EOF != ptTitle)
{
fprintf(fp, ";%04X", ptTitle);
}
else
{
fprintf(fp, ";");
}
fprintf(fp, "\n");
}
}
fclose(fp);
}
void UniData::SaveClassifyPrivateUse()
{
FILE *fp = fopen("cl_PrivateUse.txt", "w+");
if (NULL == fp)
{
return;
}
for (UTF32 pt = 0; pt <= codepoints; pt++)
{
if ( cp[pt].IsDefined()
&& (CATEGORY_OTHER|SUBCATEGORY_PRIVATE_USE) == cp[pt].GetCategory())
{
fprintf(fp, "%04X;%s\n", pt, cp[pt].GetDescription());
}
}
fclose(fp);
}
const char *CodePoint::GetCategoryName(void)
{
int i = 0;
while (CategoryTable[i].catlet)
{
if (CategoryTable[i].cat == m_category)
{
return CategoryTable[i].catlet;
}
i++;
}
return NULL;
}
const char *CodePoint::GetBiDiName(void)
{
int i = 0;
while (BiDiTable[i].BiDiLet)
{
if (BiDiTable[i].BiDi == m_bidi)
{
return BiDiTable[i].BiDiLet;
}
i++;
}
return NULL;
}
const char *CodePoint::GetDecompositionTypeName(void)
{
int i = 0;
while (DecompTypeTable[i].DecompTypeLet)
{
if (DecompTypeTable[i].DecompType == m_DecompType)
{
return DecompTypeTable[i].DecompTypeLet;
}
i++;
}
return NULL;
}
void UniData::LoadUnicodeHanFile(void)
{
FILE *fp = fopen("UnicodeHan.txt", "r");
if (NULL != fp)
{
char buffer[1024];
while (NULL != ReadLine(fp, buffer, sizeof(buffer)))
{
int nFields;
char *aFields[2];
ParseFields(buffer, 2, nFields, aFields);
if (2 == nFields)
{
UTF32 pt1, pt2;
char *p = strchr(aFields[0], '-');
if (NULL != p)
{
*p++ = '\0';
pt1 = DecodeCodePoint(aFields[0]);
pt2 = DecodeCodePoint(p);
}
else
{
pt2 = DecodeCodePoint(aFields[0]);
pt1 = pt2;
}
for (UTF32 pt = pt1; pt <= pt2; pt++)
{
if (cp[pt].IsDefined())
{
continue;
}
char hex[32];
char desc[1024];
sprintf(hex, "%04X", pt);
sprintf(desc, "%s CHARACTER %04X", aFields[1], pt);
int nFields1 = 15;
char *aFields1[15];
aFields1[0] = hex;
aFields1[1] = desc;
aFields1[2] = (char *)"So";
aFields1[3] = (char *)"0";
aFields1[4] = (char *)"ON";
aFields1[5] = (char *)"";
aFields1[6] = (char *)"";
aFields1[7] = (char *)"";
aFields1[8] = (char *)"";
aFields1[9] = (char *)"N";
aFields1[10] = (char *)"";
aFields1[11] = (char *)"";
aFields1[12] = (char *)"";
aFields1[13] = (char *)"";
aFields1[14] = (char *)"";
LoadUnicodeDataLine(pt, nFields1, aFields1);
}
}
}
fclose(fp);
}
}