+ p0 = MPLIST_PLIST (plist);
+ /* P0 ::= (TAG0 (TAG1 (TAG2 (TAG3 t:MDB) ...) ...) ...) */
+ MPLIST_DO (p0, MPLIST_NEXT (p0))
+ {
+ p1 = MPLIST_PLIST (p0);
+ /* P1 ::= (TAG1 (TAG2 (TAG3 t:MDB) ...) ...) */
+ MPLIST_DO (p1, MPLIST_NEXT (p1))
+ {
+ p2 = MPLIST_PLIST (p1);
+ /* P2 ::= (TAG2 (TAG3 t:MDB) ...) */
+ MPLIST_DO (p2, MPLIST_NEXT (p2))
+ {
+ MDatabase *mdb;
+
+ p3 = MPLIST_PLIST (p2); /* P3 ::= (TAG3 t:MDB) */
+ p3 = MPLIST_NEXT (p3);
+ mdb = MPLIST_VAL (p3);
+ if (mdb->loader == load_database)
+ free_db_info (mdb->extra_info);
+ free (mdb);
+ }
+ }
+ }
+ }
+ M17N_OBJECT_UNREF (mdatabase__list);
+}
+
+void
+mdatabase__update (void)
+{
+ MPlist *plist, *p0, *p1, *p2, *p3;
+ char path[PATH_MAX + 1];
+ MDatabaseInfo *dir_info;
+ struct stat statbuf;
+ int rescan = 0;
+
+ /* Update elements of mdatabase__dir_list. */
+ MPLIST_DO (plist, mdatabase__dir_list)
+ {
+ dir_info = MPLIST_VAL (plist);
+ if (dir_info->filename)
+ {
+ if (stat (dir_info->filename, &statbuf) == 0
+ && (statbuf.st_mode & S_IFDIR))
+ {
+ if (dir_info->time < statbuf.st_mtime)
+ {
+ rescan = 1;
+ dir_info->time = statbuf.st_mtime;
+ }
+ if (GEN_PATH (path, dir_info->filename, dir_info->len,
+ MDB_DIR, MDB_DIR_LEN)
+ && stat (path, &statbuf) >= 0
+ && dir_info->time < statbuf.st_mtime)
+ {
+ rescan = 1;
+ dir_info->time = statbuf.st_mtime;
+ }
+ dir_info->status = MDB_STATUS_UPDATED;
+ }
+ else
+ {
+ if (dir_info->status != MDB_STATUS_DISABLED)
+ {
+ rescan = 1;
+ dir_info->time = 0;
+ dir_info->status = MDB_STATUS_DISABLED;
+ }
+ }
+ }
+ }
+
+ if (! rescan)
+ return;
+
+ /* At first, mark all databases defined automatically from mdb.dir
+ file(s) as "disabled". */
+ MPLIST_DO (plist, mdatabase__list)
+ {
+ p0 = MPLIST_PLIST (plist);
+ /* P0 ::= (TAG0 (TAG1 (TAG2 (TAG3 MDB) ...) ...) ...) */
+ MPLIST_DO (p0, MPLIST_NEXT (p0))
+ {
+ p1 = MPLIST_PLIST (p0);
+ MPLIST_DO (p1, MPLIST_NEXT (p1))
+ {
+ p2 = MPLIST_PLIST (p1);
+ MPLIST_DO (p2, MPLIST_NEXT (p2))
+ {
+ MDatabase *mdb;
+ MDatabaseInfo *db_info;
+
+ p3 = MPLIST_PLIST (p2);
+ p3 = MPLIST_NEXT (p3);
+ mdb = MPLIST_VAL (p3);
+ db_info = mdb->extra_info;
+ if (db_info->status == MDB_STATUS_AUTO)
+ db_info->status = MDB_STATUS_DISABLED;
+ }
+ }
+ }
+ }
+
+ plist = mplist ();
+ MPLIST_DO (p0, mdatabase__dir_list)
+ mplist_push (plist, MPLIST_KEY (p0), MPLIST_VAL (p0));
+
+ while (! MPLIST_TAIL_P (plist))
+ {
+ MDatabaseInfo *dir_info = mplist_pop (plist);