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)
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);
296 mt = mtext__from_data (buf, i, MTEXT_FORMAT_UTF_8, 1);
299 mt = mtext__from_data (buf, i, MTEXT_FORMAT_UTF_8, 0);
302 MPLIST_SET_ADVANCE (plist, Mtext, mt);
308 read_character (MStream *st, int c)
310 unsigned char buf[MAX_UTF8_CHAR_BYTES + 1];
311 int len = CHAR_BYTES_BY_HEAD (c);
315 for (i = 1; i < len; i++)
319 || (c & 0xC0) != 0x80)
324 c = STRING_CHAR_UTF8 (buf);
331 /** Read a symbol element from ST, and add it to LIST. Return a list
332 for the next element. */
335 read_symbol_element (MPlist *plist, MStream *st, int c, int skip)
337 unsigned char buffer[1024];
339 unsigned char *buf = buffer;
345 && c != ')' && c != '(' && c != '"')
352 MTABLE_MALLOC (buf, bufsize, MERROR_PLIST);
353 memcpy (buf, buffer, i);
356 MTABLE_REALLOC (buf, bufsize, MERROR_PLIST);
363 c = escape_mnemonic[c];
375 MPLIST_SET_ADVANCE (plist, Msymbol, msymbol ((char *) buf));
382 /** Read an integer element from ST, and add it to LIST. Return a
383 list for the next element. It is assumed that we have already
384 read the character C. */
387 read_integer_element (MPlist *plist, MStream *st, int c, int skip)
397 return read_symbol_element (plist, st, '#', skip);
399 num = read_hexadesimal (st);
404 num = (c == 'x' ? read_hexadesimal (st) : read_decimal (st, c));
413 if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c))
416 num = read_character (st, c);
423 else if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c))
424 num = escape_mnemonic[c];
426 num = read_character (st, c);
432 if (c < '0' || c > '9')
435 return read_symbol_element (plist, st, '-', skip);
437 num = - read_decimal (st, c);
440 num = read_decimal (st, c);
443 MPLIST_SET_ADVANCE (plist, Minteger, (void *) num);
447 /* Read an element of various type from stream ST, and add it to LIST.
448 Return a list for the next element. The element type is decided by
449 the first token character found as below:
452 '0'..'9', '-': integer
453 '?': integer representing character code
454 the other ASCII letters: symbol
456 If KEYS is not NULL, it is a plist contains target keys and stop
457 keys. In this caes, read only a plist whose key has value 1 in
458 KEYS, and return NULL when we encounter a plist whose key has value
459 0 in KEYS while skipping any other elements. */
462 read_element (MPlist *plist, MStream *st, MPlist *keys)
466 /* Skip separators and comments. */
469 while ((c = GETC (st)) != EOF && c <= ' ');
472 while ((c = GETC (st)) != EOF && c != '\n');
483 p = read_element (p, st, NULL);
484 if (keys && p && MPLIST_SYMBOL_P (pl))
486 if (MPLIST_TAIL_P (keys))
488 while ((p = read_element (p, st, NULL)));
489 MPLIST_SET_ADVANCE (plist, Mplist, pl);
496 MPLIST_FIND (p0, MPLIST_SYMBOL (pl));
497 if (! MPLIST_TAIL_P (p0) && ! MPLIST_VAL (p0))
499 M17N_OBJECT_UNREF (pl);
502 while ((p = read_element (p, st, NULL)));
503 if (! MPLIST_TAIL_P (p0))
505 MPLIST_SET_ADVANCE (plist, Mplist, pl);
509 M17N_OBJECT_UNREF (pl);
515 while ((p = read_element (p, st, NULL)));
516 MPLIST_SET_ADVANCE (plist, Mplist, pl);
521 return (read_mtext_element (plist, st, keys ? 1 : 0));
522 if ((c >= '0' && c <= '9') || c == '-' || c == '?' || c == '#')
523 return (read_integer_element (plist, st, c, keys ? 1 : 0));
524 if (c == EOF || c == ')')
526 return (read_symbol_element (plist, st, c, keys ? 1 : 0));
529 #define PUTC(MT, C) \
532 mtext_cat_char ((MT), (C)); \
534 putc ((C), stderr); \
537 #define PUTS(MT, STR) \
540 MTEXT_CAT_ASCII ((MT), (STR)); \
542 fputs ((STR), stderr); \
547 write_symbol (MText *mt, MSymbol sym)
555 char *name = MSYMBOL_NAME (sym);
561 if (*name <= ' ' || *name == '\\' || *name == '"'
562 || *name == '(' || *name == ')')
571 write_element (MText *mt, MPlist *plist, int indent)
573 if (MPLIST_SYMBOL_P (plist))
575 write_symbol (mt, MPLIST_SYMBOL (plist));
577 else if (MPLIST_INTEGER_P (plist))
579 int num = MPLIST_INTEGER (plist);
582 sprintf (buf, "%d", num);
585 else if (MPLIST_PLIST_P (plist)
586 || MPLIST_NESTED_P (plist))
591 if (MPLIST_NESTED_P (plist))
593 write_symbol (mt, MPLIST_KEY (plist));
596 plist = MPLIST_PLIST (plist);
600 MPLIST_DO (pl, plist)
604 if (indent > 0 && (MPLIST_PLIST_P (pl) || MPLIST_MTEXT_P (pl)))
611 for (i = 1; i < indent; i++)
616 write_element (mt, pl, indent);
618 newline = (MPLIST_PLIST_P (pl) || MPLIST_MTEXT_P (pl));
622 else if (MPLIST_MTEXT_P (plist))
624 MText *this_mt = MPLIST_MTEXT (plist);
625 int from = 0, to = mtext_nchars (this_mt);
626 int stop1 = 0, stop2 = 0;
628 if (! mt && this_mt->format > MTEXT_FORMAT_UTF_8)
630 this_mt = mtext_dup (this_mt);
631 mtext__adjust_format (this_mt, MTEXT_FORMAT_UTF_8);
641 if ((stop1 = mtext_character (this_mt, from, to, '"')) < 0)
646 if ((stop2 = mtext_character (this_mt, from, to, '\\')) < 0)
650 stop = stop1++, escaped = '"';
652 stop = stop2++, escaped = '\\';
654 mtext_copy (mt, mtext_nchars (mt), this_mt, from, stop);
657 unsigned char *data = MTEXT_DATA (this_mt);
658 unsigned char *beg = data + mtext__char_to_byte (this_mt, from);
659 unsigned char *end = data + mtext__char_to_byte (this_mt, stop);
662 putc (*beg, stderr), beg++;
671 if (this_mt != MPLIST_MTEXT (plist))
672 M17N_OBJECT_UNREF (this_mt);
674 else if (MPLIST_STRING_P (plist))
676 char *str = MPLIST_STRING (plist);
680 MText *this_mt = mtext__from_data (str, strlen (str),
681 MTEXT_FORMAT_UTF_8, 0);
683 mtext_copy (mt, mtext_nchars (mt),
684 this_mt, 0, mtext_nchars (this_mt));
685 M17N_OBJECT_UNREF (this_mt);
688 fprintf (stderr, "%s", str);
694 write_symbol (mt, MPLIST_KEY (plist));
696 sprintf (buf, "%04X", (unsigned) MPLIST_VAL (plist));
708 M17N_OBJECT_ADD_ARRAY (plist_table, "Plist");
710 Minteger = msymbol ("integer");
711 Mplist = msymbol_as_managing_key ("plist");
712 Mtext = msymbol_as_managing_key ("mtext");
714 for (i = 0; i < 256; i++)
715 hex_mnemonic[i] = 255;
716 for (i = '0'; i <= '9'; i++)
717 hex_mnemonic[i] = i - '0';
718 for (i = 'A'; i <= 'F'; i++)
719 hex_mnemonic[i] = i - 'A' + 10;
720 for (i = 'a'; i <= 'f'; i++)
721 hex_mnemonic[i] = i - 'a' + 10;
722 for (i = 0; i < 256; i++)
723 escape_mnemonic[i] = i;
724 escape_mnemonic['e'] = 27;
725 escape_mnemonic['b'] = '\b';
726 escape_mnemonic['f'] = '\f';
727 escape_mnemonic['n'] = '\n';
728 escape_mnemonic['r'] = '\r';
729 escape_mnemonic['t'] = '\t';
730 escape_mnemonic['\\'] = '\\';
741 /* Parse this form of PLIST:
742 (symbol:KEY1 TYPE1:VAL1 symbol:KEY2 TYPE2:VAL2 ...)
743 and return a newly created plist of this form:
744 (KEY1:VAL1 KEY2:VAL2 ...) */
747 mplist__from_plist (MPlist *plist)
753 while (! MPLIST_TAIL_P (plist))
757 if (! MPLIST_SYMBOL_P (plist))
758 MERROR (MERROR_PLIST, NULL);
759 key = MPLIST_SYMBOL (plist);
760 plist = MPLIST_NEXT (plist);
761 type = MPLIST_KEY (plist);
762 if (type->managing_key && MPLIST_VAL (plist))
763 M17N_OBJECT_REF (MPLIST_VAL (plist));
765 MPLIST_SET_NESTED_P (p);
766 MPLIST_SET_ADVANCE (p, key, MPLIST_VAL (plist));
767 plist = MPLIST_NEXT (plist);
772 /** Parse this form of PLIST:
773 ((symbol:KEY1 ANY:VAL1 ... ) (symbol:KEY2 ANY:VAL2 ...) ...)
774 and return a newly created plist of this form:
775 (KEY1:(ANY:VAL1 ...) KEY2:(ANY:VAL2 ...) ...)
776 ANY can be any type. */
779 mplist__from_alist (MPlist *plist)
785 MPLIST_DO (plist, plist)
789 if (! MPLIST_PLIST_P (plist))
790 MERROR (MERROR_PLIST, NULL);
791 elt = MPLIST_PLIST (plist);
792 if (! MPLIST_SYMBOL_P (elt))
793 MERROR (MERROR_PLIST, NULL);
794 MPLIST_SET_NESTED_P (p);
795 MPLIST_SET_ADVANCE (p, MPLIST_SYMBOL (elt), MPLIST_NEXT (elt));
796 M17N_OBJECT_REF (MPLIST_NEXT (elt));
803 mplist__from_file (FILE *fp, MPlist *keys)
810 st.p = st.pend = st.buffer;
813 while ((pl = read_element (pl, &st, keys)));
818 /** Parse $STR of $N bytes and return a property list object. $FORMAT
819 must be either @c MTEXT_FORMAT_US_ASCII or @c MTEXT_FORMAT_UTF_8,
820 and controls how to produce @c STRING or @c M-TEXT in the
821 following definition.
823 The syntax of $STR is as follows.
825 PLIST ::= '(' ELEMENT * ')'
827 ELEMENT ::= SYMBOL | INTEGER | UNSIGNED | STRING | M-TEXT | PLIST
829 SYMBOL ::= ascii-character-sequence
831 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
833 UNSIGNED ::= '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
835 M-TEXT ::= '"' byte-sequence '"'
837 Each kind of @c ELEMENT is assigned one of these keys:
838 @c Msymbol, @c Mint, @c Munsigned, @c Mtext, @c Mplist
840 In an ascii-character-sequence, a backslush (\) is used as the escape
841 character, which means that, for instance, <tt>"abc\ def"</tt>
842 produces a symbol whose name is of length seven with the fourth
843 character being a space.
845 In a byte-sequence, "\r", "\n", "\e", and "\t" are replaced by CR,
846 NL, ESC, and TAB character respectively, "\xXX" are replaced by
847 byte 0xXX. After this replacement, the byte-sequence is decoded
848 into M-TEXT by $CODING. */
851 mplist__from_string (unsigned char *str, int n)
862 while ((pl = read_element (pl, &st, NULL)));
867 mplist__serialize (MText *mt, MPlist *plist, int pretty)
870 int separator = pretty ? '\n' : ' ';
872 MPLIST_DO (pl, plist)
875 mtext_cat_char (mt, separator);
876 write_element (mt, pl, pretty ? 0 : -1);
879 mtext_cat_char (mt, separator);
884 @brief Concatenate two plists.
886 The mplist__conc () function concatenates plist $TAIL at the end of
887 plist $PLIST and return $PLIST. If $TAIL is empty, return $PLIST
888 without modifying it. */
891 mplist__conc (MPlist *plist, MPlist *tail)
895 if (MPLIST_TAIL_P (tail))
897 MPLIST_DO (pl, plist);
898 MPLIST_KEY (pl) = MPLIST_KEY (tail);
899 MPLIST_VAL (pl) = MPLIST_VAL (tail);
900 if (MPLIST_KEY (pl)->managing_key && MPLIST_VAL (pl))
901 M17N_OBJECT_REF (MPLIST_VAL (pl));
902 if (MPLIST_NESTED_P (tail))
903 MPLIST_SET_NESTED_P (pl);
904 tail = MPLIST_NEXT (tail);
905 MPLIST_NEXT (pl) = tail;
906 M17N_OBJECT_REF (tail);
912 @brief Discard a property at the beginning of a property list.
914 The mplist__pop_unref () function removes a property at the
915 beginning of property list $PLIST, and if the property value is a
916 managed object, unref it. As a result, the second key and value
917 of the original $PLIST become the first of those of the new
921 mplist__pop_unref (MPlist *plist)
926 if (MPLIST_TAIL_P (plist))
928 key = MPLIST_KEY (plist);
929 val = mplist_pop (plist);
930 if (key->managing_key)
931 M17N_OBJECT_UNREF (val);
935 @brief Search for an element of an alist represented by a plist.
937 The mplist__assq () function treats $PLIST as an association list
938 (elements are plists (key is #Mplist) whose first element is a
939 symbol (key is #Msymbol)), and find an element whose first element
940 has key #Msymbol and value $KEY.
942 Non-plist elements of $PLIST are ignored.
945 This function returns a found element or NULL if no element
946 matches with $KEY. */
949 mplist__assq (MPlist *plist, MSymbol key)
951 MPLIST_DO (plist, plist)
952 if (MPLIST_PLIST_P (plist))
954 MPlist *pl = MPLIST_PLIST (plist);
956 if (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == key)
963 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
968 /*** @addtogroup m17nPlist */
973 @brief Symbol whose name is "integer".
975 The symbol @c Minteger has the name <tt>"integer"</tt>. The value
976 of a property whose key is @c Minteger must be an integer. */
978 @brief "integer" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
980 ¥·¥ó¥Ü¥ë @c Minteger ¤Ï <tt>"integer"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¡£¥¡¼¤¬
981 @c Minteger ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃͤÏÀ°¿ôÃͤǤʤ¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
987 @brief Symbol whose name is "plist".
989 The symbol @c Mplist has the name <tt>"plist"</tt>. It is a
990 managing key. A value of a property whose key is @c Mplist must
993 @brief "plist" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
995 ¥·¥ó¥Ü¥ë @c Mplist ¤Ï <tt>"plist"</tt>
996 ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¡£¤³¤ì¤Ï´ÉÍý¥¡¼¤Ç¤¢¤ë¡£¥¡¼¤¬ @c Mplist
997 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¤Ï plist ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
1003 @brief Symbol whose name is "mtext".
1005 The symbol @c Mtext has the name <tt>"mtext"</tt>. It is a
1006 managing key. A value of a property whose key is @c Mtext must be an
1010 @brief "mtext" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë.
1012 ¥·¥ó¥Ü¥ë @c Mtext ¤Ï <tt>"mtext"</tt>
1013 ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä´ÉÍý¥¡¼¤Ç¤¢¤ë¡£¥¡¼¤¬ @c Mtext
1014 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¤Ï M-text ¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
1020 @brief Create a property list object.
1022 The mplist () function returns a newly created property list
1023 object of length zero.
1026 This function returns a newly created property list.
1029 This function never fails. */
1031 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òºî¤ë.
1033 ´Ø¿ô mplist () ¤ÏŤµ 0 ¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤ò¿·¤·¤¯ºî¤Ã¤ÆÊÖ¤¹¡£
1036 ¤³¤Î´Ø¿ô¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹¡£
1039 ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£ */
1052 @brief Copy a property list.
1054 The mplist_copy () function copies property list $PLIST. In the
1055 copy, the values are the same as those of $PLIST.
1058 This function returns a newly created plist which is a copy of
1062 This function never fails. */
1064 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¥³¥Ô¡¼¤¹¤ë.
1066 ´Ø¿ô mplist_copy () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1067 ¤ò¥³¥Ô¡¼¤¹¤ë¡£¥³¥Ô¡¼¤Î¤¹¤Ù¤Æ¤ÎÃͤϥ³¥Ô¡¼¸µ $PLIST ¤ÎÃͤÈƱ¤¸¤Ç¤¢¤ë¡£
1070 ¤³¤Î´Ø¿ô¤Ï¿·¤·¤¯ºî¤é¤ì¤¿¡¢$PLIST ¤Î¥³¥Ô¡¼¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òÊÖ¤¹¡£
1073 ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£ */
1076 mplist_copy (MPlist *plist)
1078 MPlist *copy = mplist (), *pl = copy;
1080 MPLIST_DO (plist, plist)
1082 if (MPLIST_NESTED_P (plist))
1083 MPLIST_SET_NESTED_P (pl);
1084 pl = mplist_add (pl, MPLIST_KEY (plist), MPLIST_VAL (plist));
1092 @brief Set the value of a property in a property list.
1094 The mplist_put () function searches property list $PLIST
1095 from the beginning for a property whose key is $KEY. If such a
1096 property is found, its value is changed to $VALUE. Otherwise, a
1097 new property whose key is $KEY and value is $VALUE is appended at
1098 the end of $PLIST. See the documentation of mplist_add () for
1099 the restriction on $KEY and $VAL.
1101 If $KEY is a managing key, $VAL must be a managed object. In this
1102 case, the reference count of the old value, if not @c NULL, is
1103 decremented by one, and that of $VAL is incremented by one.
1106 If the operation was successful, mplist_put () returns a sublist of
1107 $PLIST whose first element is the just modified or added one.
1108 Otherwise, it returns @c NULL. */
1110 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÀßÄꤹ¤ë.
1112 ´Ø¿ô mplist_put () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥¡¼¤¬
1113 $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤò $VALUE
1114 ¤ËÊѹ¹¤¹¤ë¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð¡¢¥¡¼¤¬ $KEY ¤ÇÃͤ¬ $VALUE
1115 ¤Ç¤¢¤ë¿·¤·¤¤¥×¥í¥Ñ¥Æ¥£¤¬ $PLIST ¤ÎËöÈø¤ËÄɲ䵤ì¤ë¡£$KEY ¤È $VAL
1116 ¤ËÂФ¹¤ëÀ©¸Â¤Ë¤Ä¤¤¤Æ¤Ï¡¢mplist_add () ¤ÎÀâÌÀ¤ò»²¾È¡£
1118 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢
1119 $VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢¸Å¤¤Ãͤλ²¾È¿ô¤Ï
1120 @c NULL ¤Ç¤Ê¤±¤ì¤Ð 1 ¸º¤é¤µ¤ì¡¢$VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1123 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mplist_put () ¤ÏÊѹ¹¤µ¤ì¤¿¤«Äɲ䵤줿Í×ÁǤ«¤é»Ï¤Þ¤ë
1124 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1127 mplist_put (MPlist *plist, MSymbol key, void *val)
1130 MERROR (MERROR_PLIST, NULL);
1131 MPLIST_FIND (plist, key);
1132 if (key->managing_key)
1134 if (! MPLIST_TAIL_P (plist))
1135 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1137 M17N_OBJECT_REF (val);
1139 MPLIST_SET (plist, key, val);
1146 @brief Get the value of a property in a property list.
1148 The mplist_get () function searches property list $PLIST from the
1149 beginning for a property whose key is $KEY. If such a property is
1150 found, its value is returned as the type of <tt>(void *)</tt>. If
1151 not found, @c NULL is returned.
1153 When @c NULL is returned, there are two possibilities: one is the
1154 case where no property is found (see above); the other is the case
1155 where a property is found and its value is @c NULL. In case that
1156 these two cases must be distinguished, use the mplist_find_by_key ()
1159 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë.
1161 ´Ø¿ô mplist_get () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥¡¼
1162 ¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤò
1163 <tt>(void *)</tt> ·¿¤ÇÊÖ¤¹¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
1165 @c NULL ¤¬Ê֤俺ݤˤÏÆó¤Ä¤Î²ÄǽÀ¤¬¤¢¤ë:
1166 ¾åµ¤Î¤è¤¦¤Ë¥×¥í¥Ñ¥Æ¥£¤¬¸«¤Ä¤«¤é¤Ê¤«¤Ã¤¿¾ì¹ç¤È¡¢¥×¥í¥Ñ¥Æ¥£¤¬¸«¤Ä¤«¤ê¡¢¤½¤ÎÃͤ¬
1167 @c NULL ¤Ç¤¢¤ë¾ì¹ç¤Ç¤¢¤ë¡£¤³¤ì¤é¤ò¶èÊ̤¹¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤Ë¤Ï´Ø¿ô
1168 mplist_find_by_key () ¤ò»È¤¦¤³¤È¡£ */
1172 mplist_find_by_key () */
1175 mplist_get (MPlist *plist, MSymbol key)
1177 MPLIST_FIND (plist, key);
1178 return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_VAL (plist));
1184 @brief Set the value (function pointer) of a property in a property list.
1186 The mplist_put_func () function is similar to mplist_put () but for
1187 setting function pointer $FUNC in property list $PLIST for key
1188 $KEY. $KEY must not be a managing key. */
1191 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤Ë´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÀßÄꤹ¤ë.
1193 ´Ø¿ô mplist_put_func () ¤Ï´Ø¿ô mplist_put () ƱÍÍ¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1194 Ãæ¤Ç¥¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë¡£Ã¢¤·¤½¤ÎÃͤϴؿô¥Ý¥¤¥ó¥¿
1195 $FUNC ¤Ç¤¢¤ë¡£$KEY ¤Ï´ÉÍý¥¡¼¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */
1200 mplist_put (), M17N_FUNC () */
1203 mplist_put_func (MPlist *plist, MSymbol key, M17NFunc func)
1205 if (key == Mnil || key->managing_key)
1206 MERROR (MERROR_PLIST, NULL);
1207 MPLIST_FIND (plist, key);
1208 MPLIST_KEY (plist) = key;
1209 MPLIST_FUNC (plist) = func;
1210 MPLIST_SET_VAL_FUNC_P (plist);
1212 MPLIST_NEW ((plist)->next);
1219 @brief Get the value (function pointer) of a property in a property list.
1221 The mplist_get_func () function is similar to mplist_get () but for
1222 getting a function pointer from property list $PLIST by key $KEY. */
1225 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤«¤é¥×¥í¥Ñ¥Æ¥£¤Î´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÆÀ¤ë.
1227 ´Ø¿ô mplist_get_func () ¤Ï´Ø¿ô mplist_get () ¤ÈƱÍͤˡ¢¥×¥í¥Ñ¥Æ¥£¥ê
1228 ¥¹¥È $PLIST Ãæ¤Ç¥¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¡¢Ã¢¤·´Ø¿ô¥Ý¥¤¥ó¥¿¡¢
1236 mplist_get_func (MPlist *plist, MSymbol key)
1238 MPLIST_FIND (plist, key);
1239 return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_FUNC (plist));
1245 @brief Add a property at the end of a property list.
1247 The mplist_add () function appends at the end of property list
1248 $PLIST a property whose key is $KEY and value is $VAL. $KEY can
1249 be any symbol other than @c Mnil.
1251 If $KEY is a managing key, $VAL must be a managed object. In this
1252 case, the reference count of $VAL is incremented by one.
1255 If the operation was successful, mplist_add () returns a sublist of
1256 $PLIST whose first element is the just added one. Otherwise, it
1259 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈËöÈø¤Ë¥×¥í¥Ñ¥Æ¥£¤òÄɲ乤ë.
1261 ´Ø¿ô mplist_add () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎËöÈø¤Ë¥¡¼¤¬ $KEY
1262 ¤ÇÃͤ¬ $VAL ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤òÄɲ乤롣$KEY ¤Ï¡¢@c Mnil °Ê³°¤ÎǤ°Õ¤Î¥·¥ó¥Ü¥ë¤Ç¤è¤¤¡£
1264 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢$VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢
1265 $VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1268 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð mplist_add () ¤ÏÄɲ䵤줿Í×ÁǤ«¤é»Ï¤Þ¤ë $PLIST
1269 ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1272 mplist_add (MPlist *plist, MSymbol key, void *val)
1275 MERROR (MERROR_PLIST, NULL);
1276 MPLIST_FIND (plist, Mnil);
1277 if (val && key->managing_key)
1278 M17N_OBJECT_REF (val);
1279 MPLIST_KEY (plist) = key;
1280 MPLIST_VAL (plist) = val;
1281 MPLIST_NEW (plist->next);
1288 @brief Add a property at the beginning of a property list.
1290 The mplist_push () function inserts at the beginning of property
1291 list $PLIST a property whose key is $KEY and value is $VAL.
1293 If $KEY is a managing key, $VAL must be a managed object. In this
1294 case, the reference count of $VAL is incremented by one.
1297 If the operation was successful, this function returns $PLIST.
1298 Otherwise, it returns @c NULL. */
1300 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤Ë¥×¥í¥Ñ¥Æ¥£¤òÁÞÆþ¤¹¤ë.
1302 ´Ø¿ô mplist_push () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Ë¥¡¼¤¬ $KEY
1303 ¤ÇÃͤ¬ $VAL ¤Ç¤¢¤ë¥ª¥Ö¥¸¥§¥¯¥È¤òÁÞÆþ¤¹¤ë¡£
1305 $KEY ¤¬´ÉÍý¥¡¼¤Ê¤é¤Ð¡¢$VAL ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤Ê¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¤³¤Î¾ì¹ç¡¢
1306 $VAL ¤Î»²¾È¿ô¤Ï 1 Áý¤ä¤µ¤ì¤ë¡£
1309 ½èÍý¤¬À®¸ù¤¹¤ì¤Ð¤³¤Î´Ø¿ô¤Ï $PLIST ¤òÊÖ¤·¡¢¤½¤¦¤Ç¤Ê¤±¤ì¤Ð@c NULL
1313 mplist_push (MPlist *plist, MSymbol key, void *val)
1318 MERROR (MERROR_PLIST, NULL);
1320 MPLIST_KEY (pl) = MPLIST_KEY (plist);
1321 MPLIST_VAL (pl) = MPLIST_VAL (plist);
1322 if (MPLIST_NESTED_P (plist))
1323 MPLIST_SET_NESTED_P (pl);
1324 MPLIST_NEXT (pl) = MPLIST_NEXT (plist);
1326 if (val && key->managing_key)
1327 M17N_OBJECT_REF (val);
1328 MPLIST_KEY (plist) = key;
1329 MPLIST_VAL (plist) = val;
1336 @brief Remove a property at the beginning of a property list.
1338 The mplist_pop () function removes a property at the beginning of
1339 property list $PLIST. As a result, the second key and value of
1340 the $PLIST become the first ones.
1343 If the operation was successful, this function return the value of
1344 the just popped property. Otherwise, it returns @c NULL. */
1346 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤«¤é¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë.
1348 ´Ø¿ô mplist_pop () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Î¥×¥í¥Ñ¥Æ¥£¤òºï
1349 ½ü¤¹¤ë¡£·ë²Ì¤È¤·¤Æ¡¢¸µ¤Î2ÈÖÌܤΥ¡¼¤ÈÃͤ¬ÀèƬ¤Î¥¡¼¤ÈÃͤˤʤ롣
1352 ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ïºï½ü¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð
1356 mplist_pop (MPlist *plist)
1361 if (MPLIST_TAIL_P (plist))
1363 val = MPLIST_VAL (plist);
1364 next = MPLIST_NEXT (plist);
1365 MPLIST_KEY (plist) = MPLIST_KEY (next);
1366 MPLIST_VAL (plist) = MPLIST_VAL (next);
1367 if (MPLIST_KEY (plist) != Mnil
1368 && MPLIST_KEY (plist)->managing_key
1369 && MPLIST_VAL (plist))
1370 M17N_OBJECT_REF (MPLIST_VAL (plist));
1371 MPLIST_NEXT (plist) = MPLIST_NEXT (next);
1373 M17N_OBJECT_REF (plist->next);
1374 M17N_OBJECT_UNREF (next);
1380 @brief Find a property of a specific key in a property list.
1382 The mplist_find_by_key () function searches property list
1383 $PLIST from the beginning for a property whose key is $KEY. If
1384 such a property is found, a sublist of $PLIST whose first element
1385 is the found one is returned. Otherwise, @c NULL is returned.
1387 If $KEY is @c Mnil, it returns a sublist of $PLIST whose
1388 first element is the last one of $PLIST. */
1390 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃ椫¤é»ØÄê¤Î¥¡¼¤ò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤òõ¤¹.
1392 ´Ø¿ô mplist_find_by_key () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1393 ¤ò»Ï¤á¤«¤éõ ¤·¤Æ¡¢¥¡¼¤¬ $KEY
1394 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤«¤é»Ï¤Þ¤ë
1395 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
1397 $KEY ¤¬ @c Mnil ¤Ê¤é¤Ð¡¢$PLIST ¤ÎºÇ¸å¤ÎÍ×ÁǤ«¤é»Ï¤Þ¤ëÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£ */
1400 mplist_find_by_key (MPlist *plist, MSymbol key)
1402 MPLIST_FIND (plist, key);
1403 return (MPLIST_TAIL_P (plist)
1404 ? (key == Mnil ? plist : NULL)
1410 @brief Find a property of a specific value in a property list.
1412 The mplist_find_by_value () function searches property list $PLIST
1413 from the beginning for a property whose value is $VAL. If such a
1414 property is found, a sublist of $PLIST whose first element is the
1415 found one is returned. Otherwise, @c NULL is returned. */
1417 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃ椫¤é»ØÄê¤ÎÃͤò»ý¤Ä¥×¥í¥Ñ¥Æ¥£¤òõ¤¹.
1419 ´Ø¿ô mplist_find_by_value () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1420 ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢Ãͤ¬ $VAL
1421 ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤Î¥×¥í¥Ñ¥Æ¥£¤«¤é»Ï¤Þ¤ë
1422 $PLIST ¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1425 mplist_find_by_value (MPlist *plist, void *val)
1427 MPLIST_DO (plist, plist)
1429 if (MPLIST_VAL (plist) == val)
1438 @brief Return the next sublist of a property list.
1440 The mplist_next () function returns a pointer to the sublist of
1441 property list $PLIST, which begins at the second element in $PLIST. If the
1442 length of $PLIST is zero, it returns @c NULL. */
1444 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Î¼¡¤ÎÉôʬ¥ê¥¹¥È¤òÊÖ¤¹.
1446 ´Ø¿ô mplist_next () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤Î 2
1447 ÈÖÌܤÎÍ×ÁǤ«¤é»Ï¤Þ¤ëÉôʬ¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£$PLIST ¤ÎŤµ¤¬ 0
1448 ¤Ê¤é¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1451 mplist_next (MPlist *plist)
1453 return (MPLIST_TAIL_P (plist) ? NULL : plist->next);
1459 @brief Set the first property in a property list.
1461 The mplist_set () function sets the key and the value of the first
1462 property in property list $PLIST to $KEY and $VALUE, respectively.
1463 See the documentation of mplist_add () for the restriction on $KEY
1467 If the operation was successful, mplist_set () returns $PLIST.
1468 Otherwise, it returns @c NULL. */
1470 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤òÀßÄꤹ¤ë.
1472 ´Ø¿ô mplist_set () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1473 ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤ÈÃͤò¤½¤ì¤¾¤ì $KEY ¤È $VALUE ¤ËÀßÄꤹ¤ë¡£
1474 $KEY ¤È $VAL ¤ËÂФ¹¤ëÀ©¸Â¤Ë¤Ä¤¤¤Æ¤Ï¡¢mplist_add () ¤ÎÀâÌÀ¤ò»²¾È¡£
1477 ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð mplist_set () ¤Ï $PLIST ¤òÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ */
1480 mplist_set (MPlist *plist, MSymbol key, void * val)
1484 if (! MPLIST_TAIL_P (plist))
1486 key = MPLIST_KEY (plist);
1487 M17N_OBJECT_UNREF (MPLIST_NEXT (plist));
1488 MPLIST_KEY (plist) = Mnil;
1489 if (key->managing_key)
1490 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1496 if (val && key->managing_key)
1497 M17N_OBJECT_REF (val);
1498 if (! MPLIST_TAIL_P (plist)
1499 && MPLIST_KEY (plist)->managing_key)
1500 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1501 MPLIST_SET (plist, key, val);
1509 @brief Return the length of a property list.
1511 The mplist_length () function returns the number of properties in
1512 property list $PLIST. */
1514 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎŤµ¤òÊÖ¤¹.
1516 ´Ø¿ô mplist_length () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST Ãæ¤Î¥×¥í¥Ñ¥Æ¥£¤Î¿ô¤òÊÖ¤¹¡£ */
1519 mplist_length (MPlist *plist)
1523 for (n = 0; ! (MPLIST_TAIL_P (plist)); n++, plist = plist->next);
1530 @brief Return the key of the first property in a property list.
1532 The mplist_key () function returns the key of the first property
1533 in property list $PLIST. If the length of $PLIST is zero,
1534 it returns @c Mnil. */
1536 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤òÊÖ¤¹.
1538 ´Ø¿ô mplist_key () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST
1539 Ãæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤Î¥¡¼¤òÊÖ¤¹¡£$PLIST ¤ÎŤµ¤¬ 0 ¤Ê¤é¤Ð¡¢ @c Mnil
1543 mplist_key (MPlist *plist)
1545 return MPLIST_KEY (plist);
1551 @brief Return the value of the first property in a property list.
1553 The mplist_value () function returns the value of the first
1554 property in property list $PLIST. If the length of $PLIST
1555 is zero, it returns @c NULL. */
1557 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹.
1559 ´Ø¿ô mplist_value () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST Ãæ¤ÎºÇ½é¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£
1560 $PLIST ¤ÎŤµ¤¬ 0 ¤Ê¤é¤Ð¡¢ @c Mnil ¤òÊÖ¤¹¡£ */
1563 mplist_value (MPlist *plist)
1565 return MPLIST_VAL (plist);
1569 @brief Generate a property list by deserializing an M-text.
1571 The mplist_deserialize () function parses M-text $MT and returns a
1574 The syntax of $MT is as follows.
1576 MT ::= '(' ELEMENT * ')'
1578 ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
1580 SYMBOL ::= ascii-character-sequence
1582 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
1583 | '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
1585 M-TEXT ::= '"' character-sequence '"'
1587 Each alternatives of @c ELEMENT is assigned one of these keys: @c
1588 Msymbol, @c Minteger, @c Mtext, @c Mplist
1590 In an ascii-character-sequence, a backslash (\) is used as the escape
1591 character, which means that, for instance, <tt>"abc\ def"</tt>
1592 produces a symbol whose name is of length seven with the fourth
1593 character being a space. */
1595 @brief M-text ¤ò¥Ç¥·¥ê¥¢¥é¥¤¥º¤·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òºî¤ë.
1597 ´Ø¿ô mplist_deserialize () ¤Ï M-text $MT ¤ò²òÀϤ·¤Æ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤òÊÖ¤¹¡£
1599 $MT ¤Î¥·¥ó¥¿¥Ã¥¯¥¹¤Ï°Ê²¼¤ÎÄ̤ꡣ
1601 MT ::= '(' ELEMENT * ')'
1603 ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
1605 SYMBOL ::= ¥¢¥¹¥¡¼Ê¸»úÎó
1607 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
1608 | '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
1610 M-TEXT ::= '"' character-sequence '"'
1612 @c ELEMENT ¤Î³ÆÁªÂò»è¤Ï¥¡¼¡§@c Msymbol, @c Minteger, @c Mtext,
1613 @c Mplist ¤Î¤¤¤º¤ì¤«¤ò³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¡£
1615 ¥¢¥¹¥¡¼Ê¸»úÎóÆâ¤Ç¤Ï¡¢¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å (\) ¤¬¥¨¥¹¥±¡¼¥×ʸ»ú¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£¤¿¤È¤¨¤Ð
1616 <tt>"abc\ def"</tt> ¤Ï 4 ʸ»úÌܤ¬¶õÇòʸ»ú¤Ç¤¢¤êŤµ¤¬ 7
1617 ¤Ç¤¢¤ë»ý¤Ä̾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òÀ¸À®¤¹¤ë¡£ */
1620 mplist_deserialize (MText *mt)
1625 if (mt->format > MTEXT_FORMAT_UTF_8)
1627 if (MTEXT_READ_ONLY_P (mt))
1628 mt = tmp = mtext_cpy (mtext (), mt);
1630 mtext__adjust_format (mt, MTEXT_FORMAT_UTF_8);
1632 plist = mplist__from_string (MTEXT_DATA (mt), mtext_nbytes (mt));
1634 M17N_OBJECT_UNREF (tmp);
1640 /*** @addtogroup m17nDebug */
1645 @brief Dump a property list.
1647 The mdebug_dump_plist () function prints a property list $PLIST in
1648 a human readable way to the stderr. $INDENT specifies how many
1649 columns to indent the lines but the first one.
1652 This function returns $PLIST. */
1654 @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¥À¥ó¥×¤¹¤ë.
1656 ´Ø¿ô mdebug_dump_plist () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò stderr
1657 ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£
1660 ¤³¤Î´Ø¿ô¤Ï $PLIST ¤òÊÖ¤¹¡£ */
1662 mdebug_dump_plist (MPlist *plist, int indent)
1664 char *prefix = (char *) alloca (indent + 1);
1667 memset (prefix, 32, indent);
1670 fprintf (stderr, "(");
1671 MPLIST_DO (pl, plist)
1674 fprintf (stderr, "\n%s ", prefix);
1675 write_element (NULL, pl, indent + 1);
1677 fprintf (stderr, ")");