blob: cfe850748604cf438fe974849687b966e0dc155b [file] [log] [blame]
#include "config.h"
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "keymap.h"
#include "kbd.h"
#include "nls.h"
#include "contextP.h"
void __attribute__((format(printf, 6, 7)))
lk_log(struct lk_ctx *ctx, int priority,
const char *file, int line, const char *fn,
const char *fmt, ...)
{
va_list args;
if (ctx->log_fn == NULL)
return;
va_start(args, fmt);
ctx->log_fn(ctx->log_data, priority, file, line, fn, fmt, args);
va_end(args);
}
#ifndef DEBUG
#define log_unused __attribute__((unused))
#else
#define log_unused
#endif
static void __attribute__((format(printf, 6, 0)))
log_file(void *data,
int priority log_unused,
const char *file log_unused,
const int line log_unused,
const char *fn log_unused,
const char *format, va_list args)
{
FILE *fp = data;
#ifdef DEBUG
char buf[16];
const char *priname;
switch (priority) {
case LOG_EMERG:
priname = "EMERGENCY";
break;
case LOG_ALERT:
priname = "ALERT";
break;
case LOG_CRIT:
priname = "CRITICAL";
break;
case LOG_ERR:
priname = "ERROR";
break;
case LOG_WARNING:
priname = "WARNING";
break;
case LOG_NOTICE:
priname = "NOTICE";
break;
case LOG_INFO:
priname = "INFO";
break;
case LOG_DEBUG:
priname = "DEBUG";
break;
default:
snprintf(buf, sizeof(buf), "L:%d", priority);
priname = buf;
}
fprintf(fp, "libkeymap: %s %s:%d %s: ", priname, file, line, fn);
#endif
vfprintf(fp, format, args);
fprintf(fp, "\n");
}
#undef log_unused
int lk_set_log_fn(struct lk_ctx *ctx,
void (*log_fn)(void *data, int priority,
const char *file, int line, const char *fn,
const char *format, va_list args),
const void *data)
{
if (!ctx)
return -1;
ctx->log_fn = log_fn;
ctx->log_data = (void *)data;
return 0;
}
int lk_get_log_priority(struct lk_ctx *ctx)
{
if (!ctx)
return -1;
return ctx->log_priority;
}
int lk_set_log_priority(struct lk_ctx *ctx, int priority)
{
if (!ctx)
return -1;
ctx->log_priority = priority;
return 0;
}
lk_flags
lk_get_parser_flags(struct lk_ctx *ctx)
{
if (!ctx)
return -1;
return ctx->flags;
}
int lk_set_parser_flags(struct lk_ctx *ctx, lk_flags flags)
{
if (!ctx)
return -1;
ctx->flags = flags;
return 0;
}
static int
init_array(struct lk_ctx *ctx, struct lk_array **arr, size_t size)
{
int rc;
void *ptr;
ptr = malloc(sizeof(struct lk_array));
if (!ptr) {
ERR(ctx, _("out of memory"));
return -1;
}
rc = lk_array_init(ptr, size, 0);
if (rc < 0) {
ERR(ctx, _("unable to initialize array: %s"), strerror(rc));
return -1;
}
*arr = ptr;
return 0;
}
struct lk_ctx *
lk_init(void)
{
struct lk_ctx *ctx;
ctx = malloc(sizeof(struct lk_ctx));
if (!ctx)
return NULL;
memset(ctx, 0, sizeof(struct lk_ctx));
lk_set_log_fn(ctx, log_file, stderr);
lk_set_log_priority(ctx, LOG_ERR);
if (init_array(ctx, &ctx->keymap, sizeof(void *)) < 0 ||
init_array(ctx, &ctx->func_table, sizeof(void *)) < 0 ||
init_array(ctx, &ctx->accent_table, sizeof(void *)) < 0 ||
init_array(ctx, &ctx->key_constant, sizeof(char)) < 0 ||
init_array(ctx, &ctx->key_line, sizeof(int)) < 0) {
lk_free(ctx);
return NULL;
}
return ctx;
}
int lk_free(struct lk_ctx *ctx)
{
unsigned int i; //, j;
if (!ctx)
return -1;
if (ctx->keymap) {
for (i = 0; i < ctx->keymap->total; i++) {
struct lk_array *map;
map = lk_array_get_ptr(ctx->keymap, i);
if (!map)
continue;
lk_array_free(map);
free(map);
}
lk_array_free(ctx->keymap);
free(ctx->keymap);
ctx->keymap = NULL;
}
if (ctx->func_table) {
for (i = 0; i < ctx->func_table->total; i++) {
char *ptr;
ptr = lk_array_get_ptr(ctx->func_table, i);
if (!ptr)
continue;
free(ptr);
}
lk_array_free(ctx->func_table);
free(ctx->func_table);
ctx->func_table = NULL;
}
if (ctx->accent_table) {
for (i = 0; i < ctx->accent_table->total; i++) {
struct lk_array *ptr;
ptr = lk_array_get_ptr(ctx->accent_table, i);
if (!ptr)
continue;
free(ptr);
}
lk_array_free(ctx->accent_table);
free(ctx->accent_table);
ctx->accent_table = NULL;
}
if (ctx->key_constant) {
lk_array_free(ctx->key_constant);
free(ctx->key_constant);
ctx->key_constant = NULL;
}
if (ctx->key_line) {
lk_array_free(ctx->key_line);
free(ctx->key_line);
ctx->key_line = NULL;
}
return 0;
}