fontforge/Unicode/makebuildtables.c
2013-07-11 15:46:35 +02:00

559 lines
19 KiB
C

/* Copyright (C) 2000-2012 by George Williams */
/*
* 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.
* The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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>
#include <utype.h>
/* figure out how to do divide, multiply, 1/4, 3/4 */
#define forever for (;;)
typedef unsigned short unichar_t;
typedef unsigned int uint32;
#define ACUTE 0x1
#define GRAVE 0x2
#define DIAERESIS 0x4
#define CIRCUMFLEX 0x8
#define TILDE 0x10
#define RING 0x20
#define SLASH 0x40
#define BREVE 0x80
#define CARON 0x100
#define DOTABOVE 0x200
#define DOTBELOW 0x400
#define CEDILLA 0x800
#define OGONEK 0x1000
#define MACRON 0x2000
#define DBLGRAVE 0x4000
#define DBLACUTE 0x8000
#define INVBREVE 0x10000
#define DIAERESISBELOW 0x20000
#define CIRCUMFLEXBELOW 0x40000
#define TILDEBELOW 0x80000
#define RINGBELOW 0x100000
#define LINEBELOW 0x200000
#define HOOKABOVE 0x400000
#define HORN 0x800000
#define GREEK 0x8000000
#define ANY (0xfffffff)
struct names { char *name; int mask; } names[] = {
{"ACUTE", 0x1},
{"GRAVE", 0x2},
{"DIAERESIS", 0x4},
{"CIRCUMFLEX", 0x8},
{"TILDE", 0x10},
{"RING", 0x20},
{"SLASH", 0x40},
{"BREVE", 0x80},
{"CARON", 0x100},
{"DOTABOVE", 0x200},
{"DOTBELOW", 0x400},
{"CEDILLA", 0x800},
{"OGONEK", 0x1000},
{"MACRON", 0x2000},
{"DBLGRAVE", 0x4000},
{"DBLACUTE", 0x8000},
{"INVBREVE", 0x10000},
{"DIAERESISBELOW", 0x20000},
{"CIRCUMFLEXBELOW", 0x40000},
{"TILDEBELOW", 0x80000},
{"RINGBELOW", 0x100000},
{"LINEBELOW", 0x200000},
{"HOOKABOVE", 0x400000},
{"HORN", 0x800000},
{"GREEK", 0x8000000},
{NULL}};
struct names names2[] = {
{"ACUTE", 0x1},
{"GRAVE", 0x2},
{"DIAERESIS BELOW", 0x20000},
{"DIAERESIS", 0x4},
{"CIRCUMFLEX BELOW", 0x40000},
{"CIRCUMFLEX", 0x8},
{"TILDE BELOW", 0x80000},
{"TILDE", 0x10},
{"RING ABOVE", 0x20},
{"RING BELOW", 0x100000},
{"STROKE", 0x40},
{"SLASH", 0x40},
{"BREVE", 0x80},
{"CARON", 0x100},
{"DOT ABOVE", 0x200},
{"MIDDLE DOT", 0x200},
{"DOT BELOW", 0x400},
{"CEDILLA", 0x800},
{"OGONEK", 0x1000},
{"MACRON", 0x2000},
{"DOUBLE GRAVE", 0x4000},
{"DOUBLE ACUTE", 0x8000},
{"INVERTED BREVE", 0x10000},
{"LINE BELOW", 0x200000},
{"HOOK ABOVE", 0x400000},
{"HORN", 0x800000},
{NULL}};
char *charnames[] = {
/* 0x0020 */ "space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle",
/* 0x0028 */ "parenleft","parenright","asterisk","plus","comma","hyphenminus","period","slash",
/* 0x0030 */ "zero","one","two","three","four","five","six","seven",
/* 0x0038 */ "eight","nine","colon","semicolon","less","equal","greater","question",
/* 0x0040 */ "at","A","B","C","D","E","F","G",
/* 0x0048 */ "H","I","J","K","L","M","N","O",
/* 0x0050 */ "P","Q","R","S","T","U","V","W",
/* 0x0058 */ "X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore",
/* 0x0060 */ "grave","a","b","c","d","e","f","g",
/* 0x0068 */ "h","i","j","k","l","m","n","o",
/* 0x0070 */ "p","q","r","s","t","u","v","w",
/* 0x0078 */ "x","y","z","braceleft","bar","braceright","asciitilde"
};
struct { char ch; unsigned int oldstate, newstate; unsigned short result; }
predefined[] = {
{ '\'', ANY, ACUTE },
{ 'e', 0, ACUTE },
{ '`', ANY, GRAVE },
{ ':', ANY, DIAERESIS },
{ 'u', 0, DIAERESIS },
{ '^', ANY, CIRCUMFLEX },
{ 'i', 0, CIRCUMFLEX },
{ '~', ANY, TILDE },
{ 'n', 0, TILDE },
{ '0', ANY, RING },
{ '/', ANY, SLASH },
{ '7', ANY, BREVE },
{ '6', ANY, CARON },
{ '.', ANY, DOTABOVE },
{ ',', ANY, DOTBELOW },
{ '5', ANY, CEDILLA },
{ '4', ANY, OGONEK },
{ '_', ANY, MACRON },
{ '"', ANY, DBLGRAVE },
{ '@', ANY, GREEK },
{ ' ', 0, 0, 0x00a0 }, /* no break space */
{ ' ', GREEK, 0, 0x2001 }, /* em space */
{ '!', 0, 0, 0x00a1 }, /* inverted exclaim */
{ '#', 0, 0, 0x00a3 }, /* sterling */
{ '#', GREEK, 0, 0x00a5 }, /* Yen */
{ '$', 0, 0, 0x20ac }, /* Euro */
{ '$', GREEK, 0, 0x00a2 }, /* cent */
{ '\\',0, 0, 0x00ab }, /* guillemotleft */
{ '\\',GREEK, 0, 0x2039 }, /* single guillemotleft */
{ '|', 0, 0, 0x00bb }, /* guillemotright */
{ '|', GREEK, 0, 0x203a }, /* single guillemotright */
{ '*', 0, 0, 0x00b0 }, /* degree */
{ '*', GREEK, 0, 0x2022 }, /* bullet */
{ '.', GREEK, 0, 0x00b7 }, /* centered dot */
{ '-', 0, 0, 0x00ad }, /* soft hyphen */
{ '-', GREEK, 0, 0x2013 }, /* en dash */
{ '_', GREEK, 0, 0x2014 }, /* em dash */
{ '=', GREEK, 0, 0x2015 }, /* quote dash */
{ '+', 0, 0, 0x00b1 }, /* plus minus */
{ ';', 0, 0, 0x2026 }, /* ellipsis */
{ '[', 0, 0, 0x2018 }, /* open quote */
{ ']', 0, 0, 0x2019 }, /* close quote */
{ '{', 0, 0, 0x201c }, /* open double quote */
{ '}', 0, 0, 0x201c }, /* close double quote */
{ '>', 0, 0, 0x2264 }, /* greater than or equal */
{ '>', GREEK, 0, 0x2023 }, /* triangle bullet */
{ '<', 0, 0, 0x2265 }, /* less than or equal */
{ '?', 0, 0, 0x00bf }, /* inverted quest */
{ 'f', 0, 0, 0x2640 }, /* female */
{ 'g', 0, 0, 0x00a9 }, /* copyright */
{ 'h', GREEK|SLASH, 0, 0x210f },/* hbar */
{ 'h', 0, 0, 0x261e }, /* right hand */
{ 'H', 0, 0, 0x261e }, /* left hand */
{ 'm', 0, 0, 0x2642 }, /* male */
{ 'p', 0, 0, 0x00b6 }, /* paragraph */
{ 'P', 0, 0, 0x00a7 }, /* section */
{ 'r', 0, 0, 0x00ae }, /* registered */
{ 't', 0, 0, 0x2122 }, /* TM */
{ '2', BREVE, 0, 0x00bd }, /* 1/2 */
/* { 'A', 0, 0, 0x00c5 }, /* A ring */
/* { 'a', 0, 0, 0x00e5 }, /* a ring */
{ 'C', 0, 0, 0x00c7 }, /* C cedilla */
{ 'c', 0, 0, 0x00e7 }, /* c cedilla */
{ 'A', 0, 0, 0x00c6 }, /* AE */
{ 'a', 0, 0, 0x00e6 }, /* ae */
{ 'O', 0, 0, 0x0152 }, /* OE */
{ 'o', 0, 0, 0x1536 }, /* oe */
{ 's', 0, 0, 0x00df }, /* es-zet */
{ 'z', 0, 0, 0x017f }, /* long-s */
{ 'i', DOTABOVE, 0, 0x131 }, /* dotless i */
/* the mapping from ascii->greek follows the symbol font */
{ 'A', GREEK, 0, 0x391 }, /* Alpha */
{ 'B', GREEK, 0, 0x392 }, /* Beta */
{ 'C', GREEK, 0, 0x3A7 }, /* Chi */
{ 'D', GREEK, 0, 0x394 }, /* Delta */
{ 'E', GREEK, 0, 0x395 }, /* Epsilon */
{ 'F', GREEK, 0, 0x3A6 }, /* Phi */
{ 'G', GREEK, 0, 0x393 }, /* Gamma */
{ 'H', GREEK, 0, 0x397 }, /* Eta */
{ 'I', GREEK, 0, 0x399 }, /* Iota */
{ 'J', GREEK, 0, 0x3d1 }, /* Theta Symbol */
{ 'K', GREEK, 0, 0x39A }, /* Kappa */
{ 'L', GREEK, 0, 0x39B }, /* Lamda */
{ 'M', GREEK, 0, 0x39C }, /* Mu */
{ 'N', GREEK, 0, 0x39D }, /* Nu */
{ 'O', GREEK, 0, 0x39F }, /* Omicron */
{ 'P', GREEK, 0, 0x3A0 }, /* Pi */
{ 'Q', GREEK, 0, 0x398 }, /* Theta */
{ 'R', GREEK, 0, 0x3A1 }, /* Rho */
{ 'S', GREEK, 0, 0x3A3 }, /* Sigma */
{ 'T', GREEK, 0, 0x3A4 }, /* Tau */
{ 'U', GREEK, 0, 0x3A5 }, /* Upsilon */
{ 'V', GREEK, 0, 0x3c2 }, /* lowercase final sigma */
{ 'W', GREEK, 0, 0x3A9 }, /* Omega */
{ 'X', GREEK, 0, 0x39E }, /* Xi */
{ 'Y', GREEK, 0, 0x3A8 }, /* Psi */
{ 'Z', GREEK, 0, 0x396 }, /* Zeta */
{ 'a', GREEK, 0, 0x3b1 }, /* alpha */
{ 'b', GREEK, 0, 0x3b2 }, /* beta */
{ 'c', GREEK, 0, 0x3c7 }, /* chi */
{ 'd', GREEK, 0, 0x3b4 }, /* delta */
{ 'e', GREEK, 0, 0x3b5 }, /* epsilon */
{ 'f', GREEK, 0, 0x3c6 }, /* phi */
{ 'g', GREEK, 0, 0x3b3 }, /* gamma */
{ 'h', GREEK, 0, 0x3b7 }, /* eta */
{ 'i', GREEK, 0, 0x3b9 }, /* iota */
{ 'j', GREEK, 0, 0x3d5 }, /* phi Symbol */
{ 'k', GREEK, 0, 0x3bA }, /* kappa */
{ 'l', GREEK, 0, 0x3bB }, /* lamda */
{ 'm', GREEK, 0, 0x3bC }, /* mu */
{ 'n', GREEK, 0, 0x3bD }, /* nu */
{ 'o', GREEK, 0, 0x3bF }, /* omicron */
{ 'p', GREEK, 0, 0x3c0 }, /* pi */
{ 'q', GREEK, 0, 0x3b8 }, /* theta */
{ 'r', GREEK, 0, 0x3c1 }, /* rho */
{ 's', GREEK, 0, 0x3c3 }, /* sigma */
{ 't', GREEK, 0, 0x3c4 }, /* tau */
{ 'u', GREEK, 0, 0x3c5 }, /* upsilon */
{ 'v', GREEK, 0, 0x3D6 }, /* pi Symbol */
{ 'w', GREEK, 0, 0x3c9 }, /* omega */
{ 'x', GREEK, 0, 0x3bE }, /* xi */
{ 'y', GREEK, 0, 0x3c8 }, /* psi */
{ 'z', GREEK, 0, 0x3b6 }, /* zeta */
{ 'A', GREEK|DBLGRAVE, 0, 0x386 }, /* Alpha tonos */
{ 'A', GREEK|BREVE, 0, 0x1fb8 }, /* Alpha vrachy */
{ 'A', GREEK|MACRON, 0, 0x1fb9 }, /* Alpha macron */
{ 'a', GREEK|DBLGRAVE, 0, 0x3ac }, /* alpha tonos */
{ 'a', GREEK|GRAVE, 0, 0x1f70 }, /* alpha varia */
{ 'a', GREEK|ACUTE, 0, 0x1f71 }, /* alpha oxia */
{ 'a', GREEK|BREVE, 0, 0x1fb0 }, /* alpha vrachy */
{ 'a', GREEK|MACRON, 0, 0x1fb1 }, /* alpha macron */
{ 'a', GREEK|TILDE, 0, 0x1fb6 }, /* alpha perispomeni */
{ 'E', GREEK|DBLGRAVE, 0, 0x388 }, /* Epsilon tonos */
{ 'E', GREEK|GRAVE, 0, 0x1fc8 }, /* Epsilon varia */
{ 'E', GREEK|ACUTE, 0, 0x1fc9 }, /* Epsilon oxia */
{ 'e', GREEK|DBLGRAVE, 0, 0x3ad }, /* epsilon tonos */
{ 'e', GREEK|GRAVE, 0, 0x1f72 }, /* epsilon varia */
{ 'e', GREEK|ACUTE, 0, 0x1f73 }, /* epsilon oxia */
{ 'H', GREEK|DBLGRAVE, 0, 0x389 }, /* Eta tonos */
{ 'H', GREEK|GRAVE, 0, 0x1fca }, /* Eta varia */
{ 'H', GREEK|ACUTE, 0, 0x1fcb }, /* Eta oxia */
{ 'h', GREEK|DBLGRAVE, 0, 0x3ae }, /* eta tonos */
{ 'h', GREEK|GRAVE, 0, 0x1f74 }, /* eta varia */
{ 'h', GREEK|ACUTE, 0, 0x1f75 }, /* eta oxia */
{ 'h', GREEK|TILDE, 0, 0x1fc6 }, /* eta perispomeni */
{ 'I', GREEK|DBLGRAVE, 0, 0x38A }, /* Iota tonos */
{ 'I', GREEK|DIAERESIS, 0, 0x3AA }, /* Iota dialytika */
{ 'I', GREEK|GRAVE, 0, 0x1f7a }, /* Iota varia */
{ 'I', GREEK|ACUTE, 0, 0x1f7b }, /* Iota oxia */
{ 'I', GREEK|TILDE, 0, 0x1f78 }, /* Iota perispomeni */
{ 'I', GREEK|MACRON, 0, 0x1f79 }, /* Iota macron */
{ 'i', GREEK|DBLGRAVE, 0, 0x3af }, /* iota tonos */
{ 'i', GREEK|DIAERESIS, 0, 0x3ca }, /* iota dialytika */
{ 'i', GREEK|DBLGRAVE|DIAERESIS, 0, 0x390 },/* iota dialytika tonos */
{ 'i', GREEK|GRAVE, 0, 0x1f76 }, /* iota varia */
{ 'i', GREEK|ACUTE, 0, 0x1f77 }, /* iota oxia */
{ 'i', GREEK|BREVE, 0, 0x1fd0 }, /* iota vrachy */
{ 'i', GREEK|MACRON, 0, 0x1fd1 }, /* iota macron */
{ 'i', GREEK|TILDE, 0, 0x1fd6 }, /* iota perispomeni */
{ 'i', GREEK|GRAVE|DIAERESIS, 0, 0x1fd2},/* iota dialytika varia */
{ 'i', GREEK|ACUTE|DIAERESIS, 0, 0x1fd3},/* iota dialytika oxia */
{ 'i', GREEK|TILDE|DIAERESIS, 0, 0x1fd7},/* iota dialytika perispomeni */
{ 'O', GREEK|DBLGRAVE, 0, 0x38C }, /* Omicron tonos */
{ 'O', GREEK|GRAVE, 0, 0x1ff8 }, /* Omicron varia */
{ 'O', GREEK|ACUTE, 0, 0x1ff9 }, /* Omicron oxia */
{ 'o', GREEK|DBLGRAVE, 0, 0x3cc }, /* omicron tonos */
{ 'o', GREEK|GRAVE, 0, 0x1f78 }, /* omicron varia */
{ 'o', GREEK|ACUTE, 0, 0x1f79 }, /* omicron oxia */
{ 'U', GREEK|DBLGRAVE, 0, 0x38E }, /* Upsilon tonos */
{ 'U', GREEK|DIAERESIS, 0, 0x3AB }, /* Upsilon dialytika */
{ 'U', GREEK|GRAVE, 0, 0x1fea }, /* Upsilon varia */
{ 'U', GREEK|ACUTE, 0, 0x1feb }, /* Upsilon oxia */
{ 'U', GREEK|BREVE, 0, 0x1fe8 }, /* Upsilon perispomeni */
{ 'U', GREEK|MACRON, 0, 0x1fe9 }, /* Upsilon macron */
{ 'u', GREEK|DBLGRAVE, 0, 0x3cd }, /* upsilon tonos */
{ 'u', GREEK|DIAERESIS, 0, 0x3cb }, /* upsilon dialytika */
{ 'u', GREEK|DBLGRAVE|DIAERESIS, 0, 0x3b0 },/* upsilon dialytika tonos */
{ 'u', GREEK|GRAVE, 0, 0x1f7a }, /* upsilon varia */
{ 'u', GREEK|ACUTE, 0, 0x1f7b }, /* upsilon oxia */
{ 'u', GREEK|BREVE, 0, 0x1ff0 }, /* upsilon perispomeni */
{ 'u', GREEK|MACRON, 0, 0x1fe1 }, /* upsilon macron */
{ 'u', GREEK|GRAVE|DIAERESIS, 0, 0x1fe3 },/* upsilon dialytika varia */
{ 'u', GREEK|ACUTE|DIAERESIS, 0, 0x1fe4 },/* upsilon dialytika oxia */
{ 'u', GREEK|TILDE, 0, 0x1fe6 }, /* upsilon perispomeni */
{ 'u', GREEK|TILDE|DIAERESIS, 0, 0x1fe7 },/* upsilon dialytika perispomeni */
{ 'W', GREEK|DBLGRAVE, 0, 0x38F }, /* Omega tonos */
{ 'W', GREEK|GRAVE, 0, 0x1ffa }, /* Omega varia */
{ 'W', GREEK|ACUTE, 0, 0x1ffb }, /* Omega oxia */
{ 'w', GREEK|DBLGRAVE, 0, 0x3ce }, /* omega tonos */
{ 'w', GREEK|GRAVE, 0, 0x1f7a }, /* omega varia */
{ 'w', GREEK|ACUTE, 0, 0x1f7b }, /* omega oxia */
{ 0 }
};
struct transform {
uint32 oldstate;
uint32 newstate;
unichar_t resch;
struct transform *next;
} *info[95] = { 0 };
int queuelen(struct transform *queue) {
int len=0;
while ( queue!=NULL ) {
queue = queue->next;
++len;
}
return( len );
}
static char *Mask(char *buffer,int mask) {
int i,m;
char *bpt = buffer;
if ( mask==0 )
return( "0" );
if ( mask==ANY )
return("ANY");
*buffer = '\0';
for (i=0; names[i].name!=NULL; ++i ) {
if ( names[i].mask&mask ) {
if ( bpt!=buffer )
*bpt++ ='|';
strcpy(bpt,names[i].name);
bpt += strlen(bpt);
}
}
return( buffer );
}
void dumpinfo() {
FILE *out;
int i;
struct transform *t;
char buffer[400], buffer2[400];
out = fopen("gdrawbuildchars.c","w");
fprintf(out,"#include \"gdrawP.h\"\n\n" );
for ( i=0; names[i].name!=NULL; ++i )
fprintf( out, "#define\t%s\t0x%07x\n", names[i].name, names[i].mask );
fprintf(out,"\n#define\tANY\t0x%07x\n\n", ANY );
for ( i=0; i<95; ++i ) if ( info[i]!=NULL ) {
fprintf(out, "static struct gchr_transform trans_%s[] = {\n", charnames[i] );
for ( t=info[i]; t!=NULL; t=t->next )
fprintf(out, " { %s, %s, 0x%07x }%s\n", Mask(buffer,t->oldstate),
Mask(buffer2,t->newstate), t->resch, t->next==NULL?"":"," );
fprintf(out,"};\n\n");
}
fprintf(out,"struct gchr_lookup _gdraw_chrlookup[95] = {\n" );
for ( i=0; i<95; ++i ) {
if ( info[i]==NULL )
fprintf(out, " { 0 },\t\t\t/* %c */\n", i+' ' );
else
fprintf(out, " { %d, trans_%s },\t/* %c */\n", queuelen(info[i]), charnames[i], i+' ' );
}
fprintf(out,"};\n\n" );
fprintf(out, "struct gchr_accents _gdraw_accents[] = {\n" );
fprintf(out, " { 0x0301, 0x%07x },\n", ACUTE );
fprintf(out, " { 0x0300, 0x%07x },\n", GRAVE );
fprintf(out, " { 0x0308, 0x%07x },\n", DIAERESIS );
fprintf(out, " { 0x0302, 0x%07x },\n", CIRCUMFLEX );
fprintf(out, " { 0x0303, 0x%07x },\n", TILDE );
fprintf(out, " { 0x030a, 0x%07x },\n", RING );
fprintf(out, " { 0x0338, 0x%07x },\n", SLASH );
fprintf(out, " { 0x0306, 0x%07x },\n", BREVE );
fprintf(out, " { 0x030c, 0x%07x },\n", CARON );
fprintf(out, " { 0x0307, 0x%07x },\n", DOTABOVE );
fprintf(out, " { 0x0323, 0x%07x },\n", DOTBELOW );
fprintf(out, " { 0x0327, 0x%07x },\n", CEDILLA );
fprintf(out, " { 0x0328, 0x%07x },\n", OGONEK );
fprintf(out, " { 0x0304, 0x%07x },\n", MACRON );
fprintf(out, " { 0x030d, 0x%07x },\n", DBLGRAVE|GREEK );
fprintf(out, " { 0x030b, 0x%07x },\n", DBLGRAVE );
fprintf(out, " { 0x030b, 0x%07x },\n", DBLACUTE );
fprintf(out, " { 0x030b, 0x%07x },\n", INVBREVE );
fprintf(out, " { 0x030b, 0x%07x },\n", DIAERESISBELOW );
fprintf(out, " { 0x030b, 0x%07x },\n", CIRCUMFLEXBELOW );
fprintf(out, " { 0x030b, 0x%07x },\n", TILDEBELOW );
fprintf(out, " { 0x030b, 0x%07x },\n", RINGBELOW );
fprintf(out, " { 0x030b, 0x%07x },\n", LINEBELOW );
fprintf(out, " { 0x030b, 0x%07x },\n", HOOKABOVE );
fprintf(out, " { 0x030b, 0x%07x },\n", HORN );
fprintf(out, " { 0 },\n" );
fprintf(out, "};\n\n" );
fprintf(out, "uint32 _gdraw_chrs_any=ANY, _gdraw_chrs_ctlmask=GREEK, _gdraw_chrs_metamask=0;\n" );
fclose(out);
}
char *mygets(FILE *in,char *buffer) {
char *bpt = buffer;
int ch;
while ((ch = getc(in))!=EOF && ch!='\n' )
*bpt++ = ch;
*bpt = '\0';
if ( bpt==buffer && ch==EOF )
return( NULL );
return(buffer );
}
void AddTransform(int ch, uint32 oldstate, uint32 newstate, unsigned short resch ) {
struct transform *trans;
ch -= ' ';
for ( trans=info[ch]; trans!=NULL; trans = trans->next )
if ( trans->oldstate==oldstate ) {
fprintf(stderr, "Duplicate entry for %c(%d) at 0x%07x, 0x%07x,0x%07x and 0x%07x,0x%07x\n",
ch+' ', ch+' ', oldstate, trans->newstate, trans->resch, newstate, resch );
break;
}
trans = calloc(1,sizeof(struct transform));
trans->next = info[ch];
info[ch] = trans;
trans->oldstate = oldstate;
trans->newstate = newstate;
trans->resch = resch;
}
void ParseUnicodeFile(FILE *in) {
char buffer[600];
int ch, mask, base, lc, i;
char *pt;
while ( mygets(in,buffer)!=NULL ) {
ch = strtol(buffer,NULL,16);
if ( ch==0x1ec0 )
ch = 0x1ec0;
pt = buffer+4;
if ( strncmp(pt,";LATIN ",7)!=0 )
continue;
pt += 7;
if ( strncmp(pt,"CAPITAL ",8)==0 ) {
lc = 0;
pt += 8;
} else if ( strncmp(pt,"SMALL ",6)==0 ) {
lc = 1;
pt += 6;
} else
continue;
if ( strncmp(pt,"LETTER ",7)!=0 )
continue;
pt += 7;
base = *pt++;
if ( lc ) base = tolower(base);
if ( strncmp(pt," WITH ",6)!=0 )
continue;
pt += 6;
mask = 0;
forever {
for ( i=0; names2[i].name!=NULL; ++i ) {
if ( strncmp(pt,names2[i].name,strlen(names2[i].name))==0 )
break;
}
if ( names2[i].name==NULL || names2[i].mask==0 )
goto continue_2_loop;
mask |= names2[i].mask;
pt += strlen(names2[i].name);
while ( *pt!=';' && !(*pt==' ' && pt[1]=='A' && pt[2]=='N' && pt[3]=='D' && pt[4]==' '))
++pt;
if ( *pt==';' )
break;
else
pt += 5;
}
AddTransform(base,mask,0,ch);
continue_2_loop:;
}
fclose(in);
}
void AddPredefineds() {
int i;
for ( i=0; predefined[i].ch!='\0'; ++i )
AddTransform(predefined[i].ch, predefined[i].oldstate,
predefined[i].newstate, predefined[i].result );
}
struct transform *RevQueue(struct transform *cur) {
struct transform *prev=NULL, *next;
if ( cur==NULL )
return( NULL );
next = cur->next;
while ( next!=NULL ) {
cur->next = prev;
prev = cur;
cur = next;
next = cur->next;
}
cur->next = prev;
return( cur );
}
main() {
FILE *in;
int i;
AddPredefineds();
in = fopen("UnicodeData.txt","r");
if ( in==NULL ) {
fprintf(stderr,"Can't open UnicodeData.txt\n" );
exit(1);
}
ParseUnicodeFile(in);
for ( i=0; i<95; ++i )
info[i] = RevQueue(info[i]);
dumpinfo();
exit(0);
}