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 similar to mplist_put () but for
1208 setting function pointer $FUNC in property list $PLIST for key
1212 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤Ë´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÀßÄꤹ¤ë.
1214 ´Ø¿ô mplist_put_func () ¤Ï´Ø¿ô mplist_put () ƱÍÍ¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1215 Ãæ¤Ç¥¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë¡£Ã¢¤·¤½¤ÎÃͤϴؿô¥Ý¥¤¥ó¥¿
1221 mplist_put (), M17N_FUNC () */
1224 mplist_put_func (MPlist *plist, MSymbol key, M17NFunc func)
1227 MERROR (MERROR_PLIST, NULL);
1230 MPLIST_FIND (plist, key);
1231 if (MPLIST_TAIL_P (plist) || MPLIST_VAL_FUNC_P (plist))
1233 plist = MPLIST_NEXT (plist);
1236 MPLIST_KEY (plist) = (key);
1237 MPLIST_FUNC (plist) = func;
1238 MPLIST_SET_VAL_FUNC_P (plist);
1240 MPLIST_NEW ((plist)->next);
1247 @brief Get the value (function pointer) of a property in a property list.
1249 The mplist_get_func () function is similar to mplist_get () but for
1250 getting a function pointer from property list $PLIST by key $KEY. */
1253 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤«¤é¥×¥í¥Ñ¥Æ¥£¤Î´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÆÀ¤ë.
1255 ´Ø¿ô mplist_get_func () ¤Ï´Ø¿ô mplist_get () ¤ÈƱÍͤˡ¢¥×¥í¥Ñ¥Æ¥£¥ê
1256 ¥¹¥È $PLIST Ãæ¤Ç¥¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¡¢Ã¢¤·´Ø¿ô¥Ý¥¤¥ó¥¿¡¢
1264 mplist_get_func (MPlist *plist, MSymbol key)
1266 MPLIST_FIND (plist, key);
1267 return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_FUNC (plist));
1273 @brief Add a property at the end of a property list.
1275 The mplist_add () function appends at the end of property list
1276 $PLIST a property whose key is $KEY and value is $VAL. $KEY can
1277 be any symbol other than @c Mnil.
1279 If $KEY is a managing key, $VAL must be a managed object. In this
1280 case, the reference count of $VAL is incremented by one.
1283 If the operation was successful, mplist_add () returns a sublist of
1284 $PLIST whose first element is the just added one. Otherwise, it
1287 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈËöÈø¤Ë¥×¥í¥Ñ¥Æ¥£¤òÄɲ乤ë.
1289 ´Ø¿ô mplist_add () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎËöÈø¤Ë¥¡¼¤¬ $KEY
1290 ¤ÇÃͤ¬ $VAL ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤òÄɲ乤롣$KEY ¤Ï¡¢@c Mnil °Ê³°¤ÎǤ°Õ¤Î¥·¥ó¥Ü¥ë¤Ç¤è¤¤¡£
1292 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢$VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢
1293 $VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1296 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mplist_add () ¤ÏÄɲ䵤줿Í×ÁǤ«¤é»Ï¤Þ¤ë $PLIST
1297 ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1300 mplist_add (MPlist *plist, MSymbol key, void *val)
1303 MERROR (MERROR_PLIST, NULL);
1304 MPLIST_FIND (plist, Mnil);
1305 if (val && key->managing_key)
1306 M17N_OBJECT_REF (val);
1307 MPLIST_KEY (plist) = key;
1308 MPLIST_VAL (plist) = val;
1309 MPLIST_NEW (plist->next);
1316 @brief Add a property at the beginning of a property list.
1318 The mplist_push () function inserts at the beginning of property
1319 list $PLIST a property whose key is $KEY and value is $VAL.
1321 If $KEY is a managing key, $VAL must be a managed object. In this
1322 case, the reference count of $VAL is incremented by one.
1325 If the operation was successful, this function returns $PLIST.
1326 Otherwise, it returns @c NULL. */
1328 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤Ë¥×¥í¥Ñ¥Æ¥£¤òÁÞÆþ¤¹¤ë.
1330 ´Ø¿ô mplist_push () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Ë¥¡¼¤¬ $KEY
1331 ¤ÇÃͤ¬ $VAL ¤Ç¤¢¤ë¥ª¥Ö¥¸¥§¥¯¥È¤òÁÞÆþ¤¹¤ë¡£
1333 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢$VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢
1334 $VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1337 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï $PLIST ¤òÊÖ¤·¡¢¤½¤¦¤Ç¤Ê¤±¤ì¤Ð@c NULL
1341 mplist_push (MPlist *plist, MSymbol key, void *val)
1346 MERROR (MERROR_PLIST, NULL);
1348 MPLIST_KEY (pl) = MPLIST_KEY (plist);
1349 MPLIST_VAL (pl) = MPLIST_VAL (plist);
1350 MPLIST_NEXT (pl) = MPLIST_NEXT (plist);
1352 if (val && key->managing_key)
1353 M17N_OBJECT_REF (val);
1354 MPLIST_KEY (plist) = key;
1355 MPLIST_VAL (plist) = val;
1362 @brief Remove a property at the beginning of a property list.
1364 The mplist_pop () function removes a property at the beginning of
1365 property list $PLIST. As a result, the second key and value of
1366 the $PLIST become the first ones.
1369 If the operation was successful, this function return the value of
1370 the just popped property. Otherwise, it returns @c NULL. */
1372 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤«¤é¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë.
1374 ´Ø¿ô mplist_pop () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Î¥×¥í¥Ñ¥Æ¥£¤òºï
1375 ½ü¤¹¤ë¡£·ë²Ì¤È¤·¤Æ¡¢¸µ¤Î2ÈÖÌܤΥ¡¼¤ÈÃͤ¬ÀèƬ¤Î¥¡¼¤ÈÃͤˤʤ롣
1378 ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ïºï½ü¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
1382 mplist_pop (MPlist *plist)
1387 if (MPLIST_TAIL_P (plist))
1389 val = MPLIST_VAL (plist);
1390 next = MPLIST_NEXT (plist);
1391 MPLIST_KEY (plist) = MPLIST_KEY (next);
1392 MPLIST_VAL (plist) = MPLIST_VAL (next);
1393 if (MPLIST_KEY (plist) != Mnil
1394 && MPLIST_KEY (plist)->managing_key
1395 && MPLIST_VAL (plist))
1396 M17N_OBJECT_REF (MPLIST_VAL (plist));
1397 MPLIST_NEXT (plist) = MPLIST_NEXT (next);
1399 M17N_OBJECT_REF (plist->next);
1400 M17N_OBJECT_UNREF (next);
1406 @brief Find a property of a specific key in a property list.
1408 The mplist_find_by_key () function searches property list
1409 $PLIST from the beginning for a property whose key is $KEY. If
1410 such a property is found, a sublist of $PLIST whose first element
1411 is the found one is returned. Otherwise, @c NULL is returned.
1413 If $KEY is @c Mnil, it returns a sublist of $PLIST whose
1414 first element is the last one of $PLIST. */
1416 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃ椫¤é»ØÄê¤Î¥¡¼¤ò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤òõ¤¹.
1418 ´Ø¿ô mplist_find_by_key () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1419 ¤ò»Ï¤á¤«¤éõ ¤·¤Æ¡¢¥¡¼¤¬ $KEY
1420 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤«¤é»Ï¤Þ¤ë
1421 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
1423 $KEY ¤¬ @c Mnil ¤Ê¤é¤Ð¡¢$PLIST ¤ÎºÇ¸å¤ÎÍ×ÁǤ«¤é»Ï¤Þ¤ëÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£ */
1426 mplist_find_by_key (MPlist *plist, MSymbol key)
1428 MPLIST_FIND (plist, key);
1429 return (MPLIST_TAIL_P (plist)
1430 ? (key == Mnil ? plist : NULL)
1436 @brief Find a property of a specific value in a property list.
1438 The mplist_find_by_value () function searches property list $PLIST
1439 from the beginning for a property whose value is $VAL. If such a
1440 property is found, a sublist of $PLIST whose first element is the
1441 found one is returned. Otherwise, @c NULL is returned. */
1443 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃ椫¤é»ØÄê¤ÎÃͤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤òõ¤¹.
1445 ´Ø¿ô mplist_find_by_value () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1446 ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢Ãͤ¬ $VAL
1447 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤«¤é»Ï¤Þ¤ë
1448 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1451 mplist_find_by_value (MPlist *plist, void *val)
1453 MPLIST_DO (plist, plist)
1455 if (MPLIST_VAL (plist) == val)
1464 @brief Return the next sublist of a property list.
1466 The mplist_next () function returns a pointer to the sublist of
1467 property list $PLIST, which begins at the second element in $PLIST. If the
1468 length of $PLIST is zero, it returns @c NULL. */
1470 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Î¼¡¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹.
1472 ´Ø¿ô mplist_next () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤Î 2
1473 ÈÖÌܤÎÍ×ÁǤ«¤é»Ï¤Þ¤ëÉôʬ¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$PLIST ¤ÎŤµ¤¬ 0
1474 ¤Ê¤é¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1477 mplist_next (MPlist *plist)
1479 return (MPLIST_TAIL_P (plist) ? NULL : plist->next);
1485 @brief Set the first property in a property list.
1487 The mplist_set () function sets the key and the value of the first
1488 property in property list $PLIST to $KEY and $VALUE, respectively.
1489 See the documentation of mplist_add () for the restriction on $KEY
1493 If the operation was successful, mplist_set () returns $PLIST.
1494 Otherwise, it returns @c NULL. */
1496 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤òÀßÄꤹ¤ë.
1498 ´Ø¿ô mplist_set () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1499 ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤ÈÃͤò¤½¤ì¤¾¤ì $KEY ¤È $VALUE ¤ËÀßÄꤹ¤ë¡£
1500 $KEY ¤È $VAL ¤ËÂФ¹¤ëÀ©¸Â¤Ë¤Ä¤¤¤Æ¤Ï¡¢mplist_add () ¤ÎÀâÌÀ¤ò»²¾È¡£
1503 ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð mplist_set () ¤Ï $PLIST ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1506 mplist_set (MPlist *plist, MSymbol key, void * val)
1510 if (! MPLIST_TAIL_P (plist))
1512 key = MPLIST_KEY (plist);
1513 M17N_OBJECT_UNREF (MPLIST_NEXT (plist));
1514 MPLIST_KEY (plist) = Mnil;
1515 if (key->managing_key)
1516 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1522 if (val && key->managing_key)
1523 M17N_OBJECT_REF (val);
1524 if (! MPLIST_TAIL_P (plist)
1525 && MPLIST_KEY (plist)->managing_key)
1526 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1527 MPLIST_SET (plist, key, val);
1535 @brief Return the length of a property list.
1537 The mplist_length () function returns the number of properties in
1538 property list $PLIST. */
1540 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎŤµ¤òÊÖ¤¹.
1542 ´Ø¿ô mplist_length () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST Ãæ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¿ô¤òÊÖ¤¹¡£ */
1545 mplist_length (MPlist *plist)
1549 for (n = 0; ! (MPLIST_TAIL_P (plist)); n++, plist = plist->next);
1556 @brief Return the key of the first property in a property list.
1558 The mplist_key () function returns the key of the first property
1559 in property list $PLIST. If the length of $PLIST is zero,
1560 it returns @c Mnil. */
1562 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤òÊÖ¤¹.
1564 ´Ø¿ô mplist_key () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1565 Ãæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤òÊÖ¤¹¡£$PLIST ¤ÎŤµ¤¬ 0 ¤Ê¤é¤Ð¡¢ @c Mnil
1569 mplist_key (MPlist *plist)
1571 return MPLIST_KEY (plist);
1577 @brief Return the value of the first property in a property list.
1579 The mplist_value () function returns the value of the first
1580 property in property list $PLIST. If the length of $PLIST
1581 is zero, it returns @c NULL. */
1583 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹.
1585 ´Ø¿ô mplist_value () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST Ãæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£
1586 $PLIST ¤ÎŤµ¤¬ 0 ¤Ê¤é¤Ð¡¢ @c Mnil ¤òÊÖ¤¹¡£ */
1589 mplist_value (MPlist *plist)
1591 return MPLIST_VAL (plist);
1595 @brief Generate a property list by deserializing an M-text.
1597 The mplist_deserialize () function parses M-text $MT and returns a
1600 The syntax of $MT is as follows.
1602 MT ::= '(' ELEMENT * ')'
1604 ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
1606 SYMBOL ::= ascii-character-sequence
1608 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
1609 | '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
1611 M-TEXT ::= '"' character-sequence '"'
1613 Each alternatives of @c ELEMENT is assigned one of these keys: @c
1614 Msymbol, @c Minteger, @c Mtext, @c Mplist
1616 In an ascii-character-sequence, a backslash (\) is used as the escape
1617 character, which means that, for instance, <tt>"abc\ def"</tt>
1618 produces a symbol whose name is of length seven with the fourth
1619 character being a space. */
1621 @brief M-text ¤ò¥Ç¥·¥ê¥¢¥é¥¤¥º¤·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òºî¤ë.
1623 ´Ø¿ô mplist_deserialize () ¤Ï M-text $MT ¤ò²òÀϤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òÊÖ¤¹¡£
1625 $MT ¤Î¥·¥ó¥¿¥Ã¥¯¥¹¤Ï°Ê²¼¤ÎÄ̤ꡣ
1627 MT ::= '(' ELEMENT * ')'
1629 ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
1631 SYMBOL ::= ¥¢¥¹¥¡¼Ê¸»úÎó
1633 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
1634 | '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
1636 M-TEXT ::= '"' character-sequence '"'
1638 @c ELEMENT ¤Î³ÆÁªÂò»è¤Ï¥¡¼¡§@c Msymbol, @c Minteger, @c Mtext,
1639 @c Mplist ¤Î¤¤¤º¤ì¤«¤ò³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¡£
1641 ¥¢¥¹¥¡¼Ê¸»úÎóÆâ¤Ç¤Ï¡¢¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å (\) ¤¬¥¨¥¹¥±¡¼¥×ʸ»ú¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£¤¿¤È¤¨¤Ð
1642 <tt>"abc\ def"</tt> ¤Ï 4 ʸ»úÌܤ¬¶õÇòʸ»ú¤Ç¤¢¤êŤµ¤¬ 7
1643 ¤Ç¤¢¤ë»ý¤Ä̾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òÀ¸À®¤¹¤ë¡£ */
1646 mplist_deserialize (MText *mt)
1651 if (mt->format > MTEXT_FORMAT_UTF_8)
1653 if (MTEXT_READ_ONLY_P (mt))
1654 mt = tmp = mtext_cpy (mtext (), mt);
1656 mtext__adjust_format (mt, MTEXT_FORMAT_UTF_8);
1658 plist = mplist__from_string (MTEXT_DATA (mt), mtext_nbytes (mt));
1660 M17N_OBJECT_UNREF (tmp);
1666 /*** @addtogroup m17nDebug */
1671 @brief Dump a property list.
1673 The mdebug_dump_plist () function prints a property list $PLIST in
1674 a human readable way to the stderr. $INDENT specifies how many
1675 columns to indent the lines but the first one.
1678 This function returns $PLIST. */
1680 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¥À¥ó¥×¤¹¤ë.
1682 ´Ø¿ô mdebug_dump_plist () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò stderr
1683 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
1686 ¤³¤Î´Ø¿ô¤Ï $PLIST ¤òÊÖ¤¹¡£ */
1688 mdebug_dump_plist (MPlist *plist, int indent)
1690 char *prefix = (char *) alloca (indent + 1);
1693 memset (prefix, 32, indent);
1696 fprintf (stderr, "(");
1697 MPLIST_DO (pl, plist)
1700 fprintf (stderr, "\n%s ", prefix);
1701 write_element (NULL, pl, indent + 1);
1703 fprintf (stderr, ")");