<commit_before>using Xml;

namespace Caribou {

    private class XmlDeserializer : Object {

        public static string? get_layout_file_inner (string data_dir,
                                                    string group,
                                                    string variant) {
            string[] files = {@"$(group)_$(variant).xml", @"$(group).xml"};

            foreach (string fn in files) {
                string layout_fn = GLib.Path.build_filename (data_dir, fn);
                GLib.File fp = GLib.File.new_for_path (layout_fn);
                if (fp.query_exists ())
                    return layout_fn;
            }

            return null;
        }

        public static string get_layout_file (string keyboard_type, string group,
                                              string variant) throws IOError {

            List<string> dirs = new List<string> ();
            string custom_dir = Environment.get_variable("CARIBOU_LAYOUTS_DIR");

            if (custom_dir != null)
                dirs.append (Path.build_filename (custom_dir, "layouts",
                                                  keyboard_type));

            dirs.append (Path.build_filename (Environment.get_user_data_dir (),
                                              "caribou", "layouts", keyboard_type));

            foreach (string dir in Environment.get_system_data_dirs ()) {
                dirs.append (Path.build_filename (
                                 dir, "caribou", "layouts", keyboard_type));
            }

            foreach (string data_dir in dirs) {
                string fn = get_layout_file_inner (data_dir, group, variant);
                if (fn != null)
                    return fn;
            }

            // If no layout file is found, default to US
            foreach (string data_dir in dirs) {
                string fn = get_layout_file_inner (data_dir, "us", "");
                if (fn != null)
                    return fn;
            }
        }

        public static GroupModel? load_group (string keyboard_type,
                                              string group, string variant) {
            Doc* doc;

            try {
                string fn = get_layout_file (keyboard_type, group, variant);
                doc = Parser.parse_file (fn);
                if (doc == null)
                    throw new IOError.FAILED (
                        "Cannot load XML text reader for %s", fn);
            } catch (GLib.Error e) {
                stdout.printf ("Failed to load XML: %s\n", e.message);
                return null;
            }

            GroupModel grp = new GroupModel (group, variant);
            Xml.Node* node = doc->children;

            create_levels_from_xml (grp, node);<commit_msg>libcaribou: fix compile<commit_after>using Xml;

namespace Caribou {

    private class XmlDeserializer : Object {

        public static string? get_layout_file_inner (string data_dir,
                                                    string group,
                                                    string variant) {
            string[] files = {@"$(group)_$(variant).xml", @"$(group).xml"};

            foreach (string fn in files) {
                string layout_fn = GLib.Path.build_filename (data_dir, fn);
                GLib.File fp = GLib.File.new_for_path (layout_fn);
                if (fp.query_exists ())
                    return layout_fn;
            }

            return null;
        }

        public static string get_layout_file (string keyboard_type, string group,
                                              string variant) throws IOError {

            List<string> dirs = new List<string> ();
            string custom_dir = Environment.get_variable("CARIBOU_LAYOUTS_DIR");

            if (custom_dir != null)
                dirs.append (Path.build_filename (custom_dir, "layouts",
                                                  keyboard_type));

            dirs.append (Path.build_filename (Environment.get_user_data_dir (),
                                              "caribou", "layouts", keyboard_type));

            foreach (string dir in Environment.get_system_data_dirs ()) {
                dirs.append (Path.build_filename (
                                 dir, "caribou", "layouts", keyboard_type));
            }

            foreach (string data_dir in dirs) {
                string fn = get_layout_file_inner (data_dir, group, variant);
                if (fn != null)
                    return fn;
            }

            // If no layout file is found, default to US
            foreach (string data_dir in dirs) {
                string fn = get_layout_file_inner (data_dir, "us", "");
                if (fn != null)
                    return fn;
            }

            // Should not be reached, but needed to make valac happy
            throw new IOError.NOT_FOUND (
                "Could not find layout file for %s %s", group, variant);
        }

        public static GroupModel? load_group (string keyboard_type,
                                              string group, string variant) {
            Doc* doc;

            try {
                string fn = get_layout_file (keyboard_type, group, variant);
                doc = Parser.parse_file (fn);
                if (doc == null)
                    throw new IOError.FAILED (
                        "Cannot load XML text reader for %s", fn);
            } catch (GLib.Error e) {
                stdout.printf ("Failed to load XML: %s\n", e.message);
                return null;
            }

            GroupModel grp = new GroupModel (group, variant);
            Xml.Node* node = doc->children;

            create_levels_from_xml (grp, node);
{'fraction_non_alphanumeric': 0.0851063829787234, 'fraction_numerical': 0.0, 'mean_word_length': 1.2799684542586751, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1664070', 'n_tokens_mistral': 1440, 'n_tokens_neox': 1355, 'n_words': 398}