/* plist.c -- plist module.
- Copyright (C) 2003, 2004
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H15PRO112
You should have received a copy of the GNU Lesser General Public
License along with the m17n library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
02111-1307, USA. */
/***en
do {
MPlist *next = plist->next;
- if (MPLIST_KEY (plist) != Mnil && MPLIST_KEY (plist)->managing_key)
+ if (MPLIST_KEY (plist) != Mnil
+ && MPLIST_KEY (plist)->managing_key)
M17N_OBJECT_UNREF (MPLIST_VAL (plist));
M17N_OBJECT_UNREGISTER (plist_table, plist);
free (plist);
static MPlist *
read_mtext_element (MPlist *plist, MStream *st, int skip)
{
- union {
- int chars[READ_MTEXT_BUF_SIZE];
- unsigned char bytes[sizeof (int) * READ_MTEXT_BUF_SIZE];
- } buffer;
- unsigned char *bytes = buffer.bytes;
- int nbytes = sizeof (int) * READ_MTEXT_BUF_SIZE;
- int *chars = NULL;
- int nchars = 0;
- int c, i, j;
+ unsigned char buffer[READ_MTEXT_BUF_SIZE], *buf = buffer;
+ int nbytes = READ_MTEXT_BUF_SIZE;
+ int c, i;
i = 0;
while ((c = GETC (st)) != EOF && c != '"')
if (! skip)
{
- if (is_char && ! chars)
+ if (i + MAX_UTF8_CHAR_BYTES >= nbytes)
{
- chars = buffer.chars;
- for (j = i - 1; j >= 0; j--)
- chars[j] = bytes[j];
- nchars = READ_MTEXT_BUF_SIZE;
- if (bytes != buffer.bytes)
- free (bytes);
- }
-
- if (chars)
- {
- if (i + 1 >= nchars)
+ if (buf == buffer)
{
- nchars *= 2;
- if (chars == buffer.chars)
- {
- MTABLE_MALLOC (chars, nchars, MERROR_PLIST);
- memcpy (chars, buffer.chars, sizeof (int) * i);
- }
- else
- MTABLE_REALLOC (chars, nchars, MERROR_PLIST);
+ nbytes *= 2;
+ buf = malloc (nbytes);
+ memcpy (buf, buffer, i);
}
- chars[i++] = c;
- }
- else
- {
- if (i + MAX_UTF8_CHAR_BYTES >= nbytes)
+ else
{
- nbytes *= 2;
- if (bytes == buffer.bytes)
- {
- MTABLE_MALLOC (bytes, nbytes, MERROR_PLIST);
- memcpy (bytes, buffer.bytes, i);
- }
- else
- MTABLE_REALLOC (bytes, nbytes, MERROR_PLIST);
+ nbytes += READ_MTEXT_BUF_SIZE;
+ buf = realloc (buf, nbytes);
}
- bytes[i++] = c;
}
+
+ if (is_char)
+ i += CHAR_STRING_UTF8 (c, buf);
+ else
+ buf[i++] = c;
}
}
if (! skip)
{
- MText *mt;
-
- if (chars)
- {
- mt = mtext__from_data (chars, i, MTEXT_FORMAT_UTF_32, 1);
- if (chars != buffer.chars)
- free (chars);
- }
- else
- {
- mt = mtext__from_data (bytes, i, MTEXT_FORMAT_UTF_8, 1);
- if (bytes != buffer.bytes)
- free (bytes);
- }
+ MText *mt = mtext__from_data (buf, i, MTEXT_FORMAT_UTF_8,
+ (buf == buffer));
+ if (buf != buffer)
+ mt->allocated = nbytes;
MPLIST_SET_ADVANCE (plist, Mtext, mt);
}
return plist;
if (MT) \
mtext_cat_char ((MT), (C)); \
else \
- putc ((C), stderr); \
+ putc ((C), mdebug__output); \
} while (0);
#define PUTS(MT, STR) \
if (MT) \
MTEXT_CAT_ASCII ((MT), (STR)); \
else \
- fputs ((STR), stderr); \
+ fputs ((STR), mdebug__output); \
} while (0)
sprintf (buf, "%d", num);
PUTS (mt, buf);
}
- else if (MPLIST_PLIST_P (plist))
+ else if (MPLIST_PLIST_P (plist)
+ || MPLIST_NESTED_P (plist))
{
MPlist *pl;
int newline = 0;
+ if (MPLIST_NESTED_P (plist))
+ {
+ write_symbol (mt, MPLIST_KEY (plist));
+ PUTC (mt, ':');
+ }
plist = MPLIST_PLIST (plist);
PUTC (mt, '(');
if (indent >= 0)
unsigned char *end = data + mtext__char_to_byte (this_mt, stop);
while (beg < end)
- putc (*beg, stderr), beg++;
+ putc (*beg, mdebug__output), beg++;
}
if (stop == to)
break;
M17N_OBJECT_UNREF (this_mt);
}
else
- fprintf (stderr, "%s", str);
+ fprintf (mdebug__output, "%s", str);
}
else
{
+ char buf[128];
+
write_symbol (mt, MPLIST_KEY (plist));
PUTC (mt, ':');
- if (MPLIST_NESTED_P (plist))
- write_element (mt, plist, indent + 1);
- else
- {
- char buf[128];
-
- sprintf (buf, "%04X", (unsigned) MPLIST_VAL (plist));
- PUTS (mt, buf);
- }
+ sprintf (buf, "%04X", (unsigned) MPLIST_VAL (plist));
+ PUTS (mt, buf);
}
}
type = MPLIST_KEY (plist);
if (type->managing_key && MPLIST_VAL (plist))
M17N_OBJECT_REF (MPLIST_VAL (plist));
+ if (type == Mplist)
+ MPLIST_SET_NESTED_P (p);
MPLIST_SET_ADVANCE (p, key, MPLIST_VAL (plist));
plist = MPLIST_NEXT (plist);
}
elt = MPLIST_PLIST (plist);
if (! MPLIST_SYMBOL_P (elt))
MERROR (MERROR_PLIST, NULL);
+ MPLIST_SET_NESTED_P (p);
MPLIST_SET_ADVANCE (p, MPLIST_SYMBOL (elt), MPLIST_NEXT (elt));
M17N_OBJECT_REF (MPLIST_NEXT (elt));
}
MPLIST_DO (pl, plist);
MPLIST_KEY (pl) = MPLIST_KEY (tail);
MPLIST_VAL (pl) = MPLIST_VAL (tail);
- if (MPLIST_KEY (pl)->managing_key)
+ if (MPLIST_KEY (pl)->managing_key && MPLIST_VAL (pl))
M17N_OBJECT_REF (MPLIST_VAL (pl));
+ if (MPLIST_NESTED_P (tail))
+ MPLIST_SET_NESTED_P (pl);
tail = MPLIST_NEXT (tail);
MPLIST_NEXT (pl) = tail;
M17N_OBJECT_REF (tail);
MPlist *copy = mplist (), *pl = copy;
MPLIST_DO (plist, plist)
- pl = mplist_add (pl, MPLIST_KEY (plist), MPLIST_VAL (plist));
+ {
+ if (MPLIST_NESTED_P (plist))
+ MPLIST_SET_NESTED_P (pl);
+ pl = mplist_add (pl, MPLIST_KEY (plist), MPLIST_VAL (plist));
+ }
return copy;
}
/***en
@brief Get the value of a property in a property list.
- The mplist_get () function searches property list $PLIST
- from the beginning for a property whose key is $KEY. If such a
- property is found, a pointer to its value is returned as the type
- of <tt>(void *)</tt>. If not found, @c NULL is returned.
+ The mplist_get () function searches property list $PLIST from the
+ beginning for a property whose key is $KEY. If such a property is
+ found, its value is returned as the type of <tt>(void *)</tt>. If
+ not found, @c NULL is returned.
When @c NULL is returned, there are two possibilities: one is the
case where no property is found (see above); the other is the case
/***ja
@brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
- ´Ø¿ô mplist_get () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥¡¼¤¬
- $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤؤΥݥ¤¥ó¥¿¤ò
+ ´Ø¿ô mplist_get () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥¡¼
+ ¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤò
<tt>(void *)</tt> ·¿¤ÇÊÖ¤¹¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
@c NULL ¤¬Ê֤俺ݤˤÏÆó¤Ä¤Î²ÄǽÀ¤¬¤¢¤ë:
/*=*/
/***en
+ @brief Set the value (function pointer) of a property in a property list.
+
+ The mplist_put_func () function is similar to mplist_put () but for
+ setting function pointer $FUNC in property list $PLIST for key
+ $KEY. $KEY must not be a managing key. */
+
+/***ja
+ @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤Ë´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÀßÄꤹ¤ë.
+
+ ´Ø¿ô mplist_put_func () ¤Ï´Ø¿ô mplist_put () ƱÍÍ¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
+ Ãæ¤Ç¥¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë¡£Ã¢¤·¤½¤ÎÃͤϴؿô¥Ý¥¤¥ó¥¿
+ $FUNC ¤Ç¤¢¤ë¡£$KEY ¤Ï´ÉÍý¥¡¼¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
+
+
+/***
+ @seealso
+ mplist_put (), M17N_FUNC () */
+
+MPlist *
+mplist_put_func (MPlist *plist, MSymbol key, M17NFunc func)
+{
+ if (key == Mnil || key->managing_key)
+ MERROR (MERROR_PLIST, NULL);
+ MPLIST_FIND (plist, key);
+ MPLIST_KEY (plist) = key;
+ MPLIST_FUNC (plist) = func;
+ MPLIST_SET_VAL_FUNC_P (plist);
+ if (! plist->next)
+ MPLIST_NEW ((plist)->next);
+ return plist;
+}
+
+/*=*/
+
+/***en
+ @brief Get the value (function pointer) of a property in a property list.
+
+ The mplist_get_func () function is similar to mplist_get () but for
+ getting a function pointer from property list $PLIST by key $KEY. */
+
+/***ja
+ @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤«¤é¥×¥í¥Ñ¥Æ¥£¤Î´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÆÀ¤ë.
+
+ ´Ø¿ô mplist_get_func () ¤Ï´Ø¿ô mplist_get () ¤ÈƱÍͤˡ¢¥×¥í¥Ñ¥Æ¥£¥ê
+ ¥¹¥È $PLIST Ãæ¤Ç¥¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¡¢Ã¢¤·´Ø¿ô¥Ý¥¤¥ó¥¿¡¢
+ ¤òÆÀ¤ë¡£ */
+
+
+/***
+ @seealso
+ mplist_get () */
+M17NFunc
+mplist_get_func (MPlist *plist, MSymbol key)
+{
+ MPLIST_FIND (plist, key);
+ return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_FUNC (plist));
+}
+
+/*=*/
+
+/***en
@brief Add a property at the end of a property list.
The mplist_add () function appends at the end of property list
MPLIST_NEW (pl);
MPLIST_KEY (pl) = MPLIST_KEY (plist);
MPLIST_VAL (pl) = MPLIST_VAL (plist);
+ if (MPLIST_NESTED_P (plist))
+ MPLIST_SET_NESTED_P (pl);
MPLIST_NEXT (pl) = MPLIST_NEXT (plist);
plist->next = pl;
if (val && key->managing_key)
The mplist_pop () function removes a property at the beginning of
property list $PLIST. As a result, the second key and value of
- the original $PLIST become the first of those of the new $PLIST.
+ the $PLIST become the first ones.
@return
If the operation was successful, this function return the value of
/***ja
@brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤«¤é¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë.
- ´Ø¿ô mplist_pop () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
- ¤ÎÀèƬ¤Î¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë¡£·ë²Ì¤È¤·¤Æ¡¢¸µ¤Î $PLIST ¤Î2ÈÖÌܤΥ¡¼¤ÈÃͤ¬¡¢¿·¤·¤¤
- $PLIST ¤ÎÀèƬ¤Î¥¡¼¤ÈÃͤˤʤ롣
+ ´Ø¿ô mplist_pop () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Î¥×¥í¥Ñ¥Æ¥£¤òºï
+ ½ü¤¹¤ë¡£·ë²Ì¤È¤·¤Æ¡¢¸µ¤Î2ÈÖÌܤΥ¡¼¤ÈÃͤ¬ÀèƬ¤Î¥¡¼¤ÈÃͤˤʤ롣
@return
½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ïºï½ü¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
Msymbol, @c Minteger, @c Mtext, @c Mplist
In an ascii-character-sequence, a backslash (\) is used as the escape
- character, which means that, for instance, <tt>"abc\ def"</tt>
+ character, which means that, for instance, <tt>abc\ def</tt>
produces a symbol whose name is of length seven with the fourth
character being a space. */
/***ja
@c Mplist ¤Î¤¤¤º¤ì¤«¤ò³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¡£
¥¢¥¹¥¡¼Ê¸»úÎóÆâ¤Ç¤Ï¡¢¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å (\) ¤¬¥¨¥¹¥±¡¼¥×ʸ»ú¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£¤¿¤È¤¨¤Ð
- <tt>"abc\ def"</tt> ¤Ï 4 ʸ»úÌܤ¬¶õÇòʸ»ú¤Ç¤¢¤êŤµ¤¬ 7
+ <tt>abc\ def</tt> ¤Ï 4 ʸ»úÌܤ¬¶õÇòʸ»ú¤Ç¤¢¤êŤµ¤¬ 7
¤Ç¤¢¤ë»ý¤Ä̾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òÀ¸À®¤¹¤ë¡£ */
MPlist *
@brief Dump a property list.
The mdebug_dump_plist () function prints a property list $PLIST in
- a human readable way to the stderr. $INDENT specifies how many
- columns to indent the lines but the first one.
+ a human readable way to the stderr or to what specified by the
+ environment variable MDEBUG_OUTPUT_FILE. $INDENT specifies how
+ many columns to indent the lines but the first one.
@return
This function returns $PLIST. */
/***ja
@brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¥À¥ó¥×¤¹¤ë.
- ´Ø¿ô mdebug_dump_plist () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò stderr
- ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
+ ´Ø¿ô mdebug_dump_plist () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤òɸ½à¥¨¥é¡¼½Ð
+ ÎϤ⤷¤¯¤Ï´Ä¶ÊÑ¿ô MDEBUG_DUMP_FONT ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¿Í´Ö¤Ë²Ä
+ ÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
@return
¤³¤Î´Ø¿ô¤Ï $PLIST ¤òÊÖ¤¹¡£ */
memset (prefix, 32, indent);
prefix[indent] = 0;
- fprintf (stderr, "(");
+ fprintf (mdebug__output, "(");
MPLIST_DO (pl, plist)
{
if (pl != plist)
- fprintf (stderr, "\n%s ", prefix);
+ fprintf (mdebug__output, "\n%s ", prefix);
write_element (NULL, pl, indent + 1);
}
- fprintf (stderr, ")");
+ fprintf (mdebug__output, ")");
return plist;
}