*** empty log message ***
[m17n/m17n-lib.git] / src / plist.c
index f798ee5..05dd737 100644 (file)
@@ -1,5 +1,5 @@
 /* plist.c -- plist module.
-   Copyright (C) 2003, 2004
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H15PRO112
 
@@ -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;
@@ -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)
@@ -714,17 +684,12 @@ write_element (MText *mt, MPlist *plist, int indent)
     }
   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;
 }
 
@@ -1204,9 +1178,17 @@ 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 like mplist_put () but for
-    settting function pointer $FUNC in property list $PLIST for key
-    $KEY.  */
+    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
@@ -1215,17 +1197,10 @@ mplist_get (MPlist *plist, MSymbol key)
 MPlist *
 mplist_put_func (MPlist *plist, MSymbol key, M17NFunc func)
 {
-  if (key == Mnil)
+  if (key == Mnil || key->managing_key)
     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_FIND (plist, key);
+  MPLIST_KEY (plist) = key;
   MPLIST_FUNC (plist) = func;
   MPLIST_SET_VAL_FUNC_P (plist);
   if (! plist->next)
@@ -1238,22 +1213,24 @@ mplist_put_func (MPlist *plist, MSymbol key, M17NFunc func)
 /***en
     @brief Get the value (function pointer) of a property in a property list.
 
-    The mplist_get_func () funciont is like mplist_get () but for
+    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)
 {
-  while (1)
-    {
-      MPLIST_FIND (plist, key);
-      if (MPLIST_TAIL_P (plist) || MPLIST_VAL_FUNC_P (plist))
-       break;
-      plist = MPLIST_NEXT (plist);
-    };
+  MPLIST_FIND (plist, key);
   return (MPLIST_TAIL_P (plist) ? NULL : MPLIST_FUNC (plist));
 }
 
@@ -1337,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)
@@ -1604,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, <tt>"abc\ def"</tt>
+    character, which means that, for instance, <tt>abc\ def</tt>
     produces a symbol whose name is of length seven with the fourth
     character being a space.  */
 /***ja
@@ -1629,7 +1608,7 @@ mplist_value (MPlist *plist)
     @c Mplist ¤Î¤¤¤º¤ì¤«¤ò³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤ë¡£
 
     ¥¢¥¹¥­¡¼Ê¸»úÎóÆâ¤Ç¤Ï¡¢¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å (\) ¤¬¥¨¥¹¥±¡¼¥×ʸ»ú¤È¤·¤ÆÍѤ¤¤é¤ì¤ë¡£¤¿¤È¤¨¤Ð
-    <tt>"abc\ def"</tt> ¤Ï 4 Ê¸»úÌܤ¬¶õÇòʸ»ú¤Ç¤¢¤êŤµ¤¬ 7 
+    <tt>abc\ def</tt> ¤Ï 4 Ê¸»úÌܤ¬¶õÇòʸ»ú¤Ç¤¢¤êŤµ¤¬ 7 
     ¤Ç¤¢¤ë»ý¤Ä̾Á°¤ò»ý¤Ä¥·¥ó¥Ü¥ë¤òÀ¸À®¤¹¤ë¡£   */
 
 MPlist *