2011-06-30 17:37:13 +02:00
|
|
|
/* Copyright (c) 2004, 2006 MySQL AB
|
2011-05-02 19:58:45 +02:00
|
|
|
Copyright (c) 2009-2011, Monty Program Ab
|
2011-06-30 17:37:13 +02:00
|
|
|
Use is subject to license terms.
|
2011-05-02 19:58:45 +02:00
|
|
|
Copyright (c) 2009-2011, Monty Program Ab
|
2006-12-31 01:02:27 +01:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
2019-05-11 20:29:06 +02:00
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
2006-12-31 01:02:27 +01:00
|
|
|
|
2004-03-22 12:14:12 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2021-11-23 13:33:08 +01:00
|
|
|
#include "my_global.h"
|
|
|
|
#include "m_ctype.h"
|
|
|
|
#include "ctype-uca.h"
|
2004-03-22 12:14:12 +01:00
|
|
|
|
2004-03-23 15:29:07 +01:00
|
|
|
#if 0
|
2004-03-22 12:14:12 +01:00
|
|
|
#define MY_UCA_NPAGES 1024
|
|
|
|
#define MY_UCA_NCHARS 64
|
|
|
|
#define MY_UCA_CMASK 63
|
|
|
|
#define MY_UCA_PSHIFT 6
|
|
|
|
#else
|
2016-05-18 10:35:38 +02:00
|
|
|
#define MY_UCA_NPAGES 4352 /* 0x110000 characters / 0x100 chars per page */
|
2004-03-22 12:14:12 +01:00
|
|
|
#define MY_UCA_NCHARS 256
|
|
|
|
#define MY_UCA_CMASK 255
|
|
|
|
#define MY_UCA_PSHIFT 8
|
|
|
|
#endif
|
|
|
|
|
2016-05-18 10:35:38 +02:00
|
|
|
#define MAX_ALLOWED_CODE 0x10FFFF
|
|
|
|
|
2021-11-23 13:33:08 +01:00
|
|
|
|
|
|
|
typedef struct opt_st
|
|
|
|
{
|
|
|
|
const char *name_prefix; /* Name that goes into all array names */
|
|
|
|
const char *filename; /* The filename or "-" for stdin */
|
|
|
|
uint levels; /* The number of levels to dump */
|
|
|
|
} OPT;
|
|
|
|
|
|
|
|
|
|
|
|
static OPT defaults=
|
|
|
|
{
|
|
|
|
"uca",
|
|
|
|
"-",
|
|
|
|
3
|
|
|
|
};
|
|
|
|
|
2016-05-18 10:35:38 +02:00
|
|
|
|
2021-11-24 12:11:49 +01:00
|
|
|
typedef struct my_ducet_weight_st
|
|
|
|
{
|
|
|
|
uint16 weight[4][MY_UCA_MAX_WEIGHT_SIZE];
|
|
|
|
size_t weight_length;
|
|
|
|
} MY_DUCET_WEIGHT;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct my_ducet_single_char_t
|
|
|
|
{
|
|
|
|
MY_DUCET_WEIGHT weight;
|
|
|
|
} MY_DUCET_SINGLE_CHAR;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct my_allkeys_st
|
|
|
|
{
|
|
|
|
MY_DUCET_SINGLE_CHAR single_chars[MAX_ALLOWED_CODE+1];
|
|
|
|
uint version;
|
|
|
|
char version_str[32];
|
|
|
|
} MY_DUCET;
|
|
|
|
|
|
|
|
|
2016-05-18 10:35:38 +02:00
|
|
|
/* Name prefix that goes into page weight array names after global_name_prefix */
|
2021-11-23 13:33:08 +01:00
|
|
|
static const char *pname_prefix[]= {"_p", "_p", "_p"};
|
2016-05-18 10:35:38 +02:00
|
|
|
|
|
|
|
/* Name suffix that goes into page weight array names after page number */
|
2021-11-23 13:33:08 +01:00
|
|
|
static const char *pname_suffix[]= {"", "_w2", "_w3"};
|
|
|
|
|
|
|
|
|
|
|
|
void usage(const char *prog)
|
|
|
|
{
|
|
|
|
printf("Usage:\n");
|
|
|
|
printf("%s [options] filename\n", prog);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline int lstrncmp(const char *str, const LEX_CSTRING lstr)
|
|
|
|
{
|
|
|
|
return strncmp(lstr.str, str, lstr.length);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int process_option(OPT *options, const char *opt)
|
|
|
|
{
|
|
|
|
static const LEX_CSTRING opt_name_prefix= {STRING_WITH_LEN("--name-prefix=")};
|
|
|
|
static const LEX_CSTRING opt_levels= {STRING_WITH_LEN("--levels=")};
|
|
|
|
if (!lstrncmp(opt, opt_name_prefix))
|
|
|
|
{
|
|
|
|
options->name_prefix= opt + opt_name_prefix.length;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!lstrncmp(opt, opt_levels))
|
|
|
|
{
|
|
|
|
options->levels= (uint) strtoul(opt + opt_levels.length, NULL, 10);
|
|
|
|
if (options->levels < 1 || options->levels > 3)
|
|
|
|
{
|
|
|
|
printf("Bad --levels value\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
printf("Unknown option: %s\n", opt);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int process_options(OPT *options, int ac, char **av)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i= 1; i < ac; i++)
|
|
|
|
{
|
|
|
|
if (!strncmp(av[i], "--", 2))
|
|
|
|
{
|
|
|
|
if (process_option(options, av[i]))
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (i + 1 != ac)
|
|
|
|
{
|
|
|
|
usage(av[0]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
options->filename= av[i];
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
usage(av[0]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FILE *open_file(const char *name)
|
|
|
|
{
|
|
|
|
if (!strcmp(name, "-"))
|
|
|
|
return stdin;
|
|
|
|
return fopen(name, "r");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void close_file(FILE *file)
|
|
|
|
{
|
|
|
|
if (file != stdin)
|
|
|
|
fclose(file);
|
|
|
|
}
|
2016-05-18 10:35:38 +02:00
|
|
|
|
2004-11-22 10:02:27 +01:00
|
|
|
|
2021-11-24 12:11:49 +01:00
|
|
|
char *strrtrim(char *str)
|
|
|
|
{
|
|
|
|
char *end= str + strlen(str);
|
|
|
|
for ( ; str < end; end--)
|
|
|
|
{
|
|
|
|
if (end[-1] != '\r' && end[-1] != '\n' &&
|
|
|
|
end[-1] != ' ' && end[-1] != '\t')
|
|
|
|
break;
|
|
|
|
end[-1]= '\0';
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Parse a line starting with '@'.
|
|
|
|
As of 14.0.0, allkeys.txt has @version and @implicitweights lines.
|
|
|
|
Only @version is parsed here.
|
|
|
|
|
|
|
|
It could also be possible to parse @implicitweights to automatically
|
|
|
|
generate routines responsible for implicit weight handling for Siniform
|
|
|
|
ideographic scripts (Tangut, Nushu, Khitan). But as there are only a few
|
|
|
|
of them at the moment, it was easier to write these routines in ctype-uca.h
|
|
|
|
manually. So @implicitweights lines are ignored here.
|
|
|
|
*/
|
|
|
|
my_bool parse_at_line(MY_DUCET *ducet, const char *str)
|
|
|
|
{
|
|
|
|
static const LEX_CSTRING version= {STRING_WITH_LEN("@version ")};
|
|
|
|
if (!strncmp(str, version.str, version.length))
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Examples:
|
|
|
|
@version 4.0.0
|
|
|
|
@version 5.2.0
|
|
|
|
@version 14.0.0
|
|
|
|
*/
|
|
|
|
const char *src= str + version.length;
|
|
|
|
long n[3]= {0};
|
|
|
|
uint pos;
|
|
|
|
int length;
|
|
|
|
|
|
|
|
length= snprintf(ducet->version_str, sizeof(ducet->version_str)-1,
|
|
|
|
"%s", src);
|
|
|
|
ducet->version_str[length]= '\0';
|
|
|
|
|
|
|
|
for (pos= 0 ; pos < 3; pos++)
|
|
|
|
{
|
|
|
|
char *endptr;
|
|
|
|
n[pos]= strtol(src, &endptr, 10);
|
|
|
|
if (*endptr != '.' && *endptr != '\r' && *endptr != '\n' && *endptr != 0)
|
|
|
|
return TRUE;
|
|
|
|
src= endptr + 1;
|
|
|
|
}
|
|
|
|
ducet->version= MY_UCA_VERSION_ID(n[0], n[1], n[2]);
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_version(const MY_DUCET *ducet, const OPT *opt)
|
|
|
|
{
|
|
|
|
printf("\n");
|
|
|
|
printf("#define %s_version %d /* %s */\n",
|
|
|
|
opt->name_prefix, ducet->version, ducet->version_str);
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-22 12:14:12 +01:00
|
|
|
int main(int ac, char **av)
|
|
|
|
{
|
2021-11-23 13:33:08 +01:00
|
|
|
char str[1024];
|
2004-03-22 12:14:12 +01:00
|
|
|
char *weights[64];
|
2021-11-24 12:11:49 +01:00
|
|
|
static MY_DUCET ducet;
|
2021-11-23 13:33:08 +01:00
|
|
|
my_wc_t code;
|
|
|
|
uint w;
|
2004-03-23 15:29:07 +01:00
|
|
|
int pageloaded[MY_UCA_NPAGES];
|
2021-11-23 13:33:08 +01:00
|
|
|
FILE *file;
|
|
|
|
OPT options= defaults;
|
|
|
|
|
|
|
|
if (process_options(&options, ac, av))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (!(file= open_file(options.filename)))
|
|
|
|
{
|
|
|
|
printf("Could not open %s for reading\n", options.filename);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2021-11-24 12:11:49 +01:00
|
|
|
bzero(&ducet, sizeof(ducet));
|
2004-03-23 15:29:07 +01:00
|
|
|
bzero(pageloaded, sizeof(pageloaded));
|
2004-03-22 12:14:12 +01:00
|
|
|
|
2021-11-23 13:33:08 +01:00
|
|
|
while (fgets(str, sizeof(str), file))
|
2004-03-22 12:14:12 +01:00
|
|
|
{
|
|
|
|
char *comment;
|
|
|
|
char *weight;
|
|
|
|
char *s;
|
|
|
|
size_t codenum;
|
2021-11-24 12:11:49 +01:00
|
|
|
|
|
|
|
if (str[0] == '@')
|
|
|
|
{
|
|
|
|
parse_at_line(&ducet, strrtrim(str));
|
|
|
|
continue;
|
|
|
|
}
|
2004-03-22 12:14:12 +01:00
|
|
|
|
2021-11-23 13:33:08 +01:00
|
|
|
code= (my_wc_t) strtol(str,NULL,16);
|
2004-03-22 12:14:12 +01:00
|
|
|
|
2016-05-18 10:35:38 +02:00
|
|
|
if (str[0]=='#' || (code > MAX_ALLOWED_CODE))
|
2004-03-22 12:14:12 +01:00
|
|
|
continue;
|
|
|
|
if ((comment=strchr(str,'#')))
|
|
|
|
{
|
|
|
|
*comment++= '\0';
|
|
|
|
for ( ; *comment==' ' ; comment++);
|
|
|
|
}else
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if ((weight=strchr(str,';')))
|
|
|
|
{
|
|
|
|
*weight++= '\0';
|
|
|
|
for ( ; *weight==' ' ; weight++);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
continue;
|
|
|
|
|
|
|
|
codenum= 0;
|
|
|
|
s= strtok(str, " \t");
|
|
|
|
while (s)
|
|
|
|
{
|
|
|
|
s= strtok(NULL, " \t");
|
|
|
|
codenum++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (codenum>1)
|
|
|
|
{
|
2004-03-23 15:29:07 +01:00
|
|
|
/* Multi-character weight,
|
|
|
|
i.e. contraction.
|
|
|
|
Not supported yet.
|
|
|
|
*/
|
2004-03-22 12:14:12 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-11-24 12:11:49 +01:00
|
|
|
ducet.single_chars[code].weight.weight_length= 0;
|
2004-03-22 12:14:12 +01:00
|
|
|
s= strtok(weight, " []");
|
|
|
|
while (s)
|
|
|
|
{
|
2021-11-24 12:11:49 +01:00
|
|
|
weights[ducet.single_chars[code].weight.weight_length]= s;
|
2004-03-22 12:14:12 +01:00
|
|
|
s= strtok(NULL, " []");
|
2021-11-24 12:11:49 +01:00
|
|
|
ducet.single_chars[code].weight.weight_length++;
|
2004-03-22 12:14:12 +01:00
|
|
|
}
|
|
|
|
|
2021-11-24 12:11:49 +01:00
|
|
|
set_if_smaller(ducet.single_chars[code].weight.weight_length, MY_UCA_MAX_WEIGHT_SIZE-1);
|
2021-11-23 13:33:08 +01:00
|
|
|
|
2021-11-24 12:11:49 +01:00
|
|
|
for (w=0; w < ducet.single_chars[code].weight.weight_length ; w++)
|
2004-03-22 12:14:12 +01:00
|
|
|
{
|
|
|
|
size_t partnum;
|
|
|
|
|
|
|
|
partnum= 0;
|
|
|
|
s= weights[w];
|
|
|
|
while (*s)
|
|
|
|
{
|
|
|
|
char *endptr;
|
2021-11-23 13:33:08 +01:00
|
|
|
uint part= (uint) strtoul(s + 1, &endptr, 16);
|
2021-11-24 12:11:49 +01:00
|
|
|
ducet.single_chars[code].weight.weight[partnum][w]= (uint16) part;
|
2004-03-22 12:14:12 +01:00
|
|
|
s= endptr;
|
|
|
|
partnum++;
|
|
|
|
}
|
|
|
|
}
|
2004-03-23 15:29:07 +01:00
|
|
|
/* Mark that a character from this page was loaded */
|
|
|
|
pageloaded[code >> MY_UCA_PSHIFT]++;
|
2004-03-22 12:14:12 +01:00
|
|
|
}
|
2021-11-23 13:33:08 +01:00
|
|
|
|
|
|
|
close_file(file);
|
|
|
|
|
2004-03-22 12:14:12 +01:00
|
|
|
/* Now set implicit weights */
|
2016-05-18 10:35:38 +02:00
|
|
|
for (code=0; code <= MAX_ALLOWED_CODE; code++)
|
2004-03-22 12:14:12 +01:00
|
|
|
{
|
2021-11-23 13:33:08 +01:00
|
|
|
uint level;
|
|
|
|
|
2021-11-24 12:11:49 +01:00
|
|
|
if (ducet.single_chars[code].weight.weight_length)
|
2004-03-22 12:14:12 +01:00
|
|
|
continue;
|
2021-11-23 13:33:08 +01:00
|
|
|
|
|
|
|
for (level= 0; level < 4; level++)
|
|
|
|
{
|
|
|
|
MY_UCA_IMPLICIT_WEIGHT weight;
|
2021-11-24 12:11:49 +01:00
|
|
|
weight= my_uca_implicit_weight_on_level(ducet.version, code, level);
|
|
|
|
ducet.single_chars[code].weight.weight[level][0]= weight.weight[0];
|
|
|
|
ducet.single_chars[code].weight.weight[level][1]= weight.weight[1];
|
2021-11-23 13:33:08 +01:00
|
|
|
}
|
2021-11-24 12:11:49 +01:00
|
|
|
ducet.single_chars[code].weight.weight_length= 2;
|
2004-03-22 12:14:12 +01:00
|
|
|
}
|
|
|
|
|
2021-11-24 12:11:49 +01:00
|
|
|
printf("/*\n");
|
|
|
|
printf(" Generated from allkeys.txt version '%s'\n", ducet.version_str);
|
|
|
|
printf("*/\n");
|
2016-05-18 10:35:38 +02:00
|
|
|
|
2021-11-23 13:33:08 +01:00
|
|
|
for (w=0; w < options.levels; w++)
|
2004-03-22 12:14:12 +01:00
|
|
|
{
|
2004-11-22 10:02:27 +01:00
|
|
|
size_t page;
|
|
|
|
int pagemaxlen[MY_UCA_NPAGES];
|
|
|
|
|
2004-03-22 12:14:12 +01:00
|
|
|
for (page=0; page < MY_UCA_NPAGES; page++)
|
|
|
|
{
|
|
|
|
size_t offs;
|
|
|
|
size_t maxnum= 0;
|
|
|
|
size_t nchars= 0;
|
|
|
|
size_t mchars;
|
2004-11-22 10:02:27 +01:00
|
|
|
size_t ndefs= 0;
|
2016-05-18 10:35:38 +02:00
|
|
|
size_t code_line_start= page * MY_UCA_NCHARS;
|
2004-11-22 10:02:27 +01:00
|
|
|
|
|
|
|
pagemaxlen[page]= 0;
|
2004-03-22 12:14:12 +01:00
|
|
|
|
2004-03-23 15:29:07 +01:00
|
|
|
/*
|
|
|
|
Skip this page if no weights were loaded
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (!pageloaded[page])
|
|
|
|
continue;
|
2004-03-22 12:14:12 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
Calculate maximum weight
|
|
|
|
length for this page
|
|
|
|
*/
|
|
|
|
|
|
|
|
for (offs=0; offs < MY_UCA_NCHARS; offs++)
|
|
|
|
{
|
|
|
|
size_t i, num;
|
|
|
|
|
|
|
|
code= page*MY_UCA_NCHARS+offs;
|
|
|
|
|
|
|
|
/* Calculate only non-zero weights */
|
2021-11-24 12:11:49 +01:00
|
|
|
for (num=0, i=0; i < ducet.single_chars[code].weight.weight_length; i++)
|
|
|
|
if (ducet.single_chars[code].weight.weight[w][i])
|
2004-03-22 12:14:12 +01:00
|
|
|
num++;
|
|
|
|
|
|
|
|
maxnum= maxnum < num ? num : maxnum;
|
2004-11-22 10:02:27 +01:00
|
|
|
|
|
|
|
/* Check if default weight */
|
|
|
|
if (w == 1 && num == 1)
|
|
|
|
{
|
|
|
|
/* 0020 0000 ... */
|
2021-11-24 12:11:49 +01:00
|
|
|
if (ducet.single_chars[code].weight.weight[w][0] == 0x0020)
|
2004-11-22 10:02:27 +01:00
|
|
|
ndefs++;
|
|
|
|
}
|
|
|
|
else if (w == 2 && num == 1)
|
|
|
|
{
|
|
|
|
/* 0002 0000 ... */
|
2021-11-24 12:11:49 +01:00
|
|
|
if (ducet.single_chars[code].weight.weight[w][0] == 0x0002)
|
2004-11-22 10:02:27 +01:00
|
|
|
ndefs++;
|
|
|
|
}
|
2004-03-22 12:14:12 +01:00
|
|
|
}
|
2004-03-23 15:29:07 +01:00
|
|
|
maxnum++;
|
|
|
|
|
2004-11-22 10:02:27 +01:00
|
|
|
/*
|
|
|
|
If the page have only default weights
|
|
|
|
then no needs to dump it, skip.
|
|
|
|
*/
|
|
|
|
if (ndefs == MY_UCA_NCHARS)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2004-03-22 12:14:12 +01:00
|
|
|
switch (maxnum)
|
|
|
|
{
|
|
|
|
case 0: mchars= 8; break;
|
|
|
|
case 1: mchars= 8; break;
|
|
|
|
case 2: mchars= 8; break;
|
|
|
|
case 3: mchars= 9; break;
|
|
|
|
case 4: mchars= 8; break;
|
2021-11-24 12:11:49 +01:00
|
|
|
default: mchars= ducet.single_chars[code].weight.weight_length;
|
2004-03-22 12:14:12 +01:00
|
|
|
}
|
|
|
|
|
2021-11-23 13:33:08 +01:00
|
|
|
pagemaxlen[page]= (int) maxnum;
|
2004-03-23 15:29:07 +01:00
|
|
|
|
|
|
|
|
2004-03-22 12:14:12 +01:00
|
|
|
/*
|
|
|
|
Now print this page
|
|
|
|
*/
|
|
|
|
|
2004-03-23 15:29:07 +01:00
|
|
|
|
2016-05-18 10:35:38 +02:00
|
|
|
printf("static const uint16 %s%s%03X%s[]= { /* %04X (%d weights per char) */\n",
|
2021-11-23 13:33:08 +01:00
|
|
|
options.name_prefix, pname_prefix[w], (int) page, pname_suffix[w],
|
2016-05-18 10:35:38 +02:00
|
|
|
(int) page*MY_UCA_NCHARS, (int) maxnum);
|
2004-03-23 15:29:07 +01:00
|
|
|
|
2004-03-22 12:14:12 +01:00
|
|
|
for (offs=0; offs < MY_UCA_NCHARS; offs++)
|
|
|
|
{
|
2021-11-23 13:33:08 +01:00
|
|
|
uint16 weight[MY_UCA_MAX_WEIGHT_SIZE];
|
2004-03-22 12:14:12 +01:00
|
|
|
size_t num, i;
|
|
|
|
|
|
|
|
code= page*MY_UCA_NCHARS+offs;
|
|
|
|
|
|
|
|
bzero(weight,sizeof(weight));
|
|
|
|
|
|
|
|
/* Copy non-zero weights */
|
2021-11-24 12:11:49 +01:00
|
|
|
for (num=0, i=0; i < ducet.single_chars[code].weight.weight_length; i++)
|
2004-03-22 12:14:12 +01:00
|
|
|
{
|
2021-11-24 12:11:49 +01:00
|
|
|
if (ducet.single_chars[code].weight.weight[w][i])
|
2004-03-22 12:14:12 +01:00
|
|
|
{
|
2021-11-24 12:11:49 +01:00
|
|
|
weight[num]= ducet.single_chars[code].weight.weight[w][i];
|
2004-03-22 12:14:12 +01:00
|
|
|
num++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i=0; i < maxnum; i++)
|
|
|
|
{
|
2004-11-22 15:17:41 +01:00
|
|
|
/*
|
|
|
|
Invert weights for secondary level to
|
|
|
|
sort upper case letters before their
|
|
|
|
lower case counter part.
|
|
|
|
*/
|
|
|
|
int tmp= weight[i];
|
|
|
|
if (w == 2 && tmp)
|
2004-11-24 10:28:48 +01:00
|
|
|
tmp= (int)(0x20 - weight[i]);
|
2004-11-22 15:17:41 +01:00
|
|
|
|
|
|
|
|
|
|
|
printf("0x%04X", tmp);
|
2004-03-22 12:14:12 +01:00
|
|
|
if ((offs+1 != MY_UCA_NCHARS) || (i+1!=maxnum))
|
|
|
|
printf(",");
|
2016-05-18 10:35:38 +02:00
|
|
|
else
|
|
|
|
printf(" ");
|
2004-03-22 12:14:12 +01:00
|
|
|
nchars++;
|
|
|
|
}
|
|
|
|
if (nchars >=mchars)
|
|
|
|
{
|
2016-05-18 10:35:38 +02:00
|
|
|
printf(" /* %04X */\n", (int) code_line_start);
|
|
|
|
code_line_start= code + 1;
|
2004-03-22 12:14:12 +01:00
|
|
|
nchars=0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf(" ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
printf("};\n\n");
|
|
|
|
}
|
|
|
|
|
2016-05-18 10:35:38 +02:00
|
|
|
printf("const uchar %s_length%s[%d]={\n",
|
2021-11-23 13:33:08 +01:00
|
|
|
options.name_prefix, pname_suffix[w], MY_UCA_NPAGES);
|
2004-11-22 10:02:27 +01:00
|
|
|
for (page=0; page < MY_UCA_NPAGES; page++)
|
|
|
|
{
|
|
|
|
printf("%d%s%s",pagemaxlen[page],page<MY_UCA_NPAGES-1?",":"",(page+1) % 16 ? "":"\n");
|
|
|
|
}
|
|
|
|
printf("};\n");
|
|
|
|
|
|
|
|
|
2016-05-18 10:35:38 +02:00
|
|
|
printf("static const uint16 *%s_weight%s[%d]={\n",
|
2021-11-23 13:33:08 +01:00
|
|
|
options.name_prefix, pname_suffix[w], MY_UCA_NPAGES);
|
2004-11-22 10:02:27 +01:00
|
|
|
for (page=0; page < MY_UCA_NPAGES; page++)
|
|
|
|
{
|
|
|
|
const char *comma= page < MY_UCA_NPAGES-1 ? "," : "";
|
|
|
|
const char *nline= (page+1) % 4 ? "" : "\n";
|
|
|
|
if (!pagemaxlen[page])
|
2004-11-24 10:28:48 +01:00
|
|
|
printf("NULL %s%s%s", w ? " ": "", comma , nline);
|
2004-11-22 10:02:27 +01:00
|
|
|
else
|
2016-05-18 10:35:38 +02:00
|
|
|
printf("%s%s%03X%s%s%s",
|
2021-11-23 13:33:08 +01:00
|
|
|
options.name_prefix, pname_prefix[w], (int) page, pname_suffix[w],
|
2016-05-18 10:35:38 +02:00
|
|
|
comma, nline);
|
2004-11-22 10:02:27 +01:00
|
|
|
}
|
|
|
|
printf("};\n");
|
2004-03-22 12:14:12 +01:00
|
|
|
}
|
2004-11-22 10:02:27 +01:00
|
|
|
|
2021-11-24 12:11:49 +01:00
|
|
|
print_version(&ducet, &options);
|
2004-03-22 12:14:12 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|