|
Packit Service |
a721b1 |
/* database.c -- database 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 m17nDatabase
|
|
Packit Service |
a721b1 |
@brief The m17n database and API for it.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The m17n library acquires various kinds of information
|
|
Packit Service |
a721b1 |
from data in the m17n database on demand. Application
|
|
Packit Service |
a721b1 |
programs can also add/load their original data to/from the m17n
|
|
Packit Service |
a721b1 |
database by setting the variable #mdatabase_dir to an
|
|
Packit Service |
a721b1 |
application-specific directory and storing data in it. Users can
|
|
Packit Service |
a721b1 |
overwrite those data by storing preferable data in the directory
|
|
Packit Service |
a721b1 |
specified by the environment variable "M17NDIR", or if it is not
|
|
Packit Service |
a721b1 |
set, in the directory "~/.m17n.d".
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The m17n database contains multiple heterogeneous data, and each
|
|
Packit Service |
a721b1 |
data is identified by four tags; TAG0, TAG1, TAG2, TAG3. Each tag
|
|
Packit Service |
a721b1 |
must be a symbol.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
TAG0 specifies the type of data stored in the database as below.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@li
|
|
Packit Service |
a721b1 |
If TAG0 is #Mchar_table, the data is of the @e chartable @e
|
|
Packit Service |
a721b1 |
type and provides information about each character. In this case,
|
|
Packit Service |
a721b1 |
TAG1 specifies the type of the information and must be #Msymbol,
|
|
Packit Service |
a721b1 |
#Minteger, #Mstring, #Mtext, or #Mplist. TAG2 and TAG3 can be any
|
|
Packit Service |
a721b1 |
symbols.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@li
|
|
Packit Service |
a721b1 |
If TAG0 is #Mcharset, the data is of the @e charset @e type
|
|
Packit Service |
a721b1 |
and provides a decode/encode mapping table for a charset. In this
|
|
Packit Service |
a721b1 |
case, TAG1 must be a symbol representing a charset. TAG2 and TAG3
|
|
Packit Service |
a721b1 |
can be any symbols.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@li
|
|
Packit Service |
a721b1 |
If TAG0 is neither #Mchar_table nor #Mcharset, the data is of
|
|
Packit Service |
a721b1 |
the @e plist @e type. See the documentation of the
|
|
Packit Service |
a721b1 |
mdatabase_load () function for the details.
|
|
Packit Service |
a721b1 |
In this case, TAG1, TAG2, and TAG3 can be any symbols.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The notation \<TAG0, TAG1, TAG2, TAG3\> means a data with those
|
|
Packit Service |
a721b1 |
tags.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
Application programs first calls the mdatabase_find () function to
|
|
Packit Service |
a721b1 |
get a pointer to an object of the type #MDatabase. That object
|
|
Packit Service |
a721b1 |
holds information about the specified data. When it is
|
|
Packit Service |
a721b1 |
successfully returned, the mdatabase_load () function loads the
|
|
Packit Service |
a721b1 |
data. The implementation of the structure #MDatabase is
|
|
Packit Service |
a721b1 |
concealed from application programs.
|
|
Packit Service |
a721b1 |
*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@addtogroup m17nDatabase
|
|
Packit Service |
a721b1 |
@brief m17n データベースにとそれに関する API.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
m17n ライブラリは必要に応じて動的に @e m17n @e データベース
|
|
Packit Service |
a721b1 |
から情報を取得する。またアプリケーションプログラムも、独自のデータを
|
|
Packit Service |
a721b1 |
m17n データベースに追加し、それを動的に取得することができる。
|
|
Packit Service |
a721b1 |
アプリケーションプログラムが独自のデータを追加・取得するには、変数
|
|
Packit Service |
a721b1 |
#mdatabase_dir にそのアプリケーション固有のディレクトリをセットし、
|
|
Packit Service |
a721b1 |
その中にデータを格納する。ユーザがそのデータをオーバーライトしたい
|
|
Packit Service |
a721b1 |
ときは、環境変数 "M17NDIR" で指定されるディレクトリ(指定されていな
|
|
Packit Service |
a721b1 |
いときは "~/.m17n.d" というディレクトリ)に別のデータを置く。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
m17n
|
|
Packit Service |
a721b1 |
データベースには複数の多様なデータが含まれており、各データは
|
|
Packit Service |
a721b1 |
TAG0, TAG1, TAG2, TAG3(すべてシンボル)の4つのタグによって識別される。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
TAG0 によって、データベース内のデータのタイプは次のように指定される。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@li
|
|
Packit Service |
a721b1 |
TAG0 が #Mchar_table であるデータは @e chartableタイプ
|
|
Packit Service |
a721b1 |
と呼ばれ、各文字に関する情報を提供する。この場合
|
|
Packit Service |
a721b1 |
TAG1 は情報の種類を指定するシンボルであり、#Msymbol, #Minteger, #Mstring,
|
|
Packit Service |
a721b1 |
#Mtext, #Mplist のいずれかである。TAG2 と TAG3 は任意のシンボルでよい。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@li
|
|
Packit Service |
a721b1 |
TAG0 が #Mcharset であるデータは @e charsetタイプ
|
|
Packit Service |
a721b1 |
と呼ばれ、文字セット用のデコード/エンコードマップを提供する。この場合 TAG1
|
|
Packit Service |
a721b1 |
は文字セットのシンボルでなければならない。TAG2 と TAG3
|
|
Packit Service |
a721b1 |
は任意のシンボルでよい。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@li
|
|
Packit Service |
a721b1 |
TAG0 が #Mchar_table でも #Mcharset でもない場合、そのデータは @e
|
|
Packit Service |
a721b1 |
plistタイプ である。詳細に関しては関数 mdatabase_load ()
|
|
Packit Service |
a721b1 |
の説明を参照のこと。この場合 TAG1、TAG2、TAG3 は任意のシンボルでよい。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
特定のタグを持つデータベースを \<TAG0, TAG1, TAG2, TAG3\>
|
|
Packit Service |
a721b1 |
という形式で表す。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
アプリケーションプログラムは、まず関数 mdatabase_find ()
|
|
Packit Service |
a721b1 |
を使ってデータベースに関する情報を保持するオブジェクト(#MDatabase
|
|
Packit Service |
a721b1 |
型)へのポインタを得る。それに成功したら、 mdatabase_load ()
|
|
Packit Service |
a721b1 |
によって実際にデータベースをロードする。構造体 #MDatabase
|
|
Packit Service |
a721b1 |
自身がどう実装されているかは、アプリケーションプログラムからは見えない。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@latexonly \IPAlabel{database} @endlatexonly
|
|
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 <stdio.h>
|
|
Packit Service |
a721b1 |
#include <stdlib.h>
|
|
Packit Service |
a721b1 |
#include <string.h>
|
|
Packit Service |
a721b1 |
#include <ctype.h>
|
|
Packit Service |
a721b1 |
#include <sys/types.h>
|
|
Packit Service |
a721b1 |
#include <sys/stat.h>
|
|
Packit Service |
a721b1 |
#include <unistd.h>
|
|
Packit Service |
a721b1 |
#include <limits.h>
|
|
Packit Service |
a721b1 |
#include <glob.h>
|
|
Packit Service |
a721b1 |
#include <time.h>
|
|
Packit Service |
a721b1 |
#include <libgen.h>
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#include "m17n-core.h"
|
|
Packit Service |
a721b1 |
#include "m17n-misc.h"
|
|
Packit Service |
a721b1 |
#include "internal.h"
|
|
Packit Service |
a721b1 |
#include "mtext.h"
|
|
Packit Service |
a721b1 |
#include "character.h"
|
|
Packit Service |
a721b1 |
#include "database.h"
|
|
Packit Service |
a721b1 |
#include "plist.h"
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** The file containing a list of databases. */
|
|
Packit Service |
a721b1 |
#define MDB_DIR "mdb.dir"
|
|
Packit Service |
a721b1 |
/** Length of MDB_DIR. */
|
|
Packit Service |
a721b1 |
#define MDB_DIR_LEN 7
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#define MAX_TIME(TIME1, TIME2) ((TIME1) >= (TIME2) ? (TIME1) : (TIME2))
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#define GEN_PATH(path, dir, dir_len, file, file_len) \
|
|
Packit Service |
a721b1 |
(dir_len + file_len > PATH_MAX ? 0 \
|
|
Packit Service |
a721b1 |
: (memcpy (path, dir, dir_len), \
|
|
Packit Service |
a721b1 |
memcpy (path + dir_len, file, file_len), \
|
|
Packit Service |
a721b1 |
path[dir_len + file_len] = '\0', 1))
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static MSymbol Masterisk;
|
|
Packit Service |
a721b1 |
static MSymbol Mversion;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Structure for a data in the m17n database. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
struct MDatabase
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
/** Tags to identify the data. <tag>[0] specifies the type of
|
|
Packit Service |
a721b1 |
database. If it is #Mchar_table, the type is @e chartable, if
|
|
Packit Service |
a721b1 |
it is #Mcharset, the type is @e charset, otherwise the type is
|
|
Packit Service |
a721b1 |
@e plist. */
|
|
Packit Service |
a721b1 |
MSymbol tag[4];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
void *(*loader) (MSymbol *tags, void *extra_info);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** The meaning of the value is dependent on <loader>. If <loader>
|
|
Packit Service |
a721b1 |
is load_database (), the value is a string of the file name that
|
|
Packit Service |
a721b1 |
contains the data. */
|
|
Packit Service |
a721b1 |
void *extra_info;
|
|
Packit Service |
a721b1 |
};
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static MPlist *mdatabase__list;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static int
|
|
Packit Service |
a721b1 |
read_number (char *buf, int *i)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int idx = *i;
|
|
Packit Service |
a721b1 |
int c = buf[idx++];
|
|
Packit Service |
a721b1 |
int n;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (!c)
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
while (c && isspace (c)) c = buf[idx++];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (c == '0')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (buf[idx] == 'x')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
for (idx++, c = 0; (n = hex_mnemonic[(unsigned) buf[idx]]) < 16;
|
|
Packit Service |
a721b1 |
idx++)
|
|
Packit Service |
a721b1 |
c = (c << 4) | n;
|
|
Packit Service |
a721b1 |
*i = idx;
|
|
Packit Service |
a721b1 |
return c;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
c = 0;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else if (c == '\'')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
c = buf[idx++];
|
|
Packit Service |
a721b1 |
if (c == '\\')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
c = buf[idx++];
|
|
Packit Service |
a721b1 |
n = escape_mnemonic[c];
|
|
Packit Service |
a721b1 |
if (n != 255)
|
|
Packit Service |
a721b1 |
c = n;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
while (buf[idx] && buf[idx++] != '\'');
|
|
Packit Service |
a721b1 |
*i = idx;
|
|
Packit Service |
a721b1 |
return c;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else if (hex_mnemonic[c] < 10)
|
|
Packit Service |
a721b1 |
c -= '0';
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
while ((n = hex_mnemonic[(unsigned) buf[idx]]) < 10)
|
|
Packit Service |
a721b1 |
c = (c * 10) + n, idx++;
|
|
Packit Service |
a721b1 |
*i = idx;
|
|
Packit Service |
a721b1 |
return c;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Load a data of type @c chartable from the file FD, and return the
|
|
Packit Service |
a721b1 |
newly created chartable. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void *
|
|
Packit Service |
a721b1 |
load_chartable (FILE *fp, MSymbol type)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int c, from, to;
|
|
Packit Service |
a721b1 |
char buf[1024];
|
|
Packit Service |
a721b1 |
void *val;
|
|
Packit Service |
a721b1 |
MCharTable *table;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! fp)
|
|
Packit Service |
a721b1 |
MERROR (MERROR_DB, NULL);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
table = mchartable (type, (type == Msymbol ? (void *) Mnil
|
|
Packit Service |
a721b1 |
: type == Minteger ? (void *) -1
|
|
Packit Service |
a721b1 |
: NULL));
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
while (! feof (fp))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int i, len;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
for (len = 0; len < 1023 && (c = getc (fp)) != EOF && c != '\n'; len++)
|
|
Packit Service |
a721b1 |
buf[len] = c;
|
|
Packit Service |
a721b1 |
buf[len] = '\0';
|
|
Packit Service |
a721b1 |
if (hex_mnemonic[(unsigned) buf[0]] >= 10)
|
|
Packit Service |
a721b1 |
/* skip comment/invalid line */
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
i = 0;
|
|
Packit Service |
a721b1 |
from = read_number (buf, &i);
|
|
Packit Service |
a721b1 |
if (buf[i] == '-')
|
|
Packit Service |
a721b1 |
i++, to = read_number (buf, &i);
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
to = from;
|
|
Packit Service |
a721b1 |
if (from < 0 || to < from)
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
while (buf[i] && isspace ((unsigned) buf[i])) i++;
|
|
Packit Service |
a721b1 |
c = buf[i];
|
|
Packit Service |
a721b1 |
if (!c)
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (type == Mstring)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
/* VAL is a C-string. */
|
|
Packit Service |
a721b1 |
if (! (val = strdup (buf + i)))
|
|
Packit Service |
a721b1 |
MEMORY_FULL (MERROR_DB);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else if (type == Minteger)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
/* VAL is an integer. */
|
|
Packit Service |
a721b1 |
int positive = 1;
|
|
Packit Service |
a721b1 |
int n;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (c == '-')
|
|
Packit Service |
a721b1 |
i++, positive = -1;
|
|
Packit Service |
a721b1 |
n = read_number (buf, &i);
|
|
Packit Service |
a721b1 |
if (n < 0)
|
|
Packit Service |
a721b1 |
goto label_error;
|
|
Packit Service |
a721b1 |
val = (void *) (n * positive);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else if (type == Mtext)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
/* VAL is an M-text. */
|
|
Packit Service |
a721b1 |
MText *mt;
|
|
Packit Service |
a721b1 |
if (c == '"')
|
|
Packit Service |
a721b1 |
mt = mtext__from_data (buf + i, len - i - 1, MTEXT_FORMAT_UTF_8, 1);
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
mt = mtext ();
|
|
Packit Service |
a721b1 |
while ((c = read_number (buf, &i)) >= 0)
|
|
Packit Service |
a721b1 |
mt = mtext_cat_char (mt, c);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
val = (void *) mt;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else if (type == Msymbol)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
char *p = buf + i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
while (*p && ! isspace (*p))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (*p == '\\' && p[1] != '\0')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
memmove (p, p + 1, buf + len - (p + 1));
|
|
Packit Service |
a721b1 |
len--;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
p++;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
*p = '\0';
|
|
Packit Service |
a721b1 |
if (! strcmp (buf + i, "nil"))
|
|
Packit Service |
a721b1 |
val = (void *) Mnil;
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
val = (void *) msymbol (buf + i);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else if (type == Mplist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
val = (void *) mplist__from_string ((unsigned char *) buf + i,
|
|
Packit Service |
a721b1 |
strlen (buf + i));
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
val = NULL;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (from == to)
|
|
Packit Service |
a721b1 |
mchartable_set (table, from, val);
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
mchartable_set_range (table, from, to, val);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return table;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
label_error:
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (table);
|
|
Packit Service |
a721b1 |
MERROR (MERROR_DB, NULL);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static char *
|
|
Packit Service |
a721b1 |
gen_database_name (char *buf, MSymbol *tags)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
strcpy (buf, msymbol_name (tags[0]));
|
|
Packit Service |
a721b1 |
for (i = 1; i < 4; i++)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
strcat (buf, ",");
|
|
Packit Service |
a721b1 |
strcat (buf, msymbol_name (tags[i]));
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return buf;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Return the absolute file name for DB_INFO->filename or NULL if no
|
|
Packit Service |
a721b1 |
absolute file name was found. If BUF is non-NULL, store the result
|
|
Packit Service |
a721b1 |
of `stat' call in it. In that case, set *RESULT to the return
|
|
Packit Service |
a721b1 |
value of `stat'. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
char *
|
|
Packit Service |
a721b1 |
get_database_file (MDatabaseInfo *db_info, struct stat *buf, int *result)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (db_info->absolute_filename)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (buf)
|
|
Packit Service |
a721b1 |
*result = stat (db_info->absolute_filename, buf);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
struct stat stat_buf;
|
|
Packit Service |
a721b1 |
struct stat *statbuf = buf ? buf : &stat_buf;
|
|
Packit Service |
a721b1 |
int res;
|
|
Packit Service |
a721b1 |
MPlist *plist;
|
|
Packit Service |
a721b1 |
char path[PATH_MAX + 1];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPLIST_DO (plist, mdatabase__dir_list)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabaseInfo *dir_info = MPLIST_VAL (plist);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (dir_info->status != MDB_STATUS_DISABLED
|
|
Packit Service |
a721b1 |
&& GEN_PATH (path, dir_info->filename, dir_info->len,
|
|
Packit Service |
a721b1 |
db_info->filename, db_info->len)
|
|
Packit Service |
a721b1 |
&& (res = stat (path, statbuf)) == 0)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
db_info->absolute_filename = strdup (path);
|
|
Packit Service |
a721b1 |
if (result)
|
|
Packit Service |
a721b1 |
*result = res;
|
|
Packit Service |
a721b1 |
break;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
return db_info->absolute_filename;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void *
|
|
Packit Service |
a721b1 |
load_database (MSymbol *tags, void *extra_info)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabaseInfo *db_info = extra_info;
|
|
Packit Service |
a721b1 |
void *value;
|
|
Packit Service |
a721b1 |
char *filename = get_database_file (db_info, NULL, NULL);
|
|
Packit Service |
a721b1 |
FILE *fp;
|
|
Packit Service |
a721b1 |
int mdebug_flag = MDEBUG_DATABASE;
|
|
Packit Service |
a721b1 |
char buf[256];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MDEBUG_PRINT1 (" [DB] <%s>", gen_database_name (buf, tags));
|
|
Packit Service |
a721b1 |
if (! filename || ! (fp = fopen (filename, "r")))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (filename)
|
|
Packit Service |
a721b1 |
MDEBUG_PRINT1 (" open fail: %s\n", filename);
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
MDEBUG_PRINT1 (" not found: %s\n", db_info->filename);
|
|
Packit Service |
a721b1 |
MERROR (MERROR_DB, NULL);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MDEBUG_PRINT1 (" from %s\n", filename);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (tags[0] == Mchar_table)
|
|
Packit Service |
a721b1 |
value = load_chartable (fp, tags[1]);
|
|
Packit Service |
a721b1 |
else if (tags[0] == Mcharset)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (! mdatabase__load_charset_func)
|
|
Packit Service |
a721b1 |
MERROR (MERROR_DB, NULL);
|
|
Packit Service |
a721b1 |
value = (*mdatabase__load_charset_func) (fp, tags[1]);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
value = mplist__from_file (fp, NULL);
|
|
Packit Service |
a721b1 |
fclose (fp);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! value)
|
|
Packit Service |
a721b1 |
MERROR (MERROR_DB, NULL);
|
|
Packit Service |
a721b1 |
db_info->time = time (NULL);
|
|
Packit Service |
a721b1 |
return value;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Return a newly allocated MDatabaseInfo for DIRNAME. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static MDatabaseInfo *
|
|
Packit Service |
a721b1 |
get_dir_info (char *dirname)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabaseInfo *dir_info;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MSTRUCT_CALLOC (dir_info, MERROR_DB);
|
|
Packit Service |
a721b1 |
if (dirname)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int len = strlen (dirname);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (len + MDB_DIR_LEN < PATH_MAX)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MTABLE_MALLOC (dir_info->filename, len + 2, MERROR_DB);
|
|
Packit Service |
a721b1 |
memcpy (dir_info->filename, dirname, len + 1);
|
|
Packit Service |
a721b1 |
/* Append PATH_SEPARATOR if DIRNAME doesn't end with it. */
|
|
Packit Service |
a721b1 |
if (dir_info->filename[len - 1] != PATH_SEPARATOR)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
dir_info->filename[len] = PATH_SEPARATOR;
|
|
Packit Service |
a721b1 |
dir_info->filename[++len] = '\0';
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
dir_info->len = len;
|
|
Packit Service |
a721b1 |
dir_info->status = MDB_STATUS_OUTDATED;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
dir_info->status = MDB_STATUS_DISABLED;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
dir_info->status = MDB_STATUS_DISABLED;
|
|
Packit Service |
a721b1 |
return dir_info;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void register_databases_in_files (MSymbol tags[4],
|
|
Packit Service |
a721b1 |
char *filename, int len);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static MDatabase *
|
|
Packit Service |
a721b1 |
find_database (MSymbol tags[4])
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *plist;
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
MDatabase *mdb;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! mdatabase__list)
|
|
Packit Service |
a721b1 |
return NULL;
|
|
Packit Service |
a721b1 |
for (i = 0, plist = mdatabase__list; i < 4; i++)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *pl = mplist__assq (plist, tags[i]);
|
|
Packit Service |
a721b1 |
MPlist *p;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if ((p = mplist__assq (plist, Masterisk)))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabaseInfo *db_info;
|
|
Packit Service |
a721b1 |
int j;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
p = MPLIST_PLIST (p);
|
|
Packit Service |
a721b1 |
for (j = i + 1; j < 4; j++)
|
|
Packit Service |
a721b1 |
p = MPLIST_PLIST (MPLIST_NEXT (p));
|
|
Packit Service |
a721b1 |
mdb = MPLIST_VAL (MPLIST_NEXT (p));
|
|
Packit Service |
a721b1 |
db_info = mdb->extra_info;
|
|
Packit Service |
a721b1 |
if (db_info->status != MDB_STATUS_DISABLED)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
register_databases_in_files (mdb->tag,
|
|
Packit Service |
a721b1 |
db_info->filename, db_info->len);
|
|
Packit Service |
a721b1 |
db_info->status = MDB_STATUS_DISABLED;
|
|
Packit Service |
a721b1 |
return find_database (tags);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (! pl)
|
|
Packit Service |
a721b1 |
return NULL;
|
|
Packit Service |
a721b1 |
plist = MPLIST_PLIST (pl);
|
|
Packit Service |
a721b1 |
plist = MPLIST_NEXT (plist);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
mdb = MPLIST_VAL (plist);
|
|
Packit Service |
a721b1 |
return mdb;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void
|
|
Packit Service |
a721b1 |
free_db_info (MDatabaseInfo *db_info)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
free (db_info->filename);
|
|
Packit Service |
a721b1 |
if (db_info->absolute_filename
|
|
Packit Service |
a721b1 |
&& db_info->filename != db_info->absolute_filename)
|
|
Packit Service |
a721b1 |
free (db_info->absolute_filename);
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (db_info->properties);
|
|
Packit Service |
a721b1 |
free (db_info);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static int
|
|
Packit Service |
a721b1 |
check_version (MText *version)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
char *verstr = (char *) MTEXT_DATA (version);
|
|
Packit Service |
a721b1 |
char *endp = verstr + mtext_nbytes (version);
|
|
Packit Service |
a721b1 |
int ver[3];
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
ver[0] = ver[1] = ver[2] = 0;
|
|
Packit Service |
a721b1 |
for (i = 0; verstr < endp; verstr++)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (*verstr == '.')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
i++;
|
|
Packit Service |
a721b1 |
if (i == 3)
|
|
Packit Service |
a721b1 |
break;
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (! isdigit (*verstr))
|
|
Packit Service |
a721b1 |
break;
|
|
Packit Service |
a721b1 |
ver[i] = ver[i] * 10 + (*verstr - '0');
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return (ver[0] < M17NLIB_MAJOR_VERSION
|
|
Packit Service |
a721b1 |
|| (ver[0] == M17NLIB_MAJOR_VERSION
|
|
Packit Service |
a721b1 |
&& (ver[1] < M17NLIB_MINOR_VERSION
|
|
Packit Service |
a721b1 |
|| (ver[1] == M17NLIB_MINOR_VERSION
|
|
Packit Service |
a721b1 |
&& ver[2] <= M17NLIB_PATCH_LEVEL))));
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static MDatabase *
|
|
Packit Service |
a721b1 |
register_database (MSymbol tags[4],
|
|
Packit Service |
a721b1 |
void *(*loader) (MSymbol *, void *),
|
|
Packit Service |
a721b1 |
void *extra_info, enum MDatabaseStatus status,
|
|
Packit Service |
a721b1 |
MPlist *properties)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabase *mdb;
|
|
Packit Service |
a721b1 |
MDatabaseInfo *db_info;
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
MPlist *plist;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (properties)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPLIST_DO (plist, properties)
|
|
Packit Service |
a721b1 |
if (MPLIST_PLIST_P (plist))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *p = MPLIST_PLIST (plist);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (MPLIST_SYMBOL_P (p)
|
|
Packit Service |
a721b1 |
&& MPLIST_SYMBOL (p) == Mversion
|
|
Packit Service |
a721b1 |
&& MPLIST_MTEXT_P (MPLIST_NEXT (p)))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (check_version (MPLIST_MTEXT (MPLIST_NEXT (p))))
|
|
Packit Service |
a721b1 |
break;
|
|
Packit Service |
a721b1 |
return NULL;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
for (i = 0, plist = mdatabase__list; i < 4; i++)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *pl = mplist__assq (plist, tags[i]);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (pl)
|
|
Packit Service |
a721b1 |
pl = MPLIST_PLIST (pl);
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
pl = mplist ();
|
|
Packit Service |
a721b1 |
mplist_add (pl, Msymbol, tags[i]);
|
|
Packit Service |
a721b1 |
mplist_push (plist, Mplist, pl);
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (pl);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
plist = MPLIST_NEXT (pl);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (MPLIST_TAIL_P (plist))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MSTRUCT_MALLOC (mdb, MERROR_DB);
|
|
Packit Service |
a721b1 |
for (i = 0; i < 4; i++)
|
|
Packit Service |
a721b1 |
mdb->tag[i] = tags[i];
|
|
Packit Service |
a721b1 |
mdb->loader = loader;
|
|
Packit Service |
a721b1 |
if (loader == load_database)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MSTRUCT_CALLOC (db_info, MERROR_DB);
|
|
Packit Service |
a721b1 |
mdb->extra_info = db_info;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
db_info = NULL;
|
|
Packit Service |
a721b1 |
mdb->extra_info = extra_info;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
mplist_push (plist, Mt, mdb);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
mdb = MPLIST_VAL (plist);
|
|
Packit Service |
a721b1 |
if (loader == load_database)
|
|
Packit Service |
a721b1 |
db_info = mdb->extra_info;
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
db_info = NULL;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (db_info)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
db_info->status = status;
|
|
Packit Service |
a721b1 |
if (! db_info->filename
|
|
Packit Service |
a721b1 |
|| strcmp (db_info->filename, (char *) extra_info) != 0)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (db_info->filename)
|
|
Packit Service |
a721b1 |
free (db_info->filename);
|
|
Packit Service |
a721b1 |
if (db_info->absolute_filename
|
|
Packit Service |
a721b1 |
&& db_info->filename != db_info->absolute_filename)
|
|
Packit Service |
a721b1 |
free (db_info->absolute_filename);
|
|
Packit Service |
a721b1 |
db_info->filename = strdup ((char *) extra_info);
|
|
Packit Service |
a721b1 |
db_info->len = strlen ((char *) extra_info);
|
|
Packit Service |
a721b1 |
db_info->time = 0;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (db_info->filename[0] == PATH_SEPARATOR)
|
|
Packit Service |
a721b1 |
db_info->absolute_filename = db_info->filename;
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
db_info->absolute_filename = NULL;
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (db_info->properties);
|
|
Packit Service |
a721b1 |
if (properties)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
db_info->properties = properties;
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF (properties);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (mdb->tag[0] == Mchar_table
|
|
Packit Service |
a721b1 |
&& mdb->tag[2] != Mnil
|
|
Packit Service |
a721b1 |
&& (mdb->tag[1] == Mstring || mdb->tag[1] == Mtext
|
|
Packit Service |
a721b1 |
|| mdb->tag[1] == Msymbol || mdb->tag[1] == Minteger
|
|
Packit Service |
a721b1 |
|| mdb->tag[1] == Mplist))
|
|
Packit Service |
a721b1 |
mchar__define_prop (mdb->tag[2], mdb->tag[1], mdb);
|
|
Packit Service |
a721b1 |
return mdb;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void
|
|
Packit Service |
a721b1 |
register_databases_in_files (MSymbol tags[4], char *filename, int len)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int i, j;
|
|
Packit Service |
a721b1 |
MPlist *load_key = mplist ();
|
|
Packit Service |
a721b1 |
FILE *fp;
|
|
Packit Service |
a721b1 |
MPlist *plist, *pl;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPLIST_DO (plist, mdatabase__dir_list)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
glob_t globbuf;
|
|
Packit Service |
a721b1 |
int headlen;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (filename[0] == PATH_SEPARATOR)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (glob (filename, GLOB_NOSORT, NULL, &globbuf))
|
|
Packit Service |
a721b1 |
break;
|
|
Packit Service |
a721b1 |
headlen = 0;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabaseInfo *d_info = MPLIST_VAL (plist);
|
|
Packit Service |
a721b1 |
char path[PATH_MAX + 1];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (d_info->status == MDB_STATUS_DISABLED)
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
if (! GEN_PATH (path, d_info->filename, d_info->len, filename, len))
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
if (glob (path, GLOB_NOSORT, NULL, &globbuf))
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
headlen = d_info->len;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
for (i = 0; i < globbuf.gl_pathc; i++)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (! (fp = fopen (globbuf.gl_pathv[i], "r")))
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
pl = mplist__from_file (fp, load_key);
|
|
Packit Service |
a721b1 |
fclose (fp);
|
|
Packit Service |
a721b1 |
if (! pl)
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
if (MPLIST_PLIST_P (pl))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *p;
|
|
Packit Service |
a721b1 |
MSymbol tags2[4];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
for (j = 0, p = MPLIST_PLIST (pl); j < 4 && MPLIST_SYMBOL_P (p);
|
|
Packit Service |
a721b1 |
j++, p = MPLIST_NEXT (p))
|
|
Packit Service |
a721b1 |
tags2[j] = MPLIST_SYMBOL (p);
|
|
Packit Service |
a721b1 |
for (; j < 4; j++)
|
|
Packit Service |
a721b1 |
tags2[j] = Mnil;
|
|
Packit Service |
a721b1 |
for (j = 0; j < 4; j++)
|
|
Packit Service |
a721b1 |
if (tags[j] != Masterisk && tags[j] != tags2[j])
|
|
Packit Service |
a721b1 |
break;
|
|
Packit Service |
a721b1 |
if (j == 4)
|
|
Packit Service |
a721b1 |
register_database (tags2, load_database,
|
|
Packit Service |
a721b1 |
globbuf.gl_pathv[i] + headlen,
|
|
Packit Service |
a721b1 |
MDB_STATUS_AUTO, p);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (pl);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
globfree (&globbuf);
|
|
Packit Service |
a721b1 |
if (filename[0] == PATH_SEPARATOR)
|
|
Packit Service |
a721b1 |
break;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (load_key);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static int
|
|
Packit Service |
a721b1 |
expand_wildcard_database (MPlist *plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabase *mdb;
|
|
Packit Service |
a721b1 |
MDatabaseInfo *db_info;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
plist = MPLIST_NEXT (plist);
|
|
Packit Service |
a721b1 |
while (MPLIST_PLIST_P (plist))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
plist = MPLIST_PLIST (plist);
|
|
Packit Service |
a721b1 |
plist = MPLIST_NEXT (plist);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
mdb = MPLIST_VAL (plist);
|
|
Packit Service |
a721b1 |
if (mdb->loader == load_database
|
|
Packit Service |
a721b1 |
&& (db_info = mdb->extra_info)
|
|
Packit Service |
a721b1 |
&& db_info->status != MDB_STATUS_DISABLED)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
register_databases_in_files (mdb->tag, db_info->filename, db_info->len);
|
|
Packit Service |
a721b1 |
db_info->status = MDB_STATUS_DISABLED;
|
|
Packit Service |
a721b1 |
return 1;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return 0;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Internal API */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** List of database directories. */
|
|
Packit Service |
a721b1 |
MPlist *mdatabase__dir_list;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
void *(*mdatabase__load_charset_func) (FILE *fp, MSymbol charset_name);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
int
|
|
Packit Service |
a721b1 |
mdatabase__init ()
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabaseInfo *dir_info;
|
|
Packit Service |
a721b1 |
char *path;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
mdatabase__load_charset_func = NULL;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
Mchar_table = msymbol ("char-table");
|
|
Packit Service |
a721b1 |
Mcharset = msymbol ("charset");
|
|
Packit Service |
a721b1 |
Masterisk = msymbol ("*");
|
|
Packit Service |
a721b1 |
Mversion = msymbol ("version");
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
mdatabase__dir_list = mplist ();
|
|
Packit Service |
a721b1 |
/** The macro M17NDIR specifies a directory where the system-wide
|
|
Packit Service |
a721b1 |
MDB_DIR file exists. */
|
|
Packit Service |
a721b1 |
mplist_set (mdatabase__dir_list, Mt, get_dir_info (M17NDIR));
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* The variable mdatabase_dir specifies a directory where an
|
|
Packit Service |
a721b1 |
application program specific MDB_DIR file exists. */
|
|
Packit Service |
a721b1 |
if (mdatabase_dir && strlen (mdatabase_dir) > 0)
|
|
Packit Service |
a721b1 |
mplist_push (mdatabase__dir_list, Mt, get_dir_info (mdatabase_dir));
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* The environment variable M17NDIR specifies a directory where a
|
|
Packit Service |
a721b1 |
user specific MDB_DIR file exists. */
|
|
Packit Service |
a721b1 |
path = getenv ("M17NDIR");
|
|
Packit Service |
a721b1 |
if (path && strlen (path) > 0)
|
|
Packit Service |
a721b1 |
mplist_push (mdatabase__dir_list, Mt, get_dir_info (path));
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
/* If the env var M17NDIR is not set, check "~/.m17n.d". */
|
|
Packit Service |
a721b1 |
char *home = getenv ("HOME");
|
|
Packit Service |
a721b1 |
int len;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (home
|
|
Packit Service |
a721b1 |
&& (len = strlen (home))
|
|
Packit Service |
a721b1 |
&& (path = alloca (len + 9)))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
strcpy (path, home);
|
|
Packit Service |
a721b1 |
if (path[len - 1] != PATH_SEPARATOR)
|
|
Packit Service |
a721b1 |
path[len++] = PATH_SEPARATOR;
|
|
Packit Service |
a721b1 |
strcpy (path + len, ".m17n.d");
|
|
Packit Service |
a721b1 |
dir_info = get_dir_info (path);
|
|
Packit Service |
a721b1 |
mplist_push (mdatabase__dir_list, Mt, dir_info);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
mplist_push (mdatabase__dir_list, Mt, get_dir_info (NULL));
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
mdatabase__list = mplist ();
|
|
Packit Service |
a721b1 |
mdatabase__update ();
|
|
Packit Service |
a721b1 |
return 0;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
void
|
|
Packit Service |
a721b1 |
mdatabase__fini (void)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *plist, *p0, *p1, *p2, *p3;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPLIST_DO (plist, mdatabase__dir_list)
|
|
Packit Service |
a721b1 |
free_db_info (MPLIST_VAL (plist));
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (mdatabase__dir_list);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* MDATABASE_LIST ::= ((TAG0 (TAG1 (TAG2 (TAG3 t:MDB) ...) ...) ...) ...) */
|
|
Packit Service |
a721b1 |
MPLIST_DO (plist, mdatabase__list)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
p0 = MPLIST_PLIST (plist);
|
|
Packit Service |
a721b1 |
/* P0 ::= (TAG0 (TAG1 (TAG2 (TAG3 t:MDB) ...) ...) ...) */
|
|
Packit Service |
a721b1 |
MPLIST_DO (p0, MPLIST_NEXT (p0))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
p1 = MPLIST_PLIST (p0);
|
|
Packit Service |
a721b1 |
/* P1 ::= (TAG1 (TAG2 (TAG3 t:MDB) ...) ...) */
|
|
Packit Service |
a721b1 |
MPLIST_DO (p1, MPLIST_NEXT (p1))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
p2 = MPLIST_PLIST (p1);
|
|
Packit Service |
a721b1 |
/* P2 ::= (TAG2 (TAG3 t:MDB) ...) */
|
|
Packit Service |
a721b1 |
MPLIST_DO (p2, MPLIST_NEXT (p2))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabase *mdb;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
p3 = MPLIST_PLIST (p2); /* P3 ::= (TAG3 t:MDB) */
|
|
Packit Service |
a721b1 |
p3 = MPLIST_NEXT (p3);
|
|
Packit Service |
a721b1 |
mdb = MPLIST_VAL (p3);
|
|
Packit Service |
a721b1 |
if (mdb->loader == load_database)
|
|
Packit Service |
a721b1 |
free_db_info (mdb->extra_info);
|
|
Packit Service |
a721b1 |
free (mdb);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (mdatabase__list);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
void
|
|
Packit Service |
a721b1 |
mdatabase__update (void)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *plist, *p0, *p1, *p2, *p3;
|
|
Packit Service |
a721b1 |
char path[PATH_MAX + 1];
|
|
Packit Service |
a721b1 |
MDatabaseInfo *dir_info;
|
|
Packit Service |
a721b1 |
struct stat statbuf;
|
|
Packit Service |
a721b1 |
int rescan = 0;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Update elements of mdatabase__dir_list. */
|
|
Packit Service |
a721b1 |
MPLIST_DO (plist, mdatabase__dir_list)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
dir_info = MPLIST_VAL (plist);
|
|
Packit Service |
a721b1 |
if (dir_info->filename)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (stat (dir_info->filename, &statbuf) == 0
|
|
Packit Service |
a721b1 |
&& (statbuf.st_mode & S_IFDIR))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (dir_info->time < statbuf.st_mtime)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
rescan = 1;
|
|
Packit Service |
a721b1 |
dir_info->time = statbuf.st_mtime;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (GEN_PATH (path, dir_info->filename, dir_info->len,
|
|
Packit Service |
a721b1 |
MDB_DIR, MDB_DIR_LEN)
|
|
Packit Service |
a721b1 |
&& stat (path, &statbuf) >= 0
|
|
Packit Service |
a721b1 |
&& dir_info->time < statbuf.st_mtime)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
rescan = 1;
|
|
Packit Service |
a721b1 |
dir_info->time = statbuf.st_mtime;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
dir_info->status = MDB_STATUS_UPDATED;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (dir_info->status != MDB_STATUS_DISABLED)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
rescan = 1;
|
|
Packit Service |
a721b1 |
dir_info->time = 0;
|
|
Packit Service |
a721b1 |
dir_info->status = MDB_STATUS_DISABLED;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! rescan)
|
|
Packit Service |
a721b1 |
return;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* At first, mark all databases defined automatically from mdb.dir
|
|
Packit Service |
a721b1 |
file(s) as "disabled". */
|
|
Packit Service |
a721b1 |
MPLIST_DO (plist, mdatabase__list)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
p0 = MPLIST_PLIST (plist);
|
|
Packit Service |
a721b1 |
/* P0 ::= (TAG0 (TAG1 (TAG2 (TAG3 MDB) ...) ...) ...) */
|
|
Packit Service |
a721b1 |
MPLIST_DO (p0, MPLIST_NEXT (p0))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
p1 = MPLIST_PLIST (p0);
|
|
Packit Service |
a721b1 |
MPLIST_DO (p1, MPLIST_NEXT (p1))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
p2 = MPLIST_PLIST (p1);
|
|
Packit Service |
a721b1 |
MPLIST_DO (p2, MPLIST_NEXT (p2))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabase *mdb;
|
|
Packit Service |
a721b1 |
MDatabaseInfo *db_info;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
p3 = MPLIST_PLIST (p2);
|
|
Packit Service |
a721b1 |
p3 = MPLIST_NEXT (p3);
|
|
Packit Service |
a721b1 |
mdb = MPLIST_VAL (p3);
|
|
Packit Service |
a721b1 |
db_info = mdb->extra_info;
|
|
Packit Service |
a721b1 |
if (db_info->status == MDB_STATUS_AUTO)
|
|
Packit Service |
a721b1 |
db_info->status = MDB_STATUS_DISABLED;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
plist = mplist ();
|
|
Packit Service |
a721b1 |
MPLIST_DO (p0, mdatabase__dir_list)
|
|
Packit Service |
a721b1 |
mplist_push (plist, MPLIST_KEY (p0), MPLIST_VAL (p0));
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
while (! MPLIST_TAIL_P (plist))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabaseInfo *dir_info = mplist_pop (plist);
|
|
Packit Service |
a721b1 |
MPlist *pl, *p;
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
FILE *fp;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (dir_info->status == MDB_STATUS_DISABLED)
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
if (! GEN_PATH (path, dir_info->filename, dir_info->len,
|
|
Packit Service |
a721b1 |
MDB_DIR, MDB_DIR_LEN))
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
if (! (fp = fopen (path, "r")))
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
pl = mplist__from_file (fp, NULL);
|
|
Packit Service |
a721b1 |
fclose (fp);
|
|
Packit Service |
a721b1 |
if (! pl)
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
MPLIST_DO (p, pl)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MSymbol tags[4];
|
|
Packit Service |
a721b1 |
MPlist *p1;
|
|
Packit Service |
a721b1 |
MText *mt;
|
|
Packit Service |
a721b1 |
int nbytes;
|
|
Packit Service |
a721b1 |
int with_wildcard = 0;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! MPLIST_PLIST_P (p))
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
for (i = 0, p1 = MPLIST_PLIST (p); i < 4 && MPLIST_SYMBOL_P (p1);
|
|
Packit Service |
a721b1 |
i++, p1 = MPLIST_NEXT (p1))
|
|
Packit Service |
a721b1 |
with_wildcard |= ((tags[i] = MPLIST_SYMBOL (p1)) == Masterisk);
|
|
Packit Service |
a721b1 |
if (i == 0
|
|
Packit Service |
a721b1 |
|| tags[0] == Masterisk
|
|
Packit Service |
a721b1 |
|| ! MPLIST_MTEXT_P (p1))
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
for (; i < 4; i++)
|
|
Packit Service |
a721b1 |
tags[i] = with_wildcard ? Masterisk : Mnil;
|
|
Packit Service |
a721b1 |
mt = MPLIST_MTEXT (p1);
|
|
Packit Service |
a721b1 |
nbytes = mtext_nbytes (mt);
|
|
Packit Service |
a721b1 |
if (nbytes > PATH_MAX)
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
memcpy (path, MTEXT_DATA (mt), nbytes);
|
|
Packit Service |
a721b1 |
path[nbytes] = '\0';
|
|
Packit Service |
a721b1 |
if (with_wildcard)
|
|
Packit Service |
a721b1 |
register_database (tags, load_database, path,
|
|
Packit Service |
a721b1 |
MDB_STATUS_AUTO_WILDCARD, NULL);
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
register_database (tags, load_database, path,
|
|
Packit Service |
a721b1 |
MDB_STATUS_AUTO, p1);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (pl);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (plist);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mdatabase__load_for_keys (MDatabase *mdb, MPlist *keys)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int mdebug_flag = MDEBUG_DATABASE;
|
|
Packit Service |
a721b1 |
MDatabaseInfo *db_info;
|
|
Packit Service |
a721b1 |
char *filename;
|
|
Packit Service |
a721b1 |
FILE *fp;
|
|
Packit Service |
a721b1 |
MPlist *plist;
|
|
Packit Service |
a721b1 |
char name[256];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (mdb->loader != load_database
|
|
Packit Service |
a721b1 |
|| mdb->tag[0] == Mchar_table
|
|
Packit Service |
a721b1 |
|| mdb->tag[0] == Mcharset)
|
|
Packit Service |
a721b1 |
MERROR (MERROR_DB, NULL);
|
|
Packit Service |
a721b1 |
MDEBUG_PRINT1 (" [DB] <%s>.\n",
|
|
Packit Service |
a721b1 |
gen_database_name (name, mdb->tag));
|
|
Packit Service |
a721b1 |
db_info = mdb->extra_info;
|
|
Packit Service |
a721b1 |
filename = get_database_file (db_info, NULL, NULL);
|
|
Packit Service |
a721b1 |
if (! filename || ! (fp = fopen (filename, "r")))
|
|
Packit Service |
a721b1 |
MERROR (MERROR_DB, NULL);
|
|
Packit Service |
a721b1 |
plist = mplist__from_file (fp, keys);
|
|
Packit Service |
a721b1 |
fclose (fp);
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Check if the database MDB should be reloaded or not. It returns:
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
1: The database has not been updated since it was loaded last
|
|
Packit Service |
a721b1 |
time.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
0: The database has never been loaded or has been updated
|
|
Packit Service |
a721b1 |
since it was loaded last time.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
-1: The database is not loadable at the moment. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
int
|
|
Packit Service |
a721b1 |
mdatabase__check (MDatabase *mdb)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabaseInfo *db_info = (MDatabaseInfo *) mdb->extra_info;
|
|
Packit Service |
a721b1 |
struct stat buf;
|
|
Packit Service |
a721b1 |
int result;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (db_info->absolute_filename != db_info->filename
|
|
Packit Service |
a721b1 |
|| db_info->status == MDB_STATUS_AUTO)
|
|
Packit Service |
a721b1 |
mdatabase__update ();
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! get_database_file (db_info, &buf, &result)
|
|
Packit Service |
a721b1 |
|| result < 0)
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
if (db_info->time < buf.st_mtime)
|
|
Packit Service |
a721b1 |
return 0;
|
|
Packit Service |
a721b1 |
return 1;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Search directories in mdatabase__dir_list for file FILENAME. If
|
|
Packit Service |
a721b1 |
the file exist, return the absolute pathname. If FILENAME is
|
|
Packit Service |
a721b1 |
already absolute, return a copy of it. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
char *
|
|
Packit Service |
a721b1 |
mdatabase__find_file (char *filename)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
struct stat buf;
|
|
Packit Service |
a721b1 |
int result;
|
|
Packit Service |
a721b1 |
MDatabaseInfo db_info;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (filename[0] == PATH_SEPARATOR)
|
|
Packit Service |
a721b1 |
return (stat (filename, &buf) == 0 ? strdup (filename) : NULL);
|
|
Packit Service |
a721b1 |
db_info.filename = filename;
|
|
Packit Service |
a721b1 |
db_info.len = strlen (filename);
|
|
Packit Service |
a721b1 |
db_info.time = 0;
|
|
Packit Service |
a721b1 |
db_info.absolute_filename = NULL;
|
|
Packit Service |
a721b1 |
if (! get_database_file (&db_info, &buf, &result)
|
|
Packit Service |
a721b1 |
|| result < 0)
|
|
Packit Service |
a721b1 |
return NULL;
|
|
Packit Service |
a721b1 |
return db_info.absolute_filename;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
char *
|
|
Packit Service |
a721b1 |
mdatabase__file (MDatabase *mdb)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabaseInfo *db_info;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (mdb->loader != load_database)
|
|
Packit Service |
a721b1 |
return NULL;
|
|
Packit Service |
a721b1 |
db_info = mdb->extra_info;
|
|
Packit Service |
a721b1 |
return get_database_file (db_info, NULL, NULL);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
int
|
|
Packit Service |
a721b1 |
mdatabase__lock (MDatabase *mdb)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabaseInfo *db_info;
|
|
Packit Service |
a721b1 |
struct stat buf;
|
|
Packit Service |
a721b1 |
FILE *fp;
|
|
Packit Service |
a721b1 |
int len;
|
|
Packit Service |
a721b1 |
char *file;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (mdb->loader != load_database)
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
db_info = mdb->extra_info;
|
|
Packit Service |
a721b1 |
if (db_info->lock_file)
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
file = get_database_file (db_info, NULL, NULL);
|
|
Packit Service |
a721b1 |
if (! file)
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
len = strlen (file);
|
|
Packit Service |
a721b1 |
db_info->uniq_file = malloc (len + 35);
|
|
Packit Service |
a721b1 |
if (! db_info->uniq_file)
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
db_info->lock_file = malloc (len + 5);
|
|
Packit Service |
a721b1 |
if (! db_info->lock_file)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
free (db_info->uniq_file);
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
sprintf (db_info->uniq_file, "%s.%X.%X", db_info->absolute_filename,
|
|
Packit Service |
a721b1 |
(unsigned) time (NULL), (unsigned) getpid ());
|
|
Packit Service |
a721b1 |
sprintf (db_info->lock_file, "%s.LCK", db_info->absolute_filename);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
fp = fopen (db_info->uniq_file, "w");
|
|
Packit Service |
a721b1 |
if (! fp)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
char *str = strdup (db_info->uniq_file);
|
|
Packit Service |
a721b1 |
char *dir = dirname (str);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (stat (dir, &buf) == 0
|
|
Packit Service |
a721b1 |
|| mkdir (dir, 0777) < 0
|
|
Packit Service |
a721b1 |
|| ! (fp = fopen (db_info->uniq_file, "w")))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
free (db_info->uniq_file);
|
|
Packit Service |
a721b1 |
free (db_info->lock_file);
|
|
Packit Service |
a721b1 |
db_info->lock_file = NULL;
|
|
Packit Service |
a721b1 |
free (str);
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
free (str);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
fclose (fp);
|
|
Packit Service |
a721b1 |
if (link (db_info->uniq_file, db_info->lock_file) < 0
|
|
Packit Service |
a721b1 |
&& (stat (db_info->uniq_file, &buf) < 0
|
|
Packit Service |
a721b1 |
|| buf.st_nlink != 2))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
unlink (db_info->uniq_file);
|
|
Packit Service |
a721b1 |
unlink (db_info->lock_file);
|
|
Packit Service |
a721b1 |
free (db_info->uniq_file);
|
|
Packit Service |
a721b1 |
free (db_info->lock_file);
|
|
Packit Service |
a721b1 |
db_info->lock_file = NULL;
|
|
Packit Service |
a721b1 |
return 0;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return 1;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
int
|
|
Packit Service |
a721b1 |
mdatabase__save (MDatabase *mdb, MPlist *data)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabaseInfo *db_info;
|
|
Packit Service |
a721b1 |
FILE *fp;
|
|
Packit Service |
a721b1 |
char *file;
|
|
Packit Service |
a721b1 |
MText *mt;
|
|
Packit Service |
a721b1 |
int ret;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (mdb->loader != load_database)
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
db_info = mdb->extra_info;
|
|
Packit Service |
a721b1 |
if (! db_info->lock_file)
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
file = get_database_file (db_info, NULL, NULL);
|
|
Packit Service |
a721b1 |
if (! file)
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
mt = mtext ();
|
|
Packit Service |
a721b1 |
if (mplist__serialize (mt, data, 1) < 0)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (mt);
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
fp = fopen (db_info->uniq_file, "w");
|
|
Packit Service |
a721b1 |
if (! fp)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (mt);
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (mt->format > MTEXT_FORMAT_UTF_8)
|
|
Packit Service |
a721b1 |
mtext__adjust_format (mt, MTEXT_FORMAT_UTF_8);
|
|
Packit Service |
a721b1 |
fwrite (MTEXT_DATA (mt), 1, mtext_nchars (mt), fp);
|
|
Packit Service |
a721b1 |
fclose (fp);
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (mt);
|
|
Packit Service |
a721b1 |
if ((ret = rename (db_info->uniq_file, file)) < 0)
|
|
Packit Service |
a721b1 |
unlink (db_info->uniq_file);
|
|
Packit Service |
a721b1 |
free (db_info->uniq_file);
|
|
Packit Service |
a721b1 |
db_info->uniq_file = NULL;
|
|
Packit Service |
a721b1 |
return ret;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
int
|
|
Packit Service |
a721b1 |
mdatabase__unlock (MDatabase *mdb)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabaseInfo *db_info;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (mdb->loader != load_database)
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
db_info = mdb->extra_info;
|
|
Packit Service |
a721b1 |
if (! db_info->lock_file)
|
|
Packit Service |
a721b1 |
return -1;
|
|
Packit Service |
a721b1 |
unlink (db_info->lock_file);
|
|
Packit Service |
a721b1 |
free (db_info->lock_file);
|
|
Packit Service |
a721b1 |
db_info->lock_file = NULL;
|
|
Packit Service |
a721b1 |
if (db_info->uniq_file)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
unlink (db_info->uniq_file);
|
|
Packit Service |
a721b1 |
free (db_info->uniq_file);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return 0;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mdatabase__props (MDatabase *mdb)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabaseInfo *db_info;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (mdb->loader != load_database)
|
|
Packit Service |
a721b1 |
return NULL;
|
|
Packit Service |
a721b1 |
db_info = mdb->extra_info;
|
|
Packit Service |
a721b1 |
return db_info->properties;
|
|
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 m17nCharset */
|
|
Packit Service |
a721b1 |
/*** @{ */
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief The symbol @c Mcharset.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
Any decoded M-text has a text property whose key is the predefined
|
|
Packit Service |
a721b1 |
symbol @c Mcharset. The name of @c Mcharset is
|
|
Packit Service |
a721b1 |
<tt>"charset"</tt>. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief シンボル @c Mcharset.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
デコードされた M-text は、キーが @c Mcharset
|
|
Packit Service |
a721b1 |
であるようなテキストプロパティを持つ。
|
|
Packit Service |
a721b1 |
シンボル @c Mcharset は <tt>"charset"</tt> という名前を持つ。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MSymbol Mcharset;
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
/*** @} */
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*** @addtogroup m17nDatabase */
|
|
Packit Service |
a721b1 |
/*** @{ */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Directory for application specific data.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
If an application program wants to provide a data specific to the
|
|
Packit Service |
a721b1 |
program or a data overriding what supplied by the m17n database,
|
|
Packit Service |
a721b1 |
it must set this variable to a name of directory that contains the
|
|
Packit Service |
a721b1 |
data files before it calls the macro M17N_INIT (). The directory
|
|
Packit Service |
a721b1 |
may contain a file "mdb.dir" which contains a list of data
|
|
Packit Service |
a721b1 |
definitions in the format described in @ref mdbDir "mdbDir(5)".
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The default value is NULL. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief アプリケーション固有のデータ用ディレクトリ.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
アプリケーションプログラムが、そのプログラム固有のデータや m17n
|
|
Packit Service |
a721b1 |
データベースを上書きするデータを提供する場合には、マクロ M17N_INIT ()
|
|
Packit Service |
a721b1 |
を呼ぶ前にこの変数をデータファイルを含むディレクトリ名にセットしなくてはならない。ディレクトリには
|
|
Packit Service |
a721b1 |
"mdb.dir" ファイルをおくことができる。その"mdb.dir"ファイルには、
|
|
Packit Service |
a721b1 |
@ref mdbDir "mdbDir(5)" で説明されているフォーマットでデータ定義のリストを記述する。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
デフォルトの値は NULL である。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
char *mdatabase_dir;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Look for a data in the database.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mdatabase_find () function searches the m17n database for a
|
|
Packit Service |
a721b1 |
data who has tags $TAG0 through $TAG3, and returns a pointer to
|
|
Packit Service |
a721b1 |
the data. If such a data is not found, it returns @c NULL. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief データベース中のデータを探す.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mdatabase_find () は、 m17n 言語情報ベース中で $TAG0 から
|
|
Packit Service |
a721b1 |
$TAG3 までのタグを持つデータを探し、それへのポインタを返す。そのようなデータがなければ
|
|
Packit Service |
a721b1 |
@c NULL を返す。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@latexonly \IPAlabel{mdatabase_find} @endlatexonly */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MDatabase *
|
|
Packit Service |
a721b1 |
mdatabase_find (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MSymbol tags[4];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
mdatabase__update ();
|
|
Packit Service |
a721b1 |
tags[0] = tag0, tags[1] = tag1, tags[2] = tag2, tags[3] = tag3;
|
|
Packit Service |
a721b1 |
return find_database (tags);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Return a data list of the m17n database.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mdatabase_list () function searches the m17n database for data
|
|
Packit Service |
a721b1 |
who have tags $TAG0 through $TAG3, and returns their list by a
|
|
Packit Service |
a721b1 |
plist. The value #Mnil in $TAGn means a wild card that matches
|
|
Packit Service |
a721b1 |
any tag. Each element of the plist has key #Mt and value a
|
|
Packit Service |
a721b1 |
pointer to type #MDatabase. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief m17n データベースのデータリストを返す.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mdatabase_list () は m17n データベース中から $TAG0 から$TAG3
|
|
Packit Service |
a721b1 |
までのタグを持つデータを探し、そのリストをplist として返す。 $TAGn が #Mnil
|
|
Packit Service |
a721b1 |
であった場合には、任意のタグにマッチするワイルドカードとして取り扱われる。返される
|
|
Packit Service |
a721b1 |
plist の各要素はキー として #Mt を、値として #MDatabase 型へのポインタを持つ。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mdatabase_list (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *plist = mplist (), *pl = plist;
|
|
Packit Service |
a721b1 |
MPlist *p, *p0, *p1, *p2, *p3;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
mdatabase__update ();
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPLIST_DO (p, mdatabase__list)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
p0 = MPLIST_PLIST (p);
|
|
Packit Service |
a721b1 |
/* P0 ::= (TAG0 (TAG1 (TAG2 (TAG3 MDB) ...) ...) ...) */
|
|
Packit Service |
a721b1 |
if (MPLIST_SYMBOL (p0) == Masterisk
|
|
Packit Service |
a721b1 |
|| (tag0 != Mnil && MPLIST_SYMBOL (p0) != tag0))
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
MPLIST_DO (p0, MPLIST_NEXT (p0))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
p1 = MPLIST_PLIST (p0);
|
|
Packit Service |
a721b1 |
if (MPLIST_SYMBOL (p1) == Masterisk)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (expand_wildcard_database (p1))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (plist);
|
|
Packit Service |
a721b1 |
return mdatabase_list (tag0, tag1, tag2, tag3);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (tag1 != Mnil && MPLIST_SYMBOL (p1) != tag1)
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
MPLIST_DO (p1, MPLIST_NEXT (p1))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
p2 = MPLIST_PLIST (p1);
|
|
Packit Service |
a721b1 |
if (MPLIST_SYMBOL (p2) == Masterisk)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (expand_wildcard_database (p2))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (plist);
|
|
Packit Service |
a721b1 |
return mdatabase_list (tag0, tag1, tag2, tag3);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (tag2 != Mnil && MPLIST_SYMBOL (p2) != tag2)
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
MPLIST_DO (p2, MPLIST_NEXT (p2))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
p3 = MPLIST_PLIST (p2);
|
|
Packit Service |
a721b1 |
if (MPLIST_SYMBOL (p3) == Masterisk)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (expand_wildcard_database (p3))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (plist);
|
|
Packit Service |
a721b1 |
return mdatabase_list (tag0, tag1, tag2, tag3);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (tag3 != Mnil && MPLIST_SYMBOL (p3) != tag3)
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
p3 = MPLIST_NEXT (p3);
|
|
Packit Service |
a721b1 |
pl = mplist_add (pl, Mt, MPLIST_VAL (p3));
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (MPLIST_TAIL_P (plist))
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (plist);
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Define a data of the m17n database.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mdatabase_define () function defines a data that has tags
|
|
Packit Service |
a721b1 |
$TAG0 through $TAG3 and additional information $EXTRA_INFO.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
$LOADER is a pointer to a function that loads the data from the
|
|
Packit Service |
a721b1 |
database. This function is called from the mdatabase_load ()
|
|
Packit Service |
a721b1 |
function with the two arguments $TAGS and $EXTRA_INFO. Here,
|
|
Packit Service |
a721b1 |
$TAGS is the array of $TAG0 through $TAG3.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
If $LOADER is @c NULL, the default loader of the m17n library is
|
|
Packit Service |
a721b1 |
used. In this case, $EXTRA_INFO must be a string specifying a
|
|
Packit Service |
a721b1 |
filename that contains the data.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
If the operation was successful, mdatabase_define () returns a
|
|
Packit Service |
a721b1 |
pointer to the defined data, which can be used as an argument to
|
|
Packit Service |
a721b1 |
mdatabase_load (). Otherwise, it returns @c NULL. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief m17n データベースのデータを定義する.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mdatabase_define () は $TAG0 から $TAG3 までのタグおよび付加情報
|
|
Packit Service |
a721b1 |
$EXTRA_INFO を持つデータを定義する。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
$LOADER はそのデータのロードに用いられる関数へのポインタである。この関数は
|
|
Packit Service |
a721b1 |
mdatabase_load () から $TAGS と $EXTRA_INFO という二つの引数付きで呼び出される。ここで
|
|
Packit Service |
a721b1 |
$TAGS は $TAG0 から $TAG3 までの配列である。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
もし $LOADER が @c NULL なら、m17n ライブラリ標準のローダが使われる。この場合には
|
|
Packit Service |
a721b1 |
$EXTRA_INFO はデータを含むファイル名でなくてはならない。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
処理に成功すれば mdatabase_define ()
|
|
Packit Service |
a721b1 |
は定義されたデータベースへのポインタを返す。このポインタは関数 mdatabase_load ()
|
|
Packit Service |
a721b1 |
の引数として用いることができる。そうでなければ @c NULL を返す。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@latexonly \IPAlabel{mdatabase_define} @endlatexonly */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***
|
|
Packit Service |
a721b1 |
@seealso
|
|
Packit Service |
a721b1 |
mdatabase_load (), mdatabase_define () */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MDatabase *
|
|
Packit Service |
a721b1 |
mdatabase_define (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3,
|
|
Packit Service |
a721b1 |
void *(*loader) (MSymbol *, void *),
|
|
Packit Service |
a721b1 |
void *extra_info)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MDatabase *mdb;
|
|
Packit Service |
a721b1 |
MSymbol tags[4];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
tags[0] = tag0, tags[1] = tag1, tags[2] = tag2, tags[3] = tag3;
|
|
Packit Service |
a721b1 |
if (! loader)
|
|
Packit Service |
a721b1 |
loader = load_database;
|
|
Packit Service |
a721b1 |
mdb = register_database (tags, loader, extra_info, MDB_STATUS_EXPLICIT, NULL);
|
|
Packit Service |
a721b1 |
return mdb;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Load a data from the database.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mdatabase_load () function loads a data specified in $MDB and
|
|
Packit Service |
a721b1 |
returns the contents. The type of contents depends on the type of
|
|
Packit Service |
a721b1 |
the data.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
If the data is of the @e plist @e type, this function returns a
|
|
Packit Service |
a721b1 |
pointer to @e plist.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
If the database is of the @e chartable @e type, it returns a
|
|
Packit Service |
a721b1 |
chartable. The default value of the chartable is set according to
|
|
Packit Service |
a721b1 |
the second tag of the data as below:
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@li If the tag is #Msymbol, the default value is #Mnil.
|
|
Packit Service |
a721b1 |
@li If the tag is #Minteger, the default value is -1.
|
|
Packit Service |
a721b1 |
@li Otherwise, the default value is @c NULL.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
If the data is of the @e charset @e type, it returns a plist of length 2
|
|
Packit Service |
a721b1 |
(keys are both #Mt). The value of the first element is an array
|
|
Packit Service |
a721b1 |
of integers that maps code points to the corresponding character
|
|
Packit Service |
a721b1 |
codes. The value of the second element is a chartable of integers
|
|
Packit Service |
a721b1 |
that does the reverse mapping. The charset must be defined in
|
|
Packit Service |
a721b1 |
advance. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief データベースからデータをロードする.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mdatabase_load () は $MDB
|
|
Packit Service |
a721b1 |
が指すデータをロードし、その中身を返す。返されるものはデータのタイプによって異なる。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
データが @e plistタイプ ならば、 @e plist へのポインタを返す。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
データが @e chartableタイプ ならば文字テーブルを返す。
|
|
Packit Service |
a721b1 |
文字テーブルのデフォルト値は、データの第2タグによって以下のように決まる。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@li タグが #Msymbol なら、デフォルト値は #Mnil
|
|
Packit Service |
a721b1 |
@li タグが #Minteger なら、デフォルト値は -1
|
|
Packit Service |
a721b1 |
@li それ以外なら、デフォルト値は @c NULL
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
データが @e charsetタイプ ならば長さ 2 の plist を返す(キーは共に#Mt )。
|
|
Packit Service |
a721b1 |
最初の要素の値はコードポイントを対応する文字コードにマップする整数の配列である。
|
|
Packit Service |
a721b1 |
2番目の要素の値は逆のマップをする文字テーブルである。
|
|
Packit Service |
a721b1 |
この文字セットは予め定義されていなければならない。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@latexonly \IPAlabel{mdatabase_load} @endlatexonly
|
|
Packit Service |
a721b1 |
*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***
|
|
Packit Service |
a721b1 |
@seealso
|
|
Packit Service |
a721b1 |
mdatabase_load (), mdatabase_define () */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
void *
|
|
Packit Service |
a721b1 |
mdatabase_load (MDatabase *mdb)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
return (*mdb->loader) (mdb->tag, mdb->extra_info);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Get tags of a data.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mdatabase_tag () function returns an array of tags (symbols)
|
|
Packit Service |
a721b1 |
that identify the data in $MDB. The length of the array is
|
|
Packit Service |
a721b1 |
four. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief データのタグを得る.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mdatabase_tag () は、データ $MDB のタグ(シンボル)の配列を返す。配列の長さは
|
|
Packit Service |
a721b1 |
4 である。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@latexonly \IPAlabel{mdatabase_tag} @endlatexonly */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MSymbol *
|
|
Packit Service |
a721b1 |
mdatabase_tag (MDatabase *mdb)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
return mdb->tag;
|
|
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 |
*/
|