+ return (ver[0] < M17NLIB_MAJOR_VERSION
+ || (ver[0] == M17NLIB_MAJOR_VERSION
+ && (ver[1] < M17NLIB_MINOR_VERSION
+ || (ver[1] == M17NLIB_MINOR_VERSION
+ && ver[2] <= M17NLIB_PATCH_LEVEL))));
+}
+
+static MDatabase *
+register_database (MSymbol tags[4],
+ void *(*loader) (MSymbol *, void *),
+ void *extra_info, enum MDatabaseStatus status)
+{
+ MDatabase *mdb;
+ MDatabaseInfo *db_info;
+ int i;
+ MPlist *plist;
+
+ if (! mdatabase__list)
+ mdatabase__list = mplist ();
+
+ for (i = 0, plist = mdatabase__list; i < 4; i++)
+ {
+ MPlist *pl = mplist__assq (plist, tags[i]);
+
+ if (pl)
+ pl = MPLIST_PLIST (pl);
+ else
+ {
+ pl = mplist ();
+ mplist_add (pl, Msymbol, tags[i]);
+ mplist_push (plist, Mplist, pl);
+ M17N_OBJECT_UNREF (pl);
+ }
+ plist = MPLIST_NEXT (pl);
+ }
+
+ if (MPLIST_TAIL_P (plist))
+ {
+ MSTRUCT_MALLOC (mdb, MERROR_DB);
+ for (i = 0; i < 4; i++)
+ mdb->tag[i] = tags[i];
+ mdb->loader = loader;
+ if (loader == load_database)
+ {
+ MSTRUCT_CALLOC (db_info, MERROR_DB);
+ mdb->extra_info = db_info;
+ }
+ else
+ {
+ db_info = NULL;
+ mdb->extra_info = extra_info;
+ }
+ mplist_push (plist, Mt, mdb);
+ }
+ else
+ {
+ mdb = MPLIST_VAL (plist);
+ if (loader == load_database)
+ db_info = mdb->extra_info;
+ else
+ db_info = NULL;
+ }
+
+ if (db_info)
+ {
+ db_info->status = status;
+ if (! db_info->filename
+ || strcmp (db_info->filename, (char *) extra_info) != 0)
+ {
+ if (db_info->filename)
+ free (db_info->filename);
+ if (db_info->absolute_filename
+ && db_info->filename != db_info->absolute_filename)
+ free (db_info->absolute_filename);
+ db_info->filename = strdup ((char *) extra_info);
+ db_info->len = strlen ((char *) extra_info);
+ db_info->time = 0;
+ }
+ if (db_info->filename[0] == PATH_SEPARATOR)
+ db_info->absolute_filename = db_info->filename;
+ else
+ db_info->absolute_filename = NULL;
+ }
+
+ if (mdb->tag[0] == Mchar_table
+ && mdb->tag[2] != Mnil
+ && (mdb->tag[1] == Mstring || mdb->tag[1] == Mtext
+ || mdb->tag[1] == Msymbol || mdb->tag[1] == Minteger
+ || mdb->tag[1] == Mplist))
+ mchar__define_prop (mdb->tag[2], mdb->tag[1], mdb);
+ return mdb;
+}
+
+static void
+register_databases_in_files (MSymbol tags[4], glob_t *globbuf, int headlen)
+{
+ int i, j;
+ MPlist *load_key = mplist ();
+ FILE *fp;
+ MPlist *plist;
+
+ for (i = 0; i < globbuf->gl_pathc; i++)
+ {
+ if (! (fp = fopen (globbuf->gl_pathv[i], "r")))
+ continue;
+ plist = mplist__from_file (fp, load_key);
+ fclose (fp);
+ if (! plist)
+ continue;
+ if (MPLIST_PLIST_P (plist))
+ {
+ MPlist *pl;
+ MSymbol tags2[4];
+
+ for (j = 0, pl = MPLIST_PLIST (plist); j < 4 && MPLIST_SYMBOL_P (pl);
+ j++, pl = MPLIST_NEXT (pl))
+ tags2[j] = MPLIST_SYMBOL (pl);
+ for (; j < 4; j++)
+ tags2[j] = Mnil;
+ for (j = 0; j < 4; j++)
+ if (tags[j] == Masterisk ? tags2[j] == Mnil
+ : (tags[j] != Mnil && tags[j] != tags2[j]))
+ break;
+ if (j == 4)
+ {
+ MText *version = NULL;
+
+ MPLIST_DO (pl, pl)
+ version = MPLIST_MTEXT_P (pl) ? MPLIST_MTEXT (pl) : NULL;
+ if (! version || check_version (version))
+ register_database (tags2, load_database,
+ globbuf->gl_pathv[i] + headlen,
+ MDB_STATUS_AUTO);
+ }
+ }
+ M17N_OBJECT_UNREF (plist);
+ }
+ M17N_OBJECT_UNREF (load_key);