|
Packit Service |
a721b1 |
/* chartab.h -- character table module.
|
|
Packit Service |
a721b1 |
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
|
Packit Service |
a721b1 |
National Institute of Advanced Industrial Science and Technology (AIST)
|
|
Packit Service |
a721b1 |
Registration Number H15PRO112
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
This file is part of the m17n library.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The m17n library is free software; you can redistribute it and/or
|
|
Packit Service |
a721b1 |
modify it under the terms of the GNU Lesser General Public License
|
|
Packit Service |
a721b1 |
as published by the Free Software Foundation; either version 2.1 of
|
|
Packit Service |
a721b1 |
the License, or (at your option) any later version.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The m17n library is distributed in the hope that it will be useful,
|
|
Packit Service |
a721b1 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
a721b1 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
a721b1 |
Lesser General Public License for more details.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
a721b1 |
License along with the m17n library; if not, write to the Free
|
|
Packit Service |
a721b1 |
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Packit Service |
a721b1 |
Boston, MA 02110-1301 USA. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@addtogroup m17nChartable
|
|
Packit Service |
a721b1 |
@brief Chartable objects and API for them.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The m17n library supports enormous number of characters. Thus, if
|
|
Packit Service |
a721b1 |
attributes of each character are to be stored in a simple array,
|
|
Packit Service |
a721b1 |
such an array would be impractically big. The attributes usually
|
|
Packit Service |
a721b1 |
used, however, are often assigned only to a range of characters.
|
|
Packit Service |
a721b1 |
Even when all characters have attributes, characters of
|
|
Packit Service |
a721b1 |
consecutive character code tend to have the same attribute values.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The m17n library utilizes this tendency to store characters and
|
|
Packit Service |
a721b1 |
their attribute values efficiently in an object called @e
|
|
Packit Service |
a721b1 |
Chartable. Although a chartable object is not a simple array,
|
|
Packit Service |
a721b1 |
application programs can handle a chartable as if it is an array.
|
|
Packit Service |
a721b1 |
Attribute values of a character can be obtained by accessing a
|
|
Packit Service |
a721b1 |
Chartable for the attribute with the character code of the
|
|
Packit Service |
a721b1 |
specified character.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
A chartable is a managed object. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@addtogroup m17nChartable 文字テーブル
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@brief 文字テーブルとそれに関する API.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
m17n ライブラリが扱う文字の空間は広大であるため、文字毎の情報を単純な配列に格納しようとすると、その配列は巨大になりすぎ、非実用的である。
|
|
Packit Service |
a721b1 |
しかし通常必要となる文字についての情報は、ある特定の範囲の文字にのみ付いていることが多い。
|
|
Packit Service |
a721b1 |
全文字に関して情報がある場合にも、連続した文字コードを持つ文字は同じ情報を持つことが多い。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
このような傾向を利用して文字とその付加情報を効率的に格納するために、
|
|
Packit Service |
a721b1 |
m17n ライブラリは @e 文字テーブル (chartable) と呼ぶオブジェクトを用いる。
|
|
Packit Service |
a721b1 |
文字テーブルは配列ではないが、アプリケーションプログラムは文字テーブルを配列の一種として扱うことができる。
|
|
Packit Service |
a721b1 |
ある文字についての特定の情報は、その情報を持つ文字テーブルをその文字のコードで引くこと
|
|
Packit Service |
a721b1 |
で得られる。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
文字テーブルは管理下オブジェクトである。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
#if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
|
|
Packit Service |
a721b1 |
/*** @addtogroup m17nInternal
|
|
Packit Service |
a721b1 |
@{ */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#include <config.h>
|
|
Packit Service |
a721b1 |
#include <stdlib.h>
|
|
Packit Service |
a721b1 |
#include <string.h>
|
|
Packit Service |
a721b1 |
#include <limits.h>
|
|
Packit Service |
a721b1 |
#include <ctype.h>
|
|
Packit Service |
a721b1 |
#include <stdio.h>
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#include "m17n.h"
|
|
Packit Service |
a721b1 |
#include "m17n-misc.h"
|
|
Packit Service |
a721b1 |
#include "internal.h"
|
|
Packit Service |
a721b1 |
#include "symbol.h"
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static M17NObjectArray chartable_table;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*** Maximum depth of char-table. */
|
|
Packit Service |
a721b1 |
#define CHAR_TAB_MAX_DEPTH 3
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** @name Define: Number of characters covered by char-table of each level.
|
|
Packit Service |
a721b1 |
@{ */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** BITs for number of characters covered by char-table of each
|
|
Packit Service |
a721b1 |
level. */
|
|
Packit Service |
a721b1 |
#if MCHAR_MAX < 0x400000
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#define SUB_BITS_0 22 /* i.e. 0x400000 chars */
|
|
Packit Service |
a721b1 |
#define SUB_BITS_1 16 /* i.e. 0x10000 chars */
|
|
Packit Service |
a721b1 |
#define SUB_BITS_2 12 /* i.e. 0x1000 chars */
|
|
Packit Service |
a721b1 |
#define SUB_BITS_3 7 /* i.e. 0x80 chars */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#else /* MCHAR_MAX >= 0x400000 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#define SUB_BITS_0 31
|
|
Packit Service |
a721b1 |
#define SUB_BITS_1 24
|
|
Packit Service |
a721b1 |
#define SUB_BITS_2 16
|
|
Packit Service |
a721b1 |
#define SUB_BITS_3 8
|
|
Packit Service |
a721b1 |
#endif
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** @} */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** How many characters a char-table covers at each level. */
|
|
Packit Service |
a721b1 |
static const int chartab_chars[] =
|
|
Packit Service |
a721b1 |
{ (1 << SUB_BITS_0),
|
|
Packit Service |
a721b1 |
(1 << SUB_BITS_1),
|
|
Packit Service |
a721b1 |
(1 << SUB_BITS_2),
|
|
Packit Service |
a721b1 |
(1 << SUB_BITS_3) };
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** How many slots a char-table has at each level. */
|
|
Packit Service |
a721b1 |
static const int chartab_slots[] =
|
|
Packit Service |
a721b1 |
{ (1 << (SUB_BITS_0 - SUB_BITS_1)),
|
|
Packit Service |
a721b1 |
(1 << (SUB_BITS_1 - SUB_BITS_2)),
|
|
Packit Service |
a721b1 |
(1 << (SUB_BITS_2 - SUB_BITS_3)),
|
|
Packit Service |
a721b1 |
(1 << SUB_BITS_3) };
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Mask bits to obtain the valid bits from a character code for looking
|
|
Packit Service |
a721b1 |
up a char-table of each level. */
|
|
Packit Service |
a721b1 |
static const int chartab_mask[] =
|
|
Packit Service |
a721b1 |
{ (int) ((((unsigned) 1) << SUB_BITS_0) - 1),
|
|
Packit Service |
a721b1 |
(1 << SUB_BITS_1) - 1,
|
|
Packit Service |
a721b1 |
(1 << SUB_BITS_2) - 1,
|
|
Packit Service |
a721b1 |
(1 << SUB_BITS_3) - 1 };
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Bit-shifting counts to obtain a valid index from a character code
|
|
Packit Service |
a721b1 |
for looking up a char-table of each level. */
|
|
Packit Service |
a721b1 |
static const int chartab_shift[] =
|
|
Packit Service |
a721b1 |
{ SUB_BITS_1, SUB_BITS_2, SUB_BITS_3, 0 };
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Index for looking up character C in a char-table at DEPTH. */
|
|
Packit Service |
a721b1 |
#define SUB_IDX(depth, c) \
|
|
Packit Service |
a721b1 |
(((c) & chartab_mask[depth]) >> chartab_shift[depth])
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Structure of sub char-table. */
|
|
Packit Service |
a721b1 |
typedef struct MSubCharTable MSubCharTable;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
struct MSubCharTable
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
#if SUB_BITS_0 > 24
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* The depth of the table; 0, 1, 2, or 3. */
|
|
Packit Service |
a721b1 |
int depth;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* The minimum character covered by the table. */
|
|
Packit Service |
a721b1 |
int min_char;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#else /* SUB_BITS_0 <= 24 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* The value is ((<depth> << 24) | <min_char>). */
|
|
Packit Service |
a721b1 |
int depth_min_char;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#endif /* SUB_BITS_0 <= 24 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** The default value of characters covered by the table. */
|
|
Packit Service |
a721b1 |
void *default_value;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** For a table of bottom level, array of values. For a non-bottom
|
|
Packit Service |
a721b1 |
table, array of sub char-tables. It may be NULL if all
|
|
Packit Service |
a721b1 |
characters covered by the table has <default_value>. */
|
|
Packit Service |
a721b1 |
union {
|
|
Packit Service |
a721b1 |
void **values;
|
|
Packit Service |
a721b1 |
MSubCharTable *tables;
|
|
Packit Service |
a721b1 |
} contents;
|
|
Packit Service |
a721b1 |
};
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#if SUB_BITS_0 > 24
|
|
Packit Service |
a721b1 |
#define TABLE_DEPTH(table) ((table)->depth)
|
|
Packit Service |
a721b1 |
#define TABLE_MIN_CHAR(table) ((table)->min_char)
|
|
Packit Service |
a721b1 |
#define SET_DEPTH_MIN_CHAR(table, DEPTH, MIN_CHAR) \
|
|
Packit Service |
a721b1 |
((table)->depth = (DEPTH), (table)->min_char = (MIN_CHAR))
|
|
Packit Service |
a721b1 |
#else /* SUB_BITS_0 <= 24 */
|
|
Packit Service |
a721b1 |
#define TABLE_DEPTH(table) ((table)->depth_min_char >> 24)
|
|
Packit Service |
a721b1 |
#define TABLE_MIN_CHAR(table) ((table)->depth_min_char & 0xFFFFFF)
|
|
Packit Service |
a721b1 |
#define SET_DEPTH_MIN_CHAR(table, DEPTH, MIN_CHAR) \
|
|
Packit Service |
a721b1 |
((table)->depth_min_char = ((DEPTH) << 24) | (MIN_CHAR))
|
|
Packit Service |
a721b1 |
#endif /* SUB_BITS_0 <= 24 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Structure of char-table. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
struct MCharTable
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
/** Common header for a managed object. */
|
|
Packit Service |
a721b1 |
M17NObject control;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Key of the table. */
|
|
Packit Service |
a721b1 |
MSymbol key;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** The minimum and maximum characters covered by the table. */
|
|
Packit Service |
a721b1 |
int min_char, max_char;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MSubCharTable subtable;
|
|
Packit Service |
a721b1 |
};
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Local functions. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Allocate and initialize an array of sub-tables for sub char-table
|
|
Packit Service |
a721b1 |
TABLE. It is assumed that TABLE_DEPTH (TABLE) <
|
|
Packit Service |
a721b1 |
CHAR_TAB_MAX_DEPTH.*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void
|
|
Packit Service |
a721b1 |
make_sub_tables (MSubCharTable *table, int managedp)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int depth = TABLE_DEPTH (table);
|
|
Packit Service |
a721b1 |
int min_char = TABLE_MIN_CHAR (table);
|
|
Packit Service |
a721b1 |
int slots = chartab_slots[depth];
|
|
Packit Service |
a721b1 |
int chars = chartab_chars[depth + 1];
|
|
Packit Service |
a721b1 |
MSubCharTable *tables;
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MTABLE_MALLOC (tables, slots, MERROR_CHARTABLE);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
for (i = 0; i < slots; i++, min_char += chars)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
SET_DEPTH_MIN_CHAR (tables + i, depth + 1, min_char);
|
|
Packit Service |
a721b1 |
tables[i].default_value = table->default_value;
|
|
Packit Service |
a721b1 |
tables[i].contents.tables = NULL;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (managedp && table->default_value)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF_NTIMES (tables->default_value, slots);
|
|
Packit Service |
a721b1 |
table->contents.tables = tables;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Allocate and initialize an array of values for sub char-table
|
|
Packit Service |
a721b1 |
TABLE. It is assumed that TABLE_DEPTH (TABLE) ==
|
|
Packit Service |
a721b1 |
CHAR_TAB_MAX_DEPTH. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void
|
|
Packit Service |
a721b1 |
make_sub_values (MSubCharTable *table, int managedp)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int slots = chartab_slots[CHAR_TAB_MAX_DEPTH];
|
|
Packit Service |
a721b1 |
void **values;
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MTABLE_MALLOC (values, slots, MERROR_CHARTABLE);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
for (i = 0; i < slots; i++)
|
|
Packit Service |
a721b1 |
values[i] = table->default_value;
|
|
Packit Service |
a721b1 |
if (managedp && table->default_value)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF_NTIMES (table->default_value, slots);
|
|
Packit Service |
a721b1 |
table->contents.values = values;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Free contents of sub char-table TABLE and the default value of
|
|
Packit Service |
a721b1 |
TABLE. Free also the sub-tables recursively. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void
|
|
Packit Service |
a721b1 |
free_sub_tables (MSubCharTable *table, int managedp)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int depth = TABLE_DEPTH (table);
|
|
Packit Service |
a721b1 |
int slots = chartab_slots[depth];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (table->contents.tables)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (depth < CHAR_TAB_MAX_DEPTH)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
while (slots--)
|
|
Packit Service |
a721b1 |
free_sub_tables (table->contents.tables + slots, managedp);
|
|
Packit Service |
a721b1 |
free (table->contents.tables);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (managedp)
|
|
Packit Service |
a721b1 |
while (slots--)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (table->contents.values[slots])
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (table->contents.values[slots]);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
free (table->contents.values);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
table->contents.tables = NULL;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (managedp && table->default_value)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (table->default_value);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** In sub char-table TABLE, set value VAL for characters of the range
|
|
Packit Service |
a721b1 |
FROM and TO. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void
|
|
Packit Service |
a721b1 |
set_chartable_range (MSubCharTable *table, int from, int to, void *val,
|
|
Packit Service |
a721b1 |
int managedp)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int depth = TABLE_DEPTH (table);
|
|
Packit Service |
a721b1 |
int min_char = TABLE_MIN_CHAR (table);
|
|
Packit Service |
a721b1 |
int max_char = min_char + (chartab_chars[depth] - 1);
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (max_char < 0 || max_char > MCHAR_MAX)
|
|
Packit Service |
a721b1 |
max_char = MCHAR_MAX;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (from < min_char)
|
|
Packit Service |
a721b1 |
from = min_char;
|
|
Packit Service |
a721b1 |
if (to > max_char)
|
|
Packit Service |
a721b1 |
to = max_char;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (from == min_char && to == max_char)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
free_sub_tables (table, managedp);
|
|
Packit Service |
a721b1 |
if (managedp && val)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF (val);
|
|
Packit Service |
a721b1 |
table->default_value = val;
|
|
Packit Service |
a721b1 |
return;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (depth < CHAR_TAB_MAX_DEPTH)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (! table->contents.tables)
|
|
Packit Service |
a721b1 |
make_sub_tables (table, managedp);
|
|
Packit Service |
a721b1 |
i = SUB_IDX (depth, from);
|
|
Packit Service |
a721b1 |
table = table->contents.tables + i;
|
|
Packit Service |
a721b1 |
while (i < chartab_slots[depth] && TABLE_MIN_CHAR (table) <= to)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
set_chartable_range (table, from, to, val, managedp);
|
|
Packit Service |
a721b1 |
table++, i++;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int idx_from = SUB_IDX (depth, from);
|
|
Packit Service |
a721b1 |
int idx_to = SUB_IDX (depth, to);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! table->contents.values)
|
|
Packit Service |
a721b1 |
make_sub_values (table, managedp);
|
|
Packit Service |
a721b1 |
for (i = idx_from; i <= idx_to; i++)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (managedp && table->contents.values[i])
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (table->contents.values[i]);
|
|
Packit Service |
a721b1 |
table->contents.values[i] = val;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (managedp && val)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF_NTIMES (val, (idx_to - idx_from + 1));
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Lookup the sub char-table TABLE for the character C. If NEXT_C is
|
|
Packit Service |
a721b1 |
not NULL, set *NEXT_C to the next interesting character to lookup
|
|
Packit Service |
a721b1 |
for. If DEFAULT_P is zero, the next interesting character is what
|
|
Packit Service |
a721b1 |
possibly has the different value than C. Otherwise, the next
|
|
Packit Service |
a721b1 |
interesting character is what possibly has the default value (if C
|
|
Packit Service |
a721b1 |
has a value deferent from the default value) or has a value
|
|
Packit Service |
a721b1 |
different from the default value (if C has the default value). */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void *
|
|
Packit Service |
a721b1 |
lookup_chartable (MSubCharTable *table, int c, int *next_c, int default_p)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int depth = TABLE_DEPTH (table);
|
|
Packit Service |
a721b1 |
void *val;
|
|
Packit Service |
a721b1 |
void *default_value = table->default_value;
|
|
Packit Service |
a721b1 |
int idx;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
while (1)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (! table->contents.tables)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (next_c)
|
|
Packit Service |
a721b1 |
*next_c = TABLE_MIN_CHAR (table) + chartab_chars[depth];
|
|
Packit Service |
a721b1 |
return table->default_value;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (depth == CHAR_TAB_MAX_DEPTH)
|
|
Packit Service |
a721b1 |
break;
|
|
Packit Service |
a721b1 |
table = table->contents.tables + SUB_IDX (depth, c);
|
|
Packit Service |
a721b1 |
depth++;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
idx = SUB_IDX (depth, c);
|
|
Packit Service |
a721b1 |
val = table->contents.values[idx];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (next_c)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int max_char = TABLE_MIN_CHAR (table) + (chartab_chars[depth] - 1);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (max_char < 0 || max_char > MCHAR_MAX)
|
|
Packit Service |
a721b1 |
max_char = MCHAR_MAX;
|
|
Packit Service |
a721b1 |
if (default_p && val != default_value)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
do { c++, idx++; }
|
|
Packit Service |
a721b1 |
while (c >= 0 && c <= max_char
|
|
Packit Service |
a721b1 |
&& table->contents.values[idx] != default_value);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
do { c++, idx++; }
|
|
Packit Service |
a721b1 |
while (c >= 0 && c <= max_char
|
|
Packit Service |
a721b1 |
&& table->contents.values[idx] == val);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
*next_c = c;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return val;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Call FUNC for characters in sub char-table TABLE. Ignore such
|
|
Packit Service |
a721b1 |
characters that has a value IGNORE. FUNC is called with four
|
|
Packit Service |
a721b1 |
arguments; FROM, TO, VAL, and ARG (same as FUNC_ARG). If
|
|
Packit Service |
a721b1 |
DEFAULT_P is zero, FROM and TO are range of characters that has
|
|
Packit Service |
a721b1 |
the same value VAL. Otherwise, FROM and TO are range of
|
|
Packit Service |
a721b1 |
characters that has the different value than the default value of
|
|
Packit Service |
a721b1 |
TABLE. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void
|
|
Packit Service |
a721b1 |
map_chartable (MSubCharTable *table, void *ignore, int default_p,
|
|
Packit Service |
a721b1 |
void (*func) (int, int, void *, void *),
|
|
Packit Service |
a721b1 |
void *func_arg)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
void *current;
|
|
Packit Service |
a721b1 |
int from = 0;
|
|
Packit Service |
a721b1 |
int c, next_c;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
current = lookup_chartable (table, 0, &next_c, default_p);
|
|
Packit Service |
a721b1 |
c = next_c;
|
|
Packit Service |
a721b1 |
while (c >= 0 && c <= MCHAR_MAX)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
void *next = lookup_chartable (table, c, &next_c, default_p);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (current != next)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (current != ignore)
|
|
Packit Service |
a721b1 |
(*func) (from, c - 1, current, func_arg);
|
|
Packit Service |
a721b1 |
current = next;
|
|
Packit Service |
a721b1 |
from = c;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
c = next_c;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (from <= MCHAR_MAX && current != ignore)
|
|
Packit Service |
a721b1 |
(*func) (from, MCHAR_MAX, current, func_arg);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Return the smallest character whose value is not DEFAULT_VALUE in
|
|
Packit Service |
a721b1 |
TABLE. If all characters in TABLE have DEFAULT_VALUE, return
|
|
Packit Service |
a721b1 |
-1. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static int
|
|
Packit Service |
a721b1 |
chartab_min_non_default_char (MSubCharTable *table, void *default_value)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int depth = TABLE_DEPTH (table);
|
|
Packit Service |
a721b1 |
int slots;
|
|
Packit Service |
a721b1 |
int i, c;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (!table->contents.tables)
|
|
Packit Service |
a721b1 |
return (default_value == table->default_value
|
|
Packit Service |
a721b1 |
? -1 : TABLE_MIN_CHAR (table));
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
slots = chartab_slots[depth];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (depth == CHAR_TAB_MAX_DEPTH)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
for (i = 0; i < slots; i++)
|
|
Packit Service |
a721b1 |
if (table->contents.values[i] != default_value)
|
|
Packit Service |
a721b1 |
return (TABLE_MIN_CHAR (table) + i);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
for (i = 0; i < slots; i++)
|
|
Packit Service |
a721b1 |
if ((c = chartab_min_non_default_char (table->contents.tables + i,
|
|
Packit Service |
a721b1 |
default_value))
|
|
Packit Service |
a721b1 |
>= 0)
|
|
Packit Service |
a721b1 |
return c;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Return the largest character whose value is not DEFAULT_VALUE in
|
|
Packit Service |
a721b1 |
TABLE. If all characters in TABLE have DEFAULT_VALUE, return
|
|
Packit Service |
a721b1 |
-1. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static int
|
|
Packit Service |
a721b1 |
chartab_max_non_default_char (MSubCharTable *table, void *default_value)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int depth = TABLE_DEPTH (table);
|
|
Packit Service |
a721b1 |
int slots;
|
|
Packit Service |
a721b1 |
int i, c;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (!table->contents.tables)
|
|
Packit Service |
a721b1 |
return (default_value == table->default_value
|
|
Packit Service |
a721b1 |
? -1 : TABLE_MIN_CHAR (table) + chartab_chars[depth] - 1);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
slots = chartab_slots[depth];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (depth == CHAR_TAB_MAX_DEPTH)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
for (i = slots - 1; i >= 0; i--)
|
|
Packit Service |
a721b1 |
if (table->contents.values[i] != default_value)
|
|
Packit Service |
a721b1 |
return (TABLE_MIN_CHAR (table) + i);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
for (i = slots - 1; i >= 0; i--)
|
|
Packit Service |
a721b1 |
if ((c = chartab_max_non_default_char (table->contents.tables + i,
|
|
Packit Service |
a721b1 |
default_value))
|
|
Packit Service |
a721b1 |
>= 0)
|
|
Packit Service |
a721b1 |
return c;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void
|
|
Packit Service |
a721b1 |
free_chartable (void *object)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MCharTable *table = (MCharTable *) object;
|
|
Packit Service |
a721b1 |
int managedp = table->key != Mnil && table->key->managing_key;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (table->subtable.contents.tables)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
for (i = 0; i < chartab_slots[0]; i++)
|
|
Packit Service |
a721b1 |
free_sub_tables (table->subtable.contents.tables + i, managedp);
|
|
Packit Service |
a721b1 |
free (table->subtable.contents.tables);
|
|
Packit Service |
a721b1 |
if (managedp && table->subtable.default_value)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (table->subtable.default_value);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREGISTER (chartable_table, table);
|
|
Packit Service |
a721b1 |
free (object);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#include <stdio.h>
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Support function of mdebug_dump_chartab. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void
|
|
Packit Service |
a721b1 |
dump_sub_chartab (MSubCharTable *table, void *default_value,
|
|
Packit Service |
a721b1 |
MSymbol key, int indent)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int depth = TABLE_DEPTH (table);
|
|
Packit Service |
a721b1 |
int min_char = TABLE_MIN_CHAR (table);
|
|
Packit Service |
a721b1 |
int max_char = min_char + (chartab_chars[depth] - 1);
|
|
Packit Service |
a721b1 |
char *prefix = (char *) alloca (indent + 1);
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (max_char < 0 || max_char > MCHAR_MAX)
|
|
Packit Service |
a721b1 |
max_char = MCHAR_MAX;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
memset (prefix, 32, indent);
|
|
Packit Service |
a721b1 |
prefix[indent] = 0;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! table->contents.tables && table->default_value == default_value)
|
|
Packit Service |
a721b1 |
return;
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, "\n%s(sub%d (U+%04X U+%04X) ",
|
|
Packit Service |
a721b1 |
prefix, depth, min_char, max_char);
|
|
Packit Service |
a721b1 |
if (key == Msymbol)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (table->default_value)
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, "(default %s)",
|
|
Packit Service |
a721b1 |
((MSymbol) table->default_value)->name);
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, "(default nil)");
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, "(default #x%X)", (unsigned) table->default_value);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
default_value = table->default_value;
|
|
Packit Service |
a721b1 |
if (table->contents.tables)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (depth < CHAR_TAB_MAX_DEPTH)
|
|
Packit Service |
a721b1 |
for (i = 0; i < chartab_slots[depth]; i++)
|
|
Packit Service |
a721b1 |
dump_sub_chartab (table->contents.tables + i, default_value,
|
|
Packit Service |
a721b1 |
key, indent + 2);
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
for (i = 0; i < chartab_slots[depth]; i++, min_char++)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
void **val = table->contents.values + i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (val == default_value)
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
default_value = *val;
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, "\n%s (U+%04X", prefix, min_char);
|
|
Packit Service |
a721b1 |
while (i + 1 < chartab_slots[depth]
|
|
Packit Service |
a721b1 |
&& val[1] == default_value)
|
|
Packit Service |
a721b1 |
i++, val++, min_char++;
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, "-U+%04X ", min_char);
|
|
Packit Service |
a721b1 |
if (key == Msymbol)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (default_value)
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, "%s)",
|
|
Packit Service |
a721b1 |
((MSymbol) default_value)->name);
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, "nil)");
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, " #xx%X)", (unsigned) default_value);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, ")");
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Internal API */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
int
|
|
Packit Service |
a721b1 |
mchartable__init ()
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
M17N_OBJECT_ADD_ARRAY (chartable_table, "Chartable");
|
|
Packit Service |
a721b1 |
return 0;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
void
|
|
Packit Service |
a721b1 |
mchartable__fini ()
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
void *
|
|
Packit Service |
a721b1 |
mchartable__lookup (MCharTable *table, int c, int *next_c, int default_p)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
return lookup_chartable (&table->subtable, c, next_c, default_p);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*** @} */
|
|
Packit Service |
a721b1 |
#endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* External API */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*** @addtogroup m17nChartable */
|
|
Packit Service |
a721b1 |
/*** @{ */
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Symbol whose name is "char-table".
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The symbol @c Mchar_table has the name <tt>"char-table"</tt>. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief "char-table" という名前を持つシンボル.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
シンボル @c Mchar_table は名前 <tt>"char-table"</tt> を持つ。
|
|
Packit Service |
a721b1 |
*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MSymbol Mchar_table;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Create a new chartable.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mchartable () function creates a new chartable object with
|
|
Packit Service |
a721b1 |
symbol $KEY and the default value $DEFAULT_VALUE. If $KEY is a
|
|
Packit Service |
a721b1 |
managing key, the elements of the table (including the default
|
|
Packit Service |
a721b1 |
value) are managed objects or NULL.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
If the operation was successful, mchartable () returns a pointer
|
|
Packit Service |
a721b1 |
to the created chartable. Otherwise it returns @c NULL and
|
|
Packit Service |
a721b1 |
assigns an error code to the external variable #merror_code. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief 新しい文字テーブルを作る.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mchartable () はキーが $KEY で要素のデフォルト値が
|
|
Packit Service |
a721b1 |
$DEFAULT_VALUE である新しい文字テーブルを作る。もし $KEY
|
|
Packit Service |
a721b1 |
が管理キーであれば、このテーブルの要素は(デフォルト値を含めて)管理下オブジェクトか
|
|
Packit Service |
a721b1 |
NULL のいずれかである。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
処理が成功すれば mchartable () は作成された文字テーブルへのポインタを返す。
|
|
Packit Service |
a721b1 |
失敗した場合は @c NULL を返し、外部変数 #merror_code にエラーコードを設定する。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MCharTable *
|
|
Packit Service |
a721b1 |
mchartable (MSymbol key, void *default_value)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MCharTable *table;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
M17N_OBJECT (table, free_chartable, MERROR_CHARTABLE);
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REGISTER (chartable_table, table);
|
|
Packit Service |
a721b1 |
table->key = key;
|
|
Packit Service |
a721b1 |
table->min_char = -1;
|
|
Packit Service |
a721b1 |
table->max_char = -1;
|
|
Packit Service |
a721b1 |
SET_DEPTH_MIN_CHAR (&table->subtable, 0, 0);
|
|
Packit Service |
a721b1 |
table->subtable.default_value = default_value;
|
|
Packit Service |
a721b1 |
if (key != Mnil && key->managing_key && default_value)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF (default_value);
|
|
Packit Service |
a721b1 |
table->subtable.contents.tables = NULL;
|
|
Packit Service |
a721b1 |
return table;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Return the minimum character whose value is set in a chartabe.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mchartable_min_char () function return the minimum character
|
|
Packit Service |
a721b1 |
whose value is set in chartable $TABLE. No character is set its
|
|
Packit Service |
a721b1 |
value, the function returns -1.
|
|
Packit Service |
a721b1 |
*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
int
|
|
Packit Service |
a721b1 |
mchartable_min_char (MCharTable *table)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
return table->min_char;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Return the maximum character whose value is set in a chartabe.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mchartable_max_char () function return the maximum character
|
|
Packit Service |
a721b1 |
whose value is set in chartable $TABLE. No character is set its
|
|
Packit Service |
a721b1 |
value, the function returns -1.
|
|
Packit Service |
a721b1 |
*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
int
|
|
Packit Service |
a721b1 |
mchartable_max_char (MCharTable *table)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
return table->max_char;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Return the assigned value of a character in a chartable.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mchartable_lookup () function returns the value assigned to
|
|
Packit Service |
a721b1 |
character $C in chartable $TABLE. If no value has been set for $C
|
|
Packit Service |
a721b1 |
explicitly, the default value of $TABLE is returned. If $C is not
|
|
Packit Service |
a721b1 |
a valid character, mchartable_lookup () returns @c NULL and
|
|
Packit Service |
a721b1 |
assigns an error code to the external variable #merror_code. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief 文字テーブル中で文字に割り当てられた値を返す.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mchartable_lookup () は文字テーブル $TABLE 中で文字 $C
|
|
Packit Service |
a721b1 |
に割り当てられた値を返す。$C に対する明示的な値がなければ、$TABLE
|
|
Packit Service |
a721b1 |
のデフォルト値を返す。$C が妥当な文字でなければ、mchartable_lookup () は
|
|
Packit Service |
a721b1 |
@c NULL を返し、外部変数 #merror_code にエラーコードを設定する。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***
|
|
Packit Service |
a721b1 |
@errors
|
|
Packit Service |
a721b1 |
@c MERROR_CHAR
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@seealso
|
|
Packit Service |
a721b1 |
mchartable_set () */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
void *
|
|
Packit Service |
a721b1 |
mchartable_lookup (MCharTable *table, int c)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
M_CHECK_CHAR (c, NULL);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (c < table->min_char || c > table->max_char)
|
|
Packit Service |
a721b1 |
return table->subtable.default_value;
|
|
Packit Service |
a721b1 |
return lookup_chartable (&table->subtable, c, NULL, 0);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Assign a value to a character in a chartable.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mchartable_set () function sets the value of character $C in
|
|
Packit Service |
a721b1 |
chartable $TABLE to $VAL.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
If the operation was successful, mchartable_set () returns 0.
|
|
Packit Service |
a721b1 |
Otherwise it returns -1 and assigns an error code to the external
|
|
Packit Service |
a721b1 |
variable #merror_code. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief 文字テーブル中での文字の値を設定する.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mchartable_set () は、文字テーブル $TABLE 中の文字 $C
|
|
Packit Service |
a721b1 |
に値 $VAL を割り当てる。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
処理が成功すれば、mchartable_set () は 0 を返す。そうでなければ -1
|
|
Packit Service |
a721b1 |
を返し、外部変数 #merror_code にエラーコードを設定する。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***
|
|
Packit Service |
a721b1 |
@errors
|
|
Packit Service |
a721b1 |
@c MERROR_CHAR
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@seealso
|
|
Packit Service |
a721b1 |
mchartable_lookup (), mchartable_set_range () */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
int
|
|
Packit Service |
a721b1 |
mchartable_set (MCharTable *table, int c, void *val)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int managedp = table->key != Mnil && table->key->managing_key;
|
|
Packit Service |
a721b1 |
MSubCharTable *sub = &table->subtable;
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
M_CHECK_CHAR (c, -1);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (table->max_char < 0)
|
|
Packit Service |
a721b1 |
table->min_char = table->max_char = c;
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (c < table->min_char)
|
|
Packit Service |
a721b1 |
table->min_char = c;
|
|
Packit Service |
a721b1 |
else if (c > table->max_char)
|
|
Packit Service |
a721b1 |
table->max_char = c;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
for (i = 0; i < CHAR_TAB_MAX_DEPTH; i++)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (! sub->contents.tables)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (sub->default_value == val)
|
|
Packit Service |
a721b1 |
return 0;
|
|
Packit Service |
a721b1 |
make_sub_tables (sub, managedp);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
sub = sub->contents.tables + SUB_IDX (i, c);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (! sub->contents.values)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (sub->default_value == val)
|
|
Packit Service |
a721b1 |
return 0;
|
|
Packit Service |
a721b1 |
make_sub_values (sub, managedp);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
sub->contents.values[SUB_IDX (3, c)] = val;
|
|
Packit Service |
a721b1 |
if (managedp && val)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF (val);
|
|
Packit Service |
a721b1 |
return 0;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Assign a value to the characters in the specified range.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mchartable_set_range () function assigns value $VAL to the
|
|
Packit Service |
a721b1 |
characters from $FROM to $TO (both inclusive) in chartable $TABLE.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
If the operation was successful, mchartable_set_range () returns
|
|
Packit Service |
a721b1 |
0. Otherwise it returns -1 and assigns an error code to the
|
|
Packit Service |
a721b1 |
external variable #merror_code. If $FROM is greater than $TO,
|
|
Packit Service |
a721b1 |
mchartable_set_range () returns immediately without an error. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief 指定範囲の文字に値を設定する.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mchartable_set_range () は、文字テーブル $TABLE 中の $FROM
|
|
Packit Service |
a721b1 |
から $TO まで(両端を含む)の文字に、値として $VAL を設定する。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
処理が成功すれば mchartable_set_range () は 0 を返す。そうでなければ
|
|
Packit Service |
a721b1 |
-1 を返し、外部変数 #merror_code にエラーコードを設定する。$FROM が
|
|
Packit Service |
a721b1 |
$TO より大きいときには、 mchartable_set_range ()
|
|
Packit Service |
a721b1 |
は何もせず、エラーも起こさない。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***
|
|
Packit Service |
a721b1 |
@errors
|
|
Packit Service |
a721b1 |
@c MERROR_CHAR
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@seealso
|
|
Packit Service |
a721b1 |
mchartable_set () */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
int
|
|
Packit Service |
a721b1 |
mchartable_set_range (MCharTable *table, int from, int to, void *val)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int managedp = table->key != Mnil && table->key->managing_key;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
M_CHECK_CHAR (from, -1);
|
|
Packit Service |
a721b1 |
M_CHECK_CHAR (to, -1);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (from > to)
|
|
Packit Service |
a721b1 |
return 0;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (table->max_char < 0)
|
|
Packit Service |
a721b1 |
table->min_char = from, table->max_char = to;
|
|
Packit Service |
a721b1 |
else{
|
|
Packit Service |
a721b1 |
if (from < table->min_char)
|
|
Packit Service |
a721b1 |
table->min_char = from;
|
|
Packit Service |
a721b1 |
if (to > table->max_char)
|
|
Packit Service |
a721b1 |
table->max_char = to;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
set_chartable_range (&table->subtable, from, to, val, managedp);
|
|
Packit Service |
a721b1 |
return 0;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Search for characters that have non-default value.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mchartable_range () function searches chartable $TABLE for the
|
|
Packit Service |
a721b1 |
first and the last character codes that do not have the default
|
|
Packit Service |
a721b1 |
value of $TABLE, and set $FROM and $TO to them, respectively. If
|
|
Packit Service |
a721b1 |
all characters have the default value, both $FROM and $TO are set
|
|
Packit Service |
a721b1 |
to -1. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief 値がデフォルトと異なる文字を探す.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mchartable_range () は文字テーブル $TABLE 中で、$TABLE
|
|
Packit Service |
a721b1 |
のデフォルト値以外の値を持つ最初と最後の文字を探し、それぞれを $FROM
|
|
Packit Service |
a721b1 |
と $TO に設定する。すべての文字が値としてデフォルト値をとっている場合には
|
|
Packit Service |
a721b1 |
$FROM と $TO を -1に設定する。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
void
|
|
Packit Service |
a721b1 |
mchartable_range (MCharTable *table, int *from, int *to)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
*from = chartab_min_non_default_char (&table->subtable,
|
|
Packit Service |
a721b1 |
table->subtable.default_value);
|
|
Packit Service |
a721b1 |
if (*from == -1)
|
|
Packit Service |
a721b1 |
*to = -1;
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
*to = chartab_max_non_default_char (&table->subtable,
|
|
Packit Service |
a721b1 |
table->subtable.default_value);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Call a function for characters in a chartable.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mchartable_map () function calls function $FUNC for characters
|
|
Packit Service |
a721b1 |
in chartable $TABLE. No function call occurs for characters that
|
|
Packit Service |
a721b1 |
have value $IGNORE in $TABLE. Comparison of $IGNORE and character
|
|
Packit Service |
a721b1 |
value is done with the operator @c ==. Be careful when you use
|
|
Packit Service |
a721b1 |
string literals or pointers.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
Instead of calling $FUNC for each character, mchartable_map ()
|
|
Packit Service |
a721b1 |
tries to optimize the number of function calls, i.e. it makes a
|
|
Packit Service |
a721b1 |
single function call for a chunk of characters when those
|
|
Packit Service |
a721b1 |
consecutive characters have the same value.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
No matter how long the character chunk is, $FUNC is called with
|
|
Packit Service |
a721b1 |
four arguments; $FROM, $TO, $VAL, and $ARG. $FROM and $TO (both
|
|
Packit Service |
a721b1 |
inclusive) defines the range of characters that have value $VAL.
|
|
Packit Service |
a721b1 |
$ARG is the same as $FUNC_ARG.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
This function always returns 0. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief 文字テーブル中の文字に対して指定の関数を呼ぶ.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mchartable_map () は、文字テーブル $TABLE 中の文字に対して関数
|
|
Packit Service |
a721b1 |
$FUNC を呼ぶ。ただし$TABLE 中でも値が $IGNORE
|
|
Packit Service |
a721b1 |
である文字については関数呼び出しを行なわない。$IGNORE と文字の値の比較は
|
|
Packit Service |
a721b1 |
@c == で行なうので、文字列リテラルやポインタを使う際には注意を要する。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
mchartable_map () は、一文字ごとに $FUNC
|
|
Packit Service |
a721b1 |
を呼ぶのではなく、関数呼び出しの回数を最適化しようとする。
|
|
Packit Service |
a721b1 |
すなわち、連続した文字が同じ値を持っていた場合には、その文字のまとまり全体について一度の関数呼び出
|
|
Packit Service |
a721b1 |
ししか行なわない。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
文字のまとまりの大きさにかかわらず、$FUNC は $FROM, $TO, $VAL, $ARG
|
|
Packit Service |
a721b1 |
の4引数で呼ばれる。$FROM と $TO (両端を含む)は $VAL
|
|
Packit Service |
a721b1 |
を値として持つ文字の範囲を示し、$ARG は $FUNC_ARG そのものである。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
この関数は常に0を返す。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
int
|
|
Packit Service |
a721b1 |
mchartable_map (MCharTable *table, void *ignore,
|
|
Packit Service |
a721b1 |
void (*func) (int, int, void *, void *),
|
|
Packit Service |
a721b1 |
void *func_arg)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
map_chartable (&table->subtable, ignore, 0, func, func_arg);
|
|
Packit Service |
a721b1 |
return 0;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*** @} */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*** @addtogroup m17nDebug */
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
/*** @{ */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Dump a chartable.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mdebug_dump_chartab () function prints a chartable $TABLE in a
|
|
Packit Service |
a721b1 |
human readable way to the stderr or to what specified by the
|
|
Packit Service |
a721b1 |
environment variable MDEBUG_OUTPUT_FILE. $INDENT specifies how
|
|
Packit Service |
a721b1 |
many columns to indent the lines but the first one.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
This function returns $TABLE. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief 文字テーブルをダンプする.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mdebug_dump_chartab () は文字テーブル $TABLE を標準エラー出力
|
|
Packit Service |
a721b1 |
もしくは環境変数 MDEBUG_DUMP_FONT で指定されたファイルに人間に可読
|
|
Packit Service |
a721b1 |
な形で印刷する。$INDENT は2行目以降のインデントを指定する。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
この関数は $TABLE を返す。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MCharTable *
|
|
Packit Service |
a721b1 |
mdebug_dump_chartab (MCharTable *table, int indent)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, "(chartab (U+%04X U+%04X)",
|
|
Packit Service |
a721b1 |
table->min_char, table->max_char);
|
|
Packit Service |
a721b1 |
dump_sub_chartab (&table->subtable, table->subtable.default_value,
|
|
Packit Service |
a721b1 |
table->key, indent + 2);
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, ")");
|
|
Packit Service |
a721b1 |
return table;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*** @} */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*
|
|
Packit Service |
a721b1 |
Local Variables:
|
|
Packit Service |
a721b1 |
coding: euc-japan
|
|
Packit Service |
a721b1 |
End:
|
|
Packit Service |
a721b1 |
*/
|