|
Packit Service |
a721b1 |
/* plist.c -- plist 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 m17nPlist
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@brief Property List objects and API for them.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
A @e property @e list (or @e plist for short) is a list of zero or
|
|
Packit Service |
a721b1 |
more properties. A property consists of a @e key and a @e value,
|
|
Packit Service |
a721b1 |
where key is a symbol and value is anything that can be cast to
|
|
Packit Service |
a721b1 |
<tt>(void *)</tt>.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
If the key of a property is a @e managing @e key, its @e value is
|
|
Packit Service |
a721b1 |
a @e managed @e object. A property list itself is a managed
|
|
Packit Service |
a721b1 |
objects.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
If each key of a plist is one of #Msymbol, #Mtext, #Minteger, and
|
|
Packit Service |
a721b1 |
#Mplist, the plist is called as @e well-formed and represented by
|
|
Packit Service |
a721b1 |
the following notation in the documentation.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@verbatim
|
|
Packit Service |
a721b1 |
PLIST ::= '(' ELEMENT * ')'
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
ELEMENT ::= INTEGER | SYMBOL | M-TEXT | PLIST
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
M-TEXT ::= '"' text data ... '"'
|
|
Packit Service |
a721b1 |
@endverbatim
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
For instance, if a plist has four elements; integer -20, symbol of
|
|
Packit Service |
a721b1 |
name "sym", M-text of contents "abc", and plist of integer 10 and
|
|
Packit Service |
a721b1 |
symbol of name "another-symbol", it is represented as this:
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
(-20 sym "abc" (10 another-symbol))
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
*/
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@addtogroup m17nPlist
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@brief プロパティリストオブジェクトとそれに関する API.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@e プロパティリスト (または @e plist) は 0
|
|
Packit Service |
a721b1 |
個以上のプロパティのリストである。プロパティは @e キー と @e 値
|
|
Packit Service |
a721b1 |
からなる。キーはシンボルであり、値は <tt>(void *)</tt>
|
|
Packit Service |
a721b1 |
にキャストできるものならば何でも良い。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
あるプロパティのキーが @e 管理キー ならば、その @e 値 は @e 管理下
|
|
Packit Service |
a721b1 |
@e オブジェクト
|
|
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 <stdio.h>
|
|
Packit Service |
a721b1 |
#include <string.h>
|
|
Packit Service |
a721b1 |
#include <ctype.h>
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#include "config.h"
|
|
Packit Service |
a721b1 |
#include "m17n.h"
|
|
Packit Service |
a721b1 |
#include "m17n-misc.h"
|
|
Packit Service |
a721b1 |
#include "internal.h"
|
|
Packit Service |
a721b1 |
#include "character.h"
|
|
Packit Service |
a721b1 |
#include "mtext.h"
|
|
Packit Service |
a721b1 |
#include "symbol.h"
|
|
Packit Service |
a721b1 |
#include "plist.h"
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static M17NObjectArray plist_table;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Set PLIST to a newly allocated plist object. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#define MPLIST_NEW(plist) \
|
|
Packit Service |
a721b1 |
do { \
|
|
Packit Service |
a721b1 |
M17N_OBJECT (plist, free_plist, MERROR_PLIST); \
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REGISTER (plist_table, plist); \
|
|
Packit Service |
a721b1 |
} while (0)
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Set the element of PLIST to KEY and VAL. If PLIST is an anchor,
|
|
Packit Service |
a721b1 |
append a new anchor. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#define MPLIST_SET(plist, key, val) \
|
|
Packit Service |
a721b1 |
do { \
|
|
Packit Service |
a721b1 |
MPLIST_KEY (plist) = (key); \
|
|
Packit Service |
a721b1 |
MPLIST_VAL (plist) = (val); \
|
|
Packit Service |
a721b1 |
if (! (plist)->next) \
|
|
Packit Service |
a721b1 |
MPLIST_NEW ((plist)->next); \
|
|
Packit Service |
a721b1 |
} while (0)
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Set the element of PLIST to KEY and VAL. PLIST must be an anchor.
|
|
Packit Service |
a721b1 |
Append a new anchor and set PLIST to that anchor. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#define MPLIST_SET_ADVANCE(plist, key, val) \
|
|
Packit Service |
a721b1 |
do { \
|
|
Packit Service |
a721b1 |
MPLIST_KEY (plist) = (key); \
|
|
Packit Service |
a721b1 |
MPLIST_VAL (plist) = (val); \
|
|
Packit Service |
a721b1 |
MPLIST_NEW ((plist)->next); \
|
|
Packit Service |
a721b1 |
plist = (plist)->next; \
|
|
Packit Service |
a721b1 |
} while (0)
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void
|
|
Packit Service |
a721b1 |
free_plist (void *object)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *plist = (MPlist *) object;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
do {
|
|
Packit Service |
a721b1 |
MPlist *next = plist->next;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (MPLIST_KEY (plist) != Mnil
|
|
Packit Service |
a721b1 |
&& MPLIST_KEY (plist)->managing_key)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (MPLIST_VAL (plist));
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREGISTER (plist_table, plist);
|
|
Packit Service |
a721b1 |
free (plist);
|
|
Packit Service |
a721b1 |
plist = next;
|
|
Packit Service |
a721b1 |
} while (plist && plist->control.ref_count == 1);
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (plist);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Load a plist from a string. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#define READ_CHUNK 0x10000
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
typedef struct
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
/* File pointer if the stream is associated with a file. Otherwise
|
|
Packit Service |
a721b1 |
NULL. */
|
|
Packit Service |
a721b1 |
FILE *fp;
|
|
Packit Service |
a721b1 |
int eof;
|
|
Packit Service |
a721b1 |
unsigned char buffer[READ_CHUNK];
|
|
Packit Service |
a721b1 |
unsigned char *p, *pend;
|
|
Packit Service |
a721b1 |
} MStream;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static int
|
|
Packit Service |
a721b1 |
get_byte (MStream *st)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int n;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! st->fp || st->eof)
|
|
Packit Service |
a721b1 |
return EOF;
|
|
Packit Service |
a721b1 |
n = fread (st->buffer, 1, READ_CHUNK, st->fp);
|
|
Packit Service |
a721b1 |
if (n <= 0)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
st->eof = 1;
|
|
Packit Service |
a721b1 |
return EOF;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
st->p = st->buffer + 1;
|
|
Packit Service |
a721b1 |
st->pend = st->buffer + n;
|
|
Packit Service |
a721b1 |
return st->buffer[0];
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#define GETC(st) ((st)->p < (st)->pend ? *(st)->p++ : get_byte (st))
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#define UNGETC(c, st) (--((st)->p))
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Mapping table for reading a number. Hexadecimal chars
|
|
Packit Service |
a721b1 |
(0..9,A..F,a..F) are mapped to the corresponding numbers.
|
|
Packit Service |
a721b1 |
Apostrophe (code 39) is mapped to 254. All the other bytes are
|
|
Packit Service |
a721b1 |
mapped to 255. */
|
|
Packit Service |
a721b1 |
unsigned char hex_mnemonic[256];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Mapping table for escaped characters. Mnemonic characters (e, b,
|
|
Packit Service |
a721b1 |
f, n, r, or t) that follows '\' are mapped to the corresponding
|
|
Packit Service |
a721b1 |
character code. All the other bytes are mapped to themselves. */
|
|
Packit Service |
a721b1 |
unsigned char escape_mnemonic[256];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Read an integer from the stream ST. It is assumed that we have
|
|
Packit Service |
a721b1 |
already read one character C. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static int
|
|
Packit Service |
a721b1 |
read_decimal (MStream *st, int c)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int num = 0;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
while (c >= '0' && c <= '9')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
num = (num * 10) + (c - '0');
|
|
Packit Service |
a721b1 |
c = GETC (st);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (c != EOF)
|
|
Packit Service |
a721b1 |
UNGETC (c, st);
|
|
Packit Service |
a721b1 |
return num;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Read an unsigned from the stream ST. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static unsigned
|
|
Packit Service |
a721b1 |
read_hexadesimal (MStream *st)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int c;
|
|
Packit Service |
a721b1 |
unsigned num = 0, n;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
while ((c = GETC (st)) != EOF
|
|
Packit Service |
a721b1 |
&& (n = hex_mnemonic[c]) < 16)
|
|
Packit Service |
a721b1 |
num = (num << 4) | n;
|
|
Packit Service |
a721b1 |
if (c != EOF)
|
|
Packit Service |
a721b1 |
UNGETC (c, st);
|
|
Packit Service |
a721b1 |
return num;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Read an M-text element from ST, and add it to LIST. Return a list
|
|
Packit Service |
a721b1 |
for the next element. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#define READ_MTEXT_BUF_SIZE 256
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static MPlist *
|
|
Packit Service |
a721b1 |
read_mtext_element (MPlist *plist, MStream *st, int skip)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
unsigned char buffer[READ_MTEXT_BUF_SIZE], *buf = buffer;
|
|
Packit Service |
a721b1 |
int nbytes = READ_MTEXT_BUF_SIZE;
|
|
Packit Service |
a721b1 |
int c, i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
i = 0;
|
|
Packit Service |
a721b1 |
while ((c = GETC (st)) != EOF && c != '"')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int is_char = 0;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (c == '\\')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
c = GETC (st);
|
|
Packit Service |
a721b1 |
if (c == EOF)
|
|
Packit Service |
a721b1 |
break;
|
|
Packit Service |
a721b1 |
if (c == '\n')
|
|
Packit Service |
a721b1 |
continue;
|
|
Packit Service |
a721b1 |
if (c == 'x' || c == 'u')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int next_c;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
c = read_hexadesimal (st);
|
|
Packit Service |
a721b1 |
next_c = GETC (st);
|
|
Packit Service |
a721b1 |
if (next_c != ' ')
|
|
Packit Service |
a721b1 |
UNGETC (next_c, st);
|
|
Packit Service |
a721b1 |
if (c >= 0x80)
|
|
Packit Service |
a721b1 |
is_char = 1;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
c = escape_mnemonic[c];
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! skip)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (i + MAX_UTF8_CHAR_BYTES + 1 >= nbytes)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (buf == buffer)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
nbytes *= 2;
|
|
Packit Service |
a721b1 |
buf = malloc (nbytes);
|
|
Packit Service |
a721b1 |
memcpy (buf, buffer, i);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
nbytes += READ_MTEXT_BUF_SIZE;
|
|
Packit Service |
a721b1 |
buf = realloc (buf, nbytes);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (is_char)
|
|
Packit Service |
a721b1 |
i += CHAR_STRING_UTF8 (c, buf);
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
buf[i++] = c;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! skip)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MText *mt;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
buf[i] = 0;
|
|
Packit Service |
a721b1 |
mt = mtext__from_data (buf, i, MTEXT_FORMAT_UTF_8, (buf == buffer));
|
|
Packit Service |
a721b1 |
if (buf != buffer)
|
|
Packit Service |
a721b1 |
mt->allocated = nbytes;
|
|
Packit Service |
a721b1 |
MPLIST_SET_ADVANCE (plist, Mtext, mt);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static int
|
|
Packit Service |
a721b1 |
read_character (MStream *st, int c)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
unsigned char buf[MAX_UTF8_CHAR_BYTES + 1];
|
|
Packit Service |
a721b1 |
int len = CHAR_BYTES_BY_HEAD (c);
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
buf[0] = c;
|
|
Packit Service |
a721b1 |
for (i = 1; i < len; i++)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
c = GETC (st);
|
|
Packit Service |
a721b1 |
if (c == EOF
|
|
Packit Service |
a721b1 |
|| (c & 0xC0) != 0x80)
|
|
Packit Service |
a721b1 |
break;
|
|
Packit Service |
a721b1 |
buf[i] = c;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (i == len)
|
|
Packit Service |
a721b1 |
c = STRING_CHAR_UTF8 (buf);
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
c = buf[0];
|
|
Packit Service |
a721b1 |
return c;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Read a symbol element from ST, and add it to LIST. Return a list
|
|
Packit Service |
a721b1 |
for the next element. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static MPlist *
|
|
Packit Service |
a721b1 |
read_symbol_element (MPlist *plist, MStream *st, int c, int skip)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
unsigned char buffer[1024];
|
|
Packit Service |
a721b1 |
int bufsize = 1024;
|
|
Packit Service |
a721b1 |
unsigned char *buf = buffer;
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
i = 0;
|
|
Packit Service |
a721b1 |
while (c != EOF
|
|
Packit Service |
a721b1 |
&& c > ' '
|
|
Packit Service |
a721b1 |
&& c != ')' && c != '(' && c != '"')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (i >= bufsize)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
bufsize *= 2;
|
|
Packit Service |
a721b1 |
if (buf == buffer)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MTABLE_MALLOC (buf, bufsize, MERROR_PLIST);
|
|
Packit Service |
a721b1 |
memcpy (buf, buffer, i);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
MTABLE_REALLOC (buf, bufsize, MERROR_PLIST);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (c == '\\')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
c = GETC (st);
|
|
Packit Service |
a721b1 |
if (c == EOF)
|
|
Packit Service |
a721b1 |
break;
|
|
Packit Service |
a721b1 |
c = escape_mnemonic[c];
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (! skip)
|
|
Packit Service |
a721b1 |
buf[i++] = c;
|
|
Packit Service |
a721b1 |
c = GETC (st);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (c > ' ')
|
|
Packit Service |
a721b1 |
UNGETC (c, st);
|
|
Packit Service |
a721b1 |
if (! skip)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
buf[i] = 0;
|
|
Packit Service |
a721b1 |
MPLIST_SET_ADVANCE (plist, Msymbol, msymbol ((char *) buf));
|
|
Packit Service |
a721b1 |
if (buf != buffer)
|
|
Packit Service |
a721b1 |
free (buf);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Read an integer element from ST, and add it to LIST. Return a
|
|
Packit Service |
a721b1 |
list for the next element. It is assumed that we have already
|
|
Packit Service |
a721b1 |
read the character C. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static MPlist *
|
|
Packit Service |
a721b1 |
read_integer_element (MPlist *plist, MStream *st, int c, int skip)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int num;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (c == '#')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
c = GETC (st);
|
|
Packit Service |
a721b1 |
if (c != 'x')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
UNGETC (c, st);
|
|
Packit Service |
a721b1 |
return read_symbol_element (plist, st, '#', skip);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
num = read_hexadesimal (st);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else if (c == '0')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
c = GETC (st);
|
|
Packit Service |
a721b1 |
num = (c == 'x' ? read_hexadesimal (st) : read_decimal (st, c));
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else if (c == '?')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
c = GETC (st);
|
|
Packit Service |
a721b1 |
if (c == EOF)
|
|
Packit Service |
a721b1 |
num = 0;
|
|
Packit Service |
a721b1 |
else if (c != '\\')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c))
|
|
Packit Service |
a721b1 |
num = c;
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
num = read_character (st, c);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
c = GETC (st);
|
|
Packit Service |
a721b1 |
if (c == EOF)
|
|
Packit Service |
a721b1 |
num = '\\';
|
|
Packit Service |
a721b1 |
else if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c))
|
|
Packit Service |
a721b1 |
num = escape_mnemonic[c];
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
num = read_character (st, c);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else if (c == '-')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
c = GETC (st);
|
|
Packit Service |
a721b1 |
if (c < '0' || c > '9')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
UNGETC (c, st);
|
|
Packit Service |
a721b1 |
return read_symbol_element (plist, st, '-', skip);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
num = - read_decimal (st, c);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
num = read_decimal (st, c);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! skip)
|
|
Packit Service |
a721b1 |
MPLIST_SET_ADVANCE (plist, Minteger, (void *) num);
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Read an element of various type from stream ST, and add it to LIST.
|
|
Packit Service |
a721b1 |
Return a list for the next element. The element type is decided by
|
|
Packit Service |
a721b1 |
the first token character found as below:
|
|
Packit Service |
a721b1 |
'(': plist
|
|
Packit Service |
a721b1 |
'"': mtext
|
|
Packit Service |
a721b1 |
'0'..'9', '-': integer
|
|
Packit Service |
a721b1 |
'?': integer representing character code
|
|
Packit Service |
a721b1 |
the other ASCII letters: symbol
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
If KEYS is not NULL, it is a plist contains target keys and stop
|
|
Packit Service |
a721b1 |
keys. In this caes, read only a plist whose key has value 1 in
|
|
Packit Service |
a721b1 |
KEYS, and return NULL when we encounter a plist whose key has value
|
|
Packit Service |
a721b1 |
0 in KEYS while skipping any other elements. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static MPlist *
|
|
Packit Service |
a721b1 |
read_element (MPlist *plist, MStream *st, MPlist *keys)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int c;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Skip separators and comments. */
|
|
Packit Service |
a721b1 |
while (1)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
while ((c = GETC (st)) != EOF && c <= ' ');
|
|
Packit Service |
a721b1 |
if (c != ';')
|
|
Packit Service |
a721b1 |
break;
|
|
Packit Service |
a721b1 |
while ((c = GETC (st)) != EOF && c != '\n');
|
|
Packit Service |
a721b1 |
if (c == EOF)
|
|
Packit Service |
a721b1 |
break;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (c == '(')
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *pl, *p;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPLIST_NEW (pl);
|
|
Packit Service |
a721b1 |
p = pl;
|
|
Packit Service |
a721b1 |
p = read_element (p, st, NULL);
|
|
Packit Service |
a721b1 |
if (keys && p && MPLIST_SYMBOL_P (pl))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (MPLIST_TAIL_P (keys))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
while ((p = read_element (p, st, NULL)));
|
|
Packit Service |
a721b1 |
MPLIST_SET_ADVANCE (plist, Mplist, pl);
|
|
Packit Service |
a721b1 |
return NULL;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *p0 = keys;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPLIST_FIND (p0, MPLIST_SYMBOL (pl));
|
|
Packit Service |
a721b1 |
if (! MPLIST_TAIL_P (p0) && ! MPLIST_VAL (p0))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (pl);
|
|
Packit Service |
a721b1 |
return NULL;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
while ((p = read_element (p, st, NULL)));
|
|
Packit Service |
a721b1 |
if (! MPLIST_TAIL_P (p0))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPLIST_SET_ADVANCE (plist, Mplist, pl);
|
|
Packit Service |
a721b1 |
return NULL;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (pl);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (p)
|
|
Packit Service |
a721b1 |
while ((p = read_element (p, st, NULL)));
|
|
Packit Service |
a721b1 |
MPLIST_SET_ADVANCE (plist, Mplist, pl);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (c == '"')
|
|
Packit Service |
a721b1 |
return (read_mtext_element (plist, st, keys ? 1 : 0));
|
|
Packit Service |
a721b1 |
if ((c >= '0' && c <= '9') || c == '-' || c == '?' || c == '#')
|
|
Packit Service |
a721b1 |
return (read_integer_element (plist, st, c, keys ? 1 : 0));
|
|
Packit Service |
a721b1 |
if (c == EOF || c == ')')
|
|
Packit Service |
a721b1 |
return NULL;
|
|
Packit Service |
a721b1 |
return (read_symbol_element (plist, st, c, keys ? 1 : 0));
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#define PUTC(MT, C) \
|
|
Packit Service |
a721b1 |
do { \
|
|
Packit Service |
a721b1 |
if (MT) \
|
|
Packit Service |
a721b1 |
mtext_cat_char ((MT), (C)); \
|
|
Packit Service |
a721b1 |
else \
|
|
Packit Service |
a721b1 |
putc ((C), mdebug__output); \
|
|
Packit Service |
a721b1 |
} while (0);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
#define PUTS(MT, STR) \
|
|
Packit Service |
a721b1 |
do { \
|
|
Packit Service |
a721b1 |
if (MT) \
|
|
Packit Service |
a721b1 |
MTEXT_CAT_ASCII ((MT), (STR)); \
|
|
Packit Service |
a721b1 |
else \
|
|
Packit Service |
a721b1 |
fputs ((STR), mdebug__output); \
|
|
Packit Service |
a721b1 |
} while (0)
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void
|
|
Packit Service |
a721b1 |
write_symbol (MText *mt, MSymbol sym)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (sym == Mnil)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
PUTS (mt, "nil");
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
char *name = MSYMBOL_NAME (sym);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (isdigit (*name))
|
|
Packit Service |
a721b1 |
PUTC (mt, '\\');
|
|
Packit Service |
a721b1 |
while (*name)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (*name <= ' ' || *name == '\\' || *name == '"'
|
|
Packit Service |
a721b1 |
|| *name == '(' || *name == ')')
|
|
Packit Service |
a721b1 |
PUTC (mt, '\\');
|
|
Packit Service |
a721b1 |
PUTC (mt, *name);
|
|
Packit Service |
a721b1 |
name++;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
static void
|
|
Packit Service |
a721b1 |
write_element (MText *mt, MPlist *plist, int indent)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (MPLIST_SYMBOL_P (plist))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
write_symbol (mt, MPLIST_SYMBOL (plist));
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else if (MPLIST_INTEGER_P (plist))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int num = MPLIST_INTEGER (plist);
|
|
Packit Service |
a721b1 |
char buf[128];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
sprintf (buf, "%d", num);
|
|
Packit Service |
a721b1 |
PUTS (mt, buf);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else if (MPLIST_PLIST_P (plist)
|
|
Packit Service |
a721b1 |
|| MPLIST_NESTED_P (plist))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *pl;
|
|
Packit Service |
a721b1 |
int newline = 0;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (MPLIST_NESTED_P (plist))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
write_symbol (mt, MPLIST_KEY (plist));
|
|
Packit Service |
a721b1 |
PUTC (mt, ':');
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
plist = MPLIST_PLIST (plist);
|
|
Packit Service |
a721b1 |
PUTC (mt, '(');
|
|
Packit Service |
a721b1 |
if (indent >= 0)
|
|
Packit Service |
a721b1 |
indent++;
|
|
Packit Service |
a721b1 |
MPLIST_DO (pl, plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (pl != plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (indent > 0 && (MPLIST_PLIST_P (pl) || MPLIST_MTEXT_P (pl)))
|
|
Packit Service |
a721b1 |
newline = 1;
|
|
Packit Service |
a721b1 |
if (newline)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
PUTC (mt, '\n');
|
|
Packit Service |
a721b1 |
for (i = 1; i < indent; i++)
|
|
Packit Service |
a721b1 |
PUTC (mt, ' ');
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
PUTC (mt, ' ');
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
write_element (mt, pl, indent);
|
|
Packit Service |
a721b1 |
if (indent >= 0)
|
|
Packit Service |
a721b1 |
newline = (MPLIST_PLIST_P (pl) || MPLIST_MTEXT_P (pl));
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
PUTC (mt, ')');
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else if (MPLIST_MTEXT_P (plist))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MText *this_mt = MPLIST_MTEXT (plist);
|
|
Packit Service |
a721b1 |
int from = 0, to = mtext_nchars (this_mt);
|
|
Packit Service |
a721b1 |
int stop1 = 0, stop2 = 0;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! mt && this_mt->format > MTEXT_FORMAT_UTF_8)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
this_mt = mtext_dup (this_mt);
|
|
Packit Service |
a721b1 |
mtext__adjust_format (this_mt, MTEXT_FORMAT_UTF_8);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
PUTC (mt, '"');
|
|
Packit Service |
a721b1 |
while (1)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int stop, escaped;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (from == stop1)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if ((stop1 = mtext_character (this_mt, from, to, '"')) < 0)
|
|
Packit Service |
a721b1 |
stop1 = to;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (from == stop2)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if ((stop2 = mtext_character (this_mt, from, to, '\\')) < 0)
|
|
Packit Service |
a721b1 |
stop2 = to;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (stop1 < stop2)
|
|
Packit Service |
a721b1 |
stop = stop1++, escaped = '"';
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
stop = stop2++, escaped = '\\';
|
|
Packit Service |
a721b1 |
if (mt)
|
|
Packit Service |
a721b1 |
mtext_copy (mt, mtext_nchars (mt), this_mt, from, stop);
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
unsigned char *data = MTEXT_DATA (this_mt);
|
|
Packit Service |
a721b1 |
unsigned char *beg = data + mtext__char_to_byte (this_mt, from);
|
|
Packit Service |
a721b1 |
unsigned char *end = data + mtext__char_to_byte (this_mt, stop);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
while (beg < end)
|
|
Packit Service |
a721b1 |
putc (*beg, mdebug__output), beg++;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (stop == to)
|
|
Packit Service |
a721b1 |
break;
|
|
Packit Service |
a721b1 |
PUTC (mt, '\\');
|
|
Packit Service |
a721b1 |
PUTC (mt, escaped);
|
|
Packit Service |
a721b1 |
from = stop + 1;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
PUTC (mt, '"');
|
|
Packit Service |
a721b1 |
if (this_mt != MPLIST_MTEXT (plist))
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (this_mt);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else if (MPLIST_STRING_P (plist))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
char *str = MPLIST_STRING (plist);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (mt)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MText *this_mt = mtext__from_data (str, strlen (str),
|
|
Packit Service |
a721b1 |
MTEXT_FORMAT_UTF_8, 0);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
mtext_copy (mt, mtext_nchars (mt),
|
|
Packit Service |
a721b1 |
this_mt, 0, mtext_nchars (this_mt));
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (this_mt);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, "%s", str);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
char buf[128];
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
write_symbol (mt, MPLIST_KEY (plist));
|
|
Packit Service |
a721b1 |
PUTC (mt, ':');
|
|
Packit Service |
a721b1 |
sprintf (buf, "%04X", (unsigned) MPLIST_VAL (plist));
|
|
Packit Service |
a721b1 |
PUTS (mt, buf);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Internal API */
|
|
Packit Service |
a721b1 |
int
|
|
Packit Service |
a721b1 |
mplist__init ()
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int i;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
M17N_OBJECT_ADD_ARRAY (plist_table, "Plist");
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
Minteger = msymbol ("integer");
|
|
Packit Service |
a721b1 |
Mplist = msymbol_as_managing_key ("plist");
|
|
Packit Service |
a721b1 |
Mtext = msymbol_as_managing_key ("mtext");
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
for (i = 0; i < 256; i++)
|
|
Packit Service |
a721b1 |
hex_mnemonic[i] = 255;
|
|
Packit Service |
a721b1 |
for (i = '0'; i <= '9'; i++)
|
|
Packit Service |
a721b1 |
hex_mnemonic[i] = i - '0';
|
|
Packit Service |
a721b1 |
for (i = 'A'; i <= 'F'; i++)
|
|
Packit Service |
a721b1 |
hex_mnemonic[i] = i - 'A' + 10;
|
|
Packit Service |
a721b1 |
for (i = 'a'; i <= 'f'; i++)
|
|
Packit Service |
a721b1 |
hex_mnemonic[i] = i - 'a' + 10;
|
|
Packit Service |
a721b1 |
for (i = 0; i < 256; i++)
|
|
Packit Service |
a721b1 |
escape_mnemonic[i] = i;
|
|
Packit Service |
a721b1 |
escape_mnemonic['e'] = 27;
|
|
Packit Service |
a721b1 |
escape_mnemonic['b'] = '\b';
|
|
Packit Service |
a721b1 |
escape_mnemonic['f'] = '\f';
|
|
Packit Service |
a721b1 |
escape_mnemonic['n'] = '\n';
|
|
Packit Service |
a721b1 |
escape_mnemonic['r'] = '\r';
|
|
Packit Service |
a721b1 |
escape_mnemonic['t'] = '\t';
|
|
Packit Service |
a721b1 |
escape_mnemonic['\\'] = '\\';
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
return 0;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
void
|
|
Packit Service |
a721b1 |
mplist__fini (void)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/* Parse this form of PLIST:
|
|
Packit Service |
a721b1 |
(symbol:KEY1 TYPE1:VAL1 symbol:KEY2 TYPE2:VAL2 ...)
|
|
Packit Service |
a721b1 |
and return a newly created plist of this form:
|
|
Packit Service |
a721b1 |
(KEY1:VAL1 KEY2:VAL2 ...) */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist__from_plist (MPlist *plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *pl, *p;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPLIST_NEW (pl);
|
|
Packit Service |
a721b1 |
p = pl;
|
|
Packit Service |
a721b1 |
while (! MPLIST_TAIL_P (plist))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MSymbol key, type;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! MPLIST_SYMBOL_P (plist))
|
|
Packit Service |
a721b1 |
MERROR (MERROR_PLIST, NULL);
|
|
Packit Service |
a721b1 |
key = MPLIST_SYMBOL (plist);
|
|
Packit Service |
a721b1 |
plist = MPLIST_NEXT (plist);
|
|
Packit Service |
a721b1 |
type = MPLIST_KEY (plist);
|
|
Packit Service |
a721b1 |
if (type->managing_key && MPLIST_VAL (plist))
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF (MPLIST_VAL (plist));
|
|
Packit Service |
a721b1 |
if (type == Mplist)
|
|
Packit Service |
a721b1 |
MPLIST_SET_NESTED_P (p);
|
|
Packit Service |
a721b1 |
MPLIST_SET_ADVANCE (p, key, MPLIST_VAL (plist));
|
|
Packit Service |
a721b1 |
plist = MPLIST_NEXT (plist);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return pl;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Parse this form of PLIST:
|
|
Packit Service |
a721b1 |
((symbol:KEY1 ANY:VAL1 ... ) (symbol:KEY2 ANY:VAL2 ...) ...)
|
|
Packit Service |
a721b1 |
and return a newly created plist of this form:
|
|
Packit Service |
a721b1 |
(KEY1:(ANY:VAL1 ...) KEY2:(ANY:VAL2 ...) ...)
|
|
Packit Service |
a721b1 |
ANY can be any type. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist__from_alist (MPlist *plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *pl, *p;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPLIST_NEW (pl);
|
|
Packit Service |
a721b1 |
p = pl;
|
|
Packit Service |
a721b1 |
MPLIST_DO (plist, plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *elt;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (! MPLIST_PLIST_P (plist))
|
|
Packit Service |
a721b1 |
MERROR (MERROR_PLIST, NULL);
|
|
Packit Service |
a721b1 |
elt = MPLIST_PLIST (plist);
|
|
Packit Service |
a721b1 |
if (! MPLIST_SYMBOL_P (elt))
|
|
Packit Service |
a721b1 |
MERROR (MERROR_PLIST, NULL);
|
|
Packit Service |
a721b1 |
MPLIST_SET_NESTED_P (p);
|
|
Packit Service |
a721b1 |
MPLIST_SET_ADVANCE (p, MPLIST_SYMBOL (elt), MPLIST_NEXT (elt));
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF (MPLIST_NEXT (elt));
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return pl;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist__from_file (FILE *fp, MPlist *keys)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *plist, *pl;
|
|
Packit Service |
a721b1 |
MStream st;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
st.fp = fp;
|
|
Packit Service |
a721b1 |
st.eof = 0;
|
|
Packit Service |
a721b1 |
st.p = st.pend = st.buffer;
|
|
Packit Service |
a721b1 |
MPLIST_NEW (plist);
|
|
Packit Service |
a721b1 |
pl = plist;
|
|
Packit Service |
a721b1 |
while ((pl = read_element (pl, &st, keys)));
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/** Parse $STR of $N bytes and return a property list object. $FORMAT
|
|
Packit Service |
a721b1 |
must be either @c MTEXT_FORMAT_US_ASCII or @c MTEXT_FORMAT_UTF_8,
|
|
Packit Service |
a721b1 |
and controls how to produce @c STRING or @c M-TEXT in the
|
|
Packit Service |
a721b1 |
following definition.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The syntax of $STR is as follows.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
PLIST ::= '(' ELEMENT * ')'
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
ELEMENT ::= SYMBOL | INTEGER | UNSIGNED | STRING | M-TEXT | PLIST
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
SYMBOL ::= ascii-character-sequence
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
INTEGER ::= '-' ? [ '0' | .. | '9' ]+
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
UNSIGNED ::= '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
M-TEXT ::= '"' byte-sequence '"'
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
Each kind of @c ELEMENT is assigned one of these keys:
|
|
Packit Service |
a721b1 |
@c Msymbol, @c Mint, @c Munsigned, @c Mtext, @c Mplist
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
In an ascii-character-sequence, a backslush (\) is used as the escape
|
|
Packit Service |
a721b1 |
character, which means that, for instance, <tt>"abc\ def"</tt>
|
|
Packit Service |
a721b1 |
produces a symbol whose name is of length seven with the fourth
|
|
Packit Service |
a721b1 |
character being a space.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
In a byte-sequence, "\r", "\n", "\e", and "\t" are replaced by CR,
|
|
Packit Service |
a721b1 |
NL, ESC, and TAB character respectively, "\xXX" are replaced by
|
|
Packit Service |
a721b1 |
byte 0xXX. After this replacement, the byte-sequence is decoded
|
|
Packit Service |
a721b1 |
into M-TEXT by $CODING. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist__from_string (unsigned char *str, int n)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *plist, *pl;
|
|
Packit Service |
a721b1 |
MStream st;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
st.fp = NULL;
|
|
Packit Service |
a721b1 |
st.eof = 0;
|
|
Packit Service |
a721b1 |
st.p = str;
|
|
Packit Service |
a721b1 |
st.pend = str + n;
|
|
Packit Service |
a721b1 |
MPLIST_NEW (plist);
|
|
Packit Service |
a721b1 |
pl = plist;
|
|
Packit Service |
a721b1 |
while ((pl = read_element (pl, &st, NULL)));
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
int
|
|
Packit Service |
a721b1 |
mplist__serialize (MText *mt, MPlist *plist, int pretty)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *pl;
|
|
Packit Service |
a721b1 |
int separator = pretty ? '\n' : ' ';
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPLIST_DO (pl, plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (pl != plist)
|
|
Packit Service |
a721b1 |
mtext_cat_char (mt, separator);
|
|
Packit Service |
a721b1 |
write_element (mt, pl, pretty ? 0 : -1);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
if (pretty)
|
|
Packit Service |
a721b1 |
mtext_cat_char (mt, separator);
|
|
Packit Service |
a721b1 |
return 0;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/**en
|
|
Packit Service |
a721b1 |
@brief Concatenate two plists.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist__conc () function concatenates plist $TAIL at the end of
|
|
Packit Service |
a721b1 |
plist $PLIST and return $PLIST. If $TAIL is empty, return $PLIST
|
|
Packit Service |
a721b1 |
without modifying it. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist__conc (MPlist *plist, MPlist *tail)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *pl;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (MPLIST_TAIL_P (tail))
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
MPLIST_DO (pl, plist);
|
|
Packit Service |
a721b1 |
MPLIST_KEY (pl) = MPLIST_KEY (tail);
|
|
Packit Service |
a721b1 |
MPLIST_VAL (pl) = MPLIST_VAL (tail);
|
|
Packit Service |
a721b1 |
if (MPLIST_KEY (pl)->managing_key && MPLIST_VAL (pl))
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF (MPLIST_VAL (pl));
|
|
Packit Service |
a721b1 |
if (MPLIST_NESTED_P (tail))
|
|
Packit Service |
a721b1 |
MPLIST_SET_NESTED_P (pl);
|
|
Packit Service |
a721b1 |
tail = MPLIST_NEXT (tail);
|
|
Packit Service |
a721b1 |
MPLIST_NEXT (pl) = tail;
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF (tail);
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
/**en
|
|
Packit Service |
a721b1 |
@brief Discard a property at the beginning of a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist__pop_unref () function removes a property at the
|
|
Packit Service |
a721b1 |
beginning of property list $PLIST, and if the property value is a
|
|
Packit Service |
a721b1 |
managed object, unref it. As a result, the second key and value
|
|
Packit Service |
a721b1 |
of the original $PLIST become the first of those of the new
|
|
Packit Service |
a721b1 |
$PLIST. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
void
|
|
Packit Service |
a721b1 |
mplist__pop_unref (MPlist *plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MSymbol key;
|
|
Packit Service |
a721b1 |
void *val;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (MPLIST_TAIL_P (plist))
|
|
Packit Service |
a721b1 |
return;
|
|
Packit Service |
a721b1 |
key = MPLIST_KEY (plist);
|
|
Packit Service |
a721b1 |
val = mplist_pop (plist);
|
|
Packit Service |
a721b1 |
if (key->managing_key)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (val);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/**en
|
|
Packit Service |
a721b1 |
@brief Search for an element of an alist represented by a plist.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist__assq () function treats $PLIST as an association list
|
|
Packit Service |
a721b1 |
(elements are plists (key is #Mplist) whose first element is a
|
|
Packit Service |
a721b1 |
symbol (key is #Msymbol)), and find an element whose first element
|
|
Packit Service |
a721b1 |
has key #Msymbol and value $KEY.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
Non-plist elements of $PLIST are ignored.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
This function returns a found element or NULL if no element
|
|
Packit Service |
a721b1 |
matches with $KEY. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist__assq (MPlist *plist, MSymbol key)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPLIST_DO (plist, plist)
|
|
Packit Service |
a721b1 |
if (MPLIST_PLIST_P (plist))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *pl = MPLIST_PLIST (plist);
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == key)
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return NULL;
|
|
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 m17nPlist */
|
|
Packit Service |
a721b1 |
/*** @{ */
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Symbol whose name is "integer".
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The symbol @c Minteger has the name <tt>"integer"</tt>. The value
|
|
Packit Service |
a721b1 |
of a property whose key is @c Minteger must be an integer. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief "integer" を名前として持つシンボル.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
シンボル @c Minteger は <tt>"integer"</tt> という名前を持つ。キーが
|
|
Packit Service |
a721b1 |
@c Minteger であるプロパティの値は整数値でなくてはならない。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MSymbol Minteger;
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Symbol whose name is "plist".
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The symbol @c Mplist has the name <tt>"plist"</tt>. It is a
|
|
Packit Service |
a721b1 |
managing key. A value of a property whose key is @c Mplist must
|
|
Packit Service |
a721b1 |
be a plist. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief "plist" を名前として持つシンボル.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
シンボル @c Mplist は <tt>"plist"</tt>
|
|
Packit Service |
a721b1 |
という名前を持つ。これは管理キーである。キーが @c Mplist
|
|
Packit Service |
a721b1 |
であるプロパティの値は plist でなくてはならない。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MSymbol Mplist;
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Symbol whose name is "mtext".
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The symbol @c Mtext has the name <tt>"mtext"</tt>. It is a
|
|
Packit Service |
a721b1 |
managing key. A value of a property whose key is @c Mtext must be an
|
|
Packit Service |
a721b1 |
M-text. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief "mtext" を名前として持つシンボル.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
シンボル @c Mtext は <tt>"mtext"</tt>
|
|
Packit Service |
a721b1 |
という名前を持つ管理キーである。キーが @c Mtext
|
|
Packit Service |
a721b1 |
であるプロパティの値は M-text でなくてはならない。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MSymbol Mtext;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Create a property list object.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist () function returns a newly created property list
|
|
Packit Service |
a721b1 |
object of length zero.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@returns
|
|
Packit Service |
a721b1 |
This function returns a newly created property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@errors
|
|
Packit Service |
a721b1 |
This function never fails. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリストオブジェクトを作る.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist () は長さ 0 のプロパティリストオブジェクトを新しく作って返す。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@returns
|
|
Packit Service |
a721b1 |
この関数は新しく作られたプロパティリストオブジェクトを返す。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@errors
|
|
Packit Service |
a721b1 |
この関数は決して失敗しない。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist (void)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *plist;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPLIST_NEW (plist);
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Copy a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_copy () function copies property list $PLIST. In the
|
|
Packit Service |
a721b1 |
copy, the values are the same as those of $PLIST.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
This function returns a newly created plist which is a copy of
|
|
Packit Service |
a721b1 |
$PLIST.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@errors
|
|
Packit Service |
a721b1 |
This function never fails. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリストをコピーする.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_copy () はプロパティリスト $PLIST
|
|
Packit Service |
a721b1 |
をコピーする。コピーのすべての値はコピー元 $PLIST の値と同じである。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
この関数は新しく作られた、$PLIST のコピーであるプロパティリストを返す。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@errors
|
|
Packit Service |
a721b1 |
この関数は決して失敗しない。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist_copy (MPlist *plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *copy = mplist (), *pl = copy;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPLIST_DO (plist, plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (MPLIST_NESTED_P (plist))
|
|
Packit Service |
a721b1 |
MPLIST_SET_NESTED_P (pl);
|
|
Packit Service |
a721b1 |
pl = mplist_add (pl, MPLIST_KEY (plist), MPLIST_VAL (plist));
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return copy;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Set the value of a property in a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_put () function searches property list $PLIST
|
|
Packit Service |
a721b1 |
from the beginning for a property whose key is $KEY. If such a
|
|
Packit Service |
a721b1 |
property is found, its value is changed to $VALUE. Otherwise, a
|
|
Packit Service |
a721b1 |
new property whose key is $KEY and value is $VALUE is appended at
|
|
Packit Service |
a721b1 |
the end of $PLIST. See the documentation of mplist_add () for
|
|
Packit Service |
a721b1 |
the restriction on $KEY and $VAL.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
If $KEY is a managing key, $VAL must be a managed object. In this
|
|
Packit Service |
a721b1 |
case, the reference count of the old value, if not @c NULL, is
|
|
Packit Service |
a721b1 |
decremented by one, and that of $VAL is incremented by one.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
If the operation was successful, mplist_put () returns a sublist of
|
|
Packit Service |
a721b1 |
$PLIST whose first element is the just modified or added one.
|
|
Packit Service |
a721b1 |
Otherwise, it returns @c NULL. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリスト中のプロパティの値を設定する.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_put () はプロパティリスト $PLIST を始めから探して、キーが
|
|
Packit Service |
a721b1 |
$KEY であるプロパティを見つける。見つかれば、その値を $VALUE
|
|
Packit Service |
a721b1 |
に変更する。見つからなければ、キーが $KEY で値が $VALUE
|
|
Packit Service |
a721b1 |
である新しいプロパティが $PLIST の末尾に追加される。$KEY と $VAL
|
|
Packit Service |
a721b1 |
に対する制限については、mplist_add () の説明を参照。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
$KEY が管理キーならば、
|
|
Packit Service |
a721b1 |
$VAL は管理下オブジェクトでなくてはならない。この場合、古い値の参照数は
|
|
Packit Service |
a721b1 |
@c NULL でなければ 1 減らされ、$VAL の参照数は 1 増やされる。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
処理が成功すれば mplist_put () は変更されたか追加された要素から始まる
|
|
Packit Service |
a721b1 |
$PLIST の部分リストを返す。そうでなければ @c NULL を返す。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist_put (MPlist *plist, MSymbol key, void *val)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (key == Mnil)
|
|
Packit Service |
a721b1 |
MERROR (MERROR_PLIST, NULL);
|
|
Packit Service |
a721b1 |
MPLIST_FIND (plist, key);
|
|
Packit Service |
a721b1 |
if (key->managing_key)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (! MPLIST_TAIL_P (plist))
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (MPLIST_VAL (plist));
|
|
Packit Service |
a721b1 |
if (val)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF (val);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
MPLIST_SET (plist, key, val);
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Get the value of a property in a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_get () function searches property list $PLIST from the
|
|
Packit Service |
a721b1 |
beginning for a property whose key is $KEY. If such a property is
|
|
Packit Service |
a721b1 |
found, its value is returned as the type of <tt>(void *)</tt>. If
|
|
Packit Service |
a721b1 |
not found, @c NULL is returned.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
When @c NULL is returned, there are two possibilities: one is the
|
|
Packit Service |
a721b1 |
case where no property is found (see above); the other is the case
|
|
Packit Service |
a721b1 |
where a property is found and its value is @c NULL. In case that
|
|
Packit Service |
a721b1 |
these two cases must be distinguished, use the mplist_find_by_key ()
|
|
Packit Service |
a721b1 |
function. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリスト中のプロパティの値を得る.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_get () は、プロパティリスト $PLIST を始めから探して、キー
|
|
Packit Service |
a721b1 |
が $KEY であるプロパティを見つける。見つかれば、その値を
|
|
Packit Service |
a721b1 |
<tt>(void *)</tt> 型で返す。見つからなければ @c NULL を返す。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@c NULL が返った際には二つの可能性がある:
|
|
Packit Service |
a721b1 |
上記のようにプロパティが見つからなかった場合と、プロパティが見つかり、その値が
|
|
Packit Service |
a721b1 |
@c NULL である場合である。これらを区別する必要がある場合には関数
|
|
Packit Service |
a721b1 |
mplist_find_by_key () を使うこと。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***
|
|
Packit Service |
a721b1 |
@seealso
|
|
Packit Service |
a721b1 |
mplist_find_by_key () */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
void *
|
|
Packit Service |
a721b1 |
mplist_get (MPlist *plist, MSymbol key)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPLIST_FIND (plist, key);
|
|
Packit Service |
a721b1 |
return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_VAL (plist));
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Set the value (function pointer) of a property in a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_put_func () function is similar to mplist_put () but for
|
|
Packit Service |
a721b1 |
setting function pointer $FUNC in property list $PLIST for key
|
|
Packit Service |
a721b1 |
$KEY. $KEY must not be a managing key. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリスト中のプロパティに関数ポインタである値を設定する.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_put_func () は関数 mplist_put () 同様、プロパティリスト $PLIST
|
|
Packit Service |
a721b1 |
中でキーが $KEY であるプロパティに値を設定する。但しその値は関数ポインタ
|
|
Packit Service |
a721b1 |
$FUNC である。$KEY は管理キーであってはならない。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***
|
|
Packit Service |
a721b1 |
@seealso
|
|
Packit Service |
a721b1 |
mplist_put (), M17N_FUNC () */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist_put_func (MPlist *plist, MSymbol key, M17NFunc func)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (key == Mnil || key->managing_key)
|
|
Packit Service |
a721b1 |
MERROR (MERROR_PLIST, NULL);
|
|
Packit Service |
a721b1 |
MPLIST_FIND (plist, key);
|
|
Packit Service |
a721b1 |
MPLIST_KEY (plist) = key;
|
|
Packit Service |
a721b1 |
MPLIST_FUNC (plist) = func;
|
|
Packit Service |
a721b1 |
MPLIST_SET_VAL_FUNC_P (plist);
|
|
Packit Service |
a721b1 |
if (! plist->next)
|
|
Packit Service |
a721b1 |
MPLIST_NEW ((plist)->next);
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Get the value (function pointer) of a property in a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_get_func () function is similar to mplist_get () but for
|
|
Packit Service |
a721b1 |
getting a function pointer from property list $PLIST by key $KEY. */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリストからプロパティの関数ポインタである値を得る.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_get_func () は関数 mplist_get () と同様に、プロパティリ
|
|
Packit Service |
a721b1 |
スト $PLIST 中でキーが $KEY であるプロパティの値、但し関数ポインタ、
|
|
Packit Service |
a721b1 |
を得る。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***
|
|
Packit Service |
a721b1 |
@seealso
|
|
Packit Service |
a721b1 |
mplist_get () */
|
|
Packit Service |
a721b1 |
M17NFunc
|
|
Packit Service |
a721b1 |
mplist_get_func (MPlist *plist, MSymbol key)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPLIST_FIND (plist, key);
|
|
Packit Service |
a721b1 |
return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_FUNC (plist));
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Add a property at the end of a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_add () function appends at the end of property list
|
|
Packit Service |
a721b1 |
$PLIST a property whose key is $KEY and value is $VAL. $KEY can
|
|
Packit Service |
a721b1 |
be any symbol other than @c Mnil.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
If $KEY is a managing key, $VAL must be a managed object. In this
|
|
Packit Service |
a721b1 |
case, the reference count of $VAL is incremented by one.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
If the operation was successful, mplist_add () returns a sublist of
|
|
Packit Service |
a721b1 |
$PLIST whose first element is the just added one. Otherwise, it
|
|
Packit Service |
a721b1 |
returns @c NULL. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリスト末尾にプロパティを追加する.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_add () は、プロパティリスト $PLIST の末尾にキーが $KEY
|
|
Packit Service |
a721b1 |
で値が $VAL であるプロパティを追加する。$KEY は、@c Mnil 以外の任意のシンボルでよい。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
$KEY が管理キーならば、$VAL は管理下オブジェクトでなくてはならない。この場合、
|
|
Packit Service |
a721b1 |
$VAL の参照数は 1 増やされる。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
処理が成功すれば mplist_add () は追加された要素から始まる $PLIST
|
|
Packit Service |
a721b1 |
の部分リストを返す。そうでなければ @c NULL を返す。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist_add (MPlist *plist, MSymbol key, void *val)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (key == Mnil)
|
|
Packit Service |
a721b1 |
MERROR (MERROR_PLIST, NULL);
|
|
Packit Service |
a721b1 |
MPLIST_FIND (plist, Mnil);
|
|
Packit Service |
a721b1 |
if (val && key->managing_key)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF (val);
|
|
Packit Service |
a721b1 |
MPLIST_KEY (plist) = key;
|
|
Packit Service |
a721b1 |
MPLIST_VAL (plist) = val;
|
|
Packit Service |
a721b1 |
MPLIST_NEW (plist->next);
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Add a property at the beginning of a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_push () function inserts at the beginning of property
|
|
Packit Service |
a721b1 |
list $PLIST a property whose key is $KEY and value is $VAL.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
If $KEY is a managing key, $VAL must be a managed object. In this
|
|
Packit Service |
a721b1 |
case, the reference count of $VAL is incremented by one.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
If the operation was successful, this function returns $PLIST.
|
|
Packit Service |
a721b1 |
Otherwise, it returns @c NULL. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリストの先頭にプロパティを挿入する.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_push () はプロパティリスト $PLIST の先頭にキーが $KEY
|
|
Packit Service |
a721b1 |
で値が $VAL であるオブジェクトを挿入する。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
$KEY が管理キーならば、$VAL は管理下オブジェクトでなくてはならない。この場合、
|
|
Packit Service |
a721b1 |
$VAL の参照数は 1 増やされる。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
処理が成功すればこの関数は $PLIST を返し、そうでなければ@c NULL
|
|
Packit Service |
a721b1 |
を返す。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist_push (MPlist *plist, MSymbol key, void *val)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *pl;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (key == Mnil)
|
|
Packit Service |
a721b1 |
MERROR (MERROR_PLIST, NULL);
|
|
Packit Service |
a721b1 |
MPLIST_NEW (pl);
|
|
Packit Service |
a721b1 |
MPLIST_KEY (pl) = MPLIST_KEY (plist);
|
|
Packit Service |
a721b1 |
MPLIST_VAL (pl) = MPLIST_VAL (plist);
|
|
Packit Service |
a721b1 |
if (MPLIST_NESTED_P (plist))
|
|
Packit Service |
a721b1 |
MPLIST_SET_NESTED_P (pl);
|
|
Packit Service |
a721b1 |
MPLIST_NEXT (pl) = MPLIST_NEXT (plist);
|
|
Packit Service |
a721b1 |
plist->next = pl;
|
|
Packit Service |
a721b1 |
if (val && key->managing_key)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF (val);
|
|
Packit Service |
a721b1 |
MPLIST_KEY (plist) = key;
|
|
Packit Service |
a721b1 |
MPLIST_VAL (plist) = val;
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Remove a property at the beginning of a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_pop () function removes a property at the beginning of
|
|
Packit Service |
a721b1 |
property list $PLIST. As a result, the second key and value of
|
|
Packit Service |
a721b1 |
the $PLIST become the first ones.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
If the operation was successful, this function return the value of
|
|
Packit Service |
a721b1 |
the just popped property. Otherwise, it returns @c NULL. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリストの先頭からプロパティを削除する.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_pop () はプロパティリスト $PLIST の先頭のプロパティを削
|
|
Packit Service |
a721b1 |
除する。結果として、元の2番目のキーと値が先頭のキーと値になる。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
処理に成功すれば、この関数は削除されたプロパティの値を返す。そうでなければ
|
|
Packit Service |
a721b1 |
@c NULL を返す。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
void *
|
|
Packit Service |
a721b1 |
mplist_pop (MPlist *plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
void *val;
|
|
Packit Service |
a721b1 |
MPlist *next;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (MPLIST_TAIL_P (plist))
|
|
Packit Service |
a721b1 |
return NULL;
|
|
Packit Service |
a721b1 |
val = MPLIST_VAL (plist);
|
|
Packit Service |
a721b1 |
next = MPLIST_NEXT (plist);
|
|
Packit Service |
a721b1 |
MPLIST_KEY (plist) = MPLIST_KEY (next);
|
|
Packit Service |
a721b1 |
MPLIST_VAL (plist) = MPLIST_VAL (next);
|
|
Packit Service |
a721b1 |
if (MPLIST_KEY (plist) != Mnil
|
|
Packit Service |
a721b1 |
&& MPLIST_KEY (plist)->managing_key
|
|
Packit Service |
a721b1 |
&& MPLIST_VAL (plist))
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF (MPLIST_VAL (plist));
|
|
Packit Service |
a721b1 |
MPLIST_NEXT (plist) = MPLIST_NEXT (next);
|
|
Packit Service |
a721b1 |
if (plist->next)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF (plist->next);
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (next);
|
|
Packit Service |
a721b1 |
return val;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Find a property of a specific key in a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_find_by_key () function searches property list
|
|
Packit Service |
a721b1 |
$PLIST from the beginning for a property whose key is $KEY. If
|
|
Packit Service |
a721b1 |
such a property is found, a sublist of $PLIST whose first element
|
|
Packit Service |
a721b1 |
is the found one is returned. Otherwise, @c NULL is returned.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
If $KEY is @c Mnil, it returns a sublist of $PLIST whose
|
|
Packit Service |
a721b1 |
first element is the last one of $PLIST. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリスト中から指定のキーを持つプロパティを探す.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_find_by_key () はプロパティリスト $PLIST
|
|
Packit Service |
a721b1 |
を始めから探 して、キーが $KEY
|
|
Packit Service |
a721b1 |
であるプロパティを見つける。見つかれば、そのプロパティから始まる
|
|
Packit Service |
a721b1 |
$PLIST の部分リストを返す。そうでなければ @c NULL を返す。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
$KEY が @c Mnil ならば、$PLIST の最後の要素から始まる部分リストを返す。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist_find_by_key (MPlist *plist, MSymbol key)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPLIST_FIND (plist, key);
|
|
Packit Service |
a721b1 |
return (MPLIST_TAIL_P (plist)
|
|
Packit Service |
a721b1 |
? (key == Mnil ? plist : NULL)
|
|
Packit Service |
a721b1 |
: plist);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Find a property of a specific value in a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_find_by_value () function searches property list $PLIST
|
|
Packit Service |
a721b1 |
from the beginning for a property whose value is $VAL. If such a
|
|
Packit Service |
a721b1 |
property is found, a sublist of $PLIST whose first element is the
|
|
Packit Service |
a721b1 |
found one is returned. Otherwise, @c NULL is returned. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリスト中から指定の値を持つプロパティを探す.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_find_by_value () はプロパティリスト $PLIST
|
|
Packit Service |
a721b1 |
を始めから探して、値が $VAL
|
|
Packit Service |
a721b1 |
であるプロパティを見つける。見つかれば、そのプロパティから始まる
|
|
Packit Service |
a721b1 |
$PLIST の部分リストを返す。そうでなければ @c NULL を返す。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist_find_by_value (MPlist *plist, void *val)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPLIST_DO (plist, plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (MPLIST_VAL (plist) == val)
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return NULL;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Return the next sublist of a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_next () function returns a pointer to the sublist of
|
|
Packit Service |
a721b1 |
property list $PLIST, which begins at the second element in $PLIST. If the
|
|
Packit Service |
a721b1 |
length of $PLIST is zero, it returns @c NULL. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリストの次の部分リストを返す.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_next () はプロパティリスト $PLIST の 2
|
|
Packit Service |
a721b1 |
番目の要素から始まる部分リストへのポインタを返す。$PLIST の長さが 0
|
|
Packit Service |
a721b1 |
ならば @c NULL を返す。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist_next (MPlist *plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
return (MPLIST_TAIL_P (plist) ? NULL : plist->next);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Set the first property in a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_set () function sets the key and the value of the first
|
|
Packit Service |
a721b1 |
property in property list $PLIST to $KEY and $VALUE, respectively.
|
|
Packit Service |
a721b1 |
See the documentation of mplist_add () for the restriction on $KEY
|
|
Packit Service |
a721b1 |
and $VAL.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
If the operation was successful, mplist_set () returns $PLIST.
|
|
Packit Service |
a721b1 |
Otherwise, it returns @c NULL. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリストの最初のプロパティを設定する.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_set () はプロパティリスト $PLIST
|
|
Packit Service |
a721b1 |
の最初のプロパティのキーと値をそれぞれ $KEY と $VALUE に設定する。
|
|
Packit Service |
a721b1 |
$KEY と $VAL に対する制限については、mplist_add () の説明を参照。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
処理に成功すれば mplist_set () は $PLIST を返す。そうでなければ @c NULL を返す。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist_set (MPlist *plist, MSymbol key, void * val)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (key == Mnil)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (! MPLIST_TAIL_P (plist))
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
key = MPLIST_KEY (plist);
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (MPLIST_NEXT (plist));
|
|
Packit Service |
a721b1 |
MPLIST_KEY (plist) = Mnil;
|
|
Packit Service |
a721b1 |
if (key->managing_key)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (MPLIST_VAL (plist));
|
|
Packit Service |
a721b1 |
plist->next = NULL;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (val && key->managing_key)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_REF (val);
|
|
Packit Service |
a721b1 |
if (! MPLIST_TAIL_P (plist)
|
|
Packit Service |
a721b1 |
&& MPLIST_KEY (plist)->managing_key)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (MPLIST_VAL (plist));
|
|
Packit Service |
a721b1 |
MPLIST_SET (plist, key, val);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
return plist;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Return the length of a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_length () function returns the number of properties in
|
|
Packit Service |
a721b1 |
property list $PLIST. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリストの長さを返す.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_length () はプロパティリスト $PLIST 中のプロパティの数を返す。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
int
|
|
Packit Service |
a721b1 |
mplist_length (MPlist *plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
int n;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
for (n = 0; ! (MPLIST_TAIL_P (plist)); n++, plist = plist->next);
|
|
Packit Service |
a721b1 |
return n;
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Return the key of the first property in a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_key () function returns the key of the first property
|
|
Packit Service |
a721b1 |
in property list $PLIST. If the length of $PLIST is zero,
|
|
Packit Service |
a721b1 |
it returns @c Mnil. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリスト中の最初のプロパティのキーを返す.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_key () は、プロパティリスト $PLIST
|
|
Packit Service |
a721b1 |
中の最初のプロパティのキーを返す。$PLIST の長さが 0 ならば、 @c Mnil
|
|
Packit Service |
a721b1 |
を返す。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MSymbol
|
|
Packit Service |
a721b1 |
mplist_key (MPlist *plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
return MPLIST_KEY (plist);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/*=*/
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Return the value of the first property in a property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_value () function returns the value of the first
|
|
Packit Service |
a721b1 |
property in property list $PLIST. If the length of $PLIST
|
|
Packit Service |
a721b1 |
is zero, it returns @c NULL. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリスト中の最初のプロパティの値を返す.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_value () は、プロパティリスト $PLIST 中の最初のプロパティの値を返す。
|
|
Packit Service |
a721b1 |
$PLIST の長さが 0 ならば、 @c Mnil を返す。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
void *
|
|
Packit Service |
a721b1 |
mplist_value (MPlist *plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
return MPLIST_VAL (plist);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
/***en
|
|
Packit Service |
a721b1 |
@brief Generate a property list by deserializing an M-text.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mplist_deserialize () function parses M-text $MT and returns a
|
|
Packit Service |
a721b1 |
property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The syntax of $MT is as follows.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MT ::= '(' ELEMENT * ')'
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
SYMBOL ::= ascii-character-sequence
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
INTEGER ::= '-' ? [ '0' | .. | '9' ]+
|
|
Packit Service |
a721b1 |
| '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
M-TEXT ::= '"' character-sequence '"'
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
Each alternatives of @c ELEMENT is assigned one of these keys: @c
|
|
Packit Service |
a721b1 |
Msymbol, @c Minteger, @c Mtext, @c Mplist
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
In an ascii-character-sequence, a backslash (\) is used as the escape
|
|
Packit Service |
a721b1 |
character, which means that, for instance, <tt>abc\ def</tt>
|
|
Packit Service |
a721b1 |
produces a symbol whose name is of length seven with the fourth
|
|
Packit Service |
a721b1 |
character being a space. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief M-text をデシリアライズしてプロパティリストを作る.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mplist_deserialize () は M-text $MT を解析してプロパティリストを返す。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
$MT のシンタックスは以下の通り。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MT ::= '(' ELEMENT * ')'
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
SYMBOL ::= アスキー文字列
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
INTEGER ::= '-' ? [ '0' | .. | '9' ]+
|
|
Packit Service |
a721b1 |
| '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
M-TEXT ::= '"' character-sequence '"'
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@c ELEMENT の各選択肢はキー:@c Msymbol, @c Minteger, @c Mtext,
|
|
Packit Service |
a721b1 |
@c Mplist のいずれかを割り当てられている。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
アスキー文字列内では、バックスラッシュ (\) がエスケープ文字として用いられる。たとえば
|
|
Packit Service |
a721b1 |
<tt>abc\ def</tt> は 4 文字目が空白文字であり長さが 7
|
|
Packit Service |
a721b1 |
である持つ名前を持つシンボルを生成する。 */
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mplist_deserialize (MText *mt)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
MPlist *plist;
|
|
Packit Service |
a721b1 |
MText *tmp = NULL;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
if (mt->format > MTEXT_FORMAT_UTF_8)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (MTEXT_READ_ONLY_P (mt))
|
|
Packit Service |
a721b1 |
mt = tmp = mtext_cpy (mtext (), mt);
|
|
Packit Service |
a721b1 |
else
|
|
Packit Service |
a721b1 |
mtext__adjust_format (mt, MTEXT_FORMAT_UTF_8);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
plist = mplist__from_string (MTEXT_DATA (mt), mtext_nbytes (mt));
|
|
Packit Service |
a721b1 |
if (tmp)
|
|
Packit Service |
a721b1 |
M17N_OBJECT_UNREF (tmp);
|
|
Packit Service |
a721b1 |
return plist;
|
|
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 property list.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
The mdebug_dump_plist () function prints a property list $PLIST in
|
|
Packit Service |
a721b1 |
a 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 $PLIST. */
|
|
Packit Service |
a721b1 |
/***ja
|
|
Packit Service |
a721b1 |
@brief プロパティリストをダンプする.
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
関数 mdebug_dump_plist () はプロパティリスト $PLIST を標準エラー出
|
|
Packit Service |
a721b1 |
力もしくは環境変数 MDEBUG_DUMP_FONT で指定されたファイルに人間に可
|
|
Packit Service |
a721b1 |
読な形で印刷する。 $INDENT は2行目以降のインデントを指定する。
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
@return
|
|
Packit Service |
a721b1 |
この関数は $PLIST を返す。 */
|
|
Packit Service |
a721b1 |
MPlist *
|
|
Packit Service |
a721b1 |
mdebug_dump_plist (MPlist *plist, int indent)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
char *prefix = (char *) alloca (indent + 1);
|
|
Packit Service |
a721b1 |
MPlist *pl;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
memset (prefix, 32, indent);
|
|
Packit Service |
a721b1 |
prefix[indent] = 0;
|
|
Packit Service |
a721b1 |
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, "(");
|
|
Packit Service |
a721b1 |
MPLIST_DO (pl, plist)
|
|
Packit Service |
a721b1 |
{
|
|
Packit Service |
a721b1 |
if (pl != plist)
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, "\n%s ", prefix);
|
|
Packit Service |
a721b1 |
write_element (NULL, pl, indent + 1);
|
|
Packit Service |
a721b1 |
}
|
|
Packit Service |
a721b1 |
fprintf (mdebug__output, ")");
|
|
Packit Service |
a721b1 |
return plist;
|
|
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 |
*/
|