1 /* plist.c -- plist module.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
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
133 && MPLIST_KEY (plist)->managing_key)
134 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
135 M17N_OBJECT_UNREGISTER (plist_table, plist);
138 } while (plist && plist->control.ref_count == 1);
139 M17N_OBJECT_UNREF (plist);
144 /* Load a plist from a string. */
146 #define READ_CHUNK 0x10000
150 /* File pointer if the stream is associated with a file. Otherwise
154 unsigned char buffer[READ_CHUNK];
155 unsigned char *p, *pend;
159 get_byte (MStream *st)
163 if (! st->fp || st->eof)
165 n = fread (st->buffer, 1, READ_CHUNK, st->fp);
171 st->p = st->buffer + 1;
172 st->pend = st->buffer + n;
173 return st->buffer[0];
176 #define GETC(st) ((st)->p < (st)->pend ? *(st)->p++ : get_byte (st))
178 #define UNGETC(c, st) (--((st)->p))
180 /** Mapping table for reading a number. Hexadecimal chars
181 (0..9,A..F,a..F) are mapped to the corresponding numbers.
182 Apostrophe (code 39) is mapped to 254. All the other bytes are
184 unsigned char hex_mnemonic[256];
186 /** Mapping table for escaped characters. Mnemonic characters (e, b,
187 f, n, r, or t) that follows '\' are mapped to the corresponding
188 character code. All the other bytes are mapped to themselves. */
189 unsigned char escape_mnemonic[256];
192 /** Read an integer from the stream ST. It is assumed that we have
193 already read one character C. */
196 read_decimal (MStream *st, int c)
200 while (c >= '0' && c <= '9')
202 num = (num * 10) + (c - '0');
211 /** Read an unsigned from the stream ST. */
214 read_hexadesimal (MStream *st)
219 while ((c = GETC (st)) != EOF
220 && (n = hex_mnemonic[c]) < 16)
221 num = (num << 4) | n;
228 /** Read an M-text element from ST, and add it to LIST. Return a list
229 for the next element. */
231 #define READ_MTEXT_BUF_SIZE 256
234 read_mtext_element (MPlist *plist, MStream *st, int skip)
236 unsigned char buffer[READ_MTEXT_BUF_SIZE], *buf = buffer;
237 int nbytes = READ_MTEXT_BUF_SIZE;
241 while ((c = GETC (st)) != EOF && c != '"')
252 if (c == 'x' || c == 'u')
256 c = read_hexadesimal (st);
264 c = escape_mnemonic[c];
269 if (i + MAX_UTF8_CHAR_BYTES >= nbytes)
274 buf = malloc (nbytes);
275 memcpy (buf, buffer, i);
279 nbytes += READ_MTEXT_BUF_SIZE;
280 buf = realloc (buf, nbytes);
285 i += CHAR_STRING_UTF8 (c, buf);
293 MText *mt = mtext__from_data (buf, i, MTEXT_FORMAT_UTF_8,
296 mt->allocated = nbytes;
297 MPLIST_SET_ADVANCE (plist, Mtext, mt);
303 read_character (MStream *st, int c)
305 unsigned char buf[MAX_UTF8_CHAR_BYTES + 1];
306 int len = CHAR_BYTES_BY_HEAD (c);
310 for (i = 1; i < len; i++)
314 || (c & 0xC0) != 0x80)
319 c = STRING_CHAR_UTF8 (buf);
326 /** Read a symbol element from ST, and add it to LIST. Return a list
327 for the next element. */
330 read_symbol_element (MPlist *plist, MStream *st, int c, int skip)
332 unsigned char buffer[1024];
334 unsigned char *buf = buffer;
340 && c != ')' && c != '(' && c != '"')
347 MTABLE_MALLOC (buf, bufsize, MERROR_PLIST);
348 memcpy (buf, buffer, i);
351 MTABLE_REALLOC (buf, bufsize, MERROR_PLIST);
358 c = escape_mnemonic[c];
370 MPLIST_SET_ADVANCE (plist, Msymbol, msymbol ((char *) buf));
377 /** Read an integer element from ST, and add it to LIST. Return a
378 list for the next element. It is assumed that we have already
379 read the character C. */
382 read_integer_element (MPlist *plist, MStream *st, int c, int skip)
392 return read_symbol_element (plist, st, '#', skip);
394 num = read_hexadesimal (st);
399 num = (c == 'x' ? read_hexadesimal (st) : read_decimal (st, c));
408 if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c))
411 num = read_character (st, c);
418 else if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c))
419 num = escape_mnemonic[c];
421 num = read_character (st, c);
427 if (c < '0' || c > '9')
430 return read_symbol_element (plist, st, '-', skip);
432 num = - read_decimal (st, c);
435 num = read_decimal (st, c);
438 MPLIST_SET_ADVANCE (plist, Minteger, (void *) num);
442 /* Read an element of various type from stream ST, and add it to LIST.
443 Return a list for the next element. The element type is decided by
444 the first token character found as below:
447 '0'..'9', '-': integer
448 '?': integer representing character code
449 the other ASCII letters: symbol
451 If KEYS is not NULL, it is a plist contains target keys and stop
452 keys. In this caes, read only a plist whose key has value 1 in
453 KEYS, and return NULL when we encounter a plist whose key has value
454 0 in KEYS while skipping any other elements. */
457 read_element (MPlist *plist, MStream *st, MPlist *keys)
461 /* Skip separators and comments. */
464 while ((c = GETC (st)) != EOF && c <= ' ');
467 while ((c = GETC (st)) != EOF && c != '\n');
478 p = read_element (p, st, NULL);
479 if (keys && p && MPLIST_SYMBOL_P (pl))
481 if (MPLIST_TAIL_P (keys))
483 while ((p = read_element (p, st, NULL)));
484 MPLIST_SET_ADVANCE (plist, Mplist, pl);
491 MPLIST_FIND (p0, MPLIST_SYMBOL (pl));
492 if (! MPLIST_TAIL_P (p0) && ! MPLIST_VAL (p0))
494 M17N_OBJECT_UNREF (pl);
497 while ((p = read_element (p, st, NULL)));
498 if (! MPLIST_TAIL_P (p0))
500 MPLIST_SET_ADVANCE (plist, Mplist, pl);
504 M17N_OBJECT_UNREF (pl);
510 while ((p = read_element (p, st, NULL)));
511 MPLIST_SET_ADVANCE (plist, Mplist, pl);
516 return (read_mtext_element (plist, st, keys ? 1 : 0));
517 if ((c >= '0' && c <= '9') || c == '-' || c == '?' || c == '#')
518 return (read_integer_element (plist, st, c, keys ? 1 : 0));
519 if (c == EOF || c == ')')
521 return (read_symbol_element (plist, st, c, keys ? 1 : 0));
524 #define PUTC(MT, C) \
527 mtext_cat_char ((MT), (C)); \
529 putc ((C), mdebug__output); \
532 #define PUTS(MT, STR) \
535 MTEXT_CAT_ASCII ((MT), (STR)); \
537 fputs ((STR), mdebug__output); \
542 write_symbol (MText *mt, MSymbol sym)
550 char *name = MSYMBOL_NAME (sym);
556 if (*name <= ' ' || *name == '\\' || *name == '"'
557 || *name == '(' || *name == ')')
566 write_element (MText *mt, MPlist *plist, int indent)
568 if (MPLIST_SYMBOL_P (plist))
570 write_symbol (mt, MPLIST_SYMBOL (plist));
572 else if (MPLIST_INTEGER_P (plist))
574 int num = MPLIST_INTEGER (plist);
577 sprintf (buf, "%d", num);
580 else if (MPLIST_PLIST_P (plist)
581 || MPLIST_NESTED_P (plist))
586 if (MPLIST_NESTED_P (plist))
588 write_symbol (mt, MPLIST_KEY (plist));
591 plist = MPLIST_PLIST (plist);
595 MPLIST_DO (pl, plist)
599 if (indent > 0 && (MPLIST_PLIST_P (pl) || MPLIST_MTEXT_P (pl)))
606 for (i = 1; i < indent; i++)
611 write_element (mt, pl, indent);
613 newline = (MPLIST_PLIST_P (pl) || MPLIST_MTEXT_P (pl));
617 else if (MPLIST_MTEXT_P (plist))
619 MText *this_mt = MPLIST_MTEXT (plist);
620 int from = 0, to = mtext_nchars (this_mt);
621 int stop1 = 0, stop2 = 0;
623 if (! mt && this_mt->format > MTEXT_FORMAT_UTF_8)
625 this_mt = mtext_dup (this_mt);
626 mtext__adjust_format (this_mt, MTEXT_FORMAT_UTF_8);
636 if ((stop1 = mtext_character (this_mt, from, to, '"')) < 0)
641 if ((stop2 = mtext_character (this_mt, from, to, '\\')) < 0)
645 stop = stop1++, escaped = '"';
647 stop = stop2++, escaped = '\\';
649 mtext_copy (mt, mtext_nchars (mt), this_mt, from, stop);
652 unsigned char *data = MTEXT_DATA (this_mt);
653 unsigned char *beg = data + mtext__char_to_byte (this_mt, from);
654 unsigned char *end = data + mtext__char_to_byte (this_mt, stop);
657 putc (*beg, mdebug__output), beg++;
666 if (this_mt != MPLIST_MTEXT (plist))
667 M17N_OBJECT_UNREF (this_mt);
669 else if (MPLIST_STRING_P (plist))
671 char *str = MPLIST_STRING (plist);
675 MText *this_mt = mtext__from_data (str, strlen (str),
676 MTEXT_FORMAT_UTF_8, 0);
678 mtext_copy (mt, mtext_nchars (mt),
679 this_mt, 0, mtext_nchars (this_mt));
680 M17N_OBJECT_UNREF (this_mt);
683 fprintf (mdebug__output, "%s", str);
689 write_symbol (mt, MPLIST_KEY (plist));
691 sprintf (buf, "%04X", (unsigned) MPLIST_VAL (plist));
703 M17N_OBJECT_ADD_ARRAY (plist_table, "Plist");
705 Minteger = msymbol ("integer");
706 Mplist = msymbol_as_managing_key ("plist");
707 Mtext = msymbol_as_managing_key ("mtext");
709 for (i = 0; i < 256; i++)
710 hex_mnemonic[i] = 255;
711 for (i = '0'; i <= '9'; i++)
712 hex_mnemonic[i] = i - '0';
713 for (i = 'A'; i <= 'F'; i++)
714 hex_mnemonic[i] = i - 'A' + 10;
715 for (i = 'a'; i <= 'f'; i++)
716 hex_mnemonic[i] = i - 'a' + 10;
717 for (i = 0; i < 256; i++)
718 escape_mnemonic[i] = i;
719 escape_mnemonic['e'] = 27;
720 escape_mnemonic['b'] = '\b';
721 escape_mnemonic['f'] = '\f';
722 escape_mnemonic['n'] = '\n';
723 escape_mnemonic['r'] = '\r';
724 escape_mnemonic['t'] = '\t';
725 escape_mnemonic['\\'] = '\\';
736 /* Parse this form of PLIST:
737 (symbol:KEY1 TYPE1:VAL1 symbol:KEY2 TYPE2:VAL2 ...)
738 and return a newly created plist of this form:
739 (KEY1:VAL1 KEY2:VAL2 ...) */
742 mplist__from_plist (MPlist *plist)
748 while (! MPLIST_TAIL_P (plist))
752 if (! MPLIST_SYMBOL_P (plist))
753 MERROR (MERROR_PLIST, NULL);
754 key = MPLIST_SYMBOL (plist);
755 plist = MPLIST_NEXT (plist);
756 type = MPLIST_KEY (plist);
757 if (type->managing_key && MPLIST_VAL (plist))
758 M17N_OBJECT_REF (MPLIST_VAL (plist));
760 MPLIST_SET_NESTED_P (p);
761 MPLIST_SET_ADVANCE (p, key, MPLIST_VAL (plist));
762 plist = MPLIST_NEXT (plist);
767 /** Parse this form of PLIST:
768 ((symbol:KEY1 ANY:VAL1 ... ) (symbol:KEY2 ANY:VAL2 ...) ...)
769 and return a newly created plist of this form:
770 (KEY1:(ANY:VAL1 ...) KEY2:(ANY:VAL2 ...) ...)
771 ANY can be any type. */
774 mplist__from_alist (MPlist *plist)
780 MPLIST_DO (plist, plist)
784 if (! MPLIST_PLIST_P (plist))
785 MERROR (MERROR_PLIST, NULL);
786 elt = MPLIST_PLIST (plist);
787 if (! MPLIST_SYMBOL_P (elt))
788 MERROR (MERROR_PLIST, NULL);
789 MPLIST_SET_NESTED_P (p);
790 MPLIST_SET_ADVANCE (p, MPLIST_SYMBOL (elt), MPLIST_NEXT (elt));
791 M17N_OBJECT_REF (MPLIST_NEXT (elt));
798 mplist__from_file (FILE *fp, MPlist *keys)
805 st.p = st.pend = st.buffer;
808 while ((pl = read_element (pl, &st, keys)));
813 /** Parse $STR of $N bytes and return a property list object. $FORMAT
814 must be either @c MTEXT_FORMAT_US_ASCII or @c MTEXT_FORMAT_UTF_8,
815 and controls how to produce @c STRING or @c M-TEXT in the
816 following definition.
818 The syntax of $STR is as follows.
820 PLIST ::= '(' ELEMENT * ')'
822 ELEMENT ::= SYMBOL | INTEGER | UNSIGNED | STRING | M-TEXT | PLIST
824 SYMBOL ::= ascii-character-sequence
826 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
828 UNSIGNED ::= '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
830 M-TEXT ::= '"' byte-sequence '"'
832 Each kind of @c ELEMENT is assigned one of these keys:
833 @c Msymbol, @c Mint, @c Munsigned, @c Mtext, @c Mplist
835 In an ascii-character-sequence, a backslush (\) is used as the escape
836 character, which means that, for instance, <tt>"abc\ def"</tt>
837 produces a symbol whose name is of length seven with the fourth
838 character being a space.
840 In a byte-sequence, "\r", "\n", "\e", and "\t" are replaced by CR,
841 NL, ESC, and TAB character respectively, "\xXX" are replaced by
842 byte 0xXX. After this replacement, the byte-sequence is decoded
843 into M-TEXT by $CODING. */
846 mplist__from_string (unsigned char *str, int n)
857 while ((pl = read_element (pl, &st, NULL)));
862 mplist__serialize (MText *mt, MPlist *plist, int pretty)
865 int separator = pretty ? '\n' : ' ';
867 MPLIST_DO (pl, plist)
870 mtext_cat_char (mt, separator);
871 write_element (mt, pl, pretty ? 0 : -1);
874 mtext_cat_char (mt, separator);
879 @brief Concatenate two plists.
881 The mplist__conc () function concatenates plist $TAIL at the end of
882 plist $PLIST and return $PLIST. If $TAIL is empty, return $PLIST
883 without modifying it. */
886 mplist__conc (MPlist *plist, MPlist *tail)
890 if (MPLIST_TAIL_P (tail))
892 MPLIST_DO (pl, plist);
893 MPLIST_KEY (pl) = MPLIST_KEY (tail);
894 MPLIST_VAL (pl) = MPLIST_VAL (tail);
895 if (MPLIST_KEY (pl)->managing_key && MPLIST_VAL (pl))
896 M17N_OBJECT_REF (MPLIST_VAL (pl));
897 if (MPLIST_NESTED_P (tail))
898 MPLIST_SET_NESTED_P (pl);
899 tail = MPLIST_NEXT (tail);
900 MPLIST_NEXT (pl) = tail;
901 M17N_OBJECT_REF (tail);
907 @brief Discard a property at the beginning of a property list.
909 The mplist__pop_unref () function removes a property at the
910 beginning of property list $PLIST, and if the property value is a
911 managed object, unref it. As a result, the second key and value
912 of the original $PLIST become the first of those of the new
916 mplist__pop_unref (MPlist *plist)
921 if (MPLIST_TAIL_P (plist))
923 key = MPLIST_KEY (plist);
924 val = mplist_pop (plist);
925 if (key->managing_key)
926 M17N_OBJECT_UNREF (val);
930 @brief Search for an element of an alist represented by a plist.
932 The mplist__assq () function treats $PLIST as an association list
933 (elements are plists (key is #Mplist) whose first element is a
934 symbol (key is #Msymbol)), and find an element whose first element
935 has key #Msymbol and value $KEY.
937 Non-plist elements of $PLIST are ignored.
940 This function returns a found element or NULL if no element
941 matches with $KEY. */
944 mplist__assq (MPlist *plist, MSymbol key)
946 MPLIST_DO (plist, plist)
947 if (MPLIST_PLIST_P (plist))
949 MPlist *pl = MPLIST_PLIST (plist);
951 if (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == key)
958 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
963 /*** @addtogroup m17nPlist */
968 @brief Symbol whose name is "integer".
970 The symbol @c Minteger has the name <tt>"integer"</tt>. The value
971 of a property whose key is @c Minteger must be an integer. */
973 @brief "integer" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
975 ¥·¥ó¥Ü¥ë @c Minteger ¤Ï <tt>"integer"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¡£¥¡¼¤¬
976 @c Minteger ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤÏÀ°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
982 @brief Symbol whose name is "plist".
984 The symbol @c Mplist has the name <tt>"plist"</tt>. It is a
985 managing key. A value of a property whose key is @c Mplist must
988 @brief "plist" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
990 ¥·¥ó¥Ü¥ë @c Mplist ¤Ï <tt>"plist"</tt>
991 ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¡£¤³¤ì¤Ï´ÉÍý¥¡¼¤Ç¤¢¤ë¡£¥¡¼¤¬ @c Mplist
992 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¤Ï plist ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
998 @brief Symbol whose name is "mtext".
1000 The symbol @c Mtext has the name <tt>"mtext"</tt>. It is a
1001 managing key. A value of a property whose key is @c Mtext must be an
1005 @brief "mtext" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
1007 ¥·¥ó¥Ü¥ë @c Mtext ¤Ï <tt>"mtext"</tt>
1008 ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä´ÉÍý¥¡¼¤Ç¤¢¤ë¡£¥¡¼¤¬ @c Mtext
1009 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¤Ï M-text ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
1015 @brief Create a property list object.
1017 The mplist () function returns a newly created property list
1018 object of length zero.
1021 This function returns a newly created property list.
1024 This function never fails. */
1026 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë.
1028 ´Ø¿ô mplist () ¤ÏŤµ 0 ¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò¿·¤·¤¯ºî¤Ã¤ÆÊÖ¤¹¡£
1031 ¤³¤Î´Ø¿ô¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹¡£
1034 ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£ */
1047 @brief Copy a property list.
1049 The mplist_copy () function copies property list $PLIST. In the
1050 copy, the values are the same as those of $PLIST.
1053 This function returns a newly created plist which is a copy of
1057 This function never fails. */
1059 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¥³¥Ô¡¼¤¹¤ë.
1061 ´Ø¿ô mplist_copy () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1062 ¤ò¥³¥Ô¡¼¤¹¤ë¡£¥³¥Ô¡¼¤Î¤¹¤Ù¤Æ¤ÎÃͤϥ³¥Ô¡¼¸µ $PLIST ¤ÎÃͤÈƱ¤¸¤Ç¤¢¤ë¡£
1065 ¤³¤Î´Ø¿ô¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¡¢$PLIST ¤Î¥³¥Ô¡¼¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òÊÖ¤¹¡£
1068 ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£ */
1071 mplist_copy (MPlist *plist)
1073 MPlist *copy = mplist (), *pl = copy;
1075 MPLIST_DO (plist, plist)
1077 if (MPLIST_NESTED_P (plist))
1078 MPLIST_SET_NESTED_P (pl);
1079 pl = mplist_add (pl, MPLIST_KEY (plist), MPLIST_VAL (plist));
1087 @brief Set the value of a property in a property list.
1089 The mplist_put () function searches property list $PLIST
1090 from the beginning for a property whose key is $KEY. If such a
1091 property is found, its value is changed to $VALUE. Otherwise, a
1092 new property whose key is $KEY and value is $VALUE is appended at
1093 the end of $PLIST. See the documentation of mplist_add () for
1094 the restriction on $KEY and $VAL.
1096 If $KEY is a managing key, $VAL must be a managed object. In this
1097 case, the reference count of the old value, if not @c NULL, is
1098 decremented by one, and that of $VAL is incremented by one.
1101 If the operation was successful, mplist_put () returns a sublist of
1102 $PLIST whose first element is the just modified or added one.
1103 Otherwise, it returns @c NULL. */
1105 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÀßÄꤹ¤ë.
1107 ´Ø¿ô mplist_put () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥¡¼¤¬
1108 $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤò $VALUE
1109 ¤ËÊѹ¹¤¹¤ë¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¥¡¼¤¬ $KEY ¤ÇÃͤ¬ $VALUE
1110 ¤Ç¤¢¤ë¿·¤·¤¤¥×¥í¥Ñ¥Æ¥£¤¬ $PLIST ¤ÎËöÈø¤ËÄɲ䵤ì¤ë¡£$KEY ¤È $VAL
1111 ¤ËÂФ¹¤ëÀ©¸Â¤Ë¤Ä¤¤¤Æ¤Ï¡¢mplist_add () ¤ÎÀâÌÀ¤ò»²¾È¡£
1113 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢
1114 $VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢¸Å¤¤Ãͤλ²¾È¿ô¤Ï
1115 @c NULL ¤Ç¤Ê¤±¤ì¤Ð 1 ¸º¤é¤µ¤ì¡¢$VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1118 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mplist_put () ¤ÏÊѹ¹¤µ¤ì¤¿¤«Äɲ䵤줿Í×ÁǤ«¤é»Ï¤Þ¤ë
1119 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1122 mplist_put (MPlist *plist, MSymbol key, void *val)
1125 MERROR (MERROR_PLIST, NULL);
1126 MPLIST_FIND (plist, key);
1127 if (key->managing_key)
1129 if (! MPLIST_TAIL_P (plist))
1130 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1132 M17N_OBJECT_REF (val);
1134 MPLIST_SET (plist, key, val);
1141 @brief Get the value of a property in a property list.
1143 The mplist_get () function searches property list $PLIST from the
1144 beginning for a property whose key is $KEY. If such a property is
1145 found, its value is returned as the type of <tt>(void *)</tt>. If
1146 not found, @c NULL is returned.
1148 When @c NULL is returned, there are two possibilities: one is the
1149 case where no property is found (see above); the other is the case
1150 where a property is found and its value is @c NULL. In case that
1151 these two cases must be distinguished, use the mplist_find_by_key ()
1154 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
1156 ´Ø¿ô mplist_get () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥¡¼
1157 ¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤò
1158 <tt>(void *)</tt> ·¿¤ÇÊÖ¤¹¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
1160 @c NULL ¤¬Ê֤俺ݤˤÏÆó¤Ä¤Î²ÄǽÀ¤¬¤¢¤ë:
1161 ¾åµ¤Î¤è¤¦¤Ë¥×¥í¥Ñ¥Æ¥£¤¬¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¾ì¹ç¤È¡¢¥×¥í¥Ñ¥Æ¥£¤¬¸«¤Ä¤«¤ê¡¢¤½¤ÎÃͤ¬
1162 @c NULL ¤Ç¤¢¤ë¾ì¹ç¤Ç¤¢¤ë¡£¤³¤ì¤é¤ò¶èÊ̤¹¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤Ë¤Ï´Ø¿ô
1163 mplist_find_by_key () ¤ò»È¤¦¤³¤È¡£ */
1167 mplist_find_by_key () */
1170 mplist_get (MPlist *plist, MSymbol key)
1172 MPLIST_FIND (plist, key);
1173 return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_VAL (plist));
1179 @brief Set the value (function pointer) of a property in a property list.
1181 The mplist_put_func () function is similar to mplist_put () but for
1182 setting function pointer $FUNC in property list $PLIST for key
1183 $KEY. $KEY must not be a managing key. */
1186 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤Ë´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÀßÄꤹ¤ë.
1188 ´Ø¿ô mplist_put_func () ¤Ï´Ø¿ô mplist_put () ƱÍÍ¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1189 Ãæ¤Ç¥¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë¡£Ã¢¤·¤½¤ÎÃͤϴؿô¥Ý¥¤¥ó¥¿
1190 $FUNC ¤Ç¤¢¤ë¡£$KEY ¤Ï´ÉÍý¥¡¼¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
1195 mplist_put (), M17N_FUNC () */
1198 mplist_put_func (MPlist *plist, MSymbol key, M17NFunc func)
1200 if (key == Mnil || key->managing_key)
1201 MERROR (MERROR_PLIST, NULL);
1202 MPLIST_FIND (plist, key);
1203 MPLIST_KEY (plist) = key;
1204 MPLIST_FUNC (plist) = func;
1205 MPLIST_SET_VAL_FUNC_P (plist);
1207 MPLIST_NEW ((plist)->next);
1214 @brief Get the value (function pointer) of a property in a property list.
1216 The mplist_get_func () function is similar to mplist_get () but for
1217 getting a function pointer from property list $PLIST by key $KEY. */
1220 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤«¤é¥×¥í¥Ñ¥Æ¥£¤Î´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÆÀ¤ë.
1222 ´Ø¿ô mplist_get_func () ¤Ï´Ø¿ô mplist_get () ¤ÈƱÍͤˡ¢¥×¥í¥Ñ¥Æ¥£¥ê
1223 ¥¹¥È $PLIST Ãæ¤Ç¥¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¡¢Ã¢¤·´Ø¿ô¥Ý¥¤¥ó¥¿¡¢
1231 mplist_get_func (MPlist *plist, MSymbol key)
1233 MPLIST_FIND (plist, key);
1234 return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_FUNC (plist));
1240 @brief Add a property at the end of a property list.
1242 The mplist_add () function appends at the end of property list
1243 $PLIST a property whose key is $KEY and value is $VAL. $KEY can
1244 be any symbol other than @c Mnil.
1246 If $KEY is a managing key, $VAL must be a managed object. In this
1247 case, the reference count of $VAL is incremented by one.
1250 If the operation was successful, mplist_add () returns a sublist of
1251 $PLIST whose first element is the just added one. Otherwise, it
1254 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈËöÈø¤Ë¥×¥í¥Ñ¥Æ¥£¤òÄɲ乤ë.
1256 ´Ø¿ô mplist_add () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎËöÈø¤Ë¥¡¼¤¬ $KEY
1257 ¤ÇÃͤ¬ $VAL ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤òÄɲ乤롣$KEY ¤Ï¡¢@c Mnil °Ê³°¤ÎǤ°Õ¤Î¥·¥ó¥Ü¥ë¤Ç¤è¤¤¡£
1259 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢$VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢
1260 $VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1263 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mplist_add () ¤ÏÄɲ䵤줿Í×ÁǤ«¤é»Ï¤Þ¤ë $PLIST
1264 ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1267 mplist_add (MPlist *plist, MSymbol key, void *val)
1270 MERROR (MERROR_PLIST, NULL);
1271 MPLIST_FIND (plist, Mnil);
1272 if (val && key->managing_key)
1273 M17N_OBJECT_REF (val);
1274 MPLIST_KEY (plist) = key;
1275 MPLIST_VAL (plist) = val;
1276 MPLIST_NEW (plist->next);
1283 @brief Add a property at the beginning of a property list.
1285 The mplist_push () function inserts at the beginning of property
1286 list $PLIST a property whose key is $KEY and value is $VAL.
1288 If $KEY is a managing key, $VAL must be a managed object. In this
1289 case, the reference count of $VAL is incremented by one.
1292 If the operation was successful, this function returns $PLIST.
1293 Otherwise, it returns @c NULL. */
1295 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤Ë¥×¥í¥Ñ¥Æ¥£¤òÁÞÆþ¤¹¤ë.
1297 ´Ø¿ô mplist_push () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Ë¥¡¼¤¬ $KEY
1298 ¤ÇÃͤ¬ $VAL ¤Ç¤¢¤ë¥ª¥Ö¥¸¥§¥¯¥È¤òÁÞÆþ¤¹¤ë¡£
1300 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢$VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢
1301 $VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1304 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï $PLIST ¤òÊÖ¤·¡¢¤½¤¦¤Ç¤Ê¤±¤ì¤Ð@c NULL
1308 mplist_push (MPlist *plist, MSymbol key, void *val)
1313 MERROR (MERROR_PLIST, NULL);
1315 MPLIST_KEY (pl) = MPLIST_KEY (plist);
1316 MPLIST_VAL (pl) = MPLIST_VAL (plist);
1317 if (MPLIST_NESTED_P (plist))
1318 MPLIST_SET_NESTED_P (pl);
1319 MPLIST_NEXT (pl) = MPLIST_NEXT (plist);
1321 if (val && key->managing_key)
1322 M17N_OBJECT_REF (val);
1323 MPLIST_KEY (plist) = key;
1324 MPLIST_VAL (plist) = val;
1331 @brief Remove a property at the beginning of a property list.
1333 The mplist_pop () function removes a property at the beginning of
1334 property list $PLIST. As a result, the second key and value of
1335 the $PLIST become the first ones.
1338 If the operation was successful, this function return the value of
1339 the just popped property. Otherwise, it returns @c NULL. */
1341 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤«¤é¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë.
1343 ´Ø¿ô mplist_pop () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Î¥×¥í¥Ñ¥Æ¥£¤òºï
1344 ½ü¤¹¤ë¡£·ë²Ì¤È¤·¤Æ¡¢¸µ¤Î2ÈÖÌܤΥ¡¼¤ÈÃͤ¬ÀèƬ¤Î¥¡¼¤ÈÃͤˤʤ롣
1347 ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ïºï½ü¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
1351 mplist_pop (MPlist *plist)
1356 if (MPLIST_TAIL_P (plist))
1358 val = MPLIST_VAL (plist);
1359 next = MPLIST_NEXT (plist);
1360 MPLIST_KEY (plist) = MPLIST_KEY (next);
1361 MPLIST_VAL (plist) = MPLIST_VAL (next);
1362 if (MPLIST_KEY (plist) != Mnil
1363 && MPLIST_KEY (plist)->managing_key
1364 && MPLIST_VAL (plist))
1365 M17N_OBJECT_REF (MPLIST_VAL (plist));
1366 MPLIST_NEXT (plist) = MPLIST_NEXT (next);
1368 M17N_OBJECT_REF (plist->next);
1369 M17N_OBJECT_UNREF (next);
1375 @brief Find a property of a specific key in a property list.
1377 The mplist_find_by_key () function searches property list
1378 $PLIST from the beginning for a property whose key is $KEY. If
1379 such a property is found, a sublist of $PLIST whose first element
1380 is the found one is returned. Otherwise, @c NULL is returned.
1382 If $KEY is @c Mnil, it returns a sublist of $PLIST whose
1383 first element is the last one of $PLIST. */
1385 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃ椫¤é»ØÄê¤Î¥¡¼¤ò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤òõ¤¹.
1387 ´Ø¿ô mplist_find_by_key () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1388 ¤ò»Ï¤á¤«¤éõ ¤·¤Æ¡¢¥¡¼¤¬ $KEY
1389 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤«¤é»Ï¤Þ¤ë
1390 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
1392 $KEY ¤¬ @c Mnil ¤Ê¤é¤Ð¡¢$PLIST ¤ÎºÇ¸å¤ÎÍ×ÁǤ«¤é»Ï¤Þ¤ëÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£ */
1395 mplist_find_by_key (MPlist *plist, MSymbol key)
1397 MPLIST_FIND (plist, key);
1398 return (MPLIST_TAIL_P (plist)
1399 ? (key == Mnil ? plist : NULL)
1405 @brief Find a property of a specific value in a property list.
1407 The mplist_find_by_value () function searches property list $PLIST
1408 from the beginning for a property whose value is $VAL. If such a
1409 property is found, a sublist of $PLIST whose first element is the
1410 found one is returned. Otherwise, @c NULL is returned. */
1412 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃ椫¤é»ØÄê¤ÎÃͤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤òõ¤¹.
1414 ´Ø¿ô mplist_find_by_value () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1415 ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢Ãͤ¬ $VAL
1416 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤«¤é»Ï¤Þ¤ë
1417 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1420 mplist_find_by_value (MPlist *plist, void *val)
1422 MPLIST_DO (plist, plist)
1424 if (MPLIST_VAL (plist) == val)
1433 @brief Return the next sublist of a property list.
1435 The mplist_next () function returns a pointer to the sublist of
1436 property list $PLIST, which begins at the second element in $PLIST. If the
1437 length of $PLIST is zero, it returns @c NULL. */
1439 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Î¼¡¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹.
1441 ´Ø¿ô mplist_next () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤Î 2
1442 ÈÖÌܤÎÍ×ÁǤ«¤é»Ï¤Þ¤ëÉôʬ¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$PLIST ¤ÎŤµ¤¬ 0
1443 ¤Ê¤é¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1446 mplist_next (MPlist *plist)
1448 return (MPLIST_TAIL_P (plist) ? NULL : plist->next);
1454 @brief Set the first property in a property list.
1456 The mplist_set () function sets the key and the value of the first
1457 property in property list $PLIST to $KEY and $VALUE, respectively.
1458 See the documentation of mplist_add () for the restriction on $KEY
1462 If the operation was successful, mplist_set () returns $PLIST.
1463 Otherwise, it returns @c NULL. */
1465 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤òÀßÄꤹ¤ë.
1467 ´Ø¿ô mplist_set () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1468 ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤ÈÃͤò¤½¤ì¤¾¤ì $KEY ¤È $VALUE ¤ËÀßÄꤹ¤ë¡£
1469 $KEY ¤È $VAL ¤ËÂФ¹¤ëÀ©¸Â¤Ë¤Ä¤¤¤Æ¤Ï¡¢mplist_add () ¤ÎÀâÌÀ¤ò»²¾È¡£
1472 ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð mplist_set () ¤Ï $PLIST ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1475 mplist_set (MPlist *plist, MSymbol key, void * val)
1479 if (! MPLIST_TAIL_P (plist))
1481 key = MPLIST_KEY (plist);
1482 M17N_OBJECT_UNREF (MPLIST_NEXT (plist));
1483 MPLIST_KEY (plist) = Mnil;
1484 if (key->managing_key)
1485 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1491 if (val && key->managing_key)
1492 M17N_OBJECT_REF (val);
1493 if (! MPLIST_TAIL_P (plist)
1494 && MPLIST_KEY (plist)->managing_key)
1495 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1496 MPLIST_SET (plist, key, val);
1504 @brief Return the length of a property list.
1506 The mplist_length () function returns the number of properties in
1507 property list $PLIST. */
1509 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎŤµ¤òÊÖ¤¹.
1511 ´Ø¿ô mplist_length () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST Ãæ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¿ô¤òÊÖ¤¹¡£ */
1514 mplist_length (MPlist *plist)
1518 for (n = 0; ! (MPLIST_TAIL_P (plist)); n++, plist = plist->next);
1525 @brief Return the key of the first property in a property list.
1527 The mplist_key () function returns the key of the first property
1528 in property list $PLIST. If the length of $PLIST is zero,
1529 it returns @c Mnil. */
1531 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤òÊÖ¤¹.
1533 ´Ø¿ô mplist_key () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1534 Ãæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤òÊÖ¤¹¡£$PLIST ¤ÎŤµ¤¬ 0 ¤Ê¤é¤Ð¡¢ @c Mnil
1538 mplist_key (MPlist *plist)
1540 return MPLIST_KEY (plist);
1546 @brief Return the value of the first property in a property list.
1548 The mplist_value () function returns the value of the first
1549 property in property list $PLIST. If the length of $PLIST
1550 is zero, it returns @c NULL. */
1552 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹.
1554 ´Ø¿ô mplist_value () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST Ãæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£
1555 $PLIST ¤ÎŤµ¤¬ 0 ¤Ê¤é¤Ð¡¢ @c Mnil ¤òÊÖ¤¹¡£ */
1558 mplist_value (MPlist *plist)
1560 return MPLIST_VAL (plist);
1564 @brief Generate a property list by deserializing an M-text.
1566 The mplist_deserialize () function parses M-text $MT and returns a
1569 The syntax of $MT is as follows.
1571 MT ::= '(' ELEMENT * ')'
1573 ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
1575 SYMBOL ::= ascii-character-sequence
1577 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
1578 | '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
1580 M-TEXT ::= '"' character-sequence '"'
1582 Each alternatives of @c ELEMENT is assigned one of these keys: @c
1583 Msymbol, @c Minteger, @c Mtext, @c Mplist
1585 In an ascii-character-sequence, a backslash (\) is used as the escape
1586 character, which means that, for instance, <tt>abc\ def</tt>
1587 produces a symbol whose name is of length seven with the fourth
1588 character being a space. */
1590 @brief M-text ¤ò¥Ç¥·¥ê¥¢¥é¥¤¥º¤·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òºî¤ë.
1592 ´Ø¿ô mplist_deserialize () ¤Ï M-text $MT ¤ò²òÀϤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òÊÖ¤¹¡£
1594 $MT ¤Î¥·¥ó¥¿¥Ã¥¯¥¹¤Ï°Ê²¼¤ÎÄ̤ꡣ
1596 MT ::= '(' ELEMENT * ')'
1598 ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
1600 SYMBOL ::= ¥¢¥¹¥¡¼Ê¸»úÎó
1602 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
1603 | '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
1605 M-TEXT ::= '"' character-sequence '"'
1607 @c ELEMENT ¤Î³ÆÁªÂò»è¤Ï¥¡¼¡§@c Msymbol, @c Minteger, @c Mtext,
1608 @c Mplist ¤Î¤¤¤º¤ì¤«¤ò³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¡£
1610 ¥¢¥¹¥¡¼Ê¸»úÎóÆâ¤Ç¤Ï¡¢¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å (\) ¤¬¥¨¥¹¥±¡¼¥×ʸ»ú¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£¤¿¤È¤¨¤Ð
1611 <tt>abc\ def</tt> ¤Ï 4 ʸ»úÌܤ¬¶õÇòʸ»ú¤Ç¤¢¤êŤµ¤¬ 7
1612 ¤Ç¤¢¤ë»ý¤Ä̾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òÀ¸À®¤¹¤ë¡£ */
1615 mplist_deserialize (MText *mt)
1620 if (mt->format > MTEXT_FORMAT_UTF_8)
1622 if (MTEXT_READ_ONLY_P (mt))
1623 mt = tmp = mtext_cpy (mtext (), mt);
1625 mtext__adjust_format (mt, MTEXT_FORMAT_UTF_8);
1627 plist = mplist__from_string (MTEXT_DATA (mt), mtext_nbytes (mt));
1629 M17N_OBJECT_UNREF (tmp);
1635 /*** @addtogroup m17nDebug */
1640 @brief Dump a property list.
1642 The mdebug_dump_plist () function prints a property list $PLIST in
1643 a human readable way to the stderr or to what specified by the
1644 environment variable MDEBUG_OUTPUT_FILE. $INDENT specifies how
1645 many columns to indent the lines but the first one.
1648 This function returns $PLIST. */
1650 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¥À¥ó¥×¤¹¤ë.
1652 ´Ø¿ô mdebug_dump_plist () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤òɸ½à¥¨¥é¡¼½Ð
1653 ÎϤ⤷¤¯¤Ï´Ä¶ÊÑ¿ô MDEBUG_DUMP_FONT ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¿Í´Ö¤Ë²Ä
1654 ÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
1657 ¤³¤Î´Ø¿ô¤Ï $PLIST ¤òÊÖ¤¹¡£ */
1659 mdebug_dump_plist (MPlist *plist, int indent)
1661 char *prefix = (char *) alloca (indent + 1);
1664 memset (prefix, 32, indent);
1667 fprintf (mdebug__output, "(");
1668 MPLIST_DO (pl, plist)
1671 fprintf (mdebug__output, "\n%s ", prefix);
1672 write_element (NULL, pl, indent + 1);
1674 fprintf (mdebug__output, ")");