types: separate ctx

Separate the ctx object to its own field in CompatInfo, instead of doing
keymap->ctx.

The compilation functions should not have direct access to the keymap;
instead they should process the files with their own independent state
(in the *Info structs) as much as possible, and only at the end should
they be copied (i.e. commited) to the keymap. If the compilation fails,
it leaves no by-products. It's also just good form.

This was seemingly the original author's intention, but I suppose he cut
a few corners (mostly with the handling of virtual modifiers, which are
threaded through types -> compat -> symbols).

This commit is the first step and may look artificial; however the
'keymap' field will be removed shortly.

Signed-off-by: Ran Benita <ran234@gmail.com>
master
Ran Benita 2013-02-08 00:14:49 +02:00
parent 999f3792ac
commit 36cbecc5b5
1 changed files with 39 additions and 38 deletions

View File

@ -53,6 +53,7 @@ typedef struct {
int errorCount; int errorCount;
darray(KeyTypeInfo) types; darray(KeyTypeInfo) types;
struct xkb_context *ctx;
struct xkb_keymap *keymap; struct xkb_keymap *keymap;
} KeyTypesInfo; } KeyTypesInfo;
@ -67,7 +68,7 @@ MapEntryTxt(KeyTypesInfo *info, struct xkb_key_type_entry *entry)
static inline const char * static inline const char *
TypeTxt(KeyTypesInfo *info, KeyTypeInfo *type) TypeTxt(KeyTypesInfo *info, KeyTypeInfo *type)
{ {
return xkb_atom_text(info->keymap->ctx, type->name); return xkb_atom_text(info->ctx, type->name);
} }
static inline const char * static inline const char *
@ -80,7 +81,7 @@ static inline bool
ReportTypeShouldBeArray(KeyTypesInfo *info, KeyTypeInfo *type, ReportTypeShouldBeArray(KeyTypesInfo *info, KeyTypeInfo *type,
const char *field) const char *field)
{ {
return ReportShouldBeArray(info->keymap->ctx, "key type", field, return ReportShouldBeArray(info->ctx, "key type", field,
TypeTxt(info, type)); TypeTxt(info, type));
} }
@ -88,7 +89,7 @@ static inline bool
ReportTypeBadType(KeyTypesInfo *info, KeyTypeInfo *type, ReportTypeBadType(KeyTypesInfo *info, KeyTypeInfo *type,
const char *field, const char *wanted) const char *field, const char *wanted)
{ {
return ReportBadType(info->keymap->ctx, "key type", field, return ReportBadType(info->ctx, "key type", field,
TypeTxt(info, type), wanted); TypeTxt(info, type), wanted);
} }
@ -99,6 +100,7 @@ InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_keymap *keymap)
{ {
memset(info, 0, sizeof(*info)); memset(info, 0, sizeof(*info));
info->keymap = keymap; info->keymap = keymap;
info->ctx = keymap->ctx;
} }
static void static void
@ -131,16 +133,16 @@ static bool
AddKeyType(KeyTypesInfo *info, KeyTypeInfo *new, bool same_file) AddKeyType(KeyTypesInfo *info, KeyTypeInfo *new, bool same_file)
{ {
KeyTypeInfo *old; KeyTypeInfo *old;
const int verbosity = xkb_context_get_log_verbosity(info->keymap->ctx); const int verbosity = xkb_context_get_log_verbosity(info->ctx);
old = FindMatchingKeyType(info, new->name); old = FindMatchingKeyType(info, new->name);
if (old) { if (old) {
if (new->merge == MERGE_REPLACE || new->merge == MERGE_OVERRIDE) { if (new->merge == MERGE_REPLACE || new->merge == MERGE_OVERRIDE) {
if ((same_file && verbosity > 0) || verbosity > 9) { if ((same_file && verbosity > 0) || verbosity > 9) {
log_warn(info->keymap->ctx, log_warn(info->ctx,
"Multiple definitions of the %s key type; " "Multiple definitions of the %s key type; "
"Earlier definition ignored\n", "Earlier definition ignored\n",
xkb_atom_text(info->keymap->ctx, new->name)); xkb_atom_text(info->ctx, new->name));
} }
ClearKeyTypeInfo(old); ClearKeyTypeInfo(old);
@ -151,10 +153,10 @@ AddKeyType(KeyTypesInfo *info, KeyTypeInfo *new, bool same_file)
} }
if (same_file) if (same_file)
log_vrb(info->keymap->ctx, 4, log_vrb(info->ctx, 4,
"Multiple definitions of the %s key type; " "Multiple definitions of the %s key type; "
"Later definition ignored\n", "Later definition ignored\n",
xkb_atom_text(info->keymap->ctx, new->name)); xkb_atom_text(info->ctx, new->name));
ClearKeyTypeInfo(new); ClearKeyTypeInfo(new);
return true; return true;
@ -211,7 +213,7 @@ HandleIncludeKeyTypes(KeyTypesInfo *info, IncludeStmt *include)
KeyTypesInfo next_incl; KeyTypesInfo next_incl;
XkbFile *file; XkbFile *file;
file = ProcessIncludeFile(info->keymap->ctx, stmt, FILE_TYPE_TYPES); file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_TYPES);
if (!file) { if (!file) {
info->errorCount += 10; info->errorCount += 10;
ClearKeyTypesInfo(&included); ClearKeyTypesInfo(&included);
@ -243,22 +245,22 @@ SetModifiers(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
xkb_mod_mask_t mods; xkb_mod_mask_t mods;
if (arrayNdx) if (arrayNdx)
log_warn(info->keymap->ctx, log_warn(info->ctx,
"The modifiers field of a key type is not an array; " "The modifiers field of a key type is not an array; "
"Illegal array subscript ignored\n"); "Illegal array subscript ignored\n");
if (!ExprResolveModMask(info->keymap, value, MOD_BOTH, &mods)) { if (!ExprResolveModMask(info->keymap, value, MOD_BOTH, &mods)) {
log_err(info->keymap->ctx, log_err(info->ctx,
"Key type mask field must be a modifier mask; " "Key type mask field must be a modifier mask; "
"Key type definition ignored\n"); "Key type definition ignored\n");
return false; return false;
} }
if (type->defined & TYPE_FIELD_MASK) { if (type->defined & TYPE_FIELD_MASK) {
log_warn(info->keymap->ctx, log_warn(info->ctx,
"Multiple modifier mask definitions for key type %s; " "Multiple modifier mask definitions for key type %s; "
"Using %s, ignoring %s\n", "Using %s, ignoring %s\n",
xkb_atom_text(info->keymap->ctx, type->name), xkb_atom_text(info->ctx, type->name),
TypeMaskTxt(info, type), TypeMaskTxt(info, type),
ModMaskText(info->keymap, mods)); ModMaskText(info->keymap, mods));
return false; return false;
@ -291,7 +293,7 @@ AddMapEntry(KeyTypesInfo *info, KeyTypeInfo *type,
old = FindMatchingMapEntry(type, new->mods.mods); old = FindMatchingMapEntry(type, new->mods.mods);
if (old) { if (old) {
if (report && old->level != new->level) { if (report && old->level != new->level) {
log_warn(info->keymap->ctx, log_warn(info->ctx,
"Multiple map entries for %s in %s; " "Multiple map entries for %s in %s; "
"Using %d, ignoring %d\n", "Using %d, ignoring %d\n",
MapEntryTxt(info, new), TypeTxt(info, type), MapEntryTxt(info, new), TypeTxt(info, type),
@ -299,7 +301,7 @@ AddMapEntry(KeyTypesInfo *info, KeyTypeInfo *type,
(clobber ? old->level : new->level) + 1); (clobber ? old->level : new->level) + 1);
} }
else { else {
log_vrb(info->keymap->ctx, 10, log_vrb(info->ctx, 10,
"Multiple occurrences of map[%s]= %d in %s; Ignored\n", "Multiple occurrences of map[%s]= %d in %s; Ignored\n",
MapEntryTxt(info, new), new->level + 1, MapEntryTxt(info, new), new->level + 1,
TypeTxt(info, type)); TypeTxt(info, type));
@ -335,7 +337,7 @@ SetMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
return ReportTypeBadType(info, type, "map entry", "modifier mask"); return ReportTypeBadType(info, type, "map entry", "modifier mask");
if (entry.mods.mods & (~type->mods)) { if (entry.mods.mods & (~type->mods)) {
log_vrb(info->keymap->ctx, 1, log_vrb(info->ctx, 1,
"Map entry for unused modifiers in %s; " "Map entry for unused modifiers in %s; "
"Using %s instead of %s\n", "Using %s instead of %s\n",
TypeTxt(info, type), TypeTxt(info, type),
@ -344,8 +346,8 @@ SetMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
entry.mods.mods &= type->mods; entry.mods.mods &= type->mods;
} }
if (!ExprResolveLevel(info->keymap->ctx, value, &entry.level)) { if (!ExprResolveLevel(info->ctx, value, &entry.level)) {
log_err(info->keymap->ctx, log_err(info->ctx,
"Level specifications in a key type must be integer; " "Level specifications in a key type must be integer; "
"Ignoring malformed level specification\n"); "Ignoring malformed level specification\n");
return false; return false;
@ -377,7 +379,7 @@ AddPreserve(KeyTypesInfo *info, KeyTypeInfo *type,
/* Map exists with same preserve; do nothing. */ /* Map exists with same preserve; do nothing. */
if (entry->preserve.mods == preserve_mods) { if (entry->preserve.mods == preserve_mods) {
log_vrb(info->keymap->ctx, 10, log_vrb(info->ctx, 10,
"Identical definitions for preserve[%s] in %s; " "Identical definitions for preserve[%s] in %s; "
"Ignored\n", "Ignored\n",
ModMaskText(info->keymap, mods), ModMaskText(info->keymap, mods),
@ -386,7 +388,7 @@ AddPreserve(KeyTypesInfo *info, KeyTypeInfo *type,
} }
/* Map exists with different preserve; latter wins. */ /* Map exists with different preserve; latter wins. */
log_vrb(info->keymap->ctx, 1, log_vrb(info->ctx, 1,
"Multiple definitions for preserve[%s] in %s; " "Multiple definitions for preserve[%s] in %s; "
"Using %s, ignoring %s\n", "Using %s, ignoring %s\n",
ModMaskText(info->keymap, mods), ModMaskText(info->keymap, mods),
@ -430,14 +432,14 @@ SetPreserve(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
mods &= type->mods; mods &= type->mods;
after = ModMaskText(info->keymap, mods); after = ModMaskText(info->keymap, mods);
log_vrb(info->keymap->ctx, 1, log_vrb(info->ctx, 1,
"Preserve for modifiers not used by the %s type; " "Preserve for modifiers not used by the %s type; "
"Index %s converted to %s\n", "Index %s converted to %s\n",
TypeTxt(info, type), before, after); TypeTxt(info, type), before, after);
} }
if (!ExprResolveModMask(info->keymap, value, MOD_BOTH, &preserve_mods)) { if (!ExprResolveModMask(info->keymap, value, MOD_BOTH, &preserve_mods)) {
log_err(info->keymap->ctx, log_err(info->ctx,
"Preserve value in a key type is not a modifier mask; " "Preserve value in a key type is not a modifier mask; "
"Ignoring preserve[%s] in type %s\n", "Ignoring preserve[%s] in type %s\n",
ModMaskText(info->keymap, mods), ModMaskText(info->keymap, mods),
@ -452,7 +454,7 @@ SetPreserve(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
preserve_mods &= mods; preserve_mods &= mods;
after = ModMaskText(info->keymap, preserve_mods); after = ModMaskText(info->keymap, preserve_mods);
log_vrb(info->keymap->ctx, 1, log_vrb(info->ctx, 1,
"Illegal value for preserve[%s] in type %s; " "Illegal value for preserve[%s] in type %s; "
"Converted %s to %s\n", "Converted %s to %s\n",
ModMaskText(info->keymap, mods), ModMaskText(info->keymap, mods),
@ -476,7 +478,7 @@ AddLevelName(KeyTypesInfo *info, KeyTypeInfo *type,
/* Same level, same name. */ /* Same level, same name. */
if (darray_item(type->level_names, level) == name) { if (darray_item(type->level_names, level) == name) {
log_vrb(info->keymap->ctx, 10, log_vrb(info->ctx, 10,
"Duplicate names for level %d of key type %s; Ignored\n", "Duplicate names for level %d of key type %s; Ignored\n",
level + 1, TypeTxt(info, type)); level + 1, TypeTxt(info, type));
return true; return true;
@ -485,10 +487,10 @@ AddLevelName(KeyTypesInfo *info, KeyTypeInfo *type,
/* Same level, different name. */ /* Same level, different name. */
if (darray_item(type->level_names, level) != XKB_ATOM_NONE) { if (darray_item(type->level_names, level) != XKB_ATOM_NONE) {
const char *old, *new; const char *old, *new;
old = xkb_atom_text(info->keymap->ctx, old = xkb_atom_text(info->ctx,
darray_item(type->level_names, level)); darray_item(type->level_names, level));
new = xkb_atom_text(info->keymap->ctx, name); new = xkb_atom_text(info->ctx, name);
log_vrb(info->keymap->ctx, 1, log_vrb(info->ctx, 1,
"Multiple names for level %d of key type %s; " "Multiple names for level %d of key type %s; "
"Using %s, ignoring %s\n", "Using %s, ignoring %s\n",
level + 1, TypeTxt(info, type), level + 1, TypeTxt(info, type),
@ -511,19 +513,18 @@ SetLevelName(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx,
{ {
xkb_level_index_t level; xkb_level_index_t level;
xkb_atom_t level_name; xkb_atom_t level_name;
struct xkb_context *ctx = info->keymap->ctx;
if (arrayNdx == NULL) if (arrayNdx == NULL)
return ReportTypeShouldBeArray(info, type, "level name"); return ReportTypeShouldBeArray(info, type, "level name");
if (!ExprResolveLevel(ctx, arrayNdx, &level)) if (!ExprResolveLevel(info->ctx, arrayNdx, &level))
return ReportTypeBadType(info, type, "level name", "integer"); return ReportTypeBadType(info, type, "level name", "integer");
if (!ExprResolveString(ctx, value, &level_name)) { if (!ExprResolveString(info->ctx, value, &level_name)) {
log_err(info->keymap->ctx, log_err(info->ctx,
"Non-string name for level %d in key type %s; " "Non-string name for level %d in key type %s; "
"Ignoring illegal level name definition\n", "Ignoring illegal level name definition\n",
level + 1, xkb_atom_text(ctx, type->name)); level + 1, xkb_atom_text(info->ctx, type->name));
return false; return false;
} }
@ -555,7 +556,7 @@ SetKeyTypeField(KeyTypesInfo *info, KeyTypeInfo *type,
type_field = TYPE_FIELD_LEVEL_NAME; type_field = TYPE_FIELD_LEVEL_NAME;
ok = SetLevelName(info, type, arrayNdx, value); ok = SetLevelName(info, type, arrayNdx, value);
} else { } else {
log_err(info->keymap->ctx, log_err(info->ctx,
"Unknown field %s in key type %s; Definition ignored\n", "Unknown field %s in key type %s; Definition ignored\n",
field, TypeTxt(info, type)); field, TypeTxt(info, type));
} }
@ -572,13 +573,13 @@ HandleKeyTypeBody(KeyTypesInfo *info, VarDef *def, KeyTypeInfo *type)
ExprDef *arrayNdx; ExprDef *arrayNdx;
for (; def; def = (VarDef *) def->common.next) { for (; def; def = (VarDef *) def->common.next) {
ok = ExprResolveLhs(info->keymap->ctx, def->name, &elem, &field, ok = ExprResolveLhs(info->ctx, def->name, &elem, &field,
&arrayNdx); &arrayNdx);
if (!ok) if (!ok)
continue; continue;
if (elem && istreq(elem, "type")) { if (elem && istreq(elem, "type")) {
log_err(info->keymap->ctx, log_err(info->ctx,
"Support for changing the default type has been removed; " "Support for changing the default type has been removed; "
"Statement ignored\n"); "Statement ignored\n");
continue; continue;
@ -633,7 +634,7 @@ HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge)
ok = HandleKeyTypeDef(info, (KeyTypeDef *) stmt, merge); ok = HandleKeyTypeDef(info, (KeyTypeDef *) stmt, merge);
break; break;
case STMT_VAR: case STMT_VAR:
log_err(info->keymap->ctx, log_err(info->ctx,
"Support for changing the default type has been removed; " "Support for changing the default type has been removed; "
"Statement ignored\n"); "Statement ignored\n");
ok = true; ok = true;
@ -642,7 +643,7 @@ HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge)
ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge); ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge);
break; break;
default: default:
log_err(info->keymap->ctx, log_err(info->ctx,
"Key type files may not include other declarations; " "Key type files may not include other declarations; "
"Ignoring %s\n", stmt_type_to_string(stmt->type)); "Ignoring %s\n", stmt_type_to_string(stmt->type));
ok = false; ok = false;
@ -653,7 +654,7 @@ HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge)
info->errorCount++; info->errorCount++;
if (info->errorCount > 10) { if (info->errorCount > 10) {
log_err(info->keymap->ctx, log_err(info->ctx,
"Abandoning keytypes file \"%s\"\n", file->topName); "Abandoning keytypes file \"%s\"\n", file->topName);
break; break;
} }