X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fplist.c;h=1e449dbb8c68f30171db8ea63397bf39599c1ee7;hb=HEAD;hp=8926952cb191b0180272a620c7de428a8967c344;hpb=7a7762460733818a5fc76a85627d24be49891d8d;p=m17n%2Fm17n-lib.git diff --git a/src/plist.c b/src/plist.c index 8926952..1e449db 100644 --- a/src/plist.c +++ b/src/plist.c @@ -1,5 +1,5 @@ /* plist.c -- plist module. - Copyright (C) 2003, 2004 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 National Institute of Advanced Industrial Science and Technology (AIST) Registration Number H15PRO112 @@ -17,7 +17,7 @@ You should have received a copy of the GNU Lesser General Public License along with the m17n library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 02111-1307, USA. */ /***en @@ -129,7 +129,8 @@ free_plist (void *object) do { MPlist *next = plist->next; - if (MPLIST_KEY (plist) != Mnil && MPLIST_KEY (plist)->managing_key) + if (MPLIST_KEY (plist) != Mnil + && MPLIST_KEY (plist)->managing_key) M17N_OBJECT_UNREF (MPLIST_VAL (plist)); M17N_OBJECT_UNREGISTER (plist_table, plist); free (plist); @@ -232,15 +233,9 @@ read_hexadesimal (MStream *st) static MPlist * read_mtext_element (MPlist *plist, MStream *st, int skip) { - union { - int chars[READ_MTEXT_BUF_SIZE]; - unsigned char bytes[sizeof (int) * READ_MTEXT_BUF_SIZE]; - } buffer; - unsigned char *bytes = buffer.bytes; - int nbytes = sizeof (int) * READ_MTEXT_BUF_SIZE; - int *chars = NULL; - int nchars = 0; - int c, i, j; + unsigned char buffer[READ_MTEXT_BUF_SIZE], *buf = buffer; + int nbytes = READ_MTEXT_BUF_SIZE; + int c, i; i = 0; while ((c = GETC (st)) != EOF && c != '"') @@ -271,65 +266,34 @@ read_mtext_element (MPlist *plist, MStream *st, int skip) if (! skip) { - if (is_char && ! chars) + if (i + MAX_UTF8_CHAR_BYTES >= nbytes) { - chars = buffer.chars; - for (j = i - 1; j >= 0; j--) - chars[j] = bytes[j]; - nchars = READ_MTEXT_BUF_SIZE; - if (bytes != buffer.bytes) - free (bytes); - } - - if (chars) - { - if (i + 1 >= nchars) + if (buf == buffer) { - nchars *= 2; - if (chars == buffer.chars) - { - MTABLE_MALLOC (chars, nchars, MERROR_PLIST); - memcpy (chars, buffer.chars, sizeof (int) * i); - } - else - MTABLE_REALLOC (chars, nchars, MERROR_PLIST); + nbytes *= 2; + buf = malloc (nbytes); + memcpy (buf, buffer, i); } - chars[i++] = c; - } - else - { - if (i + MAX_UTF8_CHAR_BYTES >= nbytes) + else { - nbytes *= 2; - if (bytes == buffer.bytes) - { - MTABLE_MALLOC (bytes, nbytes, MERROR_PLIST); - memcpy (bytes, buffer.bytes, i); - } - else - MTABLE_REALLOC (bytes, nbytes, MERROR_PLIST); + nbytes += READ_MTEXT_BUF_SIZE; + buf = realloc (buf, nbytes); } - bytes[i++] = c; } + + if (is_char) + i += CHAR_STRING_UTF8 (c, buf); + else + buf[i++] = c; } } if (! skip) { - MText *mt; - - if (chars) - { - mt = mtext__from_data (chars, i, MTEXT_FORMAT_UTF_32, 1); - if (chars != buffer.chars) - free (chars); - } - else - { - mt = mtext__from_data (bytes, i, MTEXT_FORMAT_UTF_8, 1); - if (bytes != buffer.bytes) - free (bytes); - } + MText *mt = mtext__from_data (buf, i, MTEXT_FORMAT_UTF_8, + (buf == buffer)); + if (buf != buffer) + mt->allocated = nbytes; MPLIST_SET_ADVANCE (plist, Mtext, mt); } return plist; @@ -562,7 +526,7 @@ read_element (MPlist *plist, MStream *st, MPlist *keys) if (MT) \ mtext_cat_char ((MT), (C)); \ else \ - putc ((C), stderr); \ + putc ((C), mdebug__output); \ } while (0); #define PUTS(MT, STR) \ @@ -570,7 +534,7 @@ read_element (MPlist *plist, MStream *st, MPlist *keys) if (MT) \ MTEXT_CAT_ASCII ((MT), (STR)); \ else \ - fputs ((STR), stderr); \ + fputs ((STR), mdebug__output); \ } while (0) @@ -613,11 +577,17 @@ write_element (MText *mt, MPlist *plist, int indent) sprintf (buf, "%d", num); PUTS (mt, buf); } - else if (MPLIST_PLIST_P (plist)) + else if (MPLIST_PLIST_P (plist) + || MPLIST_NESTED_P (plist)) { MPlist *pl; int newline = 0; + if (MPLIST_NESTED_P (plist)) + { + write_symbol (mt, MPLIST_KEY (plist)); + PUTC (mt, ':'); + } plist = MPLIST_PLIST (plist); PUTC (mt, '('); if (indent >= 0) @@ -684,7 +654,7 @@ write_element (MText *mt, MPlist *plist, int indent) unsigned char *end = data + mtext__char_to_byte (this_mt, stop); while (beg < end) - putc (*beg, stderr), beg++; + putc (*beg, mdebug__output), beg++; } if (stop == to) break; @@ -710,21 +680,16 @@ write_element (MText *mt, MPlist *plist, int indent) M17N_OBJECT_UNREF (this_mt); } else - fprintf (stderr, "%s", str); + fprintf (mdebug__output, "%s", str); } else { + char buf[128]; + write_symbol (mt, MPLIST_KEY (plist)); PUTC (mt, ':'); - if (MPLIST_NESTED_P (plist)) - write_element (mt, plist, indent + 1); - else - { - char buf[128]; - - sprintf (buf, "%04X", (unsigned) MPLIST_VAL (plist)); - PUTS (mt, buf); - } + sprintf (buf, "%04X", (unsigned) MPLIST_VAL (plist)); + PUTS (mt, buf); } } @@ -791,6 +756,8 @@ mplist__from_plist (MPlist *plist) type = MPLIST_KEY (plist); if (type->managing_key && MPLIST_VAL (plist)) M17N_OBJECT_REF (MPLIST_VAL (plist)); + if (type == Mplist) + MPLIST_SET_NESTED_P (p); MPLIST_SET_ADVANCE (p, key, MPLIST_VAL (plist)); plist = MPLIST_NEXT (plist); } @@ -819,6 +786,7 @@ mplist__from_alist (MPlist *plist) elt = MPLIST_PLIST (plist); if (! MPLIST_SYMBOL_P (elt)) MERROR (MERROR_PLIST, NULL); + MPLIST_SET_NESTED_P (p); MPLIST_SET_ADVANCE (p, MPLIST_SYMBOL (elt), MPLIST_NEXT (elt)); M17N_OBJECT_REF (MPLIST_NEXT (elt)); } @@ -924,8 +892,10 @@ mplist__conc (MPlist *plist, MPlist *tail) MPLIST_DO (pl, plist); MPLIST_KEY (pl) = MPLIST_KEY (tail); MPLIST_VAL (pl) = MPLIST_VAL (tail); - if (MPLIST_KEY (pl)->managing_key) + if (MPLIST_KEY (pl)->managing_key && MPLIST_VAL (pl)) M17N_OBJECT_REF (MPLIST_VAL (pl)); + if (MPLIST_NESTED_P (tail)) + MPLIST_SET_NESTED_P (pl); tail = MPLIST_NEXT (tail); MPLIST_NEXT (pl) = tail; M17N_OBJECT_REF (tail); @@ -1103,7 +1073,11 @@ mplist_copy (MPlist *plist) MPlist *copy = mplist (), *pl = copy; MPLIST_DO (plist, plist) - pl = mplist_add (pl, MPLIST_KEY (plist), MPLIST_VAL (plist)); + { + if (MPLIST_NESTED_P (plist)) + MPLIST_SET_NESTED_P (pl); + pl = mplist_add (pl, MPLIST_KEY (plist), MPLIST_VAL (plist)); + } return copy; } @@ -1166,10 +1140,10 @@ mplist_put (MPlist *plist, MSymbol key, void *val) /***en @brief Get the value of a property in a property list. - The mplist_get () function searches property list $PLIST - from the beginning for a property whose key is $KEY. If such a - property is found, a pointer to its value is returned as the type - of (void *). If not found, @c NULL is returned. + The mplist_get () function searches property list $PLIST from the + beginning for a property whose key is $KEY. If such a property is + found, its value is returned as the type of (void *). If + not found, @c NULL is returned. When @c NULL is returned, there are two possibilities: one is the case where no property is found (see above); the other is the case @@ -1179,8 +1153,8 @@ mplist_put (MPlist *plist, MSymbol key, void *val) /***ja @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë. - ´Ø¿ô mplist_get () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥­¡¼¤¬ - $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤؤΥݥ¤¥ó¥¿¤ò + ´Ø¿ô mplist_get () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥­¡¼ + ¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤò (void *) ·¿¤ÇÊÖ¤¹¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ @c NULL ¤¬Ê֤俺ݤˤÏÆó¤Ä¤Î²ÄǽÀ­¤¬¤¢¤ë: @@ -1202,6 +1176,67 @@ mplist_get (MPlist *plist, MSymbol key) /*=*/ /***en + @brief Set the value (function pointer) of a property in a property list. + + The mplist_put_func () function is similar to mplist_put () but for + setting function pointer $FUNC in property list $PLIST for key + $KEY. $KEY must not be a managing key. */ + +/***ja + @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤Ë´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÀßÄꤹ¤ë. + + ´Ø¿ô mplist_put_func () ¤Ï´Ø¿ô mplist_put () ƱÍÍ¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST + Ãæ¤Ç¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë¡£Ã¢¤·¤½¤ÎÃͤϴؿô¥Ý¥¤¥ó¥¿ + $FUNC ¤Ç¤¢¤ë¡£$KEY ¤Ï´ÉÍý¥­¡¼¤Ç¤¢¤Ã¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£ */ + + +/*** + @seealso + mplist_put (), M17N_FUNC () */ + +MPlist * +mplist_put_func (MPlist *plist, MSymbol key, M17NFunc func) +{ + if (key == Mnil || key->managing_key) + MERROR (MERROR_PLIST, NULL); + MPLIST_FIND (plist, key); + MPLIST_KEY (plist) = key; + MPLIST_FUNC (plist) = func; + MPLIST_SET_VAL_FUNC_P (plist); + if (! plist->next) + MPLIST_NEW ((plist)->next); + return plist; +} + +/*=*/ + +/***en + @brief Get the value (function pointer) of a property in a property list. + + The mplist_get_func () function is similar to mplist_get () but for + getting a function pointer from property list $PLIST by key $KEY. */ + +/***ja + @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤«¤é¥×¥í¥Ñ¥Æ¥£¤Î´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÆÀ¤ë. + + ´Ø¿ô mplist_get_func () ¤Ï´Ø¿ô mplist_get () ¤ÈƱÍͤˡ¢¥×¥í¥Ñ¥Æ¥£¥ê + ¥¹¥È $PLIST Ãæ¤Ç¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ÎÃÍ¡¢Ã¢¤·´Ø¿ô¥Ý¥¤¥ó¥¿¡¢ + ¤òÆÀ¤ë¡£ */ + + +/*** + @seealso + mplist_get () */ +M17NFunc +mplist_get_func (MPlist *plist, MSymbol key) +{ + MPLIST_FIND (plist, key); + return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_FUNC (plist)); +} + +/*=*/ + +/***en @brief Add a property at the end of a property list. The mplist_add () function appends at the end of property list @@ -1279,6 +1314,8 @@ mplist_push (MPlist *plist, MSymbol key, void *val) MPLIST_NEW (pl); MPLIST_KEY (pl) = MPLIST_KEY (plist); MPLIST_VAL (pl) = MPLIST_VAL (plist); + if (MPLIST_NESTED_P (plist)) + MPLIST_SET_NESTED_P (pl); MPLIST_NEXT (pl) = MPLIST_NEXT (plist); plist->next = pl; if (val && key->managing_key) @@ -1295,7 +1332,7 @@ mplist_push (MPlist *plist, MSymbol key, void *val) The mplist_pop () function removes a property at the beginning of property list $PLIST. As a result, the second key and value of - the original $PLIST become the first of those of the new $PLIST. + the $PLIST become the first ones. @return If the operation was successful, this function return the value of @@ -1303,9 +1340,8 @@ mplist_push (MPlist *plist, MSymbol key, void *val) /***ja @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤«¤é¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë. - ´Ø¿ô mplist_pop () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST - ¤ÎÀèƬ¤Î¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë¡£·ë²Ì¤È¤·¤Æ¡¢¸µ¤Î $PLIST ¤Î2ÈÖÌܤΥ­¡¼¤ÈÃͤ¬¡¢¿·¤·¤¤ - $PLIST ¤ÎÀèƬ¤Î¥­¡¼¤ÈÃͤˤʤ롣 + ´Ø¿ô mplist_pop () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Î¥×¥í¥Ñ¥Æ¥£¤òºï + ½ü¤¹¤ë¡£·ë²Ì¤È¤·¤Æ¡¢¸µ¤Î2ÈÖÌܤΥ­¡¼¤ÈÃͤ¬ÀèƬ¤Î¥­¡¼¤ÈÃͤˤʤ롣 @return ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ïºï½ü¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @@ -1547,7 +1583,7 @@ mplist_value (MPlist *plist) Msymbol, @c Minteger, @c Mtext, @c Mplist In an ascii-character-sequence, a backslash (\) is used as the escape - character, which means that, for instance, "abc\ def" + character, which means that, for instance, abc\ def produces a symbol whose name is of length seven with the fourth character being a space. */ /***ja @@ -1572,7 +1608,7 @@ mplist_value (MPlist *plist) @c Mplist ¤Î¤¤¤º¤ì¤«¤ò³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¡£ ¥¢¥¹¥­¡¼Ê¸»úÎóÆâ¤Ç¤Ï¡¢¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å (\) ¤¬¥¨¥¹¥±¡¼¥×ʸ»ú¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£¤¿¤È¤¨¤Ð - "abc\ def" ¤Ï 4 ʸ»úÌܤ¬¶õÇòʸ»ú¤Ç¤¢¤êŤµ¤¬ 7 + abc\ def ¤Ï 4 ʸ»úÌܤ¬¶õÇòʸ»ú¤Ç¤¢¤êŤµ¤¬ 7 ¤Ç¤¢¤ë»ý¤Ä̾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òÀ¸À®¤¹¤ë¡£ */ MPlist * @@ -1604,16 +1640,18 @@ mplist_deserialize (MText *mt) @brief Dump a property list. The mdebug_dump_plist () function prints a property list $PLIST in - a human readable way to the stderr. $INDENT specifies how many - columns to indent the lines but the first one. + a human readable way to the stderr or to what specified by the + environment variable MDEBUG_OUTPUT_FILE. $INDENT specifies how + many columns to indent the lines but the first one. @return This function returns $PLIST. */ /***ja @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ò¥À¥ó¥×¤¹¤ë. - ´Ø¿ô mdebug_dump_plist () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò stderr - ¤Ë¿Í´Ö¤Ë²ÄÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£ + ´Ø¿ô mdebug_dump_plist () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤òɸ½à¥¨¥é¡¼½Ð + ÎϤ⤷¤¯¤Ï´Ä¶­ÊÑ¿ô MDEBUG_DUMP_FONT ¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë¿Í´Ö¤Ë²Ä + ÆɤʷÁ¤Ç°õºþ¤¹¤ë¡£ $INDENT ¤Ï£²¹ÔÌܰʹߤΥ¤¥ó¥Ç¥ó¥È¤ò»ØÄꤹ¤ë¡£ @return ¤³¤Î´Ø¿ô¤Ï $PLIST ¤òÊÖ¤¹¡£ */ @@ -1626,14 +1664,14 @@ mdebug_dump_plist (MPlist *plist, int indent) memset (prefix, 32, indent); prefix[indent] = 0; - fprintf (stderr, "("); + fprintf (mdebug__output, "("); MPLIST_DO (pl, plist) { if (pl != plist) - fprintf (stderr, "\n%s ", prefix); + fprintf (mdebug__output, "\n%s ", prefix); write_element (NULL, pl, indent + 1); } - fprintf (stderr, ")"); + fprintf (mdebug__output, ")"); return plist; }