merge FLT
[m17n/m17n-lib.git] / src / m17n-core.c
index 10325d6..2094258 100644 (file)
@@ -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
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <unistd.h>
 #include "m17n-core.h"
 #include "m17n-misc.h"
 #include "internal.h"
+#include "symbol.h"
 
 static void
 default_error_handler (enum MErrorCode err)
@@ -383,43 +385,39 @@ default_error_handler (enum MErrorCode err)
 static struct timeval time_stack[16];
 static int time_stack_index;
 
-static int report_header_printed;
+static M17NObjectArray *object_array_root;
 
-\f
-/* Internal API */
-
-int m17n__core_initialized;
-int m17n__shell_initialized;
-int m17n__gui_initialized;
-
-void
-mdebug__report_object (char *name, M17NObjectArray *array)
+static void
+report_object_array ()
 {
-  if (! (mdebug__flag & MDEBUG_FINI))
-    return;
-  if (! report_header_printed)
+  fprintf (stderr, "%16s %7s %7s %7s\n",
+          "object", "created", "freed", "alive");
+  fprintf (stderr, "%16s %7s %7s %7s\n",
+          "------", "-------", "-----", "-----");
+  for (; object_array_root; object_array_root = object_array_root->next)
     {
-      fprintf (stderr, "%16s %7s %7s %7s\n",
-              "object", "created", "freed", "alive");
-      fprintf (stderr, "%16s %7s %7s %7s\n",
-              "------", "-------", "-----", "-----");
-      report_header_printed = 1;
-    }
-  fprintf (stderr, "%16s %7d %7d %7d\n", name,
-          array->used, array->used - array->count, array->count);
-  if (array->used > 0)
-    {
-      free (array->objects);
-      array->count = array->used = 0;
+      M17NObjectArray *array = object_array_root;
+
+      fprintf (stderr, "%16s %7d %7d %7d\n", array->name,
+              array->used, array->used - array->count, array->count);
+      if (array->used > 0)
+       {
+         free (array->objects);
+         array->count = array->used = 0;
+       }
     }
 }
 
 
-void *(*mdatabase__finder) (MSymbol tag1, MSymbol tag2,
-                          MSymbol tag3, MSymbol tag4);
-void *(*mdatabase__loader) (void *);
+\f
+/* Internal API */
+
+int m17n__core_initialized;
+int m17n__shell_initialized;
+int m17n__gui_initialized;
 
-int mdebug__flag;
+int mdebug__flags[MDEBUG_MAX];
+FILE *mdebug__output;
 
 void
 mdebug__push_time ()
@@ -449,13 +447,34 @@ mdebug__print_time ()
   time_stack[time_stack_index - 1] = tv;
 }
 
-#define SET_DEBUG_FLAG(env_name, mask)         \
-  do {                                         \
-    char *env_value = getenv (env_name);       \
-                                               \
-    if (env_value && env_value[0] == '1')      \
-      mdebug__flag |= (mask);                  \
-  } while (0)
+static void
+SET_DEBUG_FLAG (char *env_name, enum MDebugFlag flag)
+{
+  char *env_value = getenv (env_name);
+
+  if (env_value)
+    {
+      int int_value = atoi (env_value);
+
+      if (flag == MDEBUG_ALL)
+       {
+         int i;
+         for (i = 0; i < MDEBUG_MAX; i++)
+           mdebug__flags[i] = int_value;
+       }
+      else
+       mdebug__flags[flag] = int_value;
+    }
+}
+
+void
+mdebug__add_object_array (M17NObjectArray *array, char *name)
+{
+  array->name = name;
+  array->count = 0;
+  array->next = object_array_root;
+  object_array_root = array;
+}
 
 
 void
@@ -473,11 +492,15 @@ mdebug__unregister_object (M17NObjectArray *array, void *object)
   array->count--;
   if (array->count >= 0)
     {
-      int i = 0;
+      int i;
 
-      while (i < array->used && array->objects[i] != object) i++;
-      if (i < array->used)
-       array->objects[i] = NULL;
+      for (i = array->used - 1; i >= 0 && array->objects[i] != object; i--);
+      if (i >= 0)
+       {
+         if (i == array->used - 1)
+           array->used--;
+         array->objects[i] = NULL;
+       }
       else
        mdebug_hook ();
     }
