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., 51 Franklin Street, Fifth Floor,
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
37 If each key of a plist is one of #Msymbol, #Mtext, #Minteger, and
38 #Mplist, the plist is called as @e well-formed and represented by
39 the following notation in the documentation.
42 PLIST ::= '(' ELEMENT * ')'
44 ELEMENT ::= INTEGER | SYMBOL | M-TEXT | PLIST
46 M-TEXT ::= '"' text data ... '"'
49 For instance, if a plist has four elements; integer -20, symbol of
50 name "sym", M-text of contents "abc", and plist of integer 10 and
51 symbol of name "another-symbol", it is represented as this:
53 (-20 sym "abc" (10 another-symbol))
59 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤È¤½¤ì¤Ë´Ø¤¹¤ë API.
61 @e ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È (¤Þ¤¿¤Ï @e plist) ¤Ï 0
62 ¸Ä°Ê¾å¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥ê¥¹¥È¤Ç¤¢¤ë¡£¥×¥í¥Ñ¥Æ¥£¤Ï @e ¥¡¼ ¤È @e ÃÍ
63 ¤«¤é¤Ê¤ë¡£¥¡¼¤Ï¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢ÃÍ¤Ï <tt>(void *)</tt>
64 ¤Ë¥¥ã¥¹¥È¤Ç¤¤ë¤â¤Î¤Ê¤é¤Ð²¿¤Ç¤âÎɤ¤¡£
66 ¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤¬ @e ´ÉÍý¥¡¼ ¤Ê¤é¤Ð¡¢¤½¤Î @e ÃÍ ¤Ï @e ´ÉÍý²¼
68 ¤Ç¤¢¤ë¡£¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¼«ÂΤâ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¡£ */
72 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
73 /*** @addtogroup m17nInternal
82 #include "m17n-misc.h"
84 #include "character.h"
89 static M17NObjectArray plist_table;
91 /** Set PLIST to a newly allocated plist object. */
93 #define MPLIST_NEW(plist) \
95 M17N_OBJECT (plist, free_plist, MERROR_PLIST); \
96 M17N_OBJECT_REGISTER (plist_table, plist); \
100 /** Set the element of PLIST to KEY and VAL. If PLIST is an anchor,
101 append a new anchor. */
103 #define MPLIST_SET(plist, key, val) \
105 MPLIST_KEY (plist) = (key); \
106 MPLIST_VAL (plist) = (val); \
107 if (! (plist)->next) \
108 MPLIST_NEW ((plist)->next); \
112 /** Set the element of PLIST to KEY and VAL. PLIST must be an anchor.
113 Append a new anchor and set PLIST to that anchor. */
115 #define MPLIST_SET_ADVANCE(plist, key, val) \
117 MPLIST_KEY (plist) = (key); \
118 MPLIST_VAL (plist) = (val); \
119 MPLIST_NEW ((plist)->next); \
120 plist = (plist)->next; \
125 free_plist (void *object)
127 MPlist *plist = (MPlist *) object;
130 MPlist *next = plist->next;
132 if (MPLIST_KEY (plist) != Mnil && MPLIST_KEY (plist)->managing_key)
133 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
134 M17N_OBJECT_UNREGISTER (plist_table, plist);
137 } while (plist && plist->control.ref_count == 1);
138 M17N_OBJECT_UNREF (plist);
143 /* Load a plist from a string. */
145 #define READ_CHUNK 0x10000
149 /* File pointer if the stream is associated with a file. Otherwise
153 unsigned char buffer[READ_CHUNK];
154 unsigned char *p, *pend;
158 get_byte (MStream *st)
162 if (! st->fp || st->eof)
164 n = fread (st->buffer, 1, READ_CHUNK, st->fp);
170 st->p = st->buffer + 1;
171 st->pend = st->buffer + n;
172 return st->buffer[0];
175 #define GETC(st) ((st)->p < (st)->pend ? *(st)->p++ : get_byte (st))
177 #define UNGETC(c, st) (--((st)->p))
179 /** Mapping table for reading a number. Hexadecimal chars
180 (0..9,A..F,a..F) are mapped to the corresponding numbers.
181 Apostrophe (code 39) is mapped to 254. All the other bytes are
183 unsigned char hex_mnemonic[256];
185 /** Mapping table for escaped characters. Mnemonic characters (e, b,
186 f, n, r, or t) that follows '\' are mapped to the corresponding
187 character code. All the other bytes are mapped to themselves. */
188 unsigned char escape_mnemonic[256];
191 /** Read an integer from the stream ST. It is assumed that we have
192 already read one character C. */
195 read_decimal (MStream *st, int c)
199 while (c >= '0' && c <= '9')
201 num = (num * 10) + (c - '0');
210 /** Read an unsigned from the stream ST. */
213 read_hexadesimal (MStream *st)
218 while ((c = GETC (st)) != EOF
219 && (n = hex_mnemonic[c]) < 16)
220 num = (num << 4) | n;
227 /** Read an M-text element from ST, and add it to LIST. Return a list
228 for the next element. */
230 #define READ_MTEXT_BUF_SIZE 256
233 read_mtext_element (MPlist *plist, MStream *st, int skip)
236 int chars[READ_MTEXT_BUF_SIZE];
237 unsigned char bytes[sizeof (int) * READ_MTEXT_BUF_SIZE];
239 unsigned char *bytes = buffer.bytes;
240 int nbytes = sizeof (int) * READ_MTEXT_BUF_SIZE;
246 while ((c = GETC (st)) != EOF && c != '"')
257 if (c == 'x' || c == 'u')
261 c = read_hexadesimal (st);
269 c = escape_mnemonic[c];
274 if (is_char && ! chars)
276 chars = buffer.chars;
277 for (j = i - 1; j >= 0; j--)
279 nchars = READ_MTEXT_BUF_SIZE;
280 if (bytes != buffer.bytes)
289 if (chars == buffer.chars)
291 MTABLE_MALLOC (chars, nchars, MERROR_PLIST);
292 memcpy (chars, buffer.chars, sizeof (int) * i);
295 MTABLE_REALLOC (chars, nchars, MERROR_PLIST);
301 if (i + MAX_UTF8_CHAR_BYTES >= nbytes)
304 if (bytes == buffer.bytes)
306 MTABLE_MALLOC (bytes, nbytes, MERROR_PLIST);
307 memcpy (bytes, buffer.bytes, i);
310 MTABLE_REALLOC (bytes, nbytes, MERROR_PLIST);
323 mt = mtext__from_data (chars, i, MTEXT_FORMAT_UTF_32, 1);
324 if (chars != buffer.chars)
329 mt = mtext__from_data (bytes, i, MTEXT_FORMAT_UTF_8, 1);
330 if (bytes != buffer.bytes)
333 MPLIST_SET_ADVANCE (plist, Mtext, mt);
339 read_character (MStream *st, int c)
341 unsigned char buf[MAX_UTF8_CHAR_BYTES + 1];
342 int len = CHAR_BYTES_BY_HEAD (c);
346 for (i = 1; i < len; i++)
350 || (c & 0xC0) != 0x80)
355 c = STRING_CHAR_UTF8 (buf);
362 /** Read a symbol element from ST, and add it to LIST. Return a list
363 for the next element. */
366 read_symbol_element (MPlist *plist, MStream *st, int c, int skip)
368 unsigned char buffer[1024];
370 unsigned char *buf = buffer;
376 && c != ')' && c != '(' && c != '"')
383 MTABLE_MALLOC (buf, bufsize, MERROR_PLIST);
384 memcpy (buf, buffer, i);
387 MTABLE_REALLOC (buf, bufsize, MERROR_PLIST);
394 c = escape_mnemonic[c];
406 MPLIST_SET_ADVANCE (plist, Msymbol, msymbol ((char *) buf));
413 /** Read an integer element from ST, and add it to LIST. Return a
414 list for the next element. It is assumed that we have already
415 read the character C. */
418 read_integer_element (MPlist *plist, MStream *st, int c, int skip)
428 return read_symbol_element (plist, st, '#', skip);
430 num = read_hexadesimal (st);
435 num = (c == 'x' ? read_hexadesimal (st) : read_decimal (st, c));
444 if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c))
447 num = read_character (st, c);
454 else if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c))
455 num = escape_mnemonic[c];
457 num = read_character (st, c);
463 if (c < '0' || c > '9')
466 return read_symbol_element (plist, st, '-', skip);
468 num = - read_decimal (st, c);
471 num = read_decimal (st, c);
474 MPLIST_SET_ADVANCE (plist, Minteger, (void *) num);
478 /* Read an element of various type from stream ST, and add it to LIST.
479 Return a list for the next element. The element type is decided by
480 the first token character found as below:
483 '0'..'9', '-': integer
484 '?': integer representing character code
485 the other ASCII letters: symbol
487 If KEYS is not NULL, it is a plist contains target keys and stop
488 keys. In this caes, read only a plist whose key has value 1 in
489 KEYS, and return NULL when we encounter a plist whose key has value
490 0 in KEYS while skipping any other elements. */
493 read_element (MPlist *plist, MStream *st, MPlist *keys)
497 /* Skip separators and comments. */
500 while ((c = GETC (st)) != EOF && c <= ' ');
503 while ((c = GETC (st)) != EOF && c != '\n');
514 p = read_element (p, st, NULL);
515 if (keys && p && MPLIST_SYMBOL_P (pl))
517 if (MPLIST_TAIL_P (keys))
519 while ((p = read_element (p, st, NULL)));
520 MPLIST_SET_ADVANCE (plist, Mplist, pl);
527 MPLIST_FIND (p0, MPLIST_SYMBOL (pl));
528 if (! MPLIST_TAIL_P (p0) && ! MPLIST_VAL (p0))
530 M17N_OBJECT_UNREF (pl);
533 while ((p = read_element (p, st, NULL)));
534 if (! MPLIST_TAIL_P (p0))
536 MPLIST_SET_ADVANCE (plist, Mplist, pl);
540 M17N_OBJECT_UNREF (pl);
546 while ((p = read_element (p, st, NULL)));
547 MPLIST_SET_ADVANCE (plist, Mplist, pl);
552 return (read_mtext_element (plist, st, keys ? 1 : 0));
553 if ((c >= '0' && c <= '9') || c == '-' || c == '?' || c == '#')
554 return (read_integer_element (plist, st, c, keys ? 1 : 0));
555 if (c == EOF || c == ')')
557 return (read_symbol_element (plist, st, c, keys ? 1 : 0));
560 #define PUTC(MT, C) \
563 mtext_cat_char ((MT), (C)); \
565 putc ((C), stderr); \
568 #define PUTS(MT, STR) \
571 MTEXT_CAT_ASCII ((MT), (STR)); \
573 fputs ((STR), stderr); \
578 write_symbol (MText *mt, MSymbol sym)
586 char *name = MSYMBOL_NAME (sym);
592 if (*name <= ' ' || *name == '\\' || *name == '"'
593 || *name == '(' || *name == ')')
602 write_element (MText *mt, MPlist *plist, int indent)
604 if (MPLIST_SYMBOL_P (plist))
606 write_symbol (mt, MPLIST_SYMBOL (plist));
608 else if (MPLIST_INTEGER_P (plist))
610 int num = MPLIST_INTEGER (plist);
613 sprintf (buf, "%d", num);
616 else if (MPLIST_PLIST_P (plist))
621 plist = MPLIST_PLIST (plist);
625 MPLIST_DO (pl, plist)
629 if (indent > 0 && (MPLIST_PLIST_P (pl) || MPLIST_MTEXT_P (pl)))
636 for (i = 1; i < indent; i++)
641 write_element (mt, pl, indent);
643 newline = (MPLIST_PLIST_P (pl) || MPLIST_MTEXT_P (pl));
647 else if (MPLIST_MTEXT_P (plist))
649 MText *this_mt = MPLIST_MTEXT (plist);
650 int from = 0, to = mtext_nchars (this_mt);
651 int stop1 = 0, stop2 = 0;
653 if (! mt && this_mt->format > MTEXT_FORMAT_UTF_8)
655 this_mt = mtext_dup (this_mt);
656 mtext__adjust_format (this_mt, MTEXT_FORMAT_UTF_8);
666 if ((stop1 = mtext_character (this_mt, from, to, '"')) < 0)
671 if ((stop2 = mtext_character (this_mt, from, to, '\\')) < 0)
675 stop = stop1++, escaped = '"';
677 stop = stop2++, escaped = '\\';
679 mtext_copy (mt, mtext_nchars (mt), this_mt, from, stop);
682 unsigned char *data = MTEXT_DATA (this_mt);
683 unsigned char *beg = data + mtext__char_to_byte (this_mt, from);
684 unsigned char *end = data + mtext__char_to_byte (this_mt, stop);
687 putc (*beg, stderr), beg++;
696 if (this_mt != MPLIST_MTEXT (plist))
697 M17N_OBJECT_UNREF (this_mt);
699 else if (MPLIST_STRING_P (plist))
701 char *str = MPLIST_STRING (plist);
705 MText *this_mt = mtext__from_data (str, strlen (str),
706 MTEXT_FORMAT_UTF_8, 0);
708 mtext_copy (mt, mtext_nchars (mt),
709 this_mt, 0, mtext_nchars (this_mt));
710 M17N_OBJECT_UNREF (this_mt);
713 fprintf (stderr, "%s", str);
717 write_symbol (mt, MPLIST_KEY (plist));
719 if (MPLIST_NESTED_P (plist))
720 write_element (mt, plist, indent + 1);
725 sprintf (buf, "%04X", (unsigned) MPLIST_VAL (plist));
738 M17N_OBJECT_ADD_ARRAY (plist_table, "Plist");
740 Minteger = msymbol ("integer");
741 Mplist = msymbol_as_managing_key ("plist");
742 Mtext = msymbol_as_managing_key ("mtext");
744 for (i = 0; i < 256; i++)
745 hex_mnemonic[i] = 255;
746 for (i = '0'; i <= '9'; i++)
747 hex_mnemonic[i] = i - '0';
748 for (i = 'A'; i <= 'F'; i++)
749 hex_mnemonic[i] = i - 'A' + 10;
750 for (i = 'a'; i <= 'f'; i++)
751 hex_mnemonic[i] = i - 'a' + 10;
752 for (i = 0; i < 256; i++)
753 escape_mnemonic[i] = i;
754 escape_mnemonic['e'] = 27;
755 escape_mnemonic['b'] = '\b';
756 escape_mnemonic['f'] = '\f';
757 escape_mnemonic['n'] = '\n';
758 escape_mnemonic['r'] = '\r';
759 escape_mnemonic['t'] = '\t';
760 escape_mnemonic['\\'] = '\\';
771 /* Parse this form of PLIST:
772 (symbol:KEY1 TYPE1:VAL1 symbol:KEY2 TYPE2:VAL2 ...)
773 and return a newly created plist of this form:
774 (KEY1:VAL1 KEY2:VAL2 ...) */
777 mplist__from_plist (MPlist *plist)
783 while (! MPLIST_TAIL_P (plist))
787 if (! MPLIST_SYMBOL_P (plist))
788 MERROR (MERROR_PLIST, NULL);
789 key = MPLIST_SYMBOL (plist);
790 plist = MPLIST_NEXT (plist);
791 type = MPLIST_KEY (plist);
792 if (type->managing_key && MPLIST_VAL (plist))
793 M17N_OBJECT_REF (MPLIST_VAL (plist));
794 MPLIST_SET_ADVANCE (p, key, MPLIST_VAL (plist));
795 plist = MPLIST_NEXT (plist);
800 /** Parse this form of PLIST:
801 ((symbol:KEY1 ANY:VAL1 ... ) (symbol:KEY2 ANY:VAL2 ...) ...)
802 and return a newly created plist of this form:
803 (KEY1:(ANY:VAL1 ...) KEY2:(ANY:VAL2 ...) ...)
804 ANY can be any type. */
807 mplist__from_alist (MPlist *plist)
813 MPLIST_DO (plist, plist)
817 if (! MPLIST_PLIST_P (plist))
818 MERROR (MERROR_PLIST, NULL);
819 elt = MPLIST_PLIST (plist);
820 if (! MPLIST_SYMBOL_P (elt))
821 MERROR (MERROR_PLIST, NULL);
822 MPLIST_SET_ADVANCE (p, MPLIST_SYMBOL (elt), MPLIST_NEXT (elt));
823 M17N_OBJECT_REF (MPLIST_NEXT (elt));
830 mplist__from_file (FILE *fp, MPlist *keys)
837 st.p = st.pend = st.buffer;
840 while ((pl = read_element (pl, &st, keys)));
845 /** Parse $STR of $N bytes and return a property list object. $FORMAT
846 must be either @c MTEXT_FORMAT_US_ASCII or @c MTEXT_FORMAT_UTF_8,
847 and controls how to produce @c STRING or @c M-TEXT in the
848 following definition.
850 The syntax of $STR is as follows.
852 PLIST ::= '(' ELEMENT * ')'
854 ELEMENT ::= SYMBOL | INTEGER | UNSIGNED | STRING | M-TEXT | PLIST
856 SYMBOL ::= ascii-character-sequence
858 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
860 UNSIGNED ::= '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
862 M-TEXT ::= '"' byte-sequence '"'
864 Each kind of @c ELEMENT is assigned one of these keys:
865 @c Msymbol, @c Mint, @c Munsigned, @c Mtext, @c Mplist
867 In an ascii-character-sequence, a backslush (\) is used as the escape
868 character, which means that, for instance, <tt>"abc\ def"</tt>
869 produces a symbol whose name is of length seven with the fourth
870 character being a space.
872 In a byte-sequence, "\r", "\n", "\e", and "\t" are replaced by CR,
873 NL, ESC, and TAB character respectively, "\xXX" are replaced by
874 byte 0xXX. After this replacement, the byte-sequence is decoded
875 into M-TEXT by $CODING. */
878 mplist__from_string (unsigned char *str, int n)
889 while ((pl = read_element (pl, &st, NULL)));
894 mplist__serialize (MText *mt, MPlist *plist, int pretty)
897 int separator = pretty ? '\n' : ' ';
899 MPLIST_DO (pl, plist)
902 mtext_cat_char (mt, separator);
903 write_element (mt, pl, pretty ? 0 : -1);
906 mtext_cat_char (mt, separator);
911 @brief Concatenate two plists.
913 The mplist__conc () function concatenates plist $TAIL at the end of
914 plist $PLIST and return $PLIST. If $TAIL is empty, return $PLIST
915 without modifying it. */
918 mplist__conc (MPlist *plist, MPlist *tail)
922 if (MPLIST_TAIL_P (tail))
924 MPLIST_DO (pl, plist);
925 MPLIST_KEY (pl) = MPLIST_KEY (tail);
926 MPLIST_VAL (pl) = MPLIST_VAL (tail);
927 if (MPLIST_KEY (pl)->managing_key)
928 M17N_OBJECT_REF (MPLIST_VAL (pl));
929 tail = MPLIST_NEXT (tail);
930 MPLIST_NEXT (pl) = tail;
931 M17N_OBJECT_REF (tail);
937 @brief Discard a property at the beginning of a property list.
939 The mplist__pop_unref () function removes a property at the
940 beginning of property list $PLIST, and if the property value is a
941 managed object, unref it. As a result, the second key and value
942 of the original $PLIST become the first of those of the new
946 mplist__pop_unref (MPlist *plist)
951 if (MPLIST_TAIL_P (plist))
953 key = MPLIST_KEY (plist);
954 val = mplist_pop (plist);
955 if (key->managing_key)
956 M17N_OBJECT_UNREF (val);
960 @brief Search for an element of an alist represented by a plist.
962 The mplist__assq () function treats $PLIST as an association list
963 (elements are plists (key is #Mplist) whose first element is a
964 symbol (key is #Msymbol)), and find an element whose first element
965 has key #Msymbol and value $KEY.
967 Non-plist elements of $PLIST are ignored.
970 This function returns a found element or NULL if no element
971 matches with $KEY. */
974 mplist__assq (MPlist *plist, MSymbol key)
976 MPLIST_DO (plist, plist)
977 if (MPLIST_PLIST_P (plist))
979 MPlist *pl = MPLIST_PLIST (plist);
981 if (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == key)
988 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
993 /*** @addtogroup m17nPlist */
998 @brief Symbol whose name is "integer".
1000 The symbol @c Minteger has the name <tt>"integer"</tt>. The value
1001 of a property whose key is @c Minteger must be an integer. */
1003 @brief "integer" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
1005 ¥·¥ó¥Ü¥ë @c Minteger ¤Ï <tt>"integer"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¡£¥¡¼¤¬
1006 @c Minteger ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤÏÀ°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
1012 @brief Symbol whose name is "plist".
1014 The symbol @c Mplist has the name <tt>"plist"</tt>. It is a
1015 managing key. A value of a property whose key is @c Mplist must
1018 @brief "plist" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
1020 ¥·¥ó¥Ü¥ë @c Mplist ¤Ï <tt>"plist"</tt>
1021 ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¡£¤³¤ì¤Ï´ÉÍý¥¡¼¤Ç¤¢¤ë¡£¥¡¼¤¬ @c Mplist
1022 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¤Ï plist ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
1028 @brief Symbol whose name is "mtext".
1030 The symbol @c Mtext has the name <tt>"mtext"</tt>. It is a
1031 managing key. A value of a property whose key is @c Mtext must be an
1035 @brief "mtext" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
1037 ¥·¥ó¥Ü¥ë @c Mtext ¤Ï <tt>"mtext"</tt>
1038 ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä´ÉÍý¥¡¼¤Ç¤¢¤ë¡£¥¡¼¤¬ @c Mtext
1039 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¤Ï M-text ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
1045 @brief Create a property list object.
1047 The mplist () function returns a newly created property list
1048 object of length zero.
1051 This function returns a newly created property list.
1054 This function never fails. */
1056 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë.
1058 ´Ø¿ô mplist () ¤ÏŤµ 0 ¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò¿·¤·¤¯ºî¤Ã¤ÆÊÖ¤¹¡£
1061 ¤³¤Î´Ø¿ô¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹¡£
1064 ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£ */
1077 @brief Copy a property list.
1079 The mplist_copy () function copies property list $PLIST. In the
1080 copy, the values are the same as those of $PLIST.
1083 This function returns a newly created plist which is a copy of
1087 This function never fails. */
1089 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¥³¥Ô¡¼¤¹¤ë.
1091 ´Ø¿ô mplist_copy () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1092 ¤ò¥³¥Ô¡¼¤¹¤ë¡£¥³¥Ô¡¼¤Î¤¹¤Ù¤Æ¤ÎÃͤϥ³¥Ô¡¼¸µ $PLIST ¤ÎÃͤÈƱ¤¸¤Ç¤¢¤ë¡£
1095 ¤³¤Î´Ø¿ô¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¡¢$PLIST ¤Î¥³¥Ô¡¼¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òÊÖ¤¹¡£
1098 ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£ */
1101 mplist_copy (MPlist *plist)
1103 MPlist *copy = mplist (), *pl = copy;
1105 MPLIST_DO (plist, plist)
1106 pl = mplist_add (pl, MPLIST_KEY (plist), MPLIST_VAL (plist));
1113 @brief Set the value of a property in a property list.
1115 The mplist_put () function searches property list $PLIST
1116 from the beginning for a property whose key is $KEY. If such a
1117 property is found, its value is changed to $VALUE. Otherwise, a
1118 new property whose key is $KEY and value is $VALUE is appended at
1119 the end of $PLIST. See the documentation of mplist_add () for
1120 the restriction on $KEY and $VAL.
1122 If $KEY is a managing key, $VAL must be a managed object. In this
1123 case, the reference count of the old value, if not @c NULL, is
1124 decremented by one, and that of $VAL is incremented by one.
1127 If the operation was successful, mplist_put () returns a sublist of
1128 $PLIST whose first element is the just modified or added one.
1129 Otherwise, it returns @c NULL. */
1131 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÀßÄꤹ¤ë.
1133 ´Ø¿ô mplist_put () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥¡¼¤¬
1134 $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤò $VALUE
1135 ¤ËÊѹ¹¤¹¤ë¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¥¡¼¤¬ $KEY ¤ÇÃͤ¬ $VALUE
1136 ¤Ç¤¢¤ë¿·¤·¤¤¥×¥í¥Ñ¥Æ¥£¤¬ $PLIST ¤ÎËöÈø¤ËÄɲ䵤ì¤ë¡£$KEY ¤È $VAL
1137 ¤ËÂФ¹¤ëÀ©¸Â¤Ë¤Ä¤¤¤Æ¤Ï¡¢mplist_add () ¤ÎÀâÌÀ¤ò»²¾È¡£
1139 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢
1140 $VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢¸Å¤¤Ãͤλ²¾È¿ô¤Ï
1141 @c NULL ¤Ç¤Ê¤±¤ì¤Ð 1 ¸º¤é¤µ¤ì¡¢$VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1144 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mplist_put () ¤ÏÊѹ¹¤µ¤ì¤¿¤«Äɲ䵤줿Í×ÁǤ«¤é»Ï¤Þ¤ë
1145 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1148 mplist_put (MPlist *plist, MSymbol key, void *val)
1151 MERROR (MERROR_PLIST, NULL);
1152 MPLIST_FIND (plist, key);
1153 if (key->managing_key)
1155 if (! MPLIST_TAIL_P (plist))
1156 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1158 M17N_OBJECT_REF (val);
1160 MPLIST_SET (plist, key, val);
1167 @brief Get the value of a property in a property list.
1169 The mplist_get () function searches property list $PLIST from the
1170 beginning for a property whose key is $KEY. If such a property is
1171 found, its value is returned as the type of <tt>(void *)</tt>. If
1172 not found, @c NULL is returned.
1174 When @c NULL is returned, there are two possibilities: one is the
1175 case where no property is found (see above); the other is the case
1176 where a property is found and its value is @c NULL. In case that
1177 these two cases must be distinguished, use the mplist_find_by_key ()
1180 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
1182 ´Ø¿ô mplist_get () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥¡¼
1183 ¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤò
1184 <tt>(void *)</tt> ·¿¤ÇÊÖ¤¹¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
1186 @c NULL ¤¬Ê֤俺ݤˤÏÆó¤Ä¤Î²ÄǽÀ¤¬¤¢¤ë:
1187 ¾åµ¤Î¤è¤¦¤Ë¥×¥í¥Ñ¥Æ¥£¤¬¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¾ì¹ç¤È¡¢¥×¥í¥Ñ¥Æ¥£¤¬¸«¤Ä¤«¤ê¡¢¤½¤ÎÃͤ¬
1188 @c NULL ¤Ç¤¢¤ë¾ì¹ç¤Ç¤¢¤ë¡£¤³¤ì¤é¤ò¶èÊ̤¹¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤Ë¤Ï´Ø¿ô
1189 mplist_find_by_key () ¤ò»È¤¦¤³¤È¡£ */
1193 mplist_find_by_key () */
1196 mplist_get (MPlist *plist, MSymbol key)
1198 MPLIST_FIND (plist, key);
1199 return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_VAL (plist));
1205 @brief Set the value (function pointer) of a property in a property list.
1207 The mplist_put_func () function is like mplist_put () but for
1208 settting function pointer $FUNC in property list $PLIST for key
1213 mplist_put (), M17N_FUNC () */
1216 mplist_put_func (MPlist *plist, MSymbol key, M17NFunc func)
1219 MERROR (MERROR_PLIST, NULL);
1222 MPLIST_FIND (plist, key);
1223 if (MPLIST_TAIL_P (plist) || MPLIST_VAL_FUNC_P (plist))
1225 plist = MPLIST_NEXT (plist);
1228 MPLIST_KEY (plist) = (key);
1229 MPLIST_FUNC (plist) = func;
1230 MPLIST_SET_VAL_FUNC_P (plist);
1232 MPLIST_NEW ((plist)->next);
1239 @brief Get the value (function pointer) of a property in a property list.
1241 The mplist_get_func () funciont is like mplist_get () but for
1242 getting a function pointer from property list $PLIST by key $KEY. */
1248 mplist_get_func (MPlist *plist, MSymbol key)
1252 MPLIST_FIND (plist, key);
1253 if (MPLIST_TAIL_P (plist) || MPLIST_VAL_FUNC_P (plist))
1255 plist = MPLIST_NEXT (plist);
1257 return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_FUNC (plist));
1263 @brief Add a property at the end of a property list.
1265 The mplist_add () function appends at the end of property list
1266 $PLIST a property whose key is $KEY and value is $VAL. $KEY can
1267 be any symbol other than @c Mnil.
1269 If $KEY is a managing key, $VAL must be a managed object. In this
1270 case, the reference count of $VAL is incremented by one.
1273 If the operation was successful, mplist_add () returns a sublist of
1274 $PLIST whose first element is the just added one. Otherwise, it
1277 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈËöÈø¤Ë¥×¥í¥Ñ¥Æ¥£¤òÄɲ乤ë.
1279 ´Ø¿ô mplist_add () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎËöÈø¤Ë¥¡¼¤¬ $KEY
1280 ¤ÇÃͤ¬ $VAL ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤òÄɲ乤롣$KEY ¤Ï¡¢@c Mnil °Ê³°¤ÎǤ°Õ¤Î¥·¥ó¥Ü¥ë¤Ç¤è¤¤¡£
1282 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢$VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢
1283 $VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1286 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mplist_add () ¤ÏÄɲ䵤줿Í×ÁǤ«¤é»Ï¤Þ¤ë $PLIST
1287 ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1290 mplist_add (MPlist *plist, MSymbol key, void *val)
1293 MERROR (MERROR_PLIST, NULL);
1294 MPLIST_FIND (plist, Mnil);
1295 if (val && key->managing_key)
1296 M17N_OBJECT_REF (val);
1297 MPLIST_KEY (plist) = key;
1298 MPLIST_VAL (plist) = val;
1299 MPLIST_NEW (plist->next);
1306 @brief Add a property at the beginning of a property list.
1308 The mplist_push () function inserts at the beginning of property
1309 list $PLIST a property whose key is $KEY and value is $VAL.
1311 If $KEY is a managing key, $VAL must be a managed object. In this
1312 case, the reference count of $VAL is incremented by one.
1315 If the operation was successful, this function returns $PLIST.
1316 Otherwise, it returns @c NULL. */
1318 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤Ë¥×¥í¥Ñ¥Æ¥£¤òÁÞÆþ¤¹¤ë.
1320 ´Ø¿ô mplist_push () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Ë¥¡¼¤¬ $KEY
1321 ¤ÇÃͤ¬ $VAL ¤Ç¤¢¤ë¥ª¥Ö¥¸¥§¥¯¥È¤òÁÞÆþ¤¹¤ë¡£
1323 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢$VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢
1324 $VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1327 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï $PLIST ¤òÊÖ¤·¡¢¤½¤¦¤Ç¤Ê¤±¤ì¤Ð@c NULL
1331 mplist_push (MPlist *plist, MSymbol key, void *val)
1336 MERROR (MERROR_PLIST, NULL);
1338 MPLIST_KEY (pl) = MPLIST_KEY (plist);
1339 MPLIST_VAL (pl) = MPLIST_VAL (plist);
1340 MPLIST_NEXT (pl) = MPLIST_NEXT (plist);
1342 if (val && key->managing_key)
1343 M17N_OBJECT_REF (val);
1344 MPLIST_KEY (plist) = key;
1345 MPLIST_VAL (plist) = val;
1352 @brief Remove a property at the beginning of a property list.
1354 The mplist_pop () function removes a property at the beginning of
1355 property list $PLIST. As a result, the second key and value of
1356 the $PLIST become the first ones.
1359 If the operation was successful, this function return the value of
1360 the just popped property. Otherwise, it returns @c NULL. */
1362 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤«¤é¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë.
1364 ´Ø¿ô mplist_pop () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Î¥×¥í¥Ñ¥Æ¥£¤òºï
1365 ½ü¤¹¤ë¡£·ë²Ì¤È¤·¤Æ¡¢¸µ¤Î2ÈÖÌܤΥ¡¼¤ÈÃͤ¬ÀèƬ¤Î¥¡¼¤ÈÃͤˤʤ롣
1368 ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ïºï½ü¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
1372 mplist_pop (MPlist *plist)
1377 if (MPLIST_TAIL_P (plist))
1379 val = MPLIST_VAL (plist);
1380 next = MPLIST_NEXT (plist);
1381 MPLIST_KEY (plist) = MPLIST_KEY (next);
1382 MPLIST_VAL (plist) = MPLIST_VAL (next);
1383 if (MPLIST_KEY (plist) != Mnil
1384 && MPLIST_KEY (plist)->managing_key
1385 && MPLIST_VAL (plist))
1386 M17N_OBJECT_REF (MPLIST_VAL (plist));
1387 MPLIST_NEXT (plist) = MPLIST_NEXT (next);
1389 M17N_OBJECT_REF (plist->next);
1390 M17N_OBJECT_UNREF (next);
1396 @brief Find a property of a specific key in a property list.
1398 The mplist_find_by_key () function searches property list
1399 $PLIST from the beginning for a property whose key is $KEY. If
1400 such a property is found, a sublist of $PLIST whose first element
1401 is the found one is returned. Otherwise, @c NULL is returned.
1403 If $KEY is @c Mnil, it returns a sublist of $PLIST whose
1404 first element is the last one of $PLIST. */
1406 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃ椫¤é»ØÄê¤Î¥¡¼¤ò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤òõ¤¹.
1408 ´Ø¿ô mplist_find_by_key () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1409 ¤ò»Ï¤á¤«¤éõ ¤·¤Æ¡¢¥¡¼¤¬ $KEY
1410 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤«¤é»Ï¤Þ¤ë
1411 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
1413 $KEY ¤¬ @c Mnil ¤Ê¤é¤Ð¡¢$PLIST ¤ÎºÇ¸å¤ÎÍ×ÁǤ«¤é»Ï¤Þ¤ëÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£ */
1416 mplist_find_by_key (MPlist *plist, MSymbol key)
1418 MPLIST_FIND (plist, key);
1419 return (MPLIST_TAIL_P (plist)
1420 ? (key == Mnil ? plist : NULL)
1426 @brief Find a property of a specific value in a property list.
1428 The mplist_find_by_value () function searches property list $PLIST
1429 from the beginning for a property whose value is $VAL. If such a
1430 property is found, a sublist of $PLIST whose first element is the
1431 found one is returned. Otherwise, @c NULL is returned. */
1433 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃ椫¤é»ØÄê¤ÎÃͤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤òõ¤¹.
1435 ´Ø¿ô mplist_find_by_value () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1436 ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢Ãͤ¬ $VAL
1437 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤«¤é»Ï¤Þ¤ë
1438 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1441 mplist_find_by_value (MPlist *plist, void *val)
1443 MPLIST_DO (plist, plist)
1445 if (MPLIST_VAL (plist) == val)
1454 @brief Return the next sublist of a property list.
1456 The mplist_next () function returns a pointer to the sublist of
1457 property list $PLIST, which begins at the second element in $PLIST. If the
1458 length of $PLIST is zero, it returns @c NULL. */
1460 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Î¼¡¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹.
1462 ´Ø¿ô mplist_next () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤Î 2
1463 ÈÖÌܤÎÍ×ÁǤ«¤é»Ï¤Þ¤ëÉôʬ¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$PLIST ¤ÎŤµ¤¬ 0
1464 ¤Ê¤é¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1467 mplist_next (MPlist *plist)
1469 return (MPLIST_TAIL_P (plist) ? NULL : plist->next);
1475 @brief Set the first property in a property list.
1477 The mplist_set () function sets the key and the value of the first
1478 property in property list $PLIST to $KEY and $VALUE, respectively.
1479 See the documentation of mplist_add () for the restriction on $KEY
1483 If the operation was successful, mplist_set () returns $PLIST.
1484 Otherwise, it returns @c NULL. */
1486 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤òÀßÄꤹ¤ë.
1488 ´Ø¿ô mplist_set () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1489 ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤ÈÃͤò¤½¤ì¤¾¤ì $KEY ¤È $VALUE ¤ËÀßÄꤹ¤ë¡£
1490 $KEY ¤È $VAL ¤ËÂФ¹¤ëÀ©¸Â¤Ë¤Ä¤¤¤Æ¤Ï¡¢mplist_add () ¤ÎÀâÌÀ¤ò»²¾È¡£
1493 ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð mplist_set () ¤Ï $PLIST ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1496 mplist_set (MPlist *plist, MSymbol key, void * val)
1500 if (! MPLIST_TAIL_P (plist))
1502 key = MPLIST_KEY (plist);
1503 M17N_OBJECT_UNREF (MPLIST_NEXT (plist));
1504 MPLIST_KEY (plist) = Mnil;
1505 if (key->managing_key)
1506 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1512 if (val && key->managing_key)
1513 M17N_OBJECT_REF (val);
1514 if (! MPLIST_TAIL_P (plist)
1515 && MPLIST_KEY (plist)->managing_key)
1516 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1517 MPLIST_SET (plist, key, val);
1525 @brief Return the length of a property list.
1527 The mplist_length () function returns the number of properties in
1528 property list $PLIST. */
1530 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎŤµ¤òÊÖ¤¹.
1532 ´Ø¿ô mplist_length () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST Ãæ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¿ô¤òÊÖ¤¹¡£ */
1535 mplist_length (MPlist *plist)
1539 for (n = 0; ! (MPLIST_TAIL_P (plist)); n++, plist = plist->next);
1546 @brief Return the key of the first property in a property list.
1548 The mplist_key () function returns the key of the first property
1549 in property list $PLIST. If the length of $PLIST is zero,
1550 it returns @c Mnil. */
1552 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤òÊÖ¤¹.
1554 ´Ø¿ô mplist_key () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1555 Ãæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤òÊÖ¤¹¡£$PLIST ¤ÎŤµ¤¬ 0 ¤Ê¤é¤Ð¡¢ @c Mnil
1559 mplist_key (MPlist *plist)
1561 return MPLIST_KEY (plist);
1567 @brief Return the value of the first property in a property list.
1569 The mplist_value () function returns the value of the first
1570 property in property list $PLIST. If the length of $PLIST
1571 is zero, it returns @c NULL. */
1573 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹.
1575 ´Ø¿ô mplist_value () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST Ãæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£
1576 $PLIST ¤ÎŤµ¤¬ 0 ¤Ê¤é¤Ð¡¢ @c Mnil ¤òÊÖ¤¹¡£ */
1579 mplist_value (MPlist *plist)
1581 return MPLIST_VAL (plist);
1585 @brief Generate a property list by deserializing an M-text.
1587 The mplist_deserialize () function parses M-text $MT and returns a
1590 The syntax of $MT is as follows.
1592 MT ::= '(' ELEMENT * ')'
1594 ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
1596 SYMBOL ::= ascii-character-sequence
1598 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
1599 | '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
1601 M-TEXT ::= '"' character-sequence '"'
1603 Each alternatives of @c ELEMENT is assigned one of these keys: @c
1604 Msymbol, @c Minteger, @c Mtext, @c Mplist
1606 In an ascii-character-sequence, a backslash (\) is used as the escape
1607 character, which means that, for instance, <tt>"abc\ def"</tt>
1608 produces a symbol whose name is of length seven with the fourth
1609 character being a space. */
1611 @brief M-text ¤ò¥Ç¥·¥ê¥¢¥é¥¤¥º¤·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òºî¤ë.
1613 ´Ø¿ô mplist_deserialize () ¤Ï M-text $MT ¤ò²òÀϤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òÊÖ¤¹¡£
1615 $MT ¤Î¥·¥ó¥¿¥Ã¥¯¥¹¤Ï°Ê²¼¤ÎÄ̤ꡣ
1617 MT ::= '(' ELEMENT * ')'
1619 ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
1621 SYMBOL ::= ¥¢¥¹¥¡¼Ê¸»úÎó
1623 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
1624 | '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
1626 M-TEXT ::= '"' character-sequence '"'
1628 @c ELEMENT ¤Î³ÆÁªÂò»è¤Ï¥¡¼¡§@c Msymbol, @c Minteger, @c Mtext,
1629 @c Mplist ¤Î¤¤¤º¤ì¤«¤ò³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¡£
1631 ¥¢¥¹¥¡¼Ê¸»úÎóÆâ¤Ç¤Ï¡¢¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å (\) ¤¬¥¨¥¹¥±¡¼¥×ʸ»ú¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£¤¿¤È¤¨¤Ð
1632 <tt>"abc\ def"</tt> ¤Ï 4 ʸ»úÌܤ¬¶õÇòʸ»ú¤Ç¤¢¤êŤµ¤¬ 7
1633 ¤Ç¤¢¤ë»ý¤Ä̾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òÀ¸À®¤¹¤ë¡£ */
1636 mplist_deserialize (MText *mt)
1641 if (mt->format > MTEXT_FORMAT_UTF_8)
1643 if (MTEXT_READ_ONLY_P (mt))
1644 mt = tmp = mtext_cpy (mtext (), mt);
1646 mtext__adjust_format (mt, MTEXT_FORMAT_UTF_8);
1648 plist = mplist__from_string (MTEXT_DATA (mt), mtext_nbytes (mt));
1650 M17N_OBJECT_UNREF (tmp);
1656 /*** @addtogroup m17nDebug */
1661 @brief Dump a property list.
1663 The mdebug_dump_plist () function prints a property list $PLIST in
1664 a human readable way to the stderr. $INDENT specifies how many
1665 columns to indent the lines but the first one.
1668 This function returns $PLIST. */
1670 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¥À¥ó¥×¤¹¤ë.
1672 ´Ø¿ô mdebug_dump_plist () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò stderr
1673 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
1676 ¤³¤Î´Ø¿ô¤Ï $PLIST ¤òÊÖ¤¹¡£ */
1678 mdebug_dump_plist (MPlist *plist, int indent)
1680 char *prefix = (char *) alloca (indent + 1);
1683 memset (prefix, 32, indent);
1686 fprintf (stderr, "(");
1687 MPLIST_DO (pl, plist)
1690 fprintf (stderr, "\n%s ", prefix);
1691 write_element (NULL, pl, indent + 1);
1693 fprintf (stderr, ")");