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
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)
237 int chars[READ_MTEXT_BUF_SIZE];
238 unsigned char bytes[sizeof (int) * READ_MTEXT_BUF_SIZE];
240 unsigned char *bytes = buffer.bytes;
241 int nbytes = sizeof (int) * READ_MTEXT_BUF_SIZE;
247 while ((c = GETC (st)) != EOF && c != '"')
258 if (c == 'x' || c == 'u')
262 c = read_hexadesimal (st);
270 c = escape_mnemonic[c];
275 if (is_char && ! chars)
277 chars = buffer.chars;
278 for (j = i - 1; j >= 0; j--)
280 nchars = READ_MTEXT_BUF_SIZE;
281 if (bytes != buffer.bytes)
290 if (chars == buffer.chars)
292 MTABLE_MALLOC (chars, nchars, MERROR_PLIST);
293 memcpy (chars, buffer.chars, sizeof (int) * i);
296 MTABLE_REALLOC (chars, nchars, MERROR_PLIST);
302 if (i + MAX_UTF8_CHAR_BYTES >= nbytes)
305 if (bytes == buffer.bytes)
307 MTABLE_MALLOC (bytes, nbytes, MERROR_PLIST);
308 memcpy (bytes, buffer.bytes, i);
311 MTABLE_REALLOC (bytes, nbytes, MERROR_PLIST);
324 mt = mtext__from_data (chars, i, MTEXT_FORMAT_UTF_32, 1);
325 if (chars != buffer.chars)
330 mt = mtext__from_data (bytes, i, MTEXT_FORMAT_UTF_8, 1);
331 if (bytes != buffer.bytes)
334 MPLIST_SET_ADVANCE (plist, Mtext, mt);
340 read_character (MStream *st, int c)
342 unsigned char buf[MAX_UTF8_CHAR_BYTES + 1];
343 int len = CHAR_BYTES_BY_HEAD (c);
347 for (i = 1; i < len; i++)
351 || (c & 0xC0) != 0x80)
356 c = STRING_CHAR_UTF8 (buf);
363 /** Read a symbol element from ST, and add it to LIST. Return a list
364 for the next element. */
367 read_symbol_element (MPlist *plist, MStream *st, int c, int skip)
369 unsigned char buffer[1024];
371 unsigned char *buf = buffer;
377 && c != ')' && c != '(' && c != '"')
384 MTABLE_MALLOC (buf, bufsize, MERROR_PLIST);
385 memcpy (buf, buffer, i);
388 MTABLE_REALLOC (buf, bufsize, MERROR_PLIST);
395 c = escape_mnemonic[c];
407 MPLIST_SET_ADVANCE (plist, Msymbol, msymbol ((char *) buf));
414 /** Read an integer element from ST, and add it to LIST. Return a
415 list for the next element. It is assumed that we have already
416 read the character C. */
419 read_integer_element (MPlist *plist, MStream *st, int c, int skip)
429 return read_symbol_element (plist, st, '#', skip);
431 num = read_hexadesimal (st);
436 num = (c == 'x' ? read_hexadesimal (st) : read_decimal (st, c));
445 if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c))
448 num = read_character (st, c);
455 else if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c))
456 num = escape_mnemonic[c];
458 num = read_character (st, c);
464 if (c < '0' || c > '9')
467 return read_symbol_element (plist, st, '-', skip);
469 num = - read_decimal (st, c);
472 num = read_decimal (st, c);
475 MPLIST_SET_ADVANCE (plist, Minteger, (void *) num);
479 /* Read an element of various type from stream ST, and add it to LIST.
480 Return a list for the next element. The element type is decided by
481 the first token character found as below:
484 '0'..'9', '-': integer
485 '?': integer representing character code
486 the other ASCII letters: symbol
488 If KEYS is not NULL, it is a plist contains target keys and stop
489 keys. In this caes, read only a plist whose key has value 1 in
490 KEYS, and return NULL when we encounter a plist whose key has value
491 0 in KEYS while skipping any other elements. */
494 read_element (MPlist *plist, MStream *st, MPlist *keys)
498 /* Skip separators and comments. */
501 while ((c = GETC (st)) != EOF && c <= ' ');
504 while ((c = GETC (st)) != EOF && c != '\n');
515 p = read_element (p, st, NULL);
516 if (keys && p && MPLIST_SYMBOL_P (pl))
518 if (MPLIST_TAIL_P (keys))
520 while ((p = read_element (p, st, NULL)));
521 MPLIST_SET_ADVANCE (plist, Mplist, pl);
528 MPLIST_FIND (p0, MPLIST_SYMBOL (pl));
529 if (! MPLIST_TAIL_P (p0) && ! MPLIST_VAL (p0))
531 M17N_OBJECT_UNREF (pl);
534 while ((p = read_element (p, st, NULL)));
535 if (! MPLIST_TAIL_P (p0))
537 MPLIST_SET_ADVANCE (plist, Mplist, pl);
541 M17N_OBJECT_UNREF (pl);
547 while ((p = read_element (p, st, NULL)));
548 MPLIST_SET_ADVANCE (plist, Mplist, pl);
553 return (read_mtext_element (plist, st, keys ? 1 : 0));
554 if ((c >= '0' && c <= '9') || c == '-' || c == '?' || c == '#')
555 return (read_integer_element (plist, st, c, keys ? 1 : 0));
556 if (c == EOF || c == ')')
558 return (read_symbol_element (plist, st, c, keys ? 1 : 0));
561 #define PUTC(MT, C) \
564 mtext_cat_char ((MT), (C)); \
566 putc ((C), stderr); \
569 #define PUTS(MT, STR) \
572 MTEXT_CAT_ASCII ((MT), (STR)); \
574 fputs ((STR), stderr); \
579 write_symbol (MText *mt, MSymbol sym)
587 char *name = MSYMBOL_NAME (sym);
593 if (*name <= ' ' || *name == '\\' || *name == '"'
594 || *name == '(' || *name == ')')
603 write_element (MText *mt, MPlist *plist, int indent)
605 if (MPLIST_SYMBOL_P (plist))
607 write_symbol (mt, MPLIST_SYMBOL (plist));
609 else if (MPLIST_INTEGER_P (plist))
611 int num = MPLIST_INTEGER (plist);
614 sprintf (buf, "%d", num);
617 else if (MPLIST_PLIST_P (plist)
618 || MPLIST_NESTED_P (plist))
623 if (MPLIST_NESTED_P (plist))
625 write_symbol (mt, MPLIST_KEY (plist));
628 plist = MPLIST_PLIST (plist);
632 MPLIST_DO (pl, plist)
636 if (indent > 0 && (MPLIST_PLIST_P (pl) || MPLIST_MTEXT_P (pl)))
643 for (i = 1; i < indent; i++)
648 write_element (mt, pl, indent);
650 newline = (MPLIST_PLIST_P (pl) || MPLIST_MTEXT_P (pl));
654 else if (MPLIST_MTEXT_P (plist))
656 MText *this_mt = MPLIST_MTEXT (plist);
657 int from = 0, to = mtext_nchars (this_mt);
658 int stop1 = 0, stop2 = 0;
660 if (! mt && this_mt->format > MTEXT_FORMAT_UTF_8)
662 this_mt = mtext_dup (this_mt);
663 mtext__adjust_format (this_mt, MTEXT_FORMAT_UTF_8);
673 if ((stop1 = mtext_character (this_mt, from, to, '"')) < 0)
678 if ((stop2 = mtext_character (this_mt, from, to, '\\')) < 0)
682 stop = stop1++, escaped = '"';
684 stop = stop2++, escaped = '\\';
686 mtext_copy (mt, mtext_nchars (mt), this_mt, from, stop);
689 unsigned char *data = MTEXT_DATA (this_mt);
690 unsigned char *beg = data + mtext__char_to_byte (this_mt, from);
691 unsigned char *end = data + mtext__char_to_byte (this_mt, stop);
694 putc (*beg, stderr), beg++;
703 if (this_mt != MPLIST_MTEXT (plist))
704 M17N_OBJECT_UNREF (this_mt);
706 else if (MPLIST_STRING_P (plist))
708 char *str = MPLIST_STRING (plist);
712 MText *this_mt = mtext__from_data (str, strlen (str),
713 MTEXT_FORMAT_UTF_8, 0);
715 mtext_copy (mt, mtext_nchars (mt),
716 this_mt, 0, mtext_nchars (this_mt));
717 M17N_OBJECT_UNREF (this_mt);
720 fprintf (stderr, "%s", str);
726 write_symbol (mt, MPLIST_KEY (plist));
728 sprintf (buf, "%04X", (unsigned) MPLIST_VAL (plist));
740 M17N_OBJECT_ADD_ARRAY (plist_table, "Plist");
742 Minteger = msymbol ("integer");
743 Mplist = msymbol_as_managing_key ("plist");
744 Mtext = msymbol_as_managing_key ("mtext");
746 for (i = 0; i < 256; i++)
747 hex_mnemonic[i] = 255;
748 for (i = '0'; i <= '9'; i++)
749 hex_mnemonic[i] = i - '0';
750 for (i = 'A'; i <= 'F'; i++)
751 hex_mnemonic[i] = i - 'A' + 10;
752 for (i = 'a'; i <= 'f'; i++)
753 hex_mnemonic[i] = i - 'a' + 10;
754 for (i = 0; i < 256; i++)
755 escape_mnemonic[i] = i;
756 escape_mnemonic['e'] = 27;
757 escape_mnemonic['b'] = '\b';
758 escape_mnemonic['f'] = '\f';
759 escape_mnemonic['n'] = '\n';
760 escape_mnemonic['r'] = '\r';
761 escape_mnemonic['t'] = '\t';
762 escape_mnemonic['\\'] = '\\';
773 /* Parse this form of PLIST:
774 (symbol:KEY1 TYPE1:VAL1 symbol:KEY2 TYPE2:VAL2 ...)
775 and return a newly created plist of this form:
776 (KEY1:VAL1 KEY2:VAL2 ...) */
779 mplist__from_plist (MPlist *plist)
785 while (! MPLIST_TAIL_P (plist))
789 if (! MPLIST_SYMBOL_P (plist))
790 MERROR (MERROR_PLIST, NULL);
791 key = MPLIST_SYMBOL (plist);
792 plist = MPLIST_NEXT (plist);
793 type = MPLIST_KEY (plist);
794 if (type->managing_key && MPLIST_VAL (plist))
795 M17N_OBJECT_REF (MPLIST_VAL (plist));
797 MPLIST_SET_NESTED_P (p);
798 MPLIST_SET_ADVANCE (p, key, MPLIST_VAL (plist));
799 plist = MPLIST_NEXT (plist);
804 /** Parse this form of PLIST:
805 ((symbol:KEY1 ANY:VAL1 ... ) (symbol:KEY2 ANY:VAL2 ...) ...)
806 and return a newly created plist of this form:
807 (KEY1:(ANY:VAL1 ...) KEY2:(ANY:VAL2 ...) ...)
808 ANY can be any type. */
811 mplist__from_alist (MPlist *plist)
817 MPLIST_DO (plist, plist)
821 if (! MPLIST_PLIST_P (plist))
822 MERROR (MERROR_PLIST, NULL);
823 elt = MPLIST_PLIST (plist);
824 if (! MPLIST_SYMBOL_P (elt))
825 MERROR (MERROR_PLIST, NULL);
826 MPLIST_SET_NESTED_P (p);
827 MPLIST_SET_ADVANCE (p, MPLIST_SYMBOL (elt), MPLIST_NEXT (elt));
828 M17N_OBJECT_REF (MPLIST_NEXT (elt));
835 mplist__from_file (FILE *fp, MPlist *keys)
842 st.p = st.pend = st.buffer;
845 while ((pl = read_element (pl, &st, keys)));
850 /** Parse $STR of $N bytes and return a property list object. $FORMAT
851 must be either @c MTEXT_FORMAT_US_ASCII or @c MTEXT_FORMAT_UTF_8,
852 and controls how to produce @c STRING or @c M-TEXT in the
853 following definition.
855 The syntax of $STR is as follows.
857 PLIST ::= '(' ELEMENT * ')'
859 ELEMENT ::= SYMBOL | INTEGER | UNSIGNED | STRING | M-TEXT | PLIST
861 SYMBOL ::= ascii-character-sequence
863 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
865 UNSIGNED ::= '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
867 M-TEXT ::= '"' byte-sequence '"'
869 Each kind of @c ELEMENT is assigned one of these keys:
870 @c Msymbol, @c Mint, @c Munsigned, @c Mtext, @c Mplist
872 In an ascii-character-sequence, a backslush (\) is used as the escape
873 character, which means that, for instance, <tt>"abc\ def"</tt>
874 produces a symbol whose name is of length seven with the fourth
875 character being a space.
877 In a byte-sequence, "\r", "\n", "\e", and "\t" are replaced by CR,
878 NL, ESC, and TAB character respectively, "\xXX" are replaced by
879 byte 0xXX. After this replacement, the byte-sequence is decoded
880 into M-TEXT by $CODING. */
883 mplist__from_string (unsigned char *str, int n)
894 while ((pl = read_element (pl, &st, NULL)));
899 mplist__serialize (MText *mt, MPlist *plist, int pretty)
902 int separator = pretty ? '\n' : ' ';
904 MPLIST_DO (pl, plist)
907 mtext_cat_char (mt, separator);
908 write_element (mt, pl, pretty ? 0 : -1);
911 mtext_cat_char (mt, separator);
916 @brief Concatenate two plists.
918 The mplist__conc () function concatenates plist $TAIL at the end of
919 plist $PLIST and return $PLIST. If $TAIL is empty, return $PLIST
920 without modifying it. */
923 mplist__conc (MPlist *plist, MPlist *tail)
927 if (MPLIST_TAIL_P (tail))
929 MPLIST_DO (pl, plist);
930 MPLIST_KEY (pl) = MPLIST_KEY (tail);
931 MPLIST_VAL (pl) = MPLIST_VAL (tail);
932 if (MPLIST_KEY (pl)->managing_key && MPLIST_VAL (pl))
933 M17N_OBJECT_REF (MPLIST_VAL (pl));
934 if (MPLIST_NESTED_P (tail))
935 MPLIST_SET_NESTED_P (pl);
936 tail = MPLIST_NEXT (tail);
937 MPLIST_NEXT (pl) = tail;
938 M17N_OBJECT_REF (tail);
944 @brief Discard a property at the beginning of a property list.
946 The mplist__pop_unref () function removes a property at the
947 beginning of property list $PLIST, and if the property value is a
948 managed object, unref it. As a result, the second key and value
949 of the original $PLIST become the first of those of the new
953 mplist__pop_unref (MPlist *plist)
958 if (MPLIST_TAIL_P (plist))
960 key = MPLIST_KEY (plist);
961 val = mplist_pop (plist);
962 if (key->managing_key)
963 M17N_OBJECT_UNREF (val);
967 @brief Search for an element of an alist represented by a plist.
969 The mplist__assq () function treats $PLIST as an association list
970 (elements are plists (key is #Mplist) whose first element is a
971 symbol (key is #Msymbol)), and find an element whose first element
972 has key #Msymbol and value $KEY.
974 Non-plist elements of $PLIST are ignored.
977 This function returns a found element or NULL if no element
978 matches with $KEY. */
981 mplist__assq (MPlist *plist, MSymbol key)
983 MPLIST_DO (plist, plist)
984 if (MPLIST_PLIST_P (plist))
986 MPlist *pl = MPLIST_PLIST (plist);
988 if (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == key)
995 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
1000 /*** @addtogroup m17nPlist */
1005 @brief Symbol whose name is "integer".
1007 The symbol @c Minteger has the name <tt>"integer"</tt>. The value
1008 of a property whose key is @c Minteger must be an integer. */
1010 @brief "integer" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
1012 ¥·¥ó¥Ü¥ë @c Minteger ¤Ï <tt>"integer"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¡£¥¡¼¤¬
1013 @c Minteger ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤÏÀ°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
1019 @brief Symbol whose name is "plist".
1021 The symbol @c Mplist has the name <tt>"plist"</tt>. It is a
1022 managing key. A value of a property whose key is @c Mplist must
1025 @brief "plist" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
1027 ¥·¥ó¥Ü¥ë @c Mplist ¤Ï <tt>"plist"</tt>
1028 ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¡£¤³¤ì¤Ï´ÉÍý¥¡¼¤Ç¤¢¤ë¡£¥¡¼¤¬ @c Mplist
1029 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¤Ï plist ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
1035 @brief Symbol whose name is "mtext".
1037 The symbol @c Mtext has the name <tt>"mtext"</tt>. It is a
1038 managing key. A value of a property whose key is @c Mtext must be an
1042 @brief "mtext" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
1044 ¥·¥ó¥Ü¥ë @c Mtext ¤Ï <tt>"mtext"</tt>
1045 ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä´ÉÍý¥¡¼¤Ç¤¢¤ë¡£¥¡¼¤¬ @c Mtext
1046 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¤Ï M-text ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
1052 @brief Create a property list object.
1054 The mplist () function returns a newly created property list
1055 object of length zero.
1058 This function returns a newly created property list.
1061 This function never fails. */
1063 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë.
1065 ´Ø¿ô mplist () ¤ÏŤµ 0 ¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò¿·¤·¤¯ºî¤Ã¤ÆÊÖ¤¹¡£
1068 ¤³¤Î´Ø¿ô¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹¡£
1071 ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£ */
1084 @brief Copy a property list.
1086 The mplist_copy () function copies property list $PLIST. In the
1087 copy, the values are the same as those of $PLIST.
1090 This function returns a newly created plist which is a copy of
1094 This function never fails. */
1096 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¥³¥Ô¡¼¤¹¤ë.
1098 ´Ø¿ô mplist_copy () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1099 ¤ò¥³¥Ô¡¼¤¹¤ë¡£¥³¥Ô¡¼¤Î¤¹¤Ù¤Æ¤ÎÃͤϥ³¥Ô¡¼¸µ $PLIST ¤ÎÃͤÈƱ¤¸¤Ç¤¢¤ë¡£
1102 ¤³¤Î´Ø¿ô¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¡¢$PLIST ¤Î¥³¥Ô¡¼¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òÊÖ¤¹¡£
1105 ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£ */
1108 mplist_copy (MPlist *plist)
1110 MPlist *copy = mplist (), *pl = copy;
1112 MPLIST_DO (plist, plist)
1114 if (MPLIST_NESTED_P (plist))
1115 MPLIST_SET_NESTED_P (pl);
1116 pl = mplist_add (pl, MPLIST_KEY (plist), MPLIST_VAL (plist));
1124 @brief Set the value of a property in a property list.
1126 The mplist_put () function searches property list $PLIST
1127 from the beginning for a property whose key is $KEY. If such a
1128 property is found, its value is changed to $VALUE. Otherwise, a
1129 new property whose key is $KEY and value is $VALUE is appended at
1130 the end of $PLIST. See the documentation of mplist_add () for
1131 the restriction on $KEY and $VAL.
1133 If $KEY is a managing key, $VAL must be a managed object. In this
1134 case, the reference count of the old value, if not @c NULL, is
1135 decremented by one, and that of $VAL is incremented by one.
1138 If the operation was successful, mplist_put () returns a sublist of
1139 $PLIST whose first element is the just modified or added one.
1140 Otherwise, it returns @c NULL. */
1142 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÀßÄꤹ¤ë.
1144 ´Ø¿ô mplist_put () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥¡¼¤¬
1145 $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤò $VALUE
1146 ¤ËÊѹ¹¤¹¤ë¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¥¡¼¤¬ $KEY ¤ÇÃͤ¬ $VALUE
1147 ¤Ç¤¢¤ë¿·¤·¤¤¥×¥í¥Ñ¥Æ¥£¤¬ $PLIST ¤ÎËöÈø¤ËÄɲ䵤ì¤ë¡£$KEY ¤È $VAL
1148 ¤ËÂФ¹¤ëÀ©¸Â¤Ë¤Ä¤¤¤Æ¤Ï¡¢mplist_add () ¤ÎÀâÌÀ¤ò»²¾È¡£
1150 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢
1151 $VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢¸Å¤¤Ãͤλ²¾È¿ô¤Ï
1152 @c NULL ¤Ç¤Ê¤±¤ì¤Ð 1 ¸º¤é¤µ¤ì¡¢$VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1155 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mplist_put () ¤ÏÊѹ¹¤µ¤ì¤¿¤«Äɲ䵤줿Í×ÁǤ«¤é»Ï¤Þ¤ë
1156 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1159 mplist_put (MPlist *plist, MSymbol key, void *val)
1162 MERROR (MERROR_PLIST, NULL);
1163 MPLIST_FIND (plist, key);
1164 if (key->managing_key)
1166 if (! MPLIST_TAIL_P (plist))
1167 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1169 M17N_OBJECT_REF (val);
1171 MPLIST_SET (plist, key, val);
1178 @brief Get the value of a property in a property list.
1180 The mplist_get () function searches property list $PLIST from the
1181 beginning for a property whose key is $KEY. If such a property is
1182 found, its value is returned as the type of <tt>(void *)</tt>. If
1183 not found, @c NULL is returned.
1185 When @c NULL is returned, there are two possibilities: one is the
1186 case where no property is found (see above); the other is the case
1187 where a property is found and its value is @c NULL. In case that
1188 these two cases must be distinguished, use the mplist_find_by_key ()
1191 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
1193 ´Ø¿ô mplist_get () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥¡¼
1194 ¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤò
1195 <tt>(void *)</tt> ·¿¤ÇÊÖ¤¹¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
1197 @c NULL ¤¬Ê֤俺ݤˤÏÆó¤Ä¤Î²ÄǽÀ¤¬¤¢¤ë:
1198 ¾åµ¤Î¤è¤¦¤Ë¥×¥í¥Ñ¥Æ¥£¤¬¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¾ì¹ç¤È¡¢¥×¥í¥Ñ¥Æ¥£¤¬¸«¤Ä¤«¤ê¡¢¤½¤ÎÃͤ¬
1199 @c NULL ¤Ç¤¢¤ë¾ì¹ç¤Ç¤¢¤ë¡£¤³¤ì¤é¤ò¶èÊ̤¹¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤Ë¤Ï´Ø¿ô
1200 mplist_find_by_key () ¤ò»È¤¦¤³¤È¡£ */
1204 mplist_find_by_key () */
1207 mplist_get (MPlist *plist, MSymbol key)
1209 MPLIST_FIND (plist, key);
1210 return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_VAL (plist));
1216 @brief Set the value (function pointer) of a property in a property list.
1218 The mplist_put_func () function is similar to mplist_put () but for
1219 setting function pointer $FUNC in property list $PLIST for key
1220 $KEY. $KEY must not be a managing key. */
1223 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤Ë´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÀßÄꤹ¤ë.
1225 ´Ø¿ô mplist_put_func () ¤Ï´Ø¿ô mplist_put () ƱÍÍ¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1226 Ãæ¤Ç¥¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë¡£Ã¢¤·¤½¤ÎÃͤϴؿô¥Ý¥¤¥ó¥¿
1227 $FUNC ¤Ç¤¢¤ë¡£$KEY ¤Ï´ÉÍý¥¡¼¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
1232 mplist_put (), M17N_FUNC () */
1235 mplist_put_func (MPlist *plist, MSymbol key, M17NFunc func)
1237 if (key == Mnil || key->managing_key)
1238 MERROR (MERROR_PLIST, NULL);
1239 MPLIST_FIND (plist, key);
1240 MPLIST_KEY (plist) = key;
1241 MPLIST_FUNC (plist) = func;
1242 MPLIST_SET_VAL_FUNC_P (plist);
1244 MPLIST_NEW ((plist)->next);
1251 @brief Get the value (function pointer) of a property in a property list.
1253 The mplist_get_func () function is similar to mplist_get () but for
1254 getting a function pointer from property list $PLIST by key $KEY. */
1257 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤«¤é¥×¥í¥Ñ¥Æ¥£¤Î´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÆÀ¤ë.
1259 ´Ø¿ô mplist_get_func () ¤Ï´Ø¿ô mplist_get () ¤ÈƱÍͤˡ¢¥×¥í¥Ñ¥Æ¥£¥ê
1260 ¥¹¥È $PLIST Ãæ¤Ç¥¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¡¢Ã¢¤·´Ø¿ô¥Ý¥¤¥ó¥¿¡¢
1268 mplist_get_func (MPlist *plist, MSymbol key)
1270 MPLIST_FIND (plist, key);
1271 return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_FUNC (plist));
1277 @brief Add a property at the end of a property list.
1279 The mplist_add () function appends at the end of property list
1280 $PLIST a property whose key is $KEY and value is $VAL. $KEY can
1281 be any symbol other than @c Mnil.
1283 If $KEY is a managing key, $VAL must be a managed object. In this
1284 case, the reference count of $VAL is incremented by one.
1287 If the operation was successful, mplist_add () returns a sublist of
1288 $PLIST whose first element is the just added one. Otherwise, it
1291 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈËöÈø¤Ë¥×¥í¥Ñ¥Æ¥£¤òÄɲ乤ë.
1293 ´Ø¿ô mplist_add () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎËöÈø¤Ë¥¡¼¤¬ $KEY
1294 ¤ÇÃͤ¬ $VAL ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤òÄɲ乤롣$KEY ¤Ï¡¢@c Mnil °Ê³°¤ÎǤ°Õ¤Î¥·¥ó¥Ü¥ë¤Ç¤è¤¤¡£
1296 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢$VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢
1297 $VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1300 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mplist_add () ¤ÏÄɲ䵤줿Í×ÁǤ«¤é»Ï¤Þ¤ë $PLIST
1301 ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1304 mplist_add (MPlist *plist, MSymbol key, void *val)
1307 MERROR (MERROR_PLIST, NULL);
1308 MPLIST_FIND (plist, Mnil);
1309 if (val && key->managing_key)
1310 M17N_OBJECT_REF (val);
1311 MPLIST_KEY (plist) = key;
1312 MPLIST_VAL (plist) = val;
1313 MPLIST_NEW (plist->next);
1320 @brief Add a property at the beginning of a property list.
1322 The mplist_push () function inserts at the beginning of property
1323 list $PLIST a property whose key is $KEY and value is $VAL.
1325 If $KEY is a managing key, $VAL must be a managed object. In this
1326 case, the reference count of $VAL is incremented by one.
1329 If the operation was successful, this function returns $PLIST.
1330 Otherwise, it returns @c NULL. */
1332 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤Ë¥×¥í¥Ñ¥Æ¥£¤òÁÞÆþ¤¹¤ë.
1334 ´Ø¿ô mplist_push () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Ë¥¡¼¤¬ $KEY
1335 ¤ÇÃͤ¬ $VAL ¤Ç¤¢¤ë¥ª¥Ö¥¸¥§¥¯¥È¤òÁÞÆþ¤¹¤ë¡£
1337 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢$VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢
1338 $VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1341 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï $PLIST ¤òÊÖ¤·¡¢¤½¤¦¤Ç¤Ê¤±¤ì¤Ð@c NULL
1345 mplist_push (MPlist *plist, MSymbol key, void *val)
1350 MERROR (MERROR_PLIST, NULL);
1352 MPLIST_KEY (pl) = MPLIST_KEY (plist);
1353 MPLIST_VAL (pl) = MPLIST_VAL (plist);
1354 if (MPLIST_NESTED_P (plist))
1355 MPLIST_SET_NESTED_P (pl);
1356 MPLIST_NEXT (pl) = MPLIST_NEXT (plist);
1358 if (val && key->managing_key)
1359 M17N_OBJECT_REF (val);
1360 MPLIST_KEY (plist) = key;
1361 MPLIST_VAL (plist) = val;
1368 @brief Remove a property at the beginning of a property list.
1370 The mplist_pop () function removes a property at the beginning of
1371 property list $PLIST. As a result, the second key and value of
1372 the $PLIST become the first ones.
1375 If the operation was successful, this function return the value of
1376 the just popped property. Otherwise, it returns @c NULL. */
1378 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤«¤é¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë.
1380 ´Ø¿ô mplist_pop () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Î¥×¥í¥Ñ¥Æ¥£¤òºï
1381 ½ü¤¹¤ë¡£·ë²Ì¤È¤·¤Æ¡¢¸µ¤Î2ÈÖÌܤΥ¡¼¤ÈÃͤ¬ÀèƬ¤Î¥¡¼¤ÈÃͤˤʤ롣
1384 ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ïºï½ü¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
1388 mplist_pop (MPlist *plist)
1393 if (MPLIST_TAIL_P (plist))
1395 val = MPLIST_VAL (plist);
1396 next = MPLIST_NEXT (plist);
1397 MPLIST_KEY (plist) = MPLIST_KEY (next);
1398 MPLIST_VAL (plist) = MPLIST_VAL (next);
1399 if (MPLIST_KEY (plist) != Mnil
1400 && MPLIST_KEY (plist)->managing_key
1401 && MPLIST_VAL (plist))
1402 M17N_OBJECT_REF (MPLIST_VAL (plist));
1403 MPLIST_NEXT (plist) = MPLIST_NEXT (next);
1405 M17N_OBJECT_REF (plist->next);
1406 M17N_OBJECT_UNREF (next);
1412 @brief Find a property of a specific key in a property list.
1414 The mplist_find_by_key () function searches property list
1415 $PLIST from the beginning for a property whose key is $KEY. If
1416 such a property is found, a sublist of $PLIST whose first element
1417 is the found one is returned. Otherwise, @c NULL is returned.
1419 If $KEY is @c Mnil, it returns a sublist of $PLIST whose
1420 first element is the last one of $PLIST. */
1422 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃ椫¤é»ØÄê¤Î¥¡¼¤ò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤òõ¤¹.
1424 ´Ø¿ô mplist_find_by_key () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1425 ¤ò»Ï¤á¤«¤éõ ¤·¤Æ¡¢¥¡¼¤¬ $KEY
1426 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤«¤é»Ï¤Þ¤ë
1427 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
1429 $KEY ¤¬ @c Mnil ¤Ê¤é¤Ð¡¢$PLIST ¤ÎºÇ¸å¤ÎÍ×ÁǤ«¤é»Ï¤Þ¤ëÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£ */
1432 mplist_find_by_key (MPlist *plist, MSymbol key)
1434 MPLIST_FIND (plist, key);
1435 return (MPLIST_TAIL_P (plist)
1436 ? (key == Mnil ? plist : NULL)
1442 @brief Find a property of a specific value in a property list.
1444 The mplist_find_by_value () function searches property list $PLIST
1445 from the beginning for a property whose value is $VAL. If such a
1446 property is found, a sublist of $PLIST whose first element is the
1447 found one is returned. Otherwise, @c NULL is returned. */
1449 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃ椫¤é»ØÄê¤ÎÃͤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤òõ¤¹.
1451 ´Ø¿ô mplist_find_by_value () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1452 ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢Ãͤ¬ $VAL
1453 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤«¤é»Ï¤Þ¤ë
1454 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1457 mplist_find_by_value (MPlist *plist, void *val)
1459 MPLIST_DO (plist, plist)
1461 if (MPLIST_VAL (plist) == val)
1470 @brief Return the next sublist of a property list.
1472 The mplist_next () function returns a pointer to the sublist of
1473 property list $PLIST, which begins at the second element in $PLIST. If the
1474 length of $PLIST is zero, it returns @c NULL. */
1476 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Î¼¡¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹.
1478 ´Ø¿ô mplist_next () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤Î 2
1479 ÈÖÌܤÎÍ×ÁǤ«¤é»Ï¤Þ¤ëÉôʬ¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$PLIST ¤ÎŤµ¤¬ 0
1480 ¤Ê¤é¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1483 mplist_next (MPlist *plist)
1485 return (MPLIST_TAIL_P (plist) ? NULL : plist->next);
1491 @brief Set the first property in a property list.
1493 The mplist_set () function sets the key and the value of the first
1494 property in property list $PLIST to $KEY and $VALUE, respectively.
1495 See the documentation of mplist_add () for the restriction on $KEY
1499 If the operation was successful, mplist_set () returns $PLIST.
1500 Otherwise, it returns @c NULL. */
1502 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤òÀßÄꤹ¤ë.
1504 ´Ø¿ô mplist_set () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1505 ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤ÈÃͤò¤½¤ì¤¾¤ì $KEY ¤È $VALUE ¤ËÀßÄꤹ¤ë¡£
1506 $KEY ¤È $VAL ¤ËÂФ¹¤ëÀ©¸Â¤Ë¤Ä¤¤¤Æ¤Ï¡¢mplist_add () ¤ÎÀâÌÀ¤ò»²¾È¡£
1509 ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð mplist_set () ¤Ï $PLIST ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1512 mplist_set (MPlist *plist, MSymbol key, void * val)
1516 if (! MPLIST_TAIL_P (plist))
1518 key = MPLIST_KEY (plist);
1519 M17N_OBJECT_UNREF (MPLIST_NEXT (plist));
1520 MPLIST_KEY (plist) = Mnil;
1521 if (key->managing_key)
1522 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1528 if (val && key->managing_key)
1529 M17N_OBJECT_REF (val);
1530 if (! MPLIST_TAIL_P (plist)
1531 && MPLIST_KEY (plist)->managing_key)
1532 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1533 MPLIST_SET (plist, key, val);
1541 @brief Return the length of a property list.
1543 The mplist_length () function returns the number of properties in
1544 property list $PLIST. */
1546 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎŤµ¤òÊÖ¤¹.
1548 ´Ø¿ô mplist_length () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST Ãæ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¿ô¤òÊÖ¤¹¡£ */
1551 mplist_length (MPlist *plist)
1555 for (n = 0; ! (MPLIST_TAIL_P (plist)); n++, plist = plist->next);
1562 @brief Return the key of the first property in a property list.
1564 The mplist_key () function returns the key of the first property
1565 in property list $PLIST. If the length of $PLIST is zero,
1566 it returns @c Mnil. */
1568 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤òÊÖ¤¹.
1570 ´Ø¿ô mplist_key () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1571 Ãæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤òÊÖ¤¹¡£$PLIST ¤ÎŤµ¤¬ 0 ¤Ê¤é¤Ð¡¢ @c Mnil
1575 mplist_key (MPlist *plist)
1577 return MPLIST_KEY (plist);
1583 @brief Return the value of the first property in a property list.
1585 The mplist_value () function returns the value of the first
1586 property in property list $PLIST. If the length of $PLIST
1587 is zero, it returns @c NULL. */
1589 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹.
1591 ´Ø¿ô mplist_value () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST Ãæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£
1592 $PLIST ¤ÎŤµ¤¬ 0 ¤Ê¤é¤Ð¡¢ @c Mnil ¤òÊÖ¤¹¡£ */
1595 mplist_value (MPlist *plist)
1597 return MPLIST_VAL (plist);
1601 @brief Generate a property list by deserializing an M-text.
1603 The mplist_deserialize () function parses M-text $MT and returns a
1606 The syntax of $MT is as follows.
1608 MT ::= '(' ELEMENT * ')'
1610 ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
1612 SYMBOL ::= ascii-character-sequence
1614 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
1615 | '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
1617 M-TEXT ::= '"' character-sequence '"'
1619 Each alternatives of @c ELEMENT is assigned one of these keys: @c
1620 Msymbol, @c Minteger, @c Mtext, @c Mplist
1622 In an ascii-character-sequence, a backslash (\) is used as the escape
1623 character, which means that, for instance, <tt>"abc\ def"</tt>
1624 produces a symbol whose name is of length seven with the fourth
1625 character being a space. */
1627 @brief M-text ¤ò¥Ç¥·¥ê¥¢¥é¥¤¥º¤·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òºî¤ë.
1629 ´Ø¿ô mplist_deserialize () ¤Ï M-text $MT ¤ò²òÀϤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òÊÖ¤¹¡£
1631 $MT ¤Î¥·¥ó¥¿¥Ã¥¯¥¹¤Ï°Ê²¼¤ÎÄ̤ꡣ
1633 MT ::= '(' ELEMENT * ')'
1635 ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
1637 SYMBOL ::= ¥¢¥¹¥¡¼Ê¸»úÎó
1639 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
1640 | '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
1642 M-TEXT ::= '"' character-sequence '"'
1644 @c ELEMENT ¤Î³ÆÁªÂò»è¤Ï¥¡¼¡§@c Msymbol, @c Minteger, @c Mtext,
1645 @c Mplist ¤Î¤¤¤º¤ì¤«¤ò³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¡£
1647 ¥¢¥¹¥¡¼Ê¸»úÎóÆâ¤Ç¤Ï¡¢¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å (\) ¤¬¥¨¥¹¥±¡¼¥×ʸ»ú¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£¤¿¤È¤¨¤Ð
1648 <tt>"abc\ def"</tt> ¤Ï 4 ʸ»úÌܤ¬¶õÇòʸ»ú¤Ç¤¢¤êŤµ¤¬ 7
1649 ¤Ç¤¢¤ë»ý¤Ä̾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òÀ¸À®¤¹¤ë¡£ */
1652 mplist_deserialize (MText *mt)
1657 if (mt->format > MTEXT_FORMAT_UTF_8)
1659 if (MTEXT_READ_ONLY_P (mt))
1660 mt = tmp = mtext_cpy (mtext (), mt);
1662 mtext__adjust_format (mt, MTEXT_FORMAT_UTF_8);
1664 plist = mplist__from_string (MTEXT_DATA (mt), mtext_nbytes (mt));
1666 M17N_OBJECT_UNREF (tmp);
1672 /*** @addtogroup m17nDebug */
1677 @brief Dump a property list.
1679 The mdebug_dump_plist () function prints a property list $PLIST in
1680 a human readable way to the stderr. $INDENT specifies how many
1681 columns to indent the lines but the first one.
1684 This function returns $PLIST. */
1686 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¥À¥ó¥×¤¹¤ë.
1688 ´Ø¿ô mdebug_dump_plist () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò stderr
1689 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
1692 ¤³¤Î´Ø¿ô¤Ï $PLIST ¤òÊÖ¤¹¡£ */
1694 mdebug_dump_plist (MPlist *plist, int indent)
1696 char *prefix = (char *) alloca (indent + 1);
1699 memset (prefix, 32, indent);
1702 fprintf (stderr, "(");
1703 MPLIST_DO (pl, plist)
1706 fprintf (stderr, "\n%s ", prefix);
1707 write_element (NULL, pl, indent + 1);
1709 fprintf (stderr, ")");