1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4 
5 #include <Ecore.h>
6 #include <ctype.h>
7 
8 #include "ecore_private.h"
9 
10 #define MY_CLASS EFL_CORE_ENV_CLASS
11 
12 typedef struct {
13    Eina_Hash *env;
14 } Efl_Core_Env_Data;
15 
16 static inline Eina_Bool
str_valid(const char * var)17 str_valid(const char *var)
18 {
19    return var && var[0] != '\0';
20 }
21 
22 static inline Eina_Bool
key_valid(const char * key)23 key_valid(const char *key)
24 {
25    if (!key || key[0] == '\0') return EINA_FALSE;
26 
27    if (isdigit(key[0])) return EINA_FALSE;
28 
29    for (int i = 0; key[i] != '\0'; ++i) {
30      if (!isalnum(key[i]) && key[i] != '_') return EINA_FALSE;
31    }
32 
33    return EINA_TRUE;
34 }
35 
36 EOLIAN static void
_efl_core_env_env_set(Eo * obj EINA_UNUSED,Efl_Core_Env_Data * pd,const char * var,const char * value)37 _efl_core_env_env_set(Eo *obj EINA_UNUSED, Efl_Core_Env_Data *pd, const char *var, const char *value)
38 {
39    EINA_SAFETY_ON_FALSE_RETURN(key_valid(var));
40    if (str_valid(value))
41      {
42         Eina_Stringshare *share;
43         share = eina_hash_set(pd->env, var, eina_stringshare_add(value));
44         if (share) eina_stringshare_del(share);
45      }
46    else
47      eina_hash_del(pd->env, var, NULL);
48 }
49 
50 EOLIAN static const char*
_efl_core_env_env_get(const Eo * obj EINA_UNUSED,Efl_Core_Env_Data * pd,const char * var)51 _efl_core_env_env_get(const Eo *obj EINA_UNUSED, Efl_Core_Env_Data *pd, const char *var)
52 {
53    EINA_SAFETY_ON_FALSE_RETURN_VAL(key_valid(var), NULL);
54 
55    return eina_hash_find(pd->env, var);
56 }
57 
58 EOLIAN static void
_efl_core_env_unset(Eo * obj EINA_UNUSED,Efl_Core_Env_Data * pd,const char * var)59 _efl_core_env_unset(Eo *obj EINA_UNUSED, Efl_Core_Env_Data *pd, const char *var)
60 {
61    EINA_SAFETY_ON_FALSE_RETURN(key_valid(var));
62    eina_hash_del_by_key(pd->env, var);
63 }
64 
65 EOLIAN static void
_efl_core_env_clear(Eo * obj EINA_UNUSED,Efl_Core_Env_Data * pd)66 _efl_core_env_clear(Eo *obj EINA_UNUSED, Efl_Core_Env_Data *pd)
67 {
68    eina_hash_free_buckets(pd->env);
69 }
70 
71 EOLIAN static Efl_Core_Env*
_efl_core_env_efl_duplicate_duplicate(const Eo * obj EINA_UNUSED,Efl_Core_Env_Data * pd)72 _efl_core_env_efl_duplicate_duplicate(const Eo *obj EINA_UNUSED, Efl_Core_Env_Data *pd)
73 {
74    Efl_Core_Env *fork = efl_add_ref(MY_CLASS, NULL);
75    Eina_Iterator *iter;
76    Eina_Hash_Tuple *tuple;
77 
78    iter = eina_hash_iterator_tuple_new(pd->env);
79 
80    EINA_ITERATOR_FOREACH(iter, tuple)
81      {
82         efl_core_env_set(fork, tuple->key, tuple->data);
83      }
84 
85    eina_iterator_free(iter);
86    return fork;
87 }
88 
89 EOLIAN static Efl_Object*
_efl_core_env_efl_object_constructor(Eo * obj,Efl_Core_Env_Data * pd)90 _efl_core_env_efl_object_constructor(Eo *obj, Efl_Core_Env_Data *pd)
91 {
92    pd->env = eina_hash_string_superfast_new((Eina_Free_Cb)eina_stringshare_del);
93 
94    return efl_constructor(efl_super(obj, MY_CLASS));
95 }
96 
97 EOLIAN static Eina_Iterator*
_efl_core_env_content_get(const Eo * obj EINA_UNUSED,Efl_Core_Env_Data * pd)98 _efl_core_env_content_get(const Eo *obj EINA_UNUSED, Efl_Core_Env_Data *pd)
99 {
100    Eina_Iterator *iter = eina_hash_iterator_key_new(pd->env);
101    return iter;
102 }
103 
104 
105 #include "efl_core_env.eo.c"
106