2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <stdlib.h> /* malloc */
20 #include <string.h> /* strdup */
24 #include <livebox-errno.h>
28 #include "livebox_internal.h"
29 #include "desc_parser.h"
32 #include "critical_log.h"
34 #define TYPE_TEXT "text"
35 #define TYPE_IMAGE "image"
36 #define TYPE_EDJE "edje"
37 #define TYPE_SIGNAL "signal"
38 #define TYPE_INFO "info"
39 #define TYPE_DRAG "drag"
41 #define INFO_SIZE "size"
42 #define INFO_CATEGORY "category"
64 static int update_text(struct livebox *handle, struct block *block, int is_pd)
66 struct livebox_script_operators *ops;
68 if (!block || !block->part || !block->data) {
69 ErrPrint("Invalid argument\n");
70 return LB_STATUS_ERROR_INVALID;
73 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
74 if (ops->update_text) {
75 ops->update_text(handle, (const char *)block->id, (const char *)block->part, (const char *)block->data);
81 static int update_image(struct livebox *handle, struct block *block, int is_pd)
83 struct livebox_script_operators *ops;
84 if (!block || !block->part) {
85 ErrPrint("Invalid argument\n");
86 return LB_STATUS_ERROR_INVALID;
89 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
90 if (ops->update_image) {
91 ops->update_image(handle, block->id, block->part, block->data, block->option);
97 static int update_script(struct livebox *handle, struct block *block, int is_pd)
99 struct livebox_script_operators *ops;
100 if (!block || !block->part) {
101 ErrPrint("Invalid argument\n");
102 return LB_STATUS_ERROR_INVALID;
105 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
106 if (ops->update_script) {
107 ops->update_script(handle, block->id, block->part, block->data, block->option);
113 static int update_signal(struct livebox *handle, struct block *block, int is_pd)
115 struct livebox_script_operators *ops;
118 ErrPrint("Invalid argument\n");
119 return LB_STATUS_ERROR_INVALID;
122 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
123 if (ops->update_signal) {
124 ops->update_signal(handle, block->id, block->data, block->part);
130 static int update_drag(struct livebox *handle, struct block *block, int is_pd)
133 struct livebox_script_operators *ops;
135 if (!block || !block->data || !block->part) {
136 ErrPrint("Invalid argument\n");
137 return LB_STATUS_ERROR_INVALID;
140 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
142 if (sscanf(block->data, "%lfx%lf", &dx, &dy) != 2) {
143 ErrPrint("Invalid format of data\n");
144 return LB_STATUS_ERROR_INVALID;
147 if (ops->update_drag) {
148 ops->update_drag(handle, block->id, block->part, dx, dy);
154 static int update_info(struct livebox *handle, struct block *block, int is_pd)
156 struct livebox_script_operators *ops;
158 if (!block || !block->part || !block->data) {
159 ErrPrint("Invalid argument\n");
160 return LB_STATUS_ERROR_INVALID;
163 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
165 if (!strcasecmp(block->part, INFO_SIZE)) {
168 if (sscanf(block->data, "%dx%d", &w, &h) != 2) {
169 ErrPrint("Invalid format (%s)\n", block->data);
170 return LB_STATUS_ERROR_INVALID;
173 if (ops->update_info_size) {
174 ops->update_info_size(handle, block->id, w, h);
176 } else if (!strcasecmp(block->part, INFO_CATEGORY)) {
177 if (ops->update_info_category) {
178 ops->update_info_category(handle, block->id, block->data);
185 static inline int update_begin(struct livebox *handle, int is_pd)
187 struct livebox_script_operators *ops;
189 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
191 if (ops->update_begin) {
192 ops->update_begin(handle);
198 static inline int update_end(struct livebox *handle, int is_pd)
200 struct livebox_script_operators *ops;
202 ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
204 if (ops->update_end) {
205 ops->update_end(handle);
211 int parse_desc(struct livebox *handle, const char *descfile, int is_pd)
229 const char *field_name[] = {
239 register int field_idx;
240 register int idx = 0;
245 int (*handler)(struct livebox *handle, struct block *block, int is_pd);
249 .handler = update_text,
253 .handler = update_image,
257 .handler = update_script,
261 .handler = update_signal,
265 .handler = update_drag,
269 .handler = update_info,
277 fp = fopen(descfile, "rt");
279 ErrPrint("Error: %s\n", strerror(errno));
280 return LB_STATUS_ERROR_IO;
283 update_begin(handle, is_pd);
300 update_end(handle, is_pd);
301 if (fclose(fp) != 0) {
302 ErrPrint("fclose: %s\n", strerror(errno));
304 return LB_STATUS_ERROR_INVALID;
317 block = calloc(1, sizeof(*block));
319 CRITICAL_LOG("Heap: %s\n", strerror(errno));
320 update_end(handle, is_pd);
321 if (fclose(fp) != 0) {
322 ErrPrint("fclose: %s\n", strerror(errno));
324 return LB_STATUS_ERROR_MEMORY;
343 if (field_name[field_idx][idx] != '\0') {
385 state = VALUE_OPTION;
388 block->option = NULL;
389 block->option_len = 0;
413 if (field_name[field_idx][idx] != ch) {
414 if (ungetc(ch, fp) != ch) {
415 ErrPrint("ungetc: %s\n", strerror(errno));
419 if (ungetc(field_name[field_idx][idx], fp) != field_name[field_idx][idx]) {
420 ErrPrint("ungetc: %s\n", strerror(errno));
425 if (field_name[field_idx] == NULL) {
437 if (idx == block->type_len) {
438 block->type_len += 256;
439 block->type = realloc(block->type, block->type_len);
441 CRITICAL_LOG("Heap: %s\n", strerror(errno));
447 block->type[idx] = '\0';
454 block->type[idx] = ch;
459 if (idx == block->part_len) {
460 block->part_len += 256;
461 block->part = realloc(block->part, block->part_len);
463 CRITICAL_LOG("Heap: %s\n", strerror(errno));
469 block->part[idx] = '\0';
476 block->part[idx] = ch;
481 if (idx == block->data_len) {
482 block->data_len += 256;
483 block->data = realloc(block->data, block->data_len);
485 CRITICAL_LOG("Heap: %s\n", strerror(errno));
491 block->data[idx] = '\0';
498 block->data[idx] = ch;
503 if (idx == block->file_len) {
504 block->file_len += 256;
505 block->file = realloc(block->file, block->file_len);
507 CRITICAL_LOG("Heap: %s\n", strerror(errno));
513 block->file[idx] = '\0';
520 block->file[idx] = ch;
525 if (idx == block->option_len) {
526 block->option_len += 256;
527 block->option = realloc(block->option, block->option_len);
528 if (!block->option) {
529 CRITICAL_LOG("Heap: %s\n", strerror(errno));
535 block->option[idx] = '\0';
542 block->option[idx] = ch;
546 if (idx == block->id_len) {
547 block->id_len += 256;
548 block->id = realloc(block->id, block->id_len);
550 CRITICAL_LOG("Heap: %s\n", strerror(errno));
556 block->id[idx] = '\0';
568 block->file = strdup(util_uri_to_path(handle->id));
575 while (handlers[i].type) {
576 if (!strcasecmp(handlers[i].type, block->type)) {
577 handlers[i].handler(handle, block, is_pd);
583 if (!handlers[i].type) {
584 ErrPrint("Unknown block type: %s\n", block->type);
604 if (state != UNKNOWN) {
608 update_end(handle, is_pd);
610 if (fclose(fp) != 0) {
611 ErrPrint("fclose: %s\n", strerror(errno));
616 ErrPrint("Parse error\n");
627 update_end(handle, is_pd);
629 if (fclose(fp) != 0) {
630 ErrPrint("fclose: %s\n", strerror(errno));
632 return LB_STATUS_ERROR_INVALID;