*
********************************************************/
+#include "config.h"
+
#include "xkbcomp-priv.h"
#include "text.h"
#include "vmod.h"
#include "include.h"
enum type_field {
- TYPE_FIELD_MASK = (1 << 0),
- TYPE_FIELD_MAP = (1 << 1),
- TYPE_FIELD_PRESERVE = (1 << 2),
+ TYPE_FIELD_MASK = (1 << 0),
+ TYPE_FIELD_MAP = (1 << 1),
+ TYPE_FIELD_PRESERVE = (1 << 2),
TYPE_FIELD_LEVEL_NAME = (1 << 3),
};
}
static inline bool
-ReportTypeBadType(KeyTypesInfo *info, KeyTypeInfo *type,
- const char *field, const char *wanted)
+ReportTypeBadType(KeyTypesInfo *info, xkb_message_code_t code,
+ KeyTypeInfo *type, const char *field, const char *wanted)
{
- return ReportBadType(info->ctx, "key type", field,
+ return ReportBadType(info->ctx, code, "key type", field,
TypeTxt(info, type), wanted);
}
{
memset(info, 0, sizeof(*info));
info->ctx = ctx;
- CopyModSet(&info->mods, mods);
+ info->mods = *mods;
}
static void
ClearKeyTypesInfo(KeyTypesInfo *info)
{
free(info->name);
- ClearModSet(&info->mods);
darray_free(info->types);
}
if (new->merge == MERGE_REPLACE || new->merge == MERGE_OVERRIDE) {
if ((same_file && verbosity > 0) || verbosity > 9) {
log_warn(info->ctx,
+ XKB_WARNING_CONFLICTING_KEY_TYPE_DEFINITIONS,
"Multiple definitions of the %s key type; "
"Earlier definition ignored\n",
xkb_atom_text(info->ctx, new->name));
if (same_file)
log_vrb(info->ctx, 4,
+ XKB_WARNING_CONFLICTING_KEY_TYPE_DEFINITIONS,
"Multiple definitions of the %s key type; "
"Later definition ignored\n",
xkb_atom_text(info->ctx, new->name));
MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
enum merge_mode merge)
{
- KeyTypeInfo *type;
-
if (from->errorCount > 0) {
into->errorCount += from->errorCount;
return;
}
- MoveModSet(&into->mods, &from->mods);
+ into->mods = from->mods;
if (into->name == NULL) {
into->name = from->name;
darray_init(from->types);
}
else {
+ KeyTypeInfo *type;
darray_foreach(type, from->types) {
type->merge = (merge == MERGE_DEFAULT ? type->merge : merge);
if (!AddKeyType(into, type, false))
xkb_mod_mask_t mods;
if (arrayNdx)
- log_warn(info->ctx,
+ log_warn(info->ctx, XKB_LOG_MESSAGE_NO_ID,
"The modifiers field of a key type is not an array; "
"Illegal array subscript ignored\n");
if (!ExprResolveModMask(info->ctx, value, MOD_BOTH, &info->mods, &mods)) {
log_err(info->ctx,
+ XKB_ERROR_UNSUPPORTED_MODIFIER_MASK,
"Key type mask field must be a modifier mask; "
"Key type definition ignored\n");
return false;
}
if (type->defined & TYPE_FIELD_MASK) {
- log_warn(info->ctx,
+ log_warn(info->ctx, XKB_LOG_MESSAGE_NO_ID,
"Multiple modifier mask definitions for key type %s; "
"Using %s, ignoring %s\n",
xkb_atom_text(info->ctx, type->name),
if (old) {
if (report && old->level != new->level) {
log_warn(info->ctx,
+ XKB_WARNING_CONFLICTING_KEY_TYPE_MAP_ENTRY,
"Multiple map entries for %s in %s; "
"Using %d, ignoring %d\n",
MapEntryTxt(info, new), TypeTxt(info, type),
}
else {
log_vrb(info->ctx, 10,
+ XKB_WARNING_CONFLICTING_KEY_TYPE_MAP_ENTRY,
"Multiple occurrences of map[%s]= %d in %s; Ignored\n",
MapEntryTxt(info, new), new->level + 1,
TypeTxt(info, type));
if (!ExprResolveModMask(info->ctx, arrayNdx, MOD_BOTH, &info->mods,
&entry.mods.mods))
- return ReportTypeBadType(info, type, "map entry", "modifier mask");
+ return ReportTypeBadType(info, XKB_ERROR_UNSUPPORTED_MODIFIER_MASK,
+ type, "map entry", "modifier mask");
if (entry.mods.mods & (~type->mods)) {
log_vrb(info->ctx, 1,
- "Map entry for unused modifiers in %s; "
+ XKB_WARNING_UNDECLARED_MODIFIERS_IN_KEY_TYPE,
+ "Map entry for modifiers not used by type %s; "
"Using %s instead of %s\n",
TypeTxt(info, type),
ModMaskText(info->ctx, &info->mods,
}
if (!ExprResolveLevel(info->ctx, value, &entry.level)) {
- log_err(info->ctx,
- "Level specifications in a key type must be integer; "
- "Ignoring malformed level specification\n");
+ log_err(info->ctx, XKB_ERROR_UNSUPPORTED_SHIFT_LEVEL,
+ "Level specifications in a key type must be integer; "
+ "Ignoring malformed level specification\n");
return false;
}
/* Map exists with same preserve; do nothing. */
if (entry->preserve.mods == preserve_mods) {
log_vrb(info->ctx, 10,
+ XKB_WARNING_DUPLICATE_ENTRY,
"Identical definitions for preserve[%s] in %s; "
"Ignored\n",
ModMaskText(info->ctx, &info->mods, mods),
/* Map exists with different preserve; latter wins. */
log_vrb(info->ctx, 1,
+ XKB_WARNING_CONFLICTING_KEY_TYPE_PRESERVE_ENTRIES,
"Multiple definitions for preserve[%s] in %s; "
"Using %s, ignoring %s\n",
ModMaskText(info->ctx, &info->mods, mods),
return ReportTypeShouldBeArray(info, type, "preserve entry");
if (!ExprResolveModMask(info->ctx, arrayNdx, MOD_BOTH, &info->mods, &mods))
- return ReportTypeBadType(info, type, "preserve entry",
- "modifier mask");
+ return ReportTypeBadType(info, XKB_ERROR_UNSUPPORTED_MODIFIER_MASK,
+ type, "preserve entry", "modifier mask");
if (mods & ~type->mods) {
const char *before, *after;
after = ModMaskText(info->ctx, &info->mods, mods);
log_vrb(info->ctx, 1,
- "Preserve for modifiers not used by the %s type; "
+ XKB_WARNING_UNDECLARED_MODIFIERS_IN_KEY_TYPE,
+ "Preserve entry for modifiers not used by the %s type; "
"Index %s converted to %s\n",
TypeTxt(info, type), before, after);
}
if (!ExprResolveModMask(info->ctx, value, MOD_BOTH, &info->mods,
&preserve_mods)) {
log_err(info->ctx,
+ XKB_ERROR_UNSUPPORTED_MODIFIER_MASK,
"Preserve value in a key type is not a modifier mask; "
"Ignoring preserve[%s] in type %s\n",
ModMaskText(info->ctx, &info->mods, mods),
after = ModMaskText(info->ctx, &info->mods, preserve_mods);
log_vrb(info->ctx, 1,
+ XKB_WARNING_ILLEGAL_KEY_TYPE_PRESERVE_RESULT,
"Illegal value for preserve[%s] in type %s; "
"Converted %s to %s\n",
ModMaskText(info->ctx, &info->mods, mods),
/* Same level, same name. */
if (darray_item(type->level_names, level) == name) {
log_vrb(info->ctx, 10,
+ XKB_WARNING_DUPLICATE_ENTRY,
"Duplicate names for level %d of key type %s; Ignored\n",
level + 1, TypeTxt(info, type));
return true;
darray_item(type->level_names, level));
new = xkb_atom_text(info->ctx, name);
log_vrb(info->ctx, 1,
+ XKB_WARNING_CONFLICTING_KEY_TYPE_LEVEL_NAMES,
"Multiple names for level %d of key type %s; "
"Using %s, ignoring %s\n",
level + 1, TypeTxt(info, type),
return ReportTypeShouldBeArray(info, type, "level name");
if (!ExprResolveLevel(info->ctx, arrayNdx, &level))
- return ReportTypeBadType(info, type, "level name", "integer");
+ return ReportTypeBadType(info, XKB_ERROR_UNSUPPORTED_SHIFT_LEVEL,
+ type, "level name", "integer");
if (!ExprResolveString(info->ctx, value, &level_name)) {
log_err(info->ctx,
+ XKB_ERROR_WRONG_FIELD_TYPE,
"Non-string name for level %d in key type %s; "
"Ignoring illegal level name definition\n",
level + 1, xkb_atom_text(info->ctx, type->name));
ok = SetLevelName(info, type, arrayNdx, value);
} else {
log_err(info->ctx,
+ XKB_ERROR_UNKNOWN_FIELD,
"Unknown field %s in key type %s; Definition ignored\n",
field, TypeTxt(info, type));
}
if (elem && istreq(elem, "type")) {
log_err(info->ctx,
+ XKB_ERROR_INVALID_SET_DEFAULT_STATEMENT,
"Support for changing the default type has been removed; "
"Statement ignored\n");
continue;
break;
case STMT_VAR:
log_err(info->ctx,
+ XKB_ERROR_WRONG_STATEMENT_TYPE,
"Support for changing the default type has been removed; "
"Statement ignored\n");
ok = true;
break;
default:
log_err(info->ctx,
+ XKB_ERROR_WRONG_STATEMENT_TYPE,
"Key type files may not include other declarations; "
"Ignoring %s\n", stmt_type_to_string(stmt->type));
ok = false;
if (info->errorCount > 10) {
log_err(info->ctx,
- "Abandoning keytypes file \"%s\"\n", file->topName);
+ XKB_ERROR_INVALID_SYNTAX,
+ "Abandoning keytypes file \"%s\"\n", file->name);
break;
}
}
static bool
CopyKeyTypesToKeymap(struct xkb_keymap *keymap, KeyTypesInfo *info)
{
- keymap->types_section_name = strdup_safe(info->name);
- XkbEscapeMapName(keymap->types_section_name);
-
- MoveModSet(&keymap->mods, &info->mods);
+ unsigned num_types;
+ struct xkb_key_type *types;
- keymap->num_types = darray_size(info->types);
- if (keymap->num_types == 0)
- keymap->num_types = 1;
-
- keymap->types = calloc(keymap->num_types, sizeof(*keymap->types));
+ num_types = darray_empty(info->types) ? 1 : darray_size(info->types);
+ types = calloc(num_types, sizeof(*types));
+ if (!types)
+ return false;
/*
* If no types were specified, a default unnamed one-level type is
* used for all keys.
*/
if (darray_empty(info->types)) {
- struct xkb_key_type *type = &keymap->types[0];
+ struct xkb_key_type *type = &types[0];
type->mods.mods = 0;
type->num_levels = 1;
type->num_entries = 0;
type->name = xkb_atom_intern_literal(keymap->ctx, "default");
type->level_names = NULL;
-
- return true;
+ type->num_level_names = 0;
}
-
- for (unsigned i = 0; i < keymap->num_types; i++) {
- KeyTypeInfo *def = &darray_item(info->types, i);
- struct xkb_key_type *type = &keymap->types[i];
-
- type->mods.mods = def->mods;
- type->num_levels = def->num_levels;
- type->entries = darray_mem(def->entries, 0);
- type->num_entries = darray_size(def->entries);
- darray_init(def->entries);
- type->name = def->name;
- type->level_names = darray_mem(def->level_names, 0);
- darray_init(def->level_names);
+ else {
+ for (unsigned i = 0; i < num_types; i++) {
+ KeyTypeInfo *def = &darray_item(info->types, i);
+ struct xkb_key_type *type = &types[i];
+
+ type->name = def->name;
+ type->mods.mods = def->mods;
+ type->num_levels = def->num_levels;
+ darray_steal(def->level_names, &type->level_names, &type->num_level_names);
+ darray_steal(def->entries, &type->entries, &type->num_entries);
+ }
}
+ keymap->types_section_name = strdup_safe(info->name);
+ XkbEscapeMapName(keymap->types_section_name);
+ keymap->num_types = num_types;
+ keymap->types = types;
+ keymap->mods = info->mods;
return true;
}