@@ -494,7 +517,7 @@ mdebug__unregister_object (M17NObjectArray *array, void *object)
 void
 m17n_init_core (void)
 {
-  int mdebug_mask = MDEBUG_INIT;
+  int mdebug_flag = MDEBUG_INIT;
 
   merror_code = MERROR_NONE;
   if (m17n__core_initialized++)
@@ -502,7 +525,7 @@ m17n_init_core (void)
 
   m17n_memory_full_handler = default_error_handler;
 
-  mdebug__flag = 0;
+  SET_DEBUG_FLAG ("MDEBUG_ALL", MDEBUG_ALL);
   SET_DEBUG_FLAG ("MDEBUG_INIT", MDEBUG_INIT);
   SET_DEBUG_FLAG ("MDEBUG_FINI", MDEBUG_FINI);
   SET_DEBUG_FLAG ("MDEBUG_CHARSET", MDEBUG_CHARSET);
@@ -512,6 +535,20 @@ m17n_init_core (void)
   SET_DEBUG_FLAG ("MDEBUG_FONT_FLT", MDEBUG_FONT_FLT);
   SET_DEBUG_FLAG ("MDEBUG_FONT_OTF", MDEBUG_FONT_OTF);
   SET_DEBUG_FLAG ("MDEBUG_INPUT", MDEBUG_INPUT);
+  {
+    char *env_value = getenv ("MDEBUG_OUTPUT_FILE");
+
+    mdebug__output = NULL;
+    if (env_value)
+      {
+       if (strcmp (env_value, "stdout"))
+         mdebug__output = stdout;
+       else
+         mdebug__output = fopen (env_value, "a");
+      }
+    if (! mdebug__output)
+      mdebug__output = stderr;
+  }
 
   MDEBUG_PUSH_TIME ();
   MDEBUG_PUSH_TIME ();
@@ -521,17 +558,27 @@ m17n_init_core (void)
   if  (mplist__init () < 0)
     goto err;
   MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize plist module."));
-  if (mtext__init () < 0)
+  if (mchar__init () < 0)
     goto err;
-  if (mtext__prop_init () < 0)
-    goto err;
-  MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize mtext module."));
+  MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize character module."));
   if  (mchartable__init () < 0)
     goto err;
   MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize chartable module."));
-
-  mdatabase__finder = NULL;
-  mdatabase__loader = NULL;
+  if (mtext__init () < 0 || mtext__prop_init () < 0)
+    goto err;
+  MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize mtext module."));
+  if (mdatabase__init () < 0)
+    goto err;
+  MDEBUG_PRINT_TIME ("INIT", (stderr, " to initialize database module."));
+
+#if ENABLE_NLS
+  bindtextdomain ("m17n-lib", GETTEXTDIR);
+  bindtextdomain ("m17n-db", GETTEXTDIR);
+  bindtextdomain ("m17n-contrib", GETTEXTDIR);
+  bind_textdomain_codeset ("m17n-lib", "UTF-8");
+  bind_textdomain_codeset ("m17n-db", "UTF-8");
+  bind_textdomain_codeset ("m17n-contrib", "UTF-8");
+#endif
 
  err:
   MDEBUG_POP_TIME ();
@@ -542,7 +589,7 @@ m17n_init_core (void)
 void
 m17n_fini_core (void)
 {
-  int mdebug_mask = MDEBUG_FINI;
+  int mdebug_flag = MDEBUG_FINI;
 
   if (m17n__core_initialized == 0
       || --m17n__core_initialized > 0)
@@ -550,20 +597,26 @@ m17n_fini_core (void)
 
   MDEBUG_PUSH_TIME ();
   MDEBUG_PUSH_TIME ();
-  MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize chartable module."));
   mchartable__fini ();
-  MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize textprop module."));
-  mtext__prop_fini ();
-  MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize mtext module."));
+  MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize chartable module."));
   mtext__fini ();
-  MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize symbol module."));
+  MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize mtext module."));
   msymbol__fini ();
-  MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize plist module."));
+  MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize symbol module."));
   mplist__fini ();
+  MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize plist module."));
+  /* We must call this after the aboves because it frees interval
+     pools.  */
+  mtext__prop_fini ();
+  MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize textprop module."));
   MDEBUG_POP_TIME ();
   MDEBUG_PRINT_TIME ("FINI", (stderr, " to finalize the core modules."));
   MDEBUG_POP_TIME ();
-  report_header_printed = 0;
+  if (mdebug__flags[MDEBUG_FINI])
+    report_object_array ();
+  msymbol__free_table ();
+  if (mdebug__output != stderr)
+    fclose (mdebug__output);
 }
 
 /*** @} */
@@ -619,8 +672,8 @@ m17n_status (void)
     zero.
 
     A property whose key is a managing key can have only a managed
-    object as its value.  Such functions as msymbol_put () and
-    mplist_put () pay special attention to such a property.
+    object as its value.  Some functions, for instance msymbol_put ()
+    and mplist_put (), pay special attention to such a property.
 
     In addition to the predefined managed object types, users can
     define their own managed object types.  See the documentation of
@@ -631,7 +684,7 @@ m17n_status (void)
 
     m17n ¥ª¥Ö¥¸¥§¥¯¥È¤Î¤¢¤ë·¿¤Î¤â¤Î¤Ï¡¢»²¾È¿ô¤Ë¤è¤Ã¤Æ´ÉÍý¤µ¤ì¤Æ¤¤¤ë¡£
     ¤½¤ì¤é¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ï @e ´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È ¤È¸Æ¤Ð¤ì¤ë¡£À¸À®¤µ¤ì¤¿»þÅÀ¤Ç¤Î»²¾È¿ô¤Ï
-    0 ¤Ë½é´ü²½¤µ¤ì¤Æ¤¤¤ë¡£´Ø¿ô m17n_object_ref () ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Î»²¾È¿ô¤ò
+    1 ¤Ë½é´ü²½¤µ¤ì¤Æ¤¤¤ë¡£´Ø¿ô m17n_object_ref () ¤Ï´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Î»²¾È¿ô¤ò
     1 Áý¤ä¤·¡¢´Ø¿ôm17n_object_unref () ¤Ï 1 ¸º¤é¤¹¡£»²¾È¿ô¤¬
     0 ¤Ë¤Ê¤Ã¤¿´ÉÍý²¼¥ª¥Ö¥¸¥§¥¯¥È¤Ï¼«Æ°Åª¤Ë²òÊü¤µ¤ì¤ë¡£
 
@@ -714,6 +767,8 @@ m17n_object (int size, void (*freer) (void *))
   M17NObject *obj = malloc (size);
 
   obj->ref_count = 1;
+  obj->ref_count_extended = 0;
+  obj->flag = 0;
   obj->u.freer = freer;
   return obj;
 }