Add really rudimentary rules caching support Keep the parsed form of the last-used rules file around, and reuse that if we get asked for the same ruleset. If not, bin it and cache the other one. Signed-off-by: Daniel Stone <daniel@fooishbar.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
diff --git a/src/xkbcomp/xkbcomp.c b/src/xkbcomp/xkbcomp.c
index f8109d4..e801a7b 100644
--- a/src/xkbcomp/xkbcomp.c
+++ b/src/xkbcomp/xkbcomp.c
@@ -76,30 +76,43 @@ XkbKeymapFileFromComponents(const XkbComponentNamesPtr ktcsg)
static XkbComponentNamesPtr
XkbComponentsFromRules(const char *rules, const XkbRF_VarDefsPtr defs)
{
- FILE *rulesFile;
- char *rulesPath;
- XkbRF_RulesPtr loaded;
+ FILE *rulesFile = NULL;
+ char *rulesPath = NULL;
+ static XkbRF_RulesPtr loaded = NULL;
+ static char *cached_name = NULL;
XkbComponentNamesPtr names = NULL;
- rulesFile = XkbFindFileInPath((char *)rules, XkmRulesFile, &rulesPath);
- if (!rulesFile) {
- ERROR("could not find \"%s\" rules in XKB path\n", rules);
- goto out;
+ if (!cached_name || strcmp(rules, cached_name) != 0) {
+ if (loaded)
+ XkbcRF_Free(loaded, True);
+ loaded = NULL;
+ free(cached_name);
+ cached_name = NULL;
}
- if (!(loaded = _XkbTypedCalloc(1, XkbRF_RulesRec))) {
- ERROR("failed to allocate XKB rules\n");
- goto unwind_file;
- }
+ if (!loaded) {
+ rulesFile = XkbFindFileInPath((char *)rules, XkmRulesFile, &rulesPath);
+ if (!rulesFile) {
+ ERROR("could not find \"%s\" rules in XKB path\n", rules);
+ goto out;
+ }
+
+ if (!(loaded = _XkbTypedCalloc(1, XkbRF_RulesRec))) {
+ ERROR("failed to allocate XKB rules\n");
+ goto unwind_file;
+ }
+
+ if (!XkbcRF_LoadRules(rulesFile, loaded)) {
+ ERROR("failed to load XKB rules \"%s\"\n", rulesPath);
+ goto unwind_file;
+ }
- if (!XkbcRF_LoadRules(rulesFile, loaded)) {
- ERROR("failed to load XKB rules \"%s\"\n", rulesPath);
- goto unwind_rules;
+ cached_name = strdup(rules);
}
if (!(names = _XkbTypedCalloc(1, XkbComponentNamesRec))) {
ERROR("failed to allocate XKB components\n");
- goto unwind_rules;
+ goto unwind_file;
}
if (!XkbcRF_GetComponents(loaded, defs, names)) {
@@ -114,10 +127,9 @@ XkbComponentsFromRules(const char *rules, const XkbRF_VarDefsPtr defs)
ERROR("no components returned from XKB rules \"%s\"\n", rulesPath);
}
-unwind_rules:
- XkbcRF_Free(loaded, True);
unwind_file:
- fclose(rulesFile);
+ if (rulesFile)
+ fclose(rulesFile);
free(rulesPath);
out:
return names;