2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (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://www.tizenopensource.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 */
21 #include <string.h> /* strdup */
34 Eina_List *cluster_list;
41 Eina_List *category_list;
46 struct cluster *cluster;
47 Eina_List *info_list; /* list of instances of the struct inst_info */
52 struct category *category;
53 Eina_List *context_list; /* context item list */
56 struct context_item_data {
63 struct context_info *info;
64 Eina_List *option_list;
68 struct context_option {
69 struct context_item *item;
74 HAPI struct context_info *group_create_context_info(struct category *category, const char *pkgname)
76 struct context_info *info;
78 info = calloc(1, sizeof(*info));
80 ErrPrint("Heap: %s\n", strerror(errno));
84 info->pkgname = strdup(pkgname);
86 ErrPrint("Heap: %s\n", strerror(errno));
91 info->category = category;
92 category->info_list = eina_list_append(category->info_list, info);
96 static inline void del_options(struct context_item *item)
98 struct context_option *option;
100 EINA_LIST_FREE(item->option_list, option) {
101 DbgFree(option->key);
102 DbgFree(option->value);
107 static inline void del_context_item(struct context_info *info)
109 struct context_item *item;
111 EINA_LIST_FREE(info->context_list, item) {
113 DbgFree(item->ctx_item);
118 HAPI struct context_item *group_add_context_item(struct context_info *info, const char *ctx_item)
120 struct context_item *item;
122 item = calloc(1, sizeof(*item));
124 ErrPrint("Heap: %s\n", strerror(errno));
128 item->ctx_item = strdup(ctx_item);
129 if (!item->ctx_item) {
130 ErrPrint("Heap: %s\n", strerror(errno));
136 info->context_list = eina_list_append(info->context_list, item);
140 HAPI int group_add_option(struct context_item *item, const char *key, const char *value)
142 struct context_option *option;
144 option = calloc(1, sizeof(*option));
146 ErrPrint("Heap: %s\n", strerror(errno));
150 option->key = strdup(key);
152 ErrPrint("Heap: %s\n", strerror(errno));
157 option->value = strdup(value);
158 if (!option->value) {
159 ErrPrint("Heap: %s\n", strerror(errno));
160 DbgFree(option->key);
166 item->option_list = eina_list_append(item->option_list, option);
170 HAPI int group_destroy_context_info(struct context_info *info)
172 struct category *category;
174 category = info->category;
176 ErrPrint("No category found\n");
180 category->info_list = eina_list_remove(category->info_list, info);
182 del_context_item(info);
183 DbgFree(info->pkgname);
188 HAPI struct cluster *group_create_cluster(const char *name)
190 struct cluster *cluster;
192 cluster = malloc(sizeof(*cluster));
194 ErrPrint("Heap: %s\n", strerror(errno));
198 cluster->name = strdup(name);
199 if (!cluster->name) {
200 ErrPrint("Heap: %s\n", strerror(errno));
205 cluster->category_list = NULL;
207 DbgPrint("Cluster %s is created\n", cluster->name);
208 s_info.cluster_list = eina_list_append(s_info.cluster_list, cluster);
212 HAPI struct cluster *group_find_cluster(const char *name)
215 struct cluster *cluster;
217 EINA_LIST_FOREACH(s_info.cluster_list, l, cluster) {
218 if (!strcasecmp(cluster->name, name))
225 HAPI struct category *group_create_category(struct cluster *cluster, const char *name)
227 struct category *category;
229 category = malloc(sizeof(*category));
231 ErrPrint("Heap: %s\n", strerror(errno));
235 category->name = strdup(name);
236 if (!category->name) {
237 ErrPrint("Heap: %s\n", strerror(errno));
242 category->cluster = cluster;
243 category->info_list = NULL;
245 DbgPrint("Category %s is created\n", category->name);
246 cluster->category_list = eina_list_append(cluster->category_list, category);
250 static inline void destroy_cluster(struct cluster *cluster)
252 struct category *category;
256 EINA_LIST_FOREACH_SAFE(cluster->category_list, l, n, category) {
257 group_destroy_category(category);
260 DbgPrint("Destroy cluster: %s\n", cluster->name);
261 DbgFree(cluster->name);
265 HAPI int group_destroy_cluster(struct cluster *cluster)
269 struct cluster *item;
271 EINA_LIST_FOREACH_SAFE(s_info.cluster_list, l, n, item) {
272 if (item == cluster) {
273 s_info.cluster_list = eina_list_remove_list(s_info.cluster_list, l);
274 destroy_cluster(cluster);
282 static inline void destroy_category(struct category *category)
286 struct context_info *info;
288 EINA_LIST_FOREACH_SAFE(category->info_list, l, n, info) {
289 group_destroy_context_info(info);
292 DbgPrint("Destroy category: %s\n", category->name);
293 DbgFree(category->name);
297 HAPI int group_destroy_category(struct category *category)
299 struct cluster *cluster;
301 cluster = category->cluster;
303 cluster->category_list = eina_list_remove(cluster->category_list, category);
305 destroy_category(category);
309 HAPI struct category *group_find_category(struct cluster *cluster, const char *name)
311 struct category *category;
314 EINA_LIST_FOREACH(cluster->category_list, l, category) {
315 if (!strcasecmp(category->name, name))
322 HAPI Eina_List * const group_context_info_list(struct category *category)
324 return category->info_list;
327 HAPI Eina_List *const group_context_item_list(struct context_info *info)
329 return info->context_list;
332 HAPI Eina_List *const group_context_option_list(struct context_item *item)
334 return item->option_list;
337 HAPI Eina_List *const group_cluster_list(void)
339 return s_info.cluster_list;
342 HAPI Eina_List * const group_category_list(struct cluster *cluster)
344 return cluster->category_list;
347 HAPI struct context_info * const group_context_info_from_item(struct context_item *item)
352 HAPI struct category * const group_category_from_context_info(struct context_info *info)
354 return info->category;
357 HAPI const char * const group_pkgname_from_context_info(struct context_info *info)
359 return info->pkgname;
362 HAPI const char * const group_option_item_key(struct context_option *option)
367 HAPI const char * const group_option_item_value(struct context_option *option)
369 return option->value;
372 HAPI const char * const group_context_item(struct context_item *item)
374 return item->ctx_item;
377 HAPI int group_context_item_add_data(struct context_item *item, const char *tag, void *data)
379 struct context_item_data *tmp;
381 tmp = malloc(sizeof(*tmp));
385 tmp->tag = strdup(tag);
392 item->data_list = eina_list_append(item->data_list, tmp);
396 HAPI void *group_context_item_data(struct context_item *item, const char *tag)
398 struct context_item_data *tmp;
401 EINA_LIST_FOREACH(item->data_list, l, tmp) {
402 if (!strcmp(tmp->tag, tag))
409 HAPI void *group_context_item_del_data(struct context_item *item, const char *tag)
411 struct context_item_data *tmp;
416 EINA_LIST_FOREACH_SAFE(item->data_list, l, n, tmp) {
417 if (!strcmp(tmp->tag, tag)) {
418 item->data_list = eina_list_remove(item->data_list, tmp);
429 HAPI const char * const group_category_name(struct category *category)
431 return category->name;
434 HAPI const char * const group_cluster_name(struct cluster *cluster)
436 return cluster->name;
439 HAPI const char *group_cluster_name_by_category(struct category *category)
441 return !category ? NULL : (category->cluster ? category->cluster->name : NULL);
444 static inline char *get_token(char *ptr, int *len)
449 ErrPrint("Start brace but len = 0\n");
453 name = malloc(*len + 1);
455 ErrPrint("Heap: %s\n", strerror(errno));
459 strncpy(name, ptr - *len, *len);
460 name[(*len)--] = '\0';
462 while (isspace(name[(*len)])) {
470 HAPI int group_add_livebox(const char *group, const char *pkgname)
472 struct cluster *cluster;
473 struct category *category;
474 struct context_info *info;
475 struct context_item *item;
487 CONTEXT_OPTION_VALUE,
488 CONTEXT_ERROR = 0xFFFFFFFF,
498 /* Skip the first space characters */
499 while (*ptr && isspace(*ptr)) ptr++;
504 name = get_token(ptr, &len);
506 ErrPrint("Failed to get token\n");
509 /* cluster{category{context{key=value,key=value},context{key=value}}} */
510 /* cluster{category} */
514 cluster = group_find_cluster(name);
516 cluster = group_create_cluster(name);
519 ErrPrint("Failed to get cluster\n");
528 category = group_find_category(cluster, name);
530 category = group_create_category(cluster, name);
533 ErrPrint("Failed to get category\n");
538 info = group_create_context_info(category, pkgname);
540 ErrPrint("Failed to create ctx info\n");
545 state = CONTEXT_ITEM;
549 item = group_add_context_item(info, name);
551 ErrPrint("Failed to create a context item\n");
556 state = CONTEXT_OPTION_KEY;
559 case CONTEXT_OPTION_KEY:
560 case CONTEXT_OPTION_VALUE:
562 ErrPrint("Invalid state\n");
571 while (*ptr && isspace(*ptr)) ptr++;
573 } else if (*ptr == ',') {
574 name = get_token(ptr, &len);
576 ErrPrint("Failed to get token (len:%d)\n", len);
579 while (*ptr && isspace(*ptr)) ptr++;
586 ErrPrint("Invalid state\n");
590 cluster = group_find_cluster(name);
592 cluster = group_create_cluster(name);
595 ErrPrint("Failed to get cluster\n");
605 ErrPrint("Invalid state\n");
609 category = group_find_category(cluster, name);
611 category = group_create_category(cluster, name);
614 ErrPrint("Failed to get category\n");
619 info = group_create_context_info(category, pkgname);
621 ErrPrint("Failed to create ctx info\n");
626 state = CONTEXT_ITEM;
630 category = group_find_category(cluster, name);
632 category = group_create_category(cluster, name);
635 ErrPrint("Failed to get category\n");
640 info = group_create_context_info(category, pkgname);
642 ErrPrint("Failed to create ctx info\n");
646 DbgPrint("Keep this syntax only for the compatibility\n");
647 } else if (is_open == 2) {
648 item = group_add_context_item(info, name);
650 ErrPrint("Failed to create a context item\n");
654 state = CONTEXT_OPTION_KEY;
656 ErrPrint("Invalid state\n");
662 case CONTEXT_OPTION_VALUE:
664 ErrPrint("Invalid state\n");
669 if (group_add_option(item, key, name) < 0)
670 ErrPrint("Failed to add a new option: %s - %s\n", key, name);
675 state = CONTEXT_OPTION_KEY;
677 case CONTEXT_OPTION_KEY:
679 ErrPrint("Invalid state (%s)\n", name);
687 while (*ptr && isspace(*ptr)) ptr++;
689 } else if (*ptr == '=') {
690 if (is_open != 3 || state != CONTEXT_OPTION_KEY) {
691 ErrPrint("Invalid state\n");
695 key = get_token(ptr, &len);
697 ErrPrint("Failed to get token\n");
701 state = CONTEXT_OPTION_VALUE;
704 while (*ptr && isspace(*ptr)) ptr++;
706 } else if (*ptr == '}') {
708 ErrPrint("Invalid state\n");
712 name = get_token(ptr, &len);
714 ErrPrint("Failed to get token, len:%d\n", len);
718 while (*ptr && isspace(*ptr)) ptr++;
724 category = group_find_category(cluster, name);
726 category = group_create_category(cluster, name);
729 ErrPrint("Failed to get category\n");
734 info = group_create_context_info(category, pkgname);
736 ErrPrint("Failed to create ctx info\n");
741 DbgPrint("Keep this syntax only for the compatibility: %s\n", name);
746 category = group_find_category(cluster, name);
748 category = group_create_category(cluster, name);
751 ErrPrint("Failed to get category\n");
756 info = group_create_context_info(category, pkgname);
758 ErrPrint("Failed to create ctx info\n");
763 DbgPrint("Keep this syntax only for the compatibility: %s\n", name);
765 } else if (is_open == 2) {
768 ErrPrint("Invalid state\n");
773 case CONTEXT_OPTION_VALUE:
775 ErrPrint("Invalid state (%s)\n", name);
780 if (group_add_option(item, key, name) < 0)
781 ErrPrint("Failed to add a new option: %s - %s\n", key, name);
786 state = CONTEXT_ITEM;
788 case CONTEXT_OPTION_KEY:
791 ErrPrint("Invalid state (%s)\n", name);
799 while (*ptr && isspace(*ptr)) ptr++;
807 if (state != CLUSTER)
813 HAPI int group_del_livebox(const char *pkgname)
821 struct cluster *cluster;
822 struct category *category;
823 struct context_info *info;
825 EINA_LIST_FOREACH_SAFE(s_info.cluster_list, l, n, cluster) {
826 EINA_LIST_FOREACH_SAFE(cluster->category_list, s_l, s_n, category) {
827 EINA_LIST_FOREACH_SAFE(category->info_list, i_l, i_n, info) {
828 if (!strcmp(pkgname, info->pkgname))
829 group_destroy_context_info(info);
832 if (!category->info_list)
833 group_destroy_category(category);
836 if (!cluster->category_list)
837 group_destroy_cluster(cluster);
843 HAPI int group_init(void)
848 HAPI int group_fini(void)
850 struct cluster *cluster;
851 struct category *category;
853 EINA_LIST_FREE(s_info.cluster_list, cluster) {
855 EINA_LIST_FREE(cluster->category_list, category) {
856 destroy_category(category);
859 destroy_cluster(cluster);