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., 59 Temple Place, Suite 330, Boston, MA
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
39 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
40 /*** @addtogroup m17nInternal
47 #include "m17n-misc.h"
49 #include "character.h"
54 static M17NObjectArray plist_table;
56 /** Set PLIST to a newly allocated plist object. */
58 #define MPLIST_NEW(plist) \
60 M17N_OBJECT (plist, free_plist, MERROR_PLIST); \
61 M17N_OBJECT_REGISTER (plist_table, plist); \
65 /** Set the element of PLIST to KEY and VAL. If PLIST is an anchor,
66 append a new anchor. */
68 #define MPLIST_SET(plist, key, val) \
70 MPLIST_KEY (plist) = (key); \
71 MPLIST_VAL (plist) = (val); \
72 if (! (plist)->next) \
73 MPLIST_NEW ((plist)->next); \
77 /** Set the element of PLIST to KEY and VAL. PLIST must be an anchor.
78 Append a new anchor and set PLIST to that anchor. */
80 #define MPLIST_SET_ADVANCE(plist, key, val) \
82 MPLIST_KEY (plist) = (key); \
83 MPLIST_VAL (plist) = (val); \
84 MPLIST_NEW ((plist)->next); \
85 plist = (plist)->next; \
90 free_plist (void *object)
92 MPlist *plist = (MPlist *) object;
95 MPlist *next = plist->next;
97 if (MPLIST_KEY (plist) != Mnil && MPLIST_KEY (plist)->managing_key)
98 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
99 M17N_OBJECT_UNREGISTER (plist_table, plist);
102 } while (plist && plist->control.ref_count == 1);
103 M17N_OBJECT_UNREF (plist);
108 /* Load a plist from a string. */
110 #define READ_CHUNK 0x10000
114 /* File pointer if the stream is associated with a file. Otherwise
118 unsigned char buffer[READ_CHUNK];
119 unsigned char *p, *pend;
123 get_byte (MStream *st)
127 if (! st->fp || st->eof)
129 n = fread (st->buffer, 1, READ_CHUNK, st->fp);
135 st->p = st->buffer + 1;
136 st->pend = st->buffer + n;
137 return st->buffer[0];
141 ((st)->p < (st)->pend ? *(st)->p++ : get_byte (st))
144 #define UNGETC(c, st) \
147 /** Mapping table for reading a number. Hexadecimal chars
148 (0..9,A..F,a..F) are mapped to the corresponding numbers.
149 Apostrophe (code 39) is mapped to 254. All the other bytes are
151 unsigned char hex_mnemonic[256];
153 /** Mapping table for escaped characters. Mnemonic characters (e, b,
154 f, n, r, or t) that follows '\' are mapped to the corresponding
155 character code. All the other bytes are mapped to themselves. */
156 unsigned char escape_mnemonic[256];
159 /** Read an integer from the stream ST. It is assumed that we have
160 already read one character C. */
163 read_decimal (MStream *st, int c)
167 while (c >= '0' && c <= '9')
169 num = (num * 10) + (c - '0');
178 /** Read an unsigned from the stream ST. */
181 read_hexadesimal (MStream *st)
186 while ((c = GETC (st)) != EOF
187 && (n = hex_mnemonic[c]) < 16)
188 num = (num << 4) | n;
195 /** Read an M-text element from ST, and add it to LIST. Return a list
196 for the next element. */
199 read_mtext_element (MPlist *plist, MStream *st)
201 unsigned char buffer[1024];
203 unsigned char *buf = buffer;
207 while ((c = GETC (st)) != EOF && c != '"')
209 if (i + MAX_UTF8_CHAR_BYTES >= bufsize)
214 MTABLE_MALLOC (buf, bufsize, MERROR_PLIST);
215 memcpy (buf, buffer, i);
218 MTABLE_REALLOC (buf, bufsize, MERROR_PLIST);
230 c = read_hexadesimal (st);
236 c = escape_mnemonic[c];
242 MPLIST_SET_ADVANCE (plist, Mtext,
243 mtext__from_data (buf, i, MTEXT_FORMAT_UTF_8, 1));
250 read_character (MStream *st, int c)
252 unsigned char buf[MAX_UTF8_CHAR_BYTES + 1];
253 int len = CHAR_BYTES_BY_HEAD (c);
257 for (i = 1; i < len; i++)
261 || (c & 0xC0) != 0x80)
266 c = STRING_CHAR_UTF8 (buf);
273 /** Read an integer element from ST, and add it to LIST. Return a
274 list for the next element. It is assumed that we have already
275 read the character C. */
278 read_integer_element (MPlist *plist, MStream *st, int c)
282 if (c == '0' || c == '#')
286 num = read_hexadesimal (st);
288 num = read_decimal (st, c);
297 if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c))
300 num = read_character (st, c);
307 else if (c < 128 || ! CHAR_UNITS_BY_HEAD_UTF8 (c))
308 num = escape_mnemonic[c];
310 num = read_character (st, c);
314 num = - read_decimal (st, GETC (st));
316 num = read_decimal (st, c);
318 MPLIST_SET_ADVANCE (plist, Minteger, (void *) num);
322 /** Read a symbol element from ST, and add it to LIST. Return a list
323 for the next element. */
326 read_symbol_element (MPlist *plist, MStream *st)
328 unsigned char buffer[1024];
330 unsigned char *buf = buffer;
334 while ((c = GETC (st)) != EOF
336 && c != ')' && c != '(' && c != '"')
343 MTABLE_MALLOC (buf, bufsize, MERROR_PLIST);
344 memcpy (buf, buffer, i);
347 MTABLE_REALLOC (buf, bufsize, MERROR_PLIST);
354 c = escape_mnemonic[c];
360 MPLIST_SET_ADVANCE (plist, Msymbol, msymbol ((char *) buf));
368 /* Read an element of various type from stream ST, and add it to LIST.
369 Return a list for the next element. The element type is decided by
370 the first token character found as below:
373 '0'..'9', '-': integer
374 '?': integer representing character code
375 the other ASCII letters: symbol
379 read_element (MPlist *plist, MStream *st)
383 /* Skip separators and comments. */
386 while ((c = GETC (st)) != EOF && c <= ' ');
389 while ((c = GETC (st)) != EOF && c != '\n');
400 while ((p = read_element (p, st)));
401 MPLIST_SET_ADVANCE (plist, Mplist, pl);
405 return read_mtext_element (plist, st);
406 if ((c >= '0' && c <= '9') || c == '-' || c == '?' || c == '#')
407 return read_integer_element (plist, st, c);
408 if (c == EOF || c == ')')
411 return read_symbol_element (plist, st);
415 write_element (MText *mt, MPlist *plist)
417 if (MPLIST_SYMBOL_P (plist))
419 MSymbol sym = MPLIST_SYMBOL (plist);
423 MTEXT_CAT_ASCII (mt, "nil");
427 char *name = MSYMBOL_NAME (sym);
428 char *buf = alloca (MSYMBOL_NAMELEN (sym) * 2 + 1), *p = buf;
432 if (*name <= ' ' || *name == '"' || *name == ')' || *name == ')')
437 MTEXT_CAT_ASCII (mt, buf);
440 else if (MPLIST_INTEGER_P (plist))
442 int num = MPLIST_INTEGER (plist);
445 sprintf (buf, "%d", num);
446 MTEXT_CAT_ASCII (mt, buf);
448 else if (MPLIST_PLIST_P (plist))
452 plist = MPLIST_PLIST (plist);
453 mtext_cat_char (mt, '(');
454 MPLIST_DO (pl, plist)
457 mtext_cat_char (mt, ' ');
458 write_element (mt, pl);
460 mtext_cat_char (mt, ')');
462 else if (MPLIST_MTEXT_P (plist))
464 mtext_cat_char (mt, '"');
465 /* Not yet implemnted */
466 mtext_cat_char (mt, '"');
470 /* Support functions for mdebug_dump_plist. */
473 dump_string (char *str)
475 char *p = str, *pend = p + strlen (p), *new, *p1;
477 new = p1 = alloca ((pend - p) * 4 + 1);
482 sprintf (p1, "\\x%02X", (unsigned char) *p);
500 fprintf (stderr, "%s", new);
504 dump_plist_element (MPlist *plist, int indent)
506 char *prefix = (char *) alloca (indent + 1);
509 memset (prefix, 32, indent);
512 key = MPLIST_KEY (plist);
513 fprintf (stderr, "(%s(#%d) ", msymbol_name (MPLIST_KEY (plist)),
514 plist->control.ref_count);
516 dump_string (msymbol_name (MPLIST_SYMBOL (plist)));
517 else if (key == Mtext)
518 mdebug_dump_mtext (MPLIST_MTEXT (plist), indent, 0);
519 else if (key == Minteger)
520 fprintf (stderr, "%x", MPLIST_INTEGER (plist));
521 else if (key == Mstring)
522 fprintf (stderr, "\"%s\"", MPLIST_STRING (plist));
523 else if (key == Mplist)
525 fprintf (stderr, "\n%s", prefix);
526 mdebug_dump_plist (MPLIST_PLIST (plist), indent);
529 fprintf (stderr, "0x%X", (unsigned) MPLIST_VAL (plist));
530 fprintf (stderr, ")");
540 plist_table.count = 0;
542 Minteger = msymbol ("integer");
543 Mplist = msymbol_as_managing_key ("plist");
544 Mtext = msymbol_as_managing_key ("mtext");
546 for (i = 0; i < 256; i++)
547 hex_mnemonic[i] = 255;
548 for (i = '0'; i <= '9'; i++)
549 hex_mnemonic[i] = i - '0';
550 for (i = 'A'; i <= 'F'; i++)
551 hex_mnemonic[i] = i - 'A' + 10;
552 for (i = 'a'; i <= 'f'; i++)
553 hex_mnemonic[i] = i - 'a' + 10;
554 for (i = 0; i < 256; i++)
555 escape_mnemonic[i] = i;
556 escape_mnemonic['e'] = 27;
557 escape_mnemonic['b'] = '\b';
558 escape_mnemonic['f'] = '\f';
559 escape_mnemonic['n'] = '\n';
560 escape_mnemonic['r'] = '\r';
561 escape_mnemonic['t'] = '\t';
562 escape_mnemonic['\\'] = '\\';
570 mdebug__report_object ("Plist", &plist_table);
574 /* Parse this form of PLIST:
575 (symbol:KEY1 TYPE1:VAL1 symbol:KEY2 TYPE2:VAL2 ...)
576 and return a newly created plist of this form:
577 (KEY1:VAL1 KEY2:VAL2 ...) */
580 mplist__from_plist (MPlist *plist)
586 while (! MPLIST_TAIL_P (plist))
590 if (! MPLIST_SYMBOL_P (plist))
591 MERROR (MERROR_PLIST, NULL);
592 key = MPLIST_SYMBOL (plist);
593 plist = MPLIST_NEXT (plist);
594 type = MPLIST_KEY (plist);
595 if (type->managing_key)
596 M17N_OBJECT_REF (MPLIST_VAL (plist));
597 MPLIST_SET_ADVANCE (p, key, MPLIST_VAL (plist));
598 plist = MPLIST_NEXT (plist);
603 /** Parse this form of PLIST:
604 ((symbol:KEY1 ANY:VAL1 ... ) (symbol:KEY2 ANY:VAL2 ...) ...)
605 and return a newly created plist of this form:
606 (KEY1:(ANY:VAL1 ...) KEY2:(ANY:VAL2 ...) ...)
607 ANY can be any type. */
610 mplist__from_alist (MPlist *plist)
616 MPLIST_DO (plist, plist)
620 if (! MPLIST_PLIST_P (plist))
621 MERROR (MERROR_PLIST, NULL);
622 elt = MPLIST_PLIST (plist);
623 if (! MPLIST_SYMBOL_P (elt))
624 MERROR (MERROR_PLIST, NULL);
625 MPLIST_SET_ADVANCE (p, MPLIST_SYMBOL (elt), MPLIST_NEXT (elt));
626 M17N_OBJECT_REF (MPLIST_NEXT (elt));
633 mplist__from_file (FILE *fp)
640 st.p = st.pend = st.buffer;
643 while ((pl = read_element (pl, &st)));
648 /** Parse $STR of $N bytes and return a property list object. $FORMAT
649 must be either @c MTEXT_FORMAT_US_ASCII or @c MTEXT_FORMAT_UTF_8,
650 and controls how to produce @c STRING or @c M-TEXT in the
651 following definition.
653 The syntax of $STR is as follows.
655 PLIST ::= '(' ELEMENT * ')'
657 ELEMENT ::= SYMBOL | INTEGER | UNSIGNED | STRING | M-TEXT | PLIST
659 SYMBOL ::= ascii-character-sequence
661 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
663 UNSIGNED ::= '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
665 M-TEXT ::= '"' byte-sequence '"'
667 Each kind of @c ELEMENT is assigned one of these keys:
668 @c Msymbol, @c Mint, @c Munsigned, @c Mtext, @c Mplist
670 In an ascii-character-sequence, a backslush (\) is used as the escape
671 character, which means that, for instance, <tt>"abc\ def"</tt>
672 produces a symbol whose name is of length seven with the fourth
673 character being a space.
675 In a byte-sequence, "\r", "\n", "\e", and "\t" are replaced by CR,
676 NL, ESC, and TAB character respectively, "\xXX" are replaced by
677 byte 0xXX. After this replacement, the byte-sequence is decoded
678 into M-TEXT by $CODING. */
681 mplist__from_string (unsigned char *str, int n)
692 while ((pl = read_element (pl, &st)));
697 mplist__serialize (MText *mt, MPlist *plist)
701 MPLIST_DO (pl, plist)
704 mtext_cat_char (mt, ' ');
705 write_element (mt, pl);
711 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
716 /*** @addtogroup m17nPlist */
721 @brief Symbol whose name is "integer".
723 The symbol @c Minteger has the name <tt>"integer"</tt>. A value
724 of a plist whose key is @c Minteger must be an integer. */
730 @brief Symbol whose name is "plist".
732 The symbol @c Mplist has the name <tt>"plist"</tt>. It is a
733 managing key. A value of a plist whose key is @c Mplist must be a
740 @brief Symbol whose name is "mtext".
742 The symbol @c Mtext has the name <tt>"mtext"</tt>. It is a
743 managing key. A value of a plist whose key is @c Mtext must be an
747 @brief "text" ¤ò̾Á°¤È¤·¤Æ»ý¤Ä¥·¥ó¥Ü¥ë
749 ÄêµÁºÑ¤ß¥·¥ó¥Ü¥ë @c Mtext ¤Ï <tt>"text"</tt> ¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä´ÉÍý
757 @brief Create a property list object.
759 The mplist () function returns a newly created property list
760 object of length zero.
763 This function returns a newly created property list.
766 This function never fails. */
781 The mplist_copy () function copies $PLIST. In the copy, the
782 values are the same as those of $PLIST.
785 This function returns a newly created plist which is a copy of
789 This function never fails. */
792 mplist_copy (MPlist *plist)
794 MPlist *copy = mplist (), *pl = copy;
796 MPLIST_DO (plist, plist)
797 pl = mplist_add (pl, MPLIST_KEY (plist), MPLIST_VAL (plist));
804 @brief Set the value of a property in a property list object.
806 The mplist_put () function searches property list object $PLIST
807 from the beginning for a property whose key is $KEY. If such a
808 property is found, its value is changed to $VALUE. Otherwise, a
809 new property whose key is $KEY and value is $VALUE is appended at
810 the end of $PLIST. See the documentation of mplist_add () for
811 the restriction on $KEY and $VAL.
813 If $KEY is a managing key, $VAL must be a managed object. In this
814 case, the reference count of the old value, if not @c NULL, is
815 decremented by one, and that of $VAL is incremented by one.
818 If the operation was successful, mplist_put () returns a sublist of
819 $PLIST whose first element is the just modified or added one.
820 Otherwise, it returns @c NULL. */
823 mplist_put (MPlist *plist, MSymbol key, void *val)
826 MERROR (MERROR_PLIST, NULL);
827 MPLIST_FIND (plist, key);
828 if (key->managing_key)
830 if (! MPLIST_TAIL_P (plist))
831 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
832 M17N_OBJECT_REF (val);
834 MPLIST_SET (plist, key, val);
841 @brief Get the value of a property in a property list object.
843 The mplist_get () function searches property list object $PLIST
844 from the beginning for a property whose key is $KEY. If such a
845 property is found, a pointer to its value is returned as the type
846 of <tt>(void *)</tt>. If not found, @c NULL is returned.
848 When @c NULL is returned, there are two possibilities: one is the
849 case where no property is found (see above); the other is the case
850 where a property is found and its value is @c NULL. In case that
851 these two cases must be distinguished, use the mplist_find_by_key ()
856 mplist_find_by_key () */
859 mplist_get (MPlist *plist, MSymbol key)
861 MPLIST_FIND (plist, key);
862 return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_VAL (plist));
868 @brief Add a property at the end of a property list object.
870 The mplist_add () function appends at the end of $PLIST a property
871 whose key is $KEY and value is $VAL. $KEY can be any symbol
874 If $KEY is a managing key, $VAL must be a managed object. In this
875 case, the reference count of $VAL is incremented by one.
878 If the operation was successful, mplist_add () returns a sublist of
879 $PLIST whose first element is the just added one. Otherwise, it
883 mplist_add (MPlist *plist, MSymbol key, void *val)
886 MERROR (MERROR_PLIST, NULL);
887 MPLIST_FIND (plist, Mnil);
888 if (key->managing_key)
889 M17N_OBJECT_REF (val);
890 MPLIST_KEY (plist) = key;
891 MPLIST_VAL (plist) = val;
892 MPLIST_NEW (plist->next);
899 @brief Push a property to a property list object.
901 The mplist_push () function pushes at the top of $PLIST a
902 property whose key is $KEY and value si $VAL.
904 If $KEY is a managing key, $VAL must be a managed object. In this
905 case, the reference count of $VAL is incremented by one.
908 If the operation was successful, this function returns $PLIST.
909 Otherwise, it returns @c NULL. */
912 mplist_push (MPlist *plist, MSymbol key, void *val)
917 MERROR (MERROR_PLIST, NULL);
919 MPLIST_KEY (pl) = MPLIST_KEY (plist);
920 MPLIST_VAL (pl) = MPLIST_VAL (plist);
921 pl->next = plist->next;
923 if (key->managing_key)
924 M17N_OBJECT_REF (val);
925 MPLIST_KEY (plist) = key;
926 MPLIST_VAL (plist) = val;
933 @brief Pop a property from a property list object.
935 The mplist_pop () function pops the topmost property from $PLIST.
936 As a result, the key and value of $PLIST becomes those of the next
940 If the operation was successful, this function return the value of
941 the just popped property. Otherwise, it returns @c NULL. */
944 mplist_pop (MPlist *plist)
949 if (MPLIST_TAIL_P (plist))
951 val = MPLIST_VAL (plist);
953 MPLIST_KEY (plist) = MPLIST_KEY (next);
954 MPLIST_VAL (plist) = MPLIST_VAL (next);
955 if (MPLIST_KEY (plist) != Mnil
956 && MPLIST_KEY (plist)->managing_key
957 && MPLIST_VAL (plist))
958 M17N_OBJECT_REF (MPLIST_VAL (plist));
959 plist->next = next->next;
961 M17N_OBJECT_REF (plist->next);
962 M17N_OBJECT_UNREF (next);
968 @brief Find a property of a specific key in a property list object.
970 The mplist_find_by_key () function searches property list object
971 $PLIST from the beginning for a property whose key is $KEY. If
972 such a property is found, a sublist of $PLIST whose first element
973 is the found one is returned. Otherwise, @c NULL is returned.
975 If $KEY is Mnil, it returns the last a sublist of $PLIST whose
976 first element is the last one of $PLIST. */
979 mplist_find_by_key (MPlist *plist, MSymbol key)
981 MPLIST_FIND (plist, key);
982 return (MPLIST_TAIL_P (plist)
983 ? (key == Mnil ? plist : NULL)
989 @brief Find a property of a specific value in a property list object.
991 The mplist_find_by_value () function searches property list object
992 $PLIST from the beginning for a property whose value is $VAL. If
993 such a property is found, a sublist of $PLIST whose first element
994 is the found one is returned. Otherwise, @c NULL is returned. */
997 mplist_find_by_value (MPlist *plist, void *val)
999 MPLIST_DO (plist, plist)
1001 if (MPLIST_VAL (plist) == val)
1010 @brief Return the next sublist of a plist.
1012 The mplist_next () function returns a pointer to the sublist of
1013 $PLIST, which begins at the second element in $PLIST. If the
1014 length of $PLIST is zero, it returns @c NULL. */
1017 mplist_next (MPlist *plist)
1019 return (MPLIST_TAIL_P (plist) ? NULL : plist->next);
1025 @brief Set the first property in a property list object.
1027 The mplist_set () function sets the key and value of the first
1028 property in property list object $PLIST to $KEY and $VALUE,
1029 respectively. See the documentation of mplist_add () for the
1030 restriction on $KEY and $VAL.
1033 If the operation was successful, mplist_set () returns $PLIST.
1034 Otherwise, it returns @c NULL. */
1037 mplist_set (MPlist *plist, MSymbol key, void * val)
1041 if (! MPLIST_TAIL_P (plist))
1043 key = MPLIST_KEY (plist);
1044 M17N_OBJECT_UNREF (MPLIST_NEXT (plist));
1045 MPLIST_KEY (plist) = Mnil;
1046 if (key->managing_key && MPLIST_VAL (plist))
1047 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1053 if (! MPLIST_TAIL_P (plist)
1054 && MPLIST_KEY (plist)->managing_key
1055 && MPLIST_VAL (plist))
1056 M17N_OBJECT_UNREF (MPLIST_VAL (plist));
1057 if (key->managing_key)
1058 M17N_OBJECT_REF (val);
1059 MPLIST_SET (plist, key, val);
1067 @brief Return the length of a plist.
1069 The mplist_length () function returns the number of properties in
1070 property list object $PLIST. */
1073 mplist_length (MPlist *plist)
1077 for (n = 0; ! (MPLIST_TAIL_P (plist)); n++, plist = plist->next);
1084 @brief Return the key of the first property in a property list object.
1086 The mplist_key () function returns the key of the first property
1087 in property list object $PLIST. If the length of $PLIST is zero,
1088 it returns @c Mnil. */
1091 mplist_key (MPlist *plist)
1093 return MPLIST_KEY (plist);
1099 @brief Return the value of the first property in a property list object.
1101 The mplist_value () function returns the value of the first
1102 property in property list object $PLIST. If the length of $PLIST
1103 is zero, it returns @c NULL. */
1106 mplist_value (MPlist *plist)
1108 return MPLIST_VAL (plist);
1112 @brief Generate a plist by deserializaing an M-text.
1114 The mplist_deserialize () function parses M-text $MT and returns a
1117 The syntax of $MT is as follows.
1119 MT ::= '(' ELEMENT * ')'
1121 ELEMENT ::= SYMBOL | INTEGER | M-TEXT | PLIST
1123 SYMBOL ::= ascii-character-sequence
1125 INTEGER ::= '-' ? [ '0' | .. | '9' ]+
1126 | '0x' [ '0' | .. | '9' | 'A' | .. | 'F' | 'a' | .. | 'f' ]+
1128 M-TEXT ::= '"' character-sequence '"'
1130 Each kind of @c ELEMENT is assigned one of these keys:
1131 @c Msymbol, @c Minteger, @c Mtext, @c Mplist
1133 In an ascii-character-sequence, a backslush (\) is used as the escape
1134 character, which means that, for instance, <tt>"abc\ def"</tt>
1135 produces a symbol whose name is of length seven with the fourth
1136 character being a space. */
1139 mplist_deserialize (MText *mt)
1141 if (mt->format > MTEXT_FORMAT_UTF_8)
1143 if (mtext__adjust_format (mt, MTEXT_FORMAT_UTF_8) < 0)
1144 MERROR (MERROR_PLIST, NULL);
1146 return mplist__from_string (MTEXT_DATA (mt), mtext_nbytes (mt));
1151 /*** @addtogroup m17nDebug */
1156 @brief Dump a plist.
1158 The mdebug_dump_plist () function prints $PLIST in a human
1159 readable way to the stderr. $INDENT specifies how many columns to
1160 indent the lines but the first one.
1163 This function returns $PLIST. */
1166 mdebug_dump_plist (MPlist *plist, int indent)
1168 char *prefix = (char *) alloca (indent + 1);
1172 memset (prefix, 32, indent);
1175 fprintf (stderr, "(");
1176 MPLIST_DO (pl, plist)
1181 fprintf (stderr, "\n%s ", prefix);
1182 dump_plist_element (pl, indent + 2);
1184 fprintf (stderr, ")");