1 #include "comps_validate.h"
2 
comps_validate_errres_create(COMPS_ValErrResult * res,COMPS_Object * args)3 static void comps_validate_errres_create(COMPS_ValErrResult *res,
4                                          COMPS_Object *args) {
5     (void)args;
6     res->err_list = COMPS_OBJECT_CREATE(COMPS_ObjList, NULL);
7 }
8 
comps_validate_errres_destroy(COMPS_ValErrResult * res)9 static void comps_validate_errres_destroy(COMPS_ValErrResult *res) {
10     COMPS_OBJECT_DESTROY(res->err_list);
11 }
12 
comps_validate_err_create(COMPS_ValErr * res,COMPS_Object * args)13 static void comps_validate_err_create(COMPS_ValErr *res,
14                                       COMPS_Object *args) {
15     (void)args;
16     res->err_object = NULL;
17     res->err_msg = NULL;
18 }
19 
comps_validate_err_destroy(COMPS_ValErr * res)20 static void comps_validate_err_destroy(COMPS_ValErr *res) {
21     COMPS_OBJECT_DESTROY(res->err_object);
22     free(res->err_msg);
23 }
24 
comps_valgenres_concat(COMPS_ValGenResult ** res1,COMPS_ValGenResult * res2)25 inline void comps_valgenres_concat(COMPS_ValGenResult **res1,
26                                      COMPS_ValGenResult *res2) {
27     if (!(*res1)) {
28         return;
29     }
30     if ((*res1)->obj_info == &COMPS_ValGenResult_ObjInfo) {
31         if (res2->obj_info == &COMPS_ValGenResult_ObjInfo) {
32 
33         } else {
34             COMPS_OBJECT_DESTROY(*res1);
35             *res1 = (COMPS_ValGenResult*)COMPS_OBJECT_INCREF(res2);
36         }
37     } else {
38         if (res2->obj_info == &COMPS_ValGenResult_ObjInfo) {
39 
40         } else {
41             comps_objlist_concat_in(((COMPS_ValErrResult*)*res1)->err_list,
42                                     ((COMPS_ValErrResult*)res2)->err_list);
43         }
44     }
45 }
46 
comps_valgenres_prefix(COMPS_ValGenResult * res,const char * prefix)47 void comps_valgenres_prefix(COMPS_ValGenResult *res, const char *prefix) {
48     COMPS_ObjListIt *it;
49     size_t oldlen;
50 
51     if (res->obj_info != &COMPS_ValErrResult_ObjInfo) return;
52     for (it = ((COMPS_ValErrResult*)res)->err_list->first; it != NULL;
53          it = it->next) {
54         oldlen = strlen(((COMPS_ValErr*)it->comps_obj)->err_msg);
55         ((COMPS_ValErr*)it->comps_obj)->err_msg = realloc(
56                                       ((COMPS_ValErr*)it->comps_obj)->err_msg,
57                                       (oldlen + strlen(prefix) +1) *
58                                       sizeof(char));
59         memmove(((COMPS_ValErr*)it->comps_obj)->err_msg + (strlen(prefix) *sizeof(char)),
60                 ((COMPS_ValErr*)it->comps_obj)->err_msg, (oldlen+1) * sizeof(char));
61         memcpy(((COMPS_ValErr*)it->comps_obj)->err_msg, prefix,
62                strlen(prefix)*sizeof(char));
63     }
64 }
65 
comps_valgenres_print(COMPS_ValGenResult * res,FILE * stream)66 void comps_valgenres_print(COMPS_ValGenResult *res, FILE *stream) {
67     COMPS_ObjListIt *it;
68 
69     if (res->obj_info != &COMPS_ValErrResult_ObjInfo) return;
70     for (it = ((COMPS_ValErrResult*)res)->err_list->first; it != NULL;
71          it = it->next) {
72         fprintf(stream, "%s\n", ((COMPS_ValErr*)it->comps_obj)->err_msg);
73     }
74 }
75 
comps_validate_rule_prop_check(COMPS_ValRuleGeneric * rule,COMPS_Object * obj)76 COMPS_ValGenResult* comps_validate_rule_prop_check(COMPS_ValRuleGeneric *rule,
77                                                    COMPS_Object *obj) {
78     #define _rule_ ((COMPS_ValRuleProp*)rule)
79     COMPS_Object *prop;
80     COMPS_ValGenResult *ret;
81 
82     prop = _rule_->get_f(obj);
83     ret = _rule_->check_f(obj, prop);
84     COMPS_OBJECT_DESTROY(prop);
85     return ret;
86 
87     #undef _rule_
88 }
89 
comps_validate_rule_list_check(COMPS_ValRuleGeneric * rule,COMPS_Object * obj)90 COMPS_ValGenResult* comps_validate_rule_list_check(COMPS_ValRuleGeneric *rule,
91                                                    COMPS_Object *obj) {
92     #define _rule_ ((COMPS_ValRuleList*)rule)
93     COMPS_ObjList *prop;
94     COMPS_ValGenResult *ret;
95 
96     prop = *(COMPS_ObjList**)((char*)obj + _rule_->offset);
97     ret = _rule_->check_f(obj, (COMPS_Object*)prop);
98     return ret;
99     #undef _rule_
100 }
101 
comps_validate_rule_list_check2(COMPS_ValRuleGeneric * rule,COMPS_Object * obj)102 COMPS_ValGenResult* comps_validate_rule_list_check2(COMPS_ValRuleGeneric *rule,
103                                                     COMPS_Object *obj) {
104     #define _rule_ ((COMPS_ValRuleList2*)rule)
105     COMPS_ObjList *prop;
106     COMPS_ValGenResult *ret;
107 
108     prop = (COMPS_ObjList*) _rule_->get_f(obj);
109     ret = _rule_->check_f(obj, (COMPS_Object*)prop);
110     COMPS_OBJECT_DESTROY(prop);
111     return ret;
112     #undef _rule_
113 }
114 
comps_validate_execute(COMPS_Object * obj,COMPS_ValRuleGeneric * rules[])115 COMPS_ValGenResult* comps_validate_execute(COMPS_Object *obj,
116                                            COMPS_ValRuleGeneric *rules[]) {
117     int i;
118     COMPS_ValGenResult *valres = NULL;
119     COMPS_ValGenResult *tmpres;
120     for (i = 0; rules[i]; i++) {
121         tmpres = rules[i]->rule_check(rules[i], obj);
122         if (tmpres->obj_info != &COMPS_ValOkResult_ObjInfo) {
123             if (!valres)
124                 valres = (COMPS_ValGenResult*)
125                          COMPS_OBJECT_CREATE(COMPS_ValErrResult, NULL);
126             comps_valgenres_prefix(tmpres, rules[i]->verbose_msg);
127             comps_valgenres_concat(&valres, tmpres);
128         }
129         COMPS_OBJECT_DESTROY(tmpres);
130     }
131     if (!valres) {
132         return (COMPS_ValGenResult*)
133                COMPS_OBJECT_CREATE(COMPS_ValOkResult, NULL);
134     }
135     return (COMPS_ValGenResult*)valres;
136 }
137 
comps_empty_check(COMPS_Object * obj,COMPS_Object * prop)138 COMPS_ValGenResult* comps_empty_check(COMPS_Object *obj, COMPS_Object *prop) {
139     char err = 0;
140     COMPS_ValGenResult *valres;
141     COMPS_ValErr *v_err;
142     (void)obj;
143 
144     if (!prop) err = 1;
145     else if (__comps_strcmp("", ((COMPS_Str*)prop)->val)) err=2;
146 
147     if (err) {
148         valres = (COMPS_ValGenResult*)COMPS_OBJECT_CREATE(COMPS_ValErrResult,
149                                                           NULL);
150         v_err = COMPS_OBJECT_CREATE(COMPS_ValErr, NULL);
151         v_err->err_object = COMPS_OBJECT_INCREF(obj);
152         if (err == 1)
153             v_err->err_msg = __comps_strcpy("attr not set");
154         else if (err == 2)
155             v_err->err_msg = __comps_strcpy("attr empty");
156         comps_objlist_append_x(((COMPS_ValErrResult*)valres)->err_list,
157                                (COMPS_Object*)v_err);
158     } else {
159         valres = (COMPS_ValGenResult*)COMPS_OBJECT_CREATE(COMPS_ValOkResult,
160                                                           NULL);
161     }
162     return valres;
163 }
comps_objlist_unique_check(COMPS_Object * object,COMPS_Object * objlist)164 COMPS_ValGenResult* comps_objlist_unique_check(COMPS_Object *object,
165                                                COMPS_Object *objlist) {
166     #define _objlist_ ((COMPS_ObjList*)objlist)
167     (void)object;
168     COMPS_ValGenResult *valres = NULL;
169     COMPS_ValErr *v_err;
170     size_t x;
171     int index;
172     void *data;
173     char *msg;
174     const char *msg_fmt = "Duplicate items at %d and %d";
175 
176     COMPS_Set *set = comps_set_create();
177     comps_set_init(set, NULL, NULL, NULL, &comps_object_cmp_v);
178     x = 0;
179     for (COMPS_ObjListIt *it = _objlist_->first;
180          it != NULL;
181          it = it->next, x++) {
182         if (!(data = comps_set_data_at(set, it->comps_obj))) {
183             comps_set_add(set, it->comps_obj);
184         } else {
185             if (!valres) {
186                 valres = (COMPS_ValGenResult*)COMPS_OBJECT_CREATE(
187                                                     COMPS_ValErrResult,
188                                                     NULL);
189             }
190             v_err = COMPS_OBJECT_CREATE(COMPS_ValErr, NULL);
191             v_err->err_object = COMPS_OBJECT_INCREF(object);
192             index = comps_objlist_index(_objlist_, (COMPS_Object*)data);
193             msg = malloc(sizeof(char) * (strlen(msg_fmt)-3)+digits_count(x)\
194                                                            +digits_count(index));
195             sprintf(msg, msg_fmt, index, x);
196             v_err->err_msg = msg;
197             comps_objlist_append_x(((COMPS_ValErrResult*)valres)->err_list,
198                                    (COMPS_Object*)v_err);
199         }
200     }
201     comps_set_destroy(&set);
202     if (!valres) {
203         valres = (COMPS_ValGenResult*)COMPS_OBJECT_CREATE(COMPS_ValOkResult,
204                                                           NULL);
205     }
206     return valres;
207     #undef _objlist_
208 }
209 
210 COMPS_ObjectInfo COMPS_ValGenResult_ObjInfo = {
211     .obj_size = sizeof(COMPS_ValGenResult),
212     .constructor = NULL,
213     .destructor = NULL
214 };
215 COMPS_ObjectInfo COMPS_ValOkResult_ObjInfo = {
216     .obj_size = sizeof(COMPS_ValOkResult),
217     .constructor = NULL,
218     .destructor = NULL
219 };
220 
221 COMPS_ObjectInfo COMPS_ValErrResult_ObjInfo = {
222     .obj_size = sizeof(COMPS_ValErrResult),
223     .constructor = (COMPS_CAST_CONSTR) &comps_validate_errres_create,
224     .destructor = (COMPS_CAST_DESTR) &comps_validate_errres_destroy
225 };
226 
227 COMPS_ObjectInfo COMPS_ValErr_ObjInfo = {
228     .obj_size = sizeof(COMPS_ValErr),
229     .constructor = (COMPS_CAST_CONSTR) &comps_validate_err_create,
230     .destructor = (COMPS_CAST_DESTR) &comps_validate_err_destroy
231 };
232