X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fplist.c;h=8cda7b9fb01131eb66f86218b3aeb7fbea29605d;hb=38c091dbfa19be7db173231b0b5101577de2098e;hp=24d06e2c557aa7c37c5e54f7b74a6e646d0fcb6a;hpb=460cab45886257c1c68e0bde79f0c9cf5646b59f;p=m17n%2Fm17n-lib.git diff --git a/src/plist.c b/src/plist.c index 24d06e2..8cda7b9 100644 --- a/src/plist.c +++ b/src/plist.c @@ -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 @@ -75,6 +75,7 @@ #include #include +#include #include "config.h" #include "m17n.h" @@ -556,31 +557,53 @@ read_element (MPlist *plist, MStream *st, MPlist *keys) return (read_symbol_element (plist, st, c, keys ? 1 : 0)); } -void -write_element (MText *mt, MPlist *plist) +#define PUTC(MT, C) \ + do { \ + if (MT) \ + mtext_cat_char ((MT), (C)); \ + else \ + putc ((C), stderr); \ + } while (0); + +#define PUTS(MT, STR) \ + do { \ + if (MT) \ + MTEXT_CAT_ASCII ((MT), (STR)); \ + else \ + fputs ((STR), stderr); \ + } while (0) + + +static void +write_symbol (MText *mt, MSymbol sym) { - if (MPLIST_SYMBOL_P (plist)) + if (sym == Mnil) { - MSymbol sym = MPLIST_SYMBOL (plist); + PUTS (mt, "nil"); + } + else + { + char *name = MSYMBOL_NAME (sym); - if (sym == Mnil) + if (isdigit (*name)) + PUTC (mt, '\\'); + while (*name) { - MTEXT_CAT_ASCII (mt, "nil"); + if (*name <= ' ' || *name == '\\' || *name == '"' + || *name == '(' || *name == ')') + PUTC (mt, '\\'); + PUTC (mt, *name); + name++; } - else - { - char *name = MSYMBOL_NAME (sym); - char *buf = alloca (MSYMBOL_NAMELEN (sym) * 2 + 1), *p = buf; + } +} - while (*name) - { - if (*name <= ' ' || *name == '"' || *name == ')' || *name == ')') - *p++ = '\\'; - *p++ = *name++; - } - *p = '\0'; - MTEXT_CAT_ASCII (mt, buf); - } +static void +write_element (MText *mt, MPlist *plist, int indent) +{ + if (MPLIST_SYMBOL_P (plist)) + { + write_symbol (mt, MPLIST_SYMBOL (plist)); } else if (MPLIST_INTEGER_P (plist)) { @@ -588,91 +611,121 @@ write_element (MText *mt, MPlist *plist) char buf[128]; sprintf (buf, "%d", num); - MTEXT_CAT_ASCII (mt, buf); + PUTS (mt, buf); } else if (MPLIST_PLIST_P (plist)) { MPlist *pl; + int newline = 0; plist = MPLIST_PLIST (plist); - mtext_cat_char (mt, '('); + PUTC (mt, '('); + if (indent >= 0) + indent++; MPLIST_DO (pl, plist) { if (pl != plist) - mtext_cat_char (mt, ' '); - write_element (mt, pl); + { + if (indent > 0 && (MPLIST_PLIST_P (pl) || MPLIST_MTEXT_P (pl))) + newline = 1; + if (newline) + { + int i; + + PUTC (mt, '\n'); + for (i = 1; i < indent; i++) + PUTC (mt, ' '); + } + PUTC (mt, ' '); + } + write_element (mt, pl, indent); + if (indent >= 0) + newline = (MPLIST_PLIST_P (pl) || MPLIST_MTEXT_P (pl)); } - mtext_cat_char (mt, ')'); + PUTC (mt, ')'); } else if (MPLIST_MTEXT_P (plist)) { - mtext_cat_char (mt, '"'); - /* Not yet implemnted */ - mtext_cat_char (mt, '"'); - } -} - -/* Support functions for mdebug_dump_plist. */ + MText *this_mt = MPLIST_MTEXT (plist); + int from = 0, to = mtext_nchars (this_mt); + int stop1 = 0, stop2 = 0; -static void -dump_string (char *str) -{ - char *p = str, *pend = p + strlen (p), *new, *p1; - - new = p1 = alloca ((pend - p) * 4 + 1); - while (p < pend) - { - if (*p < 0) + if (! mt && this_mt->format > MTEXT_FORMAT_UTF_8) { - sprintf (p1, "\\x%02X", (unsigned char) *p); - p1 += 4; + this_mt = mtext_dup (this_mt); + mtext__adjust_format (this_mt, MTEXT_FORMAT_UTF_8); } - else if (*p < ' ') + + PUTC (mt, '"'); + while (1) { - *p1++ = '^'; - *p1++ = *p + '@'; + int stop, escaped; + + if (from == stop1) + { + if ((stop1 = mtext_character (this_mt, from, to, '"')) < 0) + stop1 = to; + } + if (from == stop2) + { + if ((stop2 = mtext_character (this_mt, from, to, '\\')) < 0) + stop2 = to; + } + if (stop1 < stop2) + stop = stop1++, escaped = '"'; + else + stop = stop2++, escaped = '\\'; + if (mt) + mtext_copy (mt, mtext_nchars (mt), this_mt, from, stop); + else + { + unsigned char *data = MTEXT_DATA (this_mt); + unsigned char *beg = data + mtext__char_to_byte (this_mt, from); + unsigned char *end = data + mtext__char_to_byte (this_mt, stop); + + while (beg < end) + putc (*beg, stderr), beg++; + } + if (stop == to) + break; + PUTC (mt, '\\'); + PUTC (mt, escaped); + from = stop + 1; } - else if (*p == ' ') + PUTC (mt, '"'); + if (this_mt != MPLIST_MTEXT (plist)) + M17N_OBJECT_UNREF (this_mt); + } + else if (MPLIST_STRING_P (plist)) + { + char *str = MPLIST_STRING (plist); + + if (mt) { - *p1++ = '\\'; - *p1++ = ' '; + MText *this_mt = mtext__from_data (str, strlen (str), + MTEXT_FORMAT_UTF_8, 0); + + mtext_copy (mt, mtext_nchars (mt), + this_mt, 0, mtext_nchars (this_mt)); + M17N_OBJECT_UNREF (this_mt); } else - *p1++ = *p; - p++; + fprintf (stderr, "%s", str); } - *p1 = '\0'; - fprintf (stderr, "%s", new); -} - -static void -dump_plist_element (MPlist *plist, int indent) -{ - char *prefix = (char *) alloca (indent + 1); - MSymbol key; - - memset (prefix, 32, indent); - prefix[indent] = 0; - - key = MPLIST_KEY (plist); - fprintf (stderr, "(%s(#%d) ", msymbol_name (MPLIST_KEY (plist)), - plist->control.ref_count); - if (key == Msymbol) - dump_string (msymbol_name (MPLIST_SYMBOL (plist))); - else if (key == Mtext) - mdebug_dump_mtext (MPLIST_MTEXT (plist), indent, 0); - else if (key == Minteger) - fprintf (stderr, "%x", MPLIST_INTEGER (plist)); - else if (key == Mstring) - fprintf (stderr, "\"%s\"", MPLIST_STRING (plist)); - else if (MPLIST_NESTED_P (plist)) + else { - fprintf (stderr, "\n%s", prefix); - mdebug_dump_plist (MPLIST_PLIST (plist), indent); + 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); + } } - else - fprintf (stderr, "0x%X", (unsigned) MPLIST_VAL (plist)); - fprintf (stderr, ")"); } @@ -838,16 +891,19 @@ mplist__from_string (unsigned char *str, int n) } int -mplist__serialize (MText *mt, MPlist *plist) +mplist__serialize (MText *mt, MPlist *plist, int pretty) { MPlist *pl; + int separator = pretty ? '\n' : ' '; MPLIST_DO (pl, plist) { if (pl != plist) - mtext_cat_char (mt, ' '); - write_element (mt, pl); + mtext_cat_char (mt, separator); + write_element (mt, pl, pretty ? 0 : -1); } + if (pretty) + mtext_cat_char (mt, separator); return 0; } @@ -900,6 +956,34 @@ mplist__pop_unref (MPlist *plist) M17N_OBJECT_UNREF (val); } +/**en + @brief Search for an element of an alist represented by a plist. + + The mplist__assq () function treats $PLIST as an association list + (elements are plists (key is #Mplist) whose first element is a + symbol (key is #Msymbol)), and find an element whose first element + has key #Msymbol and value $KEY. + + Non-plist elements of $PLIST are ignored. + + @return + This function returns a found element or NULL if no element + matches with $KEY. */ + +MPlist * +mplist__assq (MPlist *plist, MSymbol key) +{ + MPLIST_DO (plist, plist) + if (MPLIST_PLIST_P (plist)) + { + MPlist *pl = MPLIST_PLIST (plist); + + if (MPLIST_SYMBOL_P (pl) && MPLIST_SYMBOL (pl) == key) + return plist; + } + return NULL; +} + /*** @} */ #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ @@ -980,7 +1064,7 @@ MSymbol Mtext; ¤³¤Î´Ø¿ô¤Ï·è¤·¤Æ¼ºÇÔ¤·¤Ê¤¤¡£ */ MPlist * -mplist () +mplist (void) { MPlist *plist; @@ -1082,10 +1166,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 @@ -1095,8 +1179,8 @@ mplist_put (MPlist *plist, MSymbol key, void *val) /***ja @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÆÀ¤ë. - ´Ø¿ô mplist_get () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥­¡¼¤¬ - $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤؤΥݥ¤¥ó¥¿¤ò + ´Ø¿ô mplist_get () ¤Ï¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ò»Ï¤á¤«¤éõ¤·¤Æ¡¢¥­¡¼ + ¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ò¸«¤Ä¤±¤ë¡£¸«¤Ä¤«¤ì¤Ð¡¢¤½¤ÎÃͤò (void *) ·¿¤ÇÊÖ¤¹¡£¸«¤Ä¤«¤é¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£ @c NULL ¤¬Ê֤俺ݤˤÏÆó¤Ä¤Î²ÄǽÀ­¤¬¤¢¤ë: @@ -1118,6 +1202,74 @@ 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. */ + +/***ja + @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥ÈÃæ¤Î¥×¥í¥Ñ¥Æ¥£¤Ë´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤¢¤ëÃͤòÀßÄꤹ¤ë. + + ´Ø¿ô mplist_put_func () ¤Ï´Ø¿ô mplist_put () ƱÍÍ¡¢¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST + Ãæ¤Ç¥­¡¼¤¬ $KEY ¤Ç¤¢¤ë¥×¥í¥Ñ¥Æ¥£¤ËÃͤòÀßÄꤹ¤ë¡£Ã¢¤·¤½¤ÎÃͤϴؿô¥Ý¥¤¥ó¥¿ + $FUNC ¤Ç¤¢¤ë¡£ */ + + +/*** + @seealso + mplist_put (), M17N_FUNC () */ + +MPlist * +mplist_put_func (MPlist *plist, MSymbol key, M17NFunc func) +{ + if (key == Mnil) + MERROR (MERROR_PLIST, NULL); + while (1) + { + MPLIST_FIND (plist, key); + if (MPLIST_TAIL_P (plist) || MPLIST_VAL_FUNC_P (plist)) + break; + plist = MPLIST_NEXT (plist); + }; + + 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 @@ -1211,7 +1363,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 @@ -1219,9 +1371,8 @@ mplist_push (MPlist *plist, MSymbol key, void *val) /***ja @brief ¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤ÎÀèƬ¤«¤é¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë. - ´Ø¿ô mplist_pop () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST - ¤ÎÀèƬ¤Î¥×¥í¥Ñ¥Æ¥£¤òºï½ü¤¹¤ë¡£·ë²Ì¤È¤·¤Æ¡¢¸µ¤Î $PLIST ¤Î2ÈÖÌܤΥ­¡¼¤ÈÃͤ¬¡¢¿·¤·¤¤ - $PLIST ¤ÎÀèƬ¤Î¥­¡¼¤ÈÃͤˤʤ롣 + ´Ø¿ô mplist_pop () ¤Ï¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È $PLIST ¤ÎÀèƬ¤Î¥×¥í¥Ñ¥Æ¥£¤òºï + ½ü¤¹¤ë¡£·ë²Ì¤È¤·¤Æ¡¢¸µ¤Î2ÈÖÌܤΥ­¡¼¤ÈÃͤ¬ÀèƬ¤Î¥­¡¼¤ÈÃͤˤʤ롣 @return ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð¡¢¤³¤Î´Ø¿ô¤Ïºï½ü¤µ¤ì¤¿¥×¥í¥Ñ¥Æ¥£¤ÎÃͤòÊÖ¤¹¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @@ -1538,7 +1689,6 @@ mdebug_dump_plist (MPlist *plist, int indent) { char *prefix = (char *) alloca (indent + 1); MPlist *pl; - int first = 1; memset (prefix, 32, indent); prefix[indent] = 0; @@ -1546,11 +1696,9 @@ mdebug_dump_plist (MPlist *plist, int indent) fprintf (stderr, "("); MPLIST_DO (pl, plist) { - if (first) - first = 0; - else + if (pl != plist) fprintf (stderr, "\n%s ", prefix); - dump_plist_element (pl, indent + 2); + write_element (NULL, pl, indent + 1); } fprintf (stderr, ")"); return plist;