1 /* plist.c -- plist module.
2 Copyright (C) 2003, 2004
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 @brief Property List objects and API for them.
28 A @e property @e list (or @e plist for short) is a list of zero or
29 more properties. A property consists of a @e key and a @e value,
30 where key is a symbol and value is anything that can be cast to
33 If the key of a property is a @e managing @e key, its @e value is
34 a @e managed @e object. A property list itself is a managed
39 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤È¤½¤ì¤Ë´Ø¤¹¤ë API.
41 @e ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È (¤Þ¤¿¤Ï @e plist) ¤Ï 0
42 ¸Ä°Ê¾å¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥ê¥¹¥È¤Ç¤¢¤ë¡£¥×¥í¥Ñ¥Æ¥£¤Ï @e ¥¡¼ ¤È @e ÃÍ
43 ¤«¤é¤Ê¤ë¡£¥¡¼¤Ï¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ÃÍ¤Ï <tt>(void *)</tt>
44 ¤Ë¥¥ã¥¹¥È¤Ç¤¤ë¤â¤Î¤Ê¤é¤Ð²¿¤Ç¤âÎɤ¤¡£
46 ¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤¬ @e ´ÉÍý¥¡¼ ¤Ê¤é¤Ð¡¢¤½¤Î @e ÃÍ ¤Ï @e ´ÉÍý²¼
48 ¤Ç¤¢¤ë¡£¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¼«ÂΤâ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£ */
52 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
53 /*** @addtogroup m17nInternal
61 #include "m17n-misc.h"
63 #include "character.h"
68 static M17NObjectArray plist_table;
70 /** Set PLIST to a newly allocated plist object. */
72 #define MPLIST_NEW(plist) \
74 M17N_OBJECT (plist, free_plist, MERROR_PLIST); \
75 M17N_OBJECT_REGISTER (plist_table, plist); \
79 /** Set the element of PLIST to KEY and VAL. If PLIST is an anchor,
80 append a new anchor. */
82 #define MPLIST_SET(plist, key, val) \
84 MPLIST_KEY (plist) = (key); \
85 MPLIST_VAL (plist) = (val); \
86 if (! (plist)->next) \
87 MPLIST_NEW ((plist)->next); \
91 /** Set the element of PLIST to KEY and VAL. PLIST must be an anchor.
92 Append a new anchor and set PLIST to that anchor. */
94 #define MPLIST_SET_ADVANCE(plist, key, val) \
96 MPLIST_KEY (plist) = (key); \
97 MPLIST_VAL (plist) = (val); \
98 MPLIST_NEW ((plist)->next); \
99 plist = (plist)->next; \
104 free_plist (void *object)
106 MPlist *plist = (MPlist *) object;
109 MPlist *next = plist->next;
111 if (MPLIST_KEY (plist) != Mnil && MPLIST_KEY (plist)->managing_key)
112 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
113 M17N_OBJECT_UNREGISTER (plist_table, plist);
116 } while (plist && plist->control.ref_count == 1);
117 M17N_OBJECT_UNREF (plist);
122 /* Load a plist from a string. */
124 #define READ_CHUNK 0x10000
128 /* File pointer if the stream is associated with a file. Otherwise
132 unsigned char buffer[READ_CHUNK];
133 unsigned char *p, *pend;
137 get_byte (MStream *st)
141 if (! st->fp || st->eof)
143 n = fread (st->buffer, 1, READ_CHUNK, st->fp);
149 st->p = st->buffer + 1;
150 st->pend = st->buffer + n;
151 return st->buffer[0];
154 #define GETC(st) ((st)->p < (st)->pend ? *(st)->p++ : get_byte (st))
156 #define UNGETC(c, st) (--((st)->p))
158 /** Mapping table for reading a number. Hexadecimal chars
159 (0..9,A..F,a..F) are mapped to the corresponding numbers.
160 Apostrophe (code 39) is mapped to 254. All the other bytes are
162 unsigned char hex_mnemonic[256];
164 /** Mapping table for escaped characters. Mnemonic characters (e, b,
165 f, n, r, or t) that follows '\' are mapped to the corresponding
166 character code. All the other bytes are mapped to themselves. */
167 unsigned char escape_mnemonic[256];
170 /** Read an integer from the stream ST. It is assumed that we have
171 already read one character C. */
174 read_decimal (MStream *st, int c)
178 while (c >= '0' && c <= '9')
180 num = (num * 10) + (c - '0');
189 /** Read an unsigned from the stream ST. */
192 read_hexadesimal (MStream *st)
197 while ((c = GETC (st)) != EOF
198 && (n = hex_mnemonic[c]) < 16)
199 num = (num << 4) | n;
206 /** Read an M-text element from ST, and add it to LIST. Return a list
207 for the next element. */
210 read_mtext_element (MPlist *plist, MStream *st, int skip)
212 unsigned char buffer[1024];
214 unsigned char *buf = buffer;
218 while ((c = GETC (st)) != EOF && c != '"')
220 if (i + MAX_UTF8_CHAR_BYTES >= bufsize)
225 MTABLE_MALLOC (buf, bufsize, MERROR_PLIST);
226 memcpy (buf, buffer, i);
229 MTABLE_REALLOC (buf, bufsize, MERROR_PLIST);
241 c = read_hexadesimal (st);
247 c = escape_mnemonic[c];
256 MPLIST_SET_ADVANCE (plist, Mtext,
257 mtext__from_data (buf, i, MTEXT_FORMAT_UTF_8, 1));
265 read_character (MStream *st, int c)
267 unsigned char buf[MAX_UTF8_CHAR_BYTES + 1];
268 int len = CHAR_BYTES_BY_HEAD (c);
272 for (i = 1; i < len; i++)
276 || (c & 0xC0) != 0x80)
281 c = STRING_CHAR_UTF8 (buf);
288 /** Read an integer element from ST, and add it to LIST. Return a
289 list for the next element. It is assumed that we have already
290 read the character C. */
293 read_integer_element (MPlist *plist, MStream *st, int c, int skip)
297 if (c == '0' || c == '#')
301 num = read_hexadesimal (st);
303 num = read_decimal (st, c);
312 if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c))
315 num = read_character (st, c);
322 else if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c))
323 num = escape_mnemonic[c];
325 num = read_character (st, c);
329 num = - read_decimal (st, GETC (st));
331 num = read_decimal (st, c);
334 MPLIST_SET_ADVANCE (plist, Minteger, (void *) num);
338 /** Read a symbol element from ST, and add it to LIST. Return a list
339 for the next element. */
342 read_symbol_element (MPlist *plist, MStream *st, int skip)
344 unsigned char buffer[1024];
346 unsigned char *buf = buffer;
350 while ((c = GETC (st)) != EOF
352 && c != ')' && c != '(' && c != '"')
359 MTABLE_MALLOC (buf, bufsize, MERROR_PLIST);
360 memcpy (buf, buffer, i);
363 MTABLE_REALLOC (buf, bufsize, MERROR_PLIST);
370 c = escape_mnemonic[c];
381 MPLIST_SET_ADVANCE (plist, Msymbol, msymbol ((char *) buf));
388 /* Read an element of various type from stream ST, and add it to LIST.
389 Return a list for the next element. The element type is decided by
390 the first token character found as below:
393 '0'..'9', '-': integer
394 '?': integer representing character code
395 the other ASCII letters: symbol
397 If KEYS is not NULL, it is a plist contains target keys and stop
398 keys. In this caes, read only a plist whose key has value 1 in
399 KEYS, and return NULL when we encounter a plist whose key has value
400 0 in KEYS while skipping any other elements. */
403 read_element (MPlist *plist, MStream *st, MPlist *keys)
407 /* Skip separators and comments. */
410 while ((c = GETC (st)) != EOF && c <= ' ');
413 while ((c = GETC (st)) != EOF && c != '\n');
424 p = read_element (p, st, NULL);
425 if (keys && p && MPLIST_SYMBOL_P (pl))
428 MPLIST_FIND (p0, MPLIST_SYMBOL (pl));
429 if (! MPLIST_TAIL_P (p0) && ! MPLIST_VAL (p0))
431 M17N_OBJECT_UNREF (pl);
434 while ((p = read_element (p, st, NULL)));
435 if (! MPLIST_TAIL_P (p0))
436 MPLIST_SET_ADVANCE (plist, Mplist, pl);
438 M17N_OBJECT_UNREF (pl);
443 while ((p = read_element (p, st, NULL)));
444 MPLIST_SET_ADVANCE (plist, Mplist, pl);
449 return (read_mtext_element (plist, st, keys ? 1 : 0));
450 if ((c >= '0' && c <= '9') || c == '-' || c == '?' || c == '#')
451 return (read_integer_element (plist, st, c, keys ? 1 : 0));
452 if (c == EOF || c == ')')
455 return (read_symbol_element (plist, st, keys ? 1 : 0));
459 write_element (MText *mt, MPlist *plist)
461 if (MPLIST_SYMBOL_P (plist))
463 MSymbol sym = MPLIST_SYMBOL (plist);
467 MTEXT_CAT_ASCII (mt, "nil");
471 char *name = MSYMBOL_NAME (sym);
472 char *buf = alloca (MSYMBOL_NAMELEN (sym) * 2 + 1), *p = buf;
476 if (*name <= ' ' || *name == '"' || *name == ')' || *name == ')')
481 MTEXT_CAT_ASCII (mt, buf);
484 else if (MPLIST_INTEGER_P (plist))
486 int num = MPLIST_INTEGER (plist);
489 sprintf (buf, "%d", num);
490 MTEXT_CAT_ASCII (mt, buf);
492 else if (MPLIST_PLIST_P (plist))
496 plist = MPLIST_PLIST (plist);
497 mtext_cat_char (mt, '(');
498 MPLIST_DO (pl, plist)
501 mtext_cat_char (mt, ' ');
502 write_element (mt, pl);
504 mtext_cat_char (mt, ')');
506 else if (MPLIST_MTEXT_P (plist))
508 mtext_cat_char (mt, '"');
509 /* Not yet implemnted */
510 mtext_cat_char (mt, '"');
514 /* Support functions for mdebug_dump_plist. */
517 dump_string (char *str)
519 char *p = str, *pend = p + strlen (p), *new, *p1;
521 new = p1 = alloca ((pend - p) * 4 + 1);
526 sprintf (p1, "\\x%02X", (unsigned char) *p);
544 fprintf (stderr, "%s", new);
548 dump_plist_element (MPlist *plist, int indent)
550 char *prefix = (char *) alloca (indent + 1);
553 memset (prefix, 32, indent);
556 key = MPLIST_KEY (plist);
557 fprintf (stderr, "(%s(#%d) ", msymbol_name (MPLIST_KEY (plist)),
558 plist->control.ref_count);
560 dump_string (msymbol_name (MPLIST_SYMBOL (plist)));
561 else if (key == Mtext)
562 mdebug_dump_mtext (MPLIST_MTEXT (plist), indent, 0);
563 else if (key == Minteger)
564 fprintf (stderr, "%x", MPLIST_INTEGER (plist));
565 else if (key == Mstring)
566 fprintf (stderr, "\"%s\"", MPLIST_STRING (plist));
567 else if (key == Mplist)
569 fprintf (stderr, "\n%s", prefix);
570 mdebug_dump_plist (MPLIST_PLIST (plist), indent);
573 fprintf (stderr, "0x%X", (unsigned) MPLIST_VAL (plist));
574 fprintf (stderr, ")");
584 plist_table.count = 0;
586 Minteger = msymbol ("integer");
587 Mplist = msymbol_as_managing_key ("plist");
588 Mtext = msymbol_as_managing_key ("mtext");
590 for (i = 0; i < 256; i++)
591 hex_mnemonic[i] = 255;
592 for (i = '0'; i <= '9'; i++)
593 hex_mnemonic[i] = i - '0';
594 for (i = 'A'; i <= 'F'; i++)
595 hex_mnemonic[i] = i - 'A' + 10;
596 for (i = 'a'; i <= 'f'; i++)
597 hex_mnemonic[i] = i - 'a' + 10;
598 for (i = 0; i < 256; i++)
599 escape_mnemonic[i] = i;
600 escape_mnemonic['e'] = 27;
601 escape_mnemonic['b'] = '\b';
602 escape_mnemonic['f'] = '\f';
603 escape_mnemonic['n'] = '\n';
604 escape_mnemonic['r'] = '\r';
605 escape_mnemonic['t'] = '\t';
606 escape_mnemonic['\\'] = '\\';
614 mdebug__report_object ("Plist", &plist_table);
618 /* Parse this form of PLIST:
619 (symbol:KEY1 TYPE1:VAL1 symbol:KEY2 TYPE2:VAL2 ...)
620 and return a newly created plist of this form:
621 (KEY1:VAL1 KEY2:VAL2 ...) */
624 mplist__from_plist (MPlist *plist)
630 while (! MPLIST_TAIL_P (plist))
634 if (! MPLIST_SYMBOL_P (plist))
635 MERROR (MERROR_PLIST, NULL);
636 key = MPLIST_SYMBOL (plist);
637 plist = MPLIST_NEXT (plist);
638 type = MPLIST_KEY (plist);
639 if (type->managing_key && MPLIST_VAL (plist))
640 M17N_OBJECT_REF (MPLIST_VAL (plist));
641 MPLIST_SET_ADVANCE (p, key, MPLIST_VAL (plist));
642 plist = MPLIST_NEXT (plist);
647 /** Parse this form of PLIST:
648 ((symbol:KEY1 ANY:VAL1 ... ) (symbol:KEY2 ANY:VAL2 ...) ...)
649 and return a newly created plist of this form:
650 (KEY1:(ANY:VAL1 ...) KEY2:(ANY:VAL2 ...) ...)
651 ANY can be any type. */
654 mplist__from_alist (MPlist *plist)
660 MPLIST_DO (plist, plist)
664 if (! MPLIST_PLIST_P (plist))
665 MERROR (MERROR_PLIST, NULL);
666 elt = MPLIST_PLIST (plist);
667 if (! MPLIST_SYMBOL_P (elt))
668 MERROR (MERROR_PLIST, NULL);
669 MPLIST_SET_ADVANCE (p, MPLIST_SYMBOL (elt), MPLIST_NEXT (elt));
670 M17N_OBJECT_REF (MPLIST_NEXT (elt));
677 mplist__from_file (FILE *fp, MPlist *keys)
684 st.p = st.pend = st.buffer;
687 while ((pl = read_element (pl, &st, keys)));
692 /** Parse $STR of $N bytes and return a property list object. $FORMAT
693 must be either @c MTEXT_FORMAT_US_ASCII or @c MTEXT_FORMAT_UTF_8,
694 and controls how to produce @c STRING or @c M-TEXT in the
695 following definition.
697 The syntax of $STR is as follows.
699 PLIST ::= '(' ELEMENT * ')'
701 ELEMENT ::= SYMBOL | INTEGER | UNSIGNED | STRING | M-TEXT | PLIST
703 SYMBOL ::= ascii-character-sequence
705 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
707 UNSIGNED ::= '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
709 M-TEXT ::= '"' byte-sequence '"'
711 Each kind of @c ELEMENT is assigned one of these keys:
712 @c Msymbol, @c Mint, @c Munsigned, @c Mtext, @c Mplist
714 In an ascii-character-sequence, a backslush (\) is used as the escape
715 character, which means that, for instance, <tt>"abc\ def"</tt>
716 produces a symbol whose name is of length seven with the fourth
717 character being a space.
719 In a byte-sequence, "\r", "\n", "\e", and "\t" are replaced by CR,
720 NL, ESC, and TAB character respectively, "\xXX" are replaced by
721 byte 0xXX. After this replacement, the byte-sequence is decoded
722 into M-TEXT by $CODING. */
725 mplist__from_string (unsigned char *str, int n)
736 while ((pl = read_element (pl, &st, NULL)));
741 mplist__serialize (MText *mt, MPlist *plist)
745 MPLIST_DO (pl, plist)
748 mtext_cat_char (mt, ' ');
749 write_element (mt, pl);
755 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
760 /*** @addtogroup m17nPlist */
765 @brief Symbol whose name is "integer".
767 The symbol @c Minteger has the name <tt>"integer"</tt>. A value
768 of a property whose key is @c Minteger must be an integer. */
770 @brief "integer" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
772 ¥·¥ó¥Ü¥ë @c Minteger ¤Ï <tt>"integer"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¡£¥¡¼¤¬
773 @c Minteger ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤÏÀ°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
779 @brief Symbol whose name is "plist".
781 The symbol @c Mplist has the name <tt>"plist"</tt>. It is a
782 managing key. A value of a property whose key is @c Mplist must
785 @brief "plist" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
787 ¥·¥ó¥Ü¥ë @c Mplist ¤Ï <tt>"plist"</tt>
788 ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¡£¤³¤ì¤Ï´ÉÍý¥¡¼¤Ç¤¢¤ë¡£¥¡¼¤¬ @c Mplist
789 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¤Ï plist ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
795 @brief Symbol whose name is "mtext".
797 The symbol @c Mtext has the name <tt>"mtext"</tt>. It is a
798 managing key. A value of a property whose key is @c Mtext must be an
802 @brief "mtext" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
804 ¥·¥ó¥Ü¥ë @c Mtext ¤Ï <tt>"mtext"</tt>
805 ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä´ÉÍý¥¡¼¤Ç¤¢¤ë¡£¥¡¼¤¬ @c Mtext
806 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¤Ï M-text ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
812 @brief Create a property list object.
814 The mplist () function returns a newly created property list
815 object of length zero.
818 This function returns a newly created property list.
821 This function never fails. */
823 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë.
825 ´Ø¿ô mplist () ¤ÏŤµ 0 ¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò¿·¤·¤¯ºî¤Ã¤ÆÊÖ¤¹¡£
828 ¤³¤Î´Ø¿ô¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹¡£
831 ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£ */
844 @brief Copy a property list.
846 The mplist_copy () function copies property list $PLIST. In the
847 copy, the values are the same as those of $PLIST.
850 This function returns a newly created plist which is a copy of
854 This function never fails. */
856 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¥³¥Ô¡¼¤¹¤ë.
858 ´Ø¿ô mplist_copy () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
859 ¤ò¥³¥Ô¡¼¤¹¤ë¡£¥³¥Ô¡¼¤Î¤¹¤Ù¤Æ¤ÎÃͤϥ³¥Ô¡¼¸µ $PLIST ¤ÎÃͤÈƱ¤¸¤Ç¤¢¤ë¡£
862 ¤³¤Î´Ø¿ô¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¡¢$PLIST ¤Î¥³¥Ô¡¼¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òÊÖ¤¹¡£
865 ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£ */
868 mplist_copy (MPlist *plist)
870 MPlist *copy = mplist (), *pl = copy;
872 MPLIST_DO (plist, plist)
873 pl = mplist_add (pl, MPLIST_KEY (plist), MPLIST_VAL (plist));
880 @brief Set the value of a property in a property list.
882 The mplist_put () function searches property list $PLIST
883 from the beginning for a property whose key is $KEY. If such a
884 property is found, its value is changed to $VALUE. Otherwise, a
885 new property whose key is $KEY and value is $VALUE is appended at
886 the end of $PLIST. See the documentation of mplist_add () for
887 the restriction on $KEY and $VAL.
889 If $KEY is a managing key, $VAL must be a managed object. In this
890 case, the reference count of the old value, if not @c NULL, is
891 decremented by one, and that of $VAL is incremented by one.
894 If the operation was successful, mplist_put () returns a sublist of
895 $PLIST whose first element is the just modified or added one.
896 Otherwise, it returns @c NULL. */
898 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÀßÄꤹ¤ë.
900 ´Ø¿ô mplist_put () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥¡¼¤¬
901 $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤò $VALUE
902 ¤ËÊѹ¹¤¹¤ë¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¥¡¼¤¬ $KEY ¤ÇÃͤ¬ $VALUE
903 ¤Ç¤¢¤ë¿·¤·¤¤¥×¥í¥Ñ¥Æ¥£¤¬ $PLIST ¤ÎËöÈø¤ËÄɲ䵤ì¤ë¡£$KEY ¤È $VAL
904 ¤ËÂФ¹¤ëÀ©¸Â¤Ë¤Ä¤¤¤Æ¤Ï¡¢mplist_add () ¤ÎÀâÌÀ¤ò»²¾È¡£
906 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢
907 $VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢¸Å¤¤Ãͤλ²¾È¿ô¤Ï
908 @c NULL ¤Ç¤Ê¤±¤ì¤Ð 1 ¸º¤é¤µ¤ì¡¢$VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
911 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mplist_put () ¤ÏÊѹ¹¤µ¤ì¤¿¤«Äɲ䵤줿Í×ÁǤ«¤é»Ï¤Þ¤ë
912 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
915 mplist_put (MPlist *plist, MSymbol key, void *val)
918 MERROR (MERROR_PLIST, NULL);
919 MPLIST_FIND (plist, key);
920 if (key->managing_key)
922 if (! MPLIST_TAIL_P (plist))
923 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
925 M17N_OBJECT_REF (val);
927 MPLIST_SET (plist, key, val);
934 @brief Get the value of a property in a property list.
936 The mplist_get () function searches property list $PLIST
937 from the beginning for a property whose key is $KEY. If such a
938 property is found, a pointer to its value is returned as the type
939 of <tt>(void *)</tt>. If not found, @c NULL is returned.
941 When @c NULL is returned, there are two possibilities: one is the
942 case where no property is found (see above); the other is the case
943 where a property is found and its value is @c NULL. In case that
944 these two cases must be distinguished, use the mplist_find_by_key ()
947 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
949 ´Ø¿ô mplist_get () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥¡¼¤¬
950 $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤؤΥݥ¤¥ó¥¿¤ò
951 <tt>(void *)</tt> ·¿¤ÇÊÖ¤¹¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
953 @c NULL ¤¬Ê֤俺ݤˤÏÆó¤Ä¤Î²ÄǽÀ¤¬¤¢¤ë:
954 ¾åµ¤Î¤è¤¦¤Ë¥×¥í¥Ñ¥Æ¥£¤¬¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¾ì¹ç¤È¡¢¥×¥í¥Ñ¥Æ¥£¤¬¸«¤Ä¤«¤ê¡¢¤½¤ÎÃͤ¬
955 @c NULL ¤Ç¤¢¤ë¾ì¹ç¤Ç¤¢¤ë¡£¤³¤ì¤é¤ò¶èÊ̤¹¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤Ë¤Ï´Ø¿ô
956 mplist_find_by_key () ¤ò»È¤¦¤³¤È¡£ */
960 mplist_find_by_key () */
963 mplist_get (MPlist *plist, MSymbol key)
965 MPLIST_FIND (plist, key);
966 return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_VAL (plist));
972 @brief Add a property at the end of a property list.
974 The mplist_add () function appends at the end of property list
975 $PLIST a property whose key is $KEY and value is $VAL. $KEY can
976 be any symbol other than @c Mnil.
978 If $KEY is a managing key, $VAL must be a managed object. In this
979 case, the reference count of $VAL is incremented by one.
982 If the operation was successful, mplist_add () returns a sublist of
983 $PLIST whose first element is the just added one. Otherwise, it
986 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈËöÈø¤Ë¥×¥í¥Ñ¥Æ¥£¤òÄɲ乤ë.
988 ´Ø¿ô mplist_add () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎËöÈø¤Ë¥¡¼¤¬ $KEY
989 ¤ÇÃͤ¬ $VAL ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤òÄɲ乤롣$KEY ¤Ï¡¢@c Mnil °Ê³°¤ÎǤ°Õ¤Î¥·¥ó¥Ü¥ë¤Ç¤è¤¤¡£
991 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢$VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢
992 $VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
995 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mplist_add () ¤ÏÄɲ䵤줿Í×ÁǤ«¤é»Ï¤Þ¤ë $PLIST
996 ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
999 mplist_add (MPlist *plist, MSymbol key, void *val)
1002 MERROR (MERROR_PLIST, NULL);
1003 MPLIST_FIND (plist, Mnil);
1004 if (val && key->managing_key)
1005 M17N_OBJECT_REF (val);
1006 MPLIST_KEY (plist) = key;
1007 MPLIST_VAL (plist) = val;
1008 MPLIST_NEW (plist->next);
1015 @brief Add a property at the beginning of a property list.
1017 The mplist_push () function inserts at the beginning of property
1018 list $PLIST a property whose key is $KEY and value is $VAL.
1020 If $KEY is a managing key, $VAL must be a managed object. In this
1021 case, the reference count of $VAL is incremented by one.
1024 If the operation was successful, this function returns $PLIST.
1025 Otherwise, it returns @c NULL. */
1027 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤Ë¥×¥í¥Ñ¥Æ¥£¤òÁÞÆþ¤¹¤ë.
1029 ´Ø¿ô mplist_push () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Ë¥¡¼¤¬ $KEY
1030 ¤ÇÃͤ¬ $VAL ¤Ç¤¢¤ë¥ª¥Ö¥¸¥§¥¯¥È¤òÁÞÆþ¤¹¤ë¡£
1032 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢$VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢
1033 $VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1036 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï $PLIST ¤òÊÖ¤·¡¢¤½¤¦¤Ç¤Ê¤±¤ì¤Ð@c NULL
1040 mplist_push (MPlist *plist, MSymbol key, void *val)
1045 MERROR (MERROR_PLIST, NULL);
1047 MPLIST_KEY (pl) = MPLIST_KEY (plist);
1048 MPLIST_VAL (pl) = MPLIST_VAL (plist);
1049 MPLIST_NEXT (pl) = MPLIST_NEXT (plist);
1051 if (val && key->managing_key)
1052 M17N_OBJECT_REF (val);
1053 MPLIST_KEY (plist) = key;
1054 MPLIST_VAL (plist) = val;
1061 @brief Remove a property at the beginning of a property list.
1063 The mplist_pop () function removes a property at the beginning of
1064 property list $PLIST. As a result, the second key and value of
1065 the original $PLIST become the first of those of the new $PLIST.
1068 If the operation was successful, this function return the value of
1069 the just popped property. Otherwise, it returns @c NULL. */
1071 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤«¤é¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë.
1073 ´Ø¿ô mplist_pop () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1074 ¤ÎÀèƬ¤Î¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë¡£·ë²Ì¤È¤·¤Æ¡¢¸µ¤Î $PLIST ¤Î2ÈÖÌܤΥ¡¼¤ÈÃͤ¬¡¢¿·¤·¤¤
1075 $PLIST ¤ÎÀèƬ¤Î¥¡¼¤ÈÃͤˤʤ롣
1078 ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ïºï½ü¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
1082 mplist_pop (MPlist *plist)
1087 if (MPLIST_TAIL_P (plist))
1089 val = MPLIST_VAL (plist);
1090 next = MPLIST_NEXT (plist);
1091 MPLIST_KEY (plist) = MPLIST_KEY (next);
1092 MPLIST_VAL (plist) = MPLIST_VAL (next);
1093 if (MPLIST_KEY (plist) != Mnil
1094 && MPLIST_KEY (plist)->managing_key
1095 && MPLIST_VAL (plist))
1096 M17N_OBJECT_REF (MPLIST_VAL (plist));
1097 MPLIST_NEXT (plist) = MPLIST_NEXT (next);
1099 M17N_OBJECT_REF (plist->next);
1100 M17N_OBJECT_UNREF (next);
1106 @brief Find a property of a specific key in a property list.
1108 The mplist_find_by_key () function searches property list
1109 $PLIST from the beginning for a property whose key is $KEY. If
1110 such a property is found, a sublist of $PLIST whose first element
1111 is the found one is returned. Otherwise, @c NULL is returned.
1113 If $KEY is @c Mnil, it returns a sublist of $PLIST whose
1114 first element is the last one of $PLIST. */
1116 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃ椫¤é»ØÄê¤Î¥¡¼¤ò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤òõ¤¹.
1118 ´Ø¿ô mplist_find_by_key () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1119 ¤ò»Ï¤á¤«¤éõ ¤·¤Æ¡¢¥¡¼¤¬ $KEY
1120 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤«¤é»Ï¤Þ¤ë
1121 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
1123 $KEY ¤¬ @c Mnil ¤Ê¤é¤Ð¡¢$PLIST ¤ÎºÇ¸å¤ÎÍ×ÁǤ«¤é»Ï¤Þ¤ëÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£ */
1126 mplist_find_by_key (MPlist *plist, MSymbol key)
1128 MPLIST_FIND (plist, key);
1129 return (MPLIST_TAIL_P (plist)
1130 ? (key == Mnil ? plist : NULL)
1136 @brief Find a property of a specific value in a property list.
1138 The mplist_find_by_value () function searches property list $PLIST
1139 from the beginning for a property whose value is $VAL. If such a
1140 property is found, a sublist of $PLIST whose first element is the
1141 found one is returned. Otherwise, @c NULL is returned. */
1143 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃ椫¤é»ØÄê¤ÎÃͤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤òõ¤¹.
1145 ´Ø¿ô mplist_find_by_value () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1146 ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢Ãͤ¬ $VAL
1147 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤«¤é»Ï¤Þ¤ë
1148 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1151 mplist_find_by_value (MPlist *plist, void *val)
1153 MPLIST_DO (plist, plist)
1155 if (MPLIST_VAL (plist) == val)
1164 @brief Return the next sublist of a property list.
1166 The mplist_next () function returns a pointer to the sublist of
1167 property list $PLIST, which begins at the second element in $PLIST. If the
1168 length of $PLIST is zero, it returns @c NULL. */
1170 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Î¼¡¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹.
1172 ´Ø¿ô mplist_next () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤Î 2
1173 ÈÖÌܤÎÍ×ÁǤ«¤é»Ï¤Þ¤ëÉôʬ¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$PLIST ¤ÎŤµ¤¬ 0
1174 ¤Ê¤é¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1177 mplist_next (MPlist *plist)
1179 return (MPLIST_TAIL_P (plist) ? NULL : plist->next);
1185 @brief Set the first property in a property list.
1187 The mplist_set () function sets the key and the value of the first
1188 property in property list $PLIST to $KEY and $VALUE, respectively.
1189 See the documentation of mplist_add () for the restriction on $KEY
1193 If the operation was successful, mplist_set () returns $PLIST.
1194 Otherwise, it returns @c NULL. */
1196 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤òÀßÄꤹ¤ë.
1198 ´Ø¿ô mplist_set () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1199 ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤ÈÃͤò¤½¤ì¤¾¤ì $KEY ¤È $VALUE ¤ËÀßÄꤹ¤ë¡£
1200 $KEY ¤È $VAL ¤ËÂФ¹¤ëÀ©¸Â¤Ë¤Ä¤¤¤Æ¤Ï¡¢mplist_add () ¤ÎÀâÌÀ¤ò»²¾È¡£
1203 ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð mplist_set () ¤Ï $PLIST ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1206 mplist_set (MPlist *plist, MSymbol key, void * val)
1210 if (! MPLIST_TAIL_P (plist))
1212 key = MPLIST_KEY (plist);
1213 M17N_OBJECT_UNREF (MPLIST_NEXT (plist));
1214 MPLIST_KEY (plist) = Mnil;
1215 if (key->managing_key)
1216 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1222 if (! MPLIST_TAIL_P (plist)
1223 && MPLIST_KEY (plist)->managing_key)
1224 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1225 if (val && key->managing_key)
1226 M17N_OBJECT_REF (val);
1227 MPLIST_SET (plist, key, val);
1235 @brief Return the length of a property list.
1237 The mplist_length () function returns the number of properties in
1238 property list $PLIST. */
1240 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎŤµ¤òÊÖ¤¹.
1242 ´Ø¿ô mplist_length () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST Ãæ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¿ô¤òÊÖ¤¹¡£ */
1245 mplist_length (MPlist *plist)
1249 for (n = 0; ! (MPLIST_TAIL_P (plist)); n++, plist = plist->next);
1256 @brief Return the key of the first property in a property list.
1258 The mplist_key () function returns the key of the first property
1259 in property list $PLIST. If the length of $PLIST is zero,
1260 it returns @c Mnil. */
1262 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤òÊÖ¤¹.
1264 ´Ø¿ô mplist_key () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1265 Ãæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤òÊÖ¤¹¡£$PLIST ¤ÎŤµ¤¬ 0 ¤Ê¤é¤Ð¡¢ @c Mnil
1269 mplist_key (MPlist *plist)
1271 return MPLIST_KEY (plist);
1277 @brief Return the value of the first property in a property list.
1279 The mplist_value () function returns the value of the first
1280 property in property list $PLIST. If the length of $PLIST
1281 is zero, it returns @c NULL. */
1283 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹.
1285 ´Ø¿ô mplist_value () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST Ãæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£
1286 $PLIST ¤ÎŤµ¤¬ 0 ¤Ê¤é¤Ð¡¢ @c Mnil ¤òÊÖ¤¹¡£ */
1289 mplist_value (MPlist *plist)
1291 return MPLIST_VAL (plist);
1295 @brief Generate a property list by deserializaing an M-text.
1297 The mplist_deserialize () function parses M-text $MT and returns a
1300 The syntax of $MT is as follows.
1302 MT ::= '(' ELEMENT * ')'
1304 ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
1306 SYMBOL ::= ascii-character-sequence
1308 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
1309 | '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
1311 M-TEXT ::= '"' character-sequence '"'
1313 Each alternatives of @c ELEMENT is assigned one of these keys: @c
1314 Msymbol, @c Minteger, @c Mtext, @c Mplist
1316 In an ascii-character-sequence, a backslash (\) is used as the escape
1317 character, which means that, for instance, <tt>"abc\ def"</tt>
1318 produces a symbol whose name is of length seven with the fourth
1319 character being a space. */
1321 @brief M-text ¤ò¥Ç¥·¥ê¥¢¥é¥¤¥º¤·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òºî¤ë.
1323 ´Ø¿ô mplist_deserialize () ¤Ï M-text $MT ¤ò²òÀϤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òÊÖ¤¹¡£
1325 $MT ¤Î¥·¥ó¥¿¥Ã¥¯¥¹¤Ï°Ê²¼¤ÎÄ̤ꡣ
1327 MT ::= '(' ELEMENT * ')'
1329 ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
1331 SYMBOL ::= ¥¢¥¹¥¡¼Ê¸»úÎó
1333 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
1334 | '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
1336 M-TEXT ::= '"' character-sequence '"'
1338 @c ELEMENT ¤Î³ÆÁªÂò»è¤Ï¥¡¼¡§@c Msymbol, @c Minteger, @c Mtext,
1339 @c Mplist ¤Î¤¤¤º¤ì¤«¤ò³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¡£
1341 ¥¢¥¹¥¡¼Ê¸»úÎóÆâ¤Ç¤Ï¡¢¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å (\) ¤¬¥¨¥¹¥±¡¼¥×ʸ»ú¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£¤¿¤È¤¨¤Ð
1342 <tt>"abc\ def"</tt> ¤Ï 4 ʸ»úÌܤ¬¶õÇòʸ»ú¤Ç¤¢¤êŤµ¤¬ 7
1343 ¤Ç¤¢¤ë»ý¤Ä̾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òÀ¸À®¤¹¤ë¡£ */
1346 mplist_deserialize (MText *mt)
1351 if (mt->format > MTEXT_FORMAT_UTF_8)
1353 if (MTEXT_READ_ONLY_P (mt))
1354 mt = tmp = mtext_cpy (mtext (), mt);
1356 mtext__adjust_format (mt, MTEXT_FORMAT_UTF_8);
1358 plist = mplist__from_string (MTEXT_DATA (mt), mtext_nbytes (mt));
1360 M17N_OBJECT_UNREF (tmp);
1366 /*** @addtogroup m17nDebug */
1371 @brief Dump a property list.
1373 The mdebug_dump_plist () function prints a property list $PLIST in
1374 a human readable way to the stderr. $INDENT specifies how many
1375 columns to indent the lines but the first one.
1378 This function returns $PLIST. */
1380 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¥À¥ó¥×¤¹¤ë.
1382 ´Ø¿ô mdebug_dump_plist () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò stderr
1383 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
1386 ¤³¤Î´Ø¿ô¤Ï $PLIST ¤òÊÖ¤¹¡£ */
1388 mdebug_dump_plist (MPlist *plist, int indent)
1390 char *prefix = (char *) alloca (indent + 1);
1394 memset (prefix, 32, indent);
1397 fprintf (stderr, "(");
1398 MPLIST_DO (pl, plist)
1403 fprintf (stderr, "\n%s ", prefix);
1404 dump_plist_element (pl, indent + 2);
1406 fprintf (stderr, ")");