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 */
23 #include <sys/types.h>
29 #include <dynamicbox_errno.h>
30 #include <dynamicbox_service.h>
31 #include <dynamicbox_buffer.h>
34 #include "dynamicbox.h"
35 #include "dynamicbox_internal.h"
36 #include "desc_parser.h"
40 #define INFO_SIZE "size"
41 #define INFO_CATEGORY "category"
43 static const char *type_list[] = {
56 static const char *field_list[] = {
99 /* Should be released */
101 const char *filename;
104 static int update_text(dynamicbox_h handle, struct block *block, int is_gbar)
106 struct dynamicbox_script_operators *ops;
108 if (!block || !block->part || !block->data) {
109 ErrPrint("Invalid argument\n");
110 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
113 ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops;
114 if (ops->update_text) {
115 ops->update_text(handle, (const char *)block->id, (const char *)block->part, (const char *)block->data);
121 static int update_image(dynamicbox_h handle, struct block *block, int is_gbar)
123 struct dynamicbox_script_operators *ops;
125 if (!block || !block->part) {
126 ErrPrint("Invalid argument\n");
127 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
130 ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops;
131 if (ops->update_image) {
132 ops->update_image(handle, block->id, block->part, block->data, block->option);
138 static int update_script(dynamicbox_h handle, struct block *block, int is_gbar)
140 struct dynamicbox_script_operators *ops;
142 if (!block || !block->part) {
143 ErrPrint("Invalid argument\n");
144 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
147 ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops;
148 if (ops->update_script) {
149 ops->update_script(handle, block->id, block->target, block->part, block->data, block->option);
155 static int update_signal(dynamicbox_h handle, struct block *block, int is_gbar)
157 struct dynamicbox_script_operators *ops;
160 ErrPrint("Invalid argument\n");
161 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
164 ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops;
165 if (ops->update_signal) {
166 ops->update_signal(handle, block->id, block->data, block->part);
172 static int update_drag(dynamicbox_h handle, struct block *block, int is_gbar)
175 struct dynamicbox_script_operators *ops;
177 if (!block || !block->data || !block->part) {
178 ErrPrint("Invalid argument\n");
179 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
182 if (sscanf(block->data, "%lfx%lf", &dx, &dy) != 2) {
183 ErrPrint("Invalid format of data\n");
184 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
187 ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops;
188 if (ops->update_drag) {
189 ops->update_drag(handle, block->id, block->part, dx, dy);
195 static int update_info(dynamicbox_h handle, struct block *block, int is_gbar)
197 struct dynamicbox_script_operators *ops;
199 if (!block || !block->part || !block->data) {
200 ErrPrint("Invalid argument\n");
201 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
204 ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops;
205 if (!strcasecmp(block->part, INFO_SIZE)) {
208 if (sscanf(block->data, "%dx%d", &w, &h) != 2) {
209 ErrPrint("Invalid format (%s)\n", block->data);
210 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
213 if (ops->update_info_size) {
214 ops->update_info_size(handle, block->id, w, h);
216 } else if (!strcasecmp(block->part, INFO_CATEGORY)) {
217 if (ops->update_info_category) {
218 ops->update_info_category(handle, block->id, block->data);
225 static int update_access(dynamicbox_h handle, struct block *block, int is_gbar)
227 struct dynamicbox_script_operators *ops;
230 ErrPrint("Invalid argument\n");
231 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
234 ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops;
235 if (ops->update_access) {
236 ops->update_access(handle, block->id, block->part, block->data, block->option);
242 static int operate_access(dynamicbox_h handle, struct block *block, int is_gbar)
244 struct dynamicbox_script_operators *ops;
247 ErrPrint("Invalid argument\n");
248 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
251 ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops;
252 if (ops->operate_access) {
253 ops->operate_access(handle, block->id, block->part, block->data, block->option);
259 static int update_color(dynamicbox_h handle, struct block *block, int is_gbar)
261 struct dynamicbox_script_operators *ops;
264 ErrPrint("Invalid argument\n");
265 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
268 ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops;
269 if (ops->update_color) {
270 ops->update_color(handle, block->id, block->part, block->data);
276 static inline int update_begin(dynamicbox_h handle, int is_gbar)
278 struct dynamicbox_script_operators *ops;
280 ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops;
281 if (ops->update_begin) {
282 ops->update_begin(handle);
288 static inline int update_end(dynamicbox_h handle, int is_gbar)
290 struct dynamicbox_script_operators *ops;
292 ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops;
293 if (ops->update_end) {
294 ops->update_end(handle);
300 static inline void delete_block(struct block *block)
302 free(block->filebuf);
306 static inline void consuming_parsed_block(dynamicbox_h handle, int is_gbar, struct block *block)
308 typedef int (*update_function_t)(dynamicbox_h handle, struct block *block, int is_gbar);
309 static update_function_t updators[] = {
322 if (block->type >= 0 || block->type < TYPE_MAX) {
323 (void)updators[block->type](handle, block, is_gbar);
325 ErrPrint("Block type[%d] is not valid\n", block->type);
329 static inline char *load_file(const char *filename)
331 char *filebuf = NULL;
337 fd = open(filename, O_RDONLY);
339 ErrPrint("open: %s (%s)\n", strerror(errno), filename);
343 filesize = lseek(fd, 0L, SEEK_END);
344 if (filesize == (off_t)-1) {
345 ErrPrint("lseek: %s\n", strerror(errno));
349 if (lseek(fd, 0L, SEEK_SET) < 0) {
350 ErrPrint("lseek: %s\n", strerror(errno));
354 filebuf = malloc(filesize + 1);
356 ErrPrint("malloc: %s\n", strerror(errno));
360 while (readsize < filesize) {
361 ret = read(fd, filebuf + readsize, (size_t)filesize - readsize);
363 if (errno == EINTR) {
364 DbgPrint("Read is interrupted\n");
368 ErrPrint("read: %s\n", strerror(errno));
378 filebuf[readsize] = '\0';
383 * Now, we are ready to parse the filebuf.
388 ErrPrint("close: %s\n", strerror(errno));
394 int parse_desc(struct dynamicbox_common *common, const char *filename, int is_gbar)
403 struct block *block = NULL;
404 struct dlist *block_list = NULL;
407 struct dlist *handle_iterator;
408 dynamicbox_h handler;
418 filebuf = load_file(filename);
420 return DBOX_STATUS_ERROR_IO_ERROR;
426 while (*fileptr && state != ERROR) {
429 if (*fileptr == '{') {
430 block = calloc(1, sizeof(*block));
432 ErrPrint("calloc: %s\n", strerror(errno));
441 if (isspace(*fileptr)) {
445 } else if (*fileptr == '=') {
449 } else if (ptr == NULL) {
454 while (field_list[field_idx]) {
455 if (field_list[field_idx][field_len] == *fileptr) {
461 if (!field_list[field_idx]) {
462 ErrPrint("Invalid field\n");
469 if (field_list[field_idx][field_len] != *fileptr) {
471 while (field_list[field_idx]) {
472 if (!strncmp(field_list[field_idx], fileptr - field_len, field_len)) {
479 if (!field_list[field_idx]) {
481 ErrPrint("field is not valid\n");
493 if (isspace(*fileptr)) {
497 if (*fileptr == '\0') {
499 ErrPrint("Type is not valid\n");
508 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
512 if (type_list[type_idx][type_len] != *fileptr) {
514 while (type_list[type_idx]) {
515 if (!strncmp(type_list[type_idx], fileptr - type_len, type_len)) {
522 if (!type_list[type_idx]) {
524 ErrPrint("type is not valid (%s)\n", fileptr - type_len);
530 block->type = type_idx;
542 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
557 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
572 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
587 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
602 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
617 if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
632 if (isspace(*fileptr)) {
633 } else if (*fileptr == '}') {
635 block->filename = filename;
636 block_list = dlist_append(block_list, block);
651 if (state != BEGIN) {
654 ErrPrint("State %d\n", state);
659 dlist_foreach_safe(block_list, l, n, block) {
661 block_list = dlist_remove(block_list, l);
664 return DBOX_STATUS_ERROR_FAULT;
668 block = dlist_data(dlist_prev(block_list));
670 block->filebuf = filebuf;
672 ErrPrint("Last block is not exists (There is no parsed block)\n");
676 ErrPrint("Begin: Set content for object\n");
677 dlist_foreach(common->dynamicbox_list, l, handler) {
678 update_begin(handler, is_gbar);
681 dlist_foreach_safe(block_list, l, n, block) {
682 dlist_foreach(common->dynamicbox_list, handle_iterator, handler) {
683 consuming_parsed_block(handler, is_gbar, block);
686 block_list = dlist_remove(block_list, l);
690 dlist_foreach(common->dynamicbox_list, l, handler) {
691 update_end(handler, is_gbar);
693 ErrPrint("End: Set content for object\n");
695 return DBOX_STATUS_ERROR_NONE;