Imported Upstream version 2.0.90
[platform/upstream/kbd.git] / src / libkeymap / common.c
1 #include "config.h"
2
3 #include <string.h>
4 #include <stdlib.h>
5 #include <stdarg.h>
6
7 #include "keymap.h"
8
9 #include "libcommon.h"
10 #include "contextP.h"
11
12 void
13 lk_log(struct lk_ctx *ctx, int priority,
14        const char *file, int line, const char *fn,
15        const char *fmt, ...)
16 {
17         va_list args;
18         if (ctx->log_fn == NULL)
19                 return;
20         va_start(args, fmt);
21         ctx->log_fn(ctx->log_data, priority, file, line, fn, fmt, args);
22         va_end(args);
23 }
24
25 #ifndef DEBUG
26 #define log_unused __attribute__((unused))
27 #else
28 #define log_unused
29 #endif
30
31 static void __attribute__((format(printf, 6, 0)))
32 log_file(void *data,
33          int priority log_unused,
34          const char *file log_unused,
35          const int line log_unused,
36          const char *fn log_unused,
37          const char *format, va_list args)
38 {
39         FILE *fp = data;
40 #ifdef DEBUG
41         char buf[16];
42         const char *priname;
43
44         switch (priority) {
45                 case LOG_EMERG:
46                         priname = "EMERGENCY";
47                         break;
48                 case LOG_ALERT:
49                         priname = "ALERT";
50                         break;
51                 case LOG_CRIT:
52                         priname = "CRITICAL";
53                         break;
54                 case LOG_ERR:
55                         priname = "ERROR";
56                         break;
57                 case LOG_WARNING:
58                         priname = "WARNING";
59                         break;
60                 case LOG_NOTICE:
61                         priname = "NOTICE";
62                         break;
63                 case LOG_INFO:
64                         priname = "INFO";
65                         break;
66                 case LOG_DEBUG:
67                         priname = "DEBUG";
68                         break;
69                 default:
70                         snprintf(buf, sizeof(buf), "L:%d", priority);
71                         priname = buf;
72         }
73         fprintf(fp, "libkeymap: %s %s:%d %s: ", priname, file, line, fn);
74 #endif
75         vfprintf(fp, format, args);
76         fprintf(fp, "\n");
77 }
78
79 #undef log_unused
80
81 int lk_set_log_fn(struct lk_ctx *ctx, lk_logger_t log_fn, const void *data)
82 {
83         if (!ctx)
84                 return -1;
85
86         ctx->log_fn   = log_fn;
87         ctx->log_data = (void *)data;
88
89         return 0;
90 }
91
92 int lk_get_log_priority(struct lk_ctx *ctx)
93 {
94         if (!ctx)
95                 return -1;
96
97         return ctx->log_priority;
98 }
99
100 int lk_set_log_priority(struct lk_ctx *ctx, int priority)
101 {
102         if (!ctx)
103                 return -1;
104
105         ctx->log_priority = priority;
106         return 0;
107 }
108
109 lk_flags
110 lk_get_parser_flags(struct lk_ctx *ctx)
111 {
112         if (!ctx)
113                 return -1;
114
115         return ctx->flags;
116 }
117
118 int lk_set_parser_flags(struct lk_ctx *ctx, lk_flags flags)
119 {
120         if (!ctx)
121                 return -1;
122
123         ctx->flags = flags;
124         return 0;
125 }
126
127 static int
128 init_array(struct lk_ctx *ctx, struct lk_array **arr, ssize_t size)
129 {
130         int rc;
131         void *ptr;
132
133         ptr = malloc(sizeof(struct lk_array));
134         if (!ptr) {
135                 ERR(ctx, _("out of memory"));
136                 return -1;
137         }
138
139         rc = lk_array_init(ptr, size, 0);
140         if (rc < 0) {
141                 ERR(ctx, _("unable to initialize array: %s"), strerror(rc));
142                 return -1;
143         }
144
145         *arr = ptr;
146
147         return 0;
148 }
149
150 struct lk_ctx *
151 lk_init(void)
152 {
153         struct lk_ctx *ctx;
154
155         ctx = malloc(sizeof(struct lk_ctx));
156         if (!ctx)
157                 return NULL;
158
159         memset(ctx, 0, sizeof(struct lk_ctx));
160
161         lk_set_log_fn(ctx, log_file, stderr);
162         lk_set_log_priority(ctx, LOG_ERR);
163
164         if (init_array(ctx, &ctx->keymap, sizeof(void *)) < 0 ||
165             init_array(ctx, &ctx->func_table, sizeof(void *)) < 0 ||
166             init_array(ctx, &ctx->accent_table, sizeof(void *)) < 0 ||
167             init_array(ctx, &ctx->key_constant, sizeof(char)) < 0 ||
168             init_array(ctx, &ctx->key_line, sizeof(int)) < 0) {
169                 lk_free(ctx);
170                 return NULL;
171         }
172
173         ctx->kbdfile_ctx = kbdfile_context_new();
174
175         if (ctx->kbdfile_ctx == NULL) {
176                 lk_free(ctx);
177                 return NULL;
178         }
179
180         return ctx;
181 }
182
183 int lk_free(struct lk_ctx *ctx)
184 {
185         unsigned int i; //, j;
186
187         if (!ctx)
188                 return -1;
189
190         if (ctx->keymap) {
191                 for (i = 0; i < ctx->keymap->total; i++) {
192                         struct lk_array *map;
193
194                         map = lk_array_get_ptr(ctx->keymap, i);
195                         if (!map)
196                                 continue;
197
198                         lk_array_free(map);
199                         free(map);
200                 }
201                 lk_array_free(ctx->keymap);
202                 free(ctx->keymap);
203
204                 ctx->keymap = NULL;
205         }
206
207         if (ctx->func_table) {
208                 for (i = 0; i < ctx->func_table->total; i++) {
209                         char *ptr;
210
211                         ptr = lk_array_get_ptr(ctx->func_table, i);
212                         if (!ptr)
213                                 continue;
214
215                         free(ptr);
216                 }
217                 lk_array_free(ctx->func_table);
218                 free(ctx->func_table);
219
220                 ctx->func_table = NULL;
221         }
222
223         if (ctx->accent_table) {
224                 for (i = 0; i < ctx->accent_table->total; i++) {
225                         struct lk_array *ptr;
226
227                         ptr = lk_array_get_ptr(ctx->accent_table, i);
228                         if (!ptr)
229                                 continue;
230
231                         free(ptr);
232                 }
233                 lk_array_free(ctx->accent_table);
234                 free(ctx->accent_table);
235
236                 ctx->accent_table = NULL;
237         }
238
239         if (ctx->key_constant) {
240                 lk_array_free(ctx->key_constant);
241                 free(ctx->key_constant);
242                 ctx->key_constant = NULL;
243         }
244
245         if (ctx->key_line) {
246                 lk_array_free(ctx->key_line);
247                 free(ctx->key_line);
248                 ctx->key_line = NULL;
249         }
250
251         if (ctx->kbdfile_ctx != NULL)
252                 ctx->kbdfile_ctx = kbdfile_context_free(ctx->kbdfile_ctx);
253
254         free(ctx);
255
256         return 0;
257 }