summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Zaoui <daniel.zaoui@yahoo.com>2018-07-12 15:52:37 +0300
committerDaniel Zaoui <daniel.zaoui@yahoo.com>2018-07-12 15:54:02 +0300
commitd813400307147beae64fe907e46fa1bfce7054dc (patch)
treeed7283d7002170e4a0c70d1812af36e95eb1a544
parent1f7667819b8c17d4743b7b8cc664f4353c682c0a (diff)
Support of structs parameters
@fix T7102
-rw-r--r--src/lib/Clouseau_Debug.h3
-rw-r--r--src/lib/clouseau_debug.c253
-rw-r--r--src/lib/extensions/objects_introspection/main.c10
3 files changed, 189 insertions, 77 deletions
diff --git a/src/lib/Clouseau_Debug.h b/src/lib/Clouseau_Debug.h
index 671ce51..6b106e8 100644
--- a/src/lib/Clouseau_Debug.h
+++ b/src/lib/Clouseau_Debug.h
@@ -51,7 +51,8 @@ typedef enum
51 EOLIAN_DEBUG_UINT, 51 EOLIAN_DEBUG_UINT,
52 EOLIAN_DEBUG_LIST, 52 EOLIAN_DEBUG_LIST,
53 EOLIAN_DEBUG_OBJECT, 53 EOLIAN_DEBUG_OBJECT,
54 EOLIAN_DEBUG_VOID 54 EOLIAN_DEBUG_VOID,
55 EOLIAN_DEBUG_STRUCT
55} Eolian_Debug_Basic_Type; 56} Eolian_Debug_Basic_Type;
56 57
57typedef struct 58typedef struct
diff --git a/src/lib/clouseau_debug.c b/src/lib/clouseau_debug.c
index 22a78cd..6dc96a9 100644
--- a/src/lib/clouseau_debug.c
+++ b/src/lib/clouseau_debug.c
@@ -133,6 +133,8 @@ const Debug_Param_Info debug_types[] =
133 {EOLIAN_DEBUG_UINT, "%u", &ffi_type_uint, 4}, 133 {EOLIAN_DEBUG_UINT, "%u", &ffi_type_uint, 4},
134 {EOLIAN_DEBUG_LIST, "%p", &ffi_type_pointer, 8}, 134 {EOLIAN_DEBUG_LIST, "%p", &ffi_type_pointer, 8},
135 {EOLIAN_DEBUG_OBJECT, "%p", &ffi_type_pointer, 8}, 135 {EOLIAN_DEBUG_OBJECT, "%p", &ffi_type_pointer, 8},
136 {EOLIAN_DEBUG_VOID, "%p", &ffi_type_pointer, 8},
137 {EOLIAN_DEBUG_STRUCT, "%p", &ffi_type_pointer, 8},
136 {0, NULL, 0, 0} 138 {0, NULL, 0, 0}
137}; 139};
138 140
@@ -152,6 +154,7 @@ _eolian_type_resolve(const Eolian_Type *eo_type)
152 154
153 if (type_base == EOLIAN_TYPE_REGULAR) 155 if (type_base == EOLIAN_TYPE_REGULAR)
154 { 156 {
157 const Eolian_Typedecl *tdecl;
155 const char *full_name = eolian_type_name_get(eo_type); 158 const char *full_name = eolian_type_name_get(eo_type);
156 const Eolian_Typedecl *alias = eolian_state_alias_by_name_get(eos, full_name); 159 const Eolian_Typedecl *alias = eolian_state_alias_by_name_get(eos, full_name);
157 if (alias) 160 if (alias)
@@ -168,11 +171,65 @@ _eolian_type_resolve(const Eolian_Type *eo_type)
168 if (!strcmp(full_name, eolian_types[i].name) && 171 if (!strcmp(full_name, eolian_types[i].name) &&
169 eolian_types[i].etype == type) return i; 172 eolian_types[i].etype == type) return i;
170 } 173 }
174 tdecl = eolian_type_typedecl_get(eo_type);
175 if (tdecl && eolian_typedecl_type_get(tdecl) == EOLIAN_TYPEDECL_STRUCT)
176 return EOLIAN_DEBUG_STRUCT;
171 } 177 }
172 178
173 return EOLIAN_DEBUG_INVALID_TYPE; 179 return EOLIAN_DEBUG_INVALID_TYPE;
174} 180}
175 181
182static ffi_type *
183_ffi_type_struct_get(const Eolian_Type *eo_type)
184{
185 const Eolian_Struct_Type_Field *f;
186 const Eolian_Typedecl *tdecl;
187 Eina_Iterator *iter;
188 int i = 0, count = 0;
189 ffi_type **types;
190 ffi_type *s_type = calloc(1, sizeof(*s_type));
191
192 s_type->type = FFI_TYPE_STRUCT;
193
194 tdecl = eolian_type_typedecl_get(eo_type);
195 iter = eolian_typedecl_struct_fields_get(tdecl);
196 EINA_ITERATOR_FOREACH(iter, f) count++;
197 eina_iterator_free(iter);
198 types = calloc(1, count * sizeof(ffi_type *));
199 s_type->elements = types;
200
201 iter = eolian_typedecl_struct_fields_get(tdecl);
202 EINA_ITERATOR_FOREACH(iter, f)
203 {
204 const Eolian_Type *feo_type = eolian_typedecl_struct_field_type_get(f);
205 Eolian_Debug_Basic_Type ftype = _eolian_type_resolve(feo_type);
206 types[i++] = debug_types[ftype].ffi_type_p;
207 }
208 types[i] = NULL;
209 eina_iterator_free(iter);
210 return s_type;
211}
212
213unsigned int
214_struct_mem_len_get(const Eolian_Type *eo_type)
215{
216 const Eolian_Struct_Type_Field *f;
217 const Eolian_Typedecl *tdecl;
218 Eina_Iterator *iter;
219 unsigned int len = 0;
220
221 tdecl = eolian_type_typedecl_get(eo_type);
222 iter = eolian_typedecl_struct_fields_get(tdecl);
223 EINA_ITERATOR_FOREACH(iter, f)
224 {
225 const Eolian_Type *feo_type = eolian_typedecl_struct_field_type_get(f);
226 Eolian_Debug_Basic_Type ftype = _eolian_type_resolve(feo_type);
227 len += debug_types[ftype].size;
228 }
229 eina_iterator_free(iter);
230 return len;
231}
232
176static int 233static int
177_function_invoke(Eo *ptr, const Eolian_Function *foo, Eolian_Function_Type foo_type, 234_function_invoke(Eo *ptr, const Eolian_Function *foo, Eolian_Function_Type foo_type,
178 Eolian_Debug_Parameter *params, Eolian_Debug_Return *ret) 235 Eolian_Debug_Parameter *params, Eolian_Debug_Return *ret)
@@ -182,7 +239,9 @@ _function_invoke(Eo *ptr, const Eolian_Function *foo, Eolian_Function_Type foo_t
182 ffi_type *types[EOLIAN_DEBUG_MAXARGS]; /* FFI types */ 239 ffi_type *types[EOLIAN_DEBUG_MAXARGS]; /* FFI types */
183 void *values[EOLIAN_DEBUG_MAXARGS]; /* FFI Values */ 240 void *values[EOLIAN_DEBUG_MAXARGS]; /* FFI Values */
184 void *pointers[EOLIAN_DEBUG_MAXARGS]; /* Used as values for out params, as we have to give a pointer to a pointer */ 241 void *pointers[EOLIAN_DEBUG_MAXARGS]; /* Used as values for out params, as we have to give a pointer to a pointer */
242 void *result = NULL;
185 Eolian_Function_Parameter *eo_param; 243 Eolian_Function_Parameter *eo_param;
244 const Eolian_Type *eo_type;
186 Eina_Iterator *itr; 245 Eina_Iterator *itr;
187 Eolian_Debug_Basic_Type ed_type; 246 Eolian_Debug_Basic_Type ed_type;
188 int argc, ffi_argc = 0; 247 int argc, ffi_argc = 0;
@@ -200,7 +259,8 @@ _function_invoke(Eo *ptr, const Eolian_Function *foo, Eolian_Function_Type foo_t
200 EINA_ITERATOR_FOREACH(itr, eo_param) 259 EINA_ITERATOR_FOREACH(itr, eo_param)
201 { 260 {
202 /* Not verified */ 261 /* Not verified */
203 ed_type = _eolian_type_resolve(eolian_parameter_type_get(eo_param)); 262 eo_type = eolian_parameter_type_get(eo_param);
263 ed_type = _eolian_type_resolve(eo_type);
204 if (!ed_type) goto error; 264 if (!ed_type) goto error;
205 265
206 types[ffi_argc] = debug_types[ed_type].ffi_type_p; 266 types[ffi_argc] = debug_types[ed_type].ffi_type_p;
@@ -214,7 +274,8 @@ _function_invoke(Eo *ptr, const Eolian_Function *foo, Eolian_Function_Type foo_t
214 eolian_property_values_get(foo, foo_type); 274 eolian_property_values_get(foo, foo_type);
215 EINA_ITERATOR_FOREACH(itr, eo_param) 275 EINA_ITERATOR_FOREACH(itr, eo_param)
216 { 276 {
217 ed_type = _eolian_type_resolve(eolian_parameter_type_get(eo_param)); 277 eo_type = eolian_parameter_type_get(eo_param);
278 ed_type = _eolian_type_resolve(eo_type);
218 if (!ed_type) goto error; 279 if (!ed_type) goto error;
219 params[argc].eparam = eo_param; 280 params[argc].eparam = eo_param;
220 281
@@ -222,10 +283,18 @@ _function_invoke(Eo *ptr, const Eolian_Function *foo, Eolian_Function_Type foo_t
222 (foo_type == EOLIAN_METHOD && eolian_parameter_direction_get(eo_param) == EOLIAN_OUT_PARAM)) 283 (foo_type == EOLIAN_METHOD && eolian_parameter_direction_get(eo_param) == EOLIAN_OUT_PARAM))
223 { 284 {
224 /* Out parameter */ 285 /* Out parameter */
225 params[argc].value.value.value = 0; 286 if (ed_type == EOLIAN_DEBUG_STRUCT)
287 {
288 params[argc].value.value.value = (uint64_t) calloc(_struct_mem_len_get(eo_type), 1);
289 pointers[ffi_argc] = (char *)params[argc].value.value.value;
290 }
291 else
292 {
293 params[argc].value.value.value = 0;
294 pointers[ffi_argc] = &(params[argc].value.value.value);
295 }
226 params[argc].value.type = ed_type; 296 params[argc].value.type = ed_type;
227 types[ffi_argc] = &ffi_type_pointer; 297 types[ffi_argc] = &ffi_type_pointer;
228 pointers[ffi_argc] = &(params[argc].value.value.value);
229 values[ffi_argc] = &pointers[ffi_argc]; 298 values[ffi_argc] = &pointers[ffi_argc];
230 } 299 }
231 else 300 else
@@ -238,7 +307,8 @@ _function_invoke(Eo *ptr, const Eolian_Function *foo, Eolian_Function_Type foo_t
238 argc++; 307 argc++;
239 } 308 }
240 309
241 const Eolian_Type *eo_type = eolian_function_return_type_get(foo, foo_type); 310 eo_type = eolian_function_return_type_get(foo, foo_type);
311 Eina_Bool param_as_ret = EINA_FALSE;
242 ffi_type *ffi_ret_type = &ffi_type_void; 312 ffi_type *ffi_ret_type = &ffi_type_void;
243 if (eo_type) 313 if (eo_type)
244 { 314 {
@@ -249,11 +319,22 @@ _function_invoke(Eo *ptr, const Eolian_Function *foo, Eolian_Function_Type foo_t
249 } 319 }
250 else if (argc == 1 && foo_type == EOLIAN_PROP_GET) 320 else if (argc == 1 && foo_type == EOLIAN_PROP_GET)
251 { 321 {
322 param_as_ret = EINA_TRUE;
323 eo_type = eolian_parameter_type_get(params[0].eparam);
324 ed_type = _eolian_type_resolve(eo_type);
325 if (ed_type == EOLIAN_DEBUG_STRUCT)
326 {
327 ffi_ret_type = _ffi_type_struct_get(eo_type);
328 }
329 else
330 {
331 ffi_ret_type = debug_types[params[0].value.type].ffi_type_p;
332 }
333 result = (char *)params[0].value.value.value;
252 /* If there is no return type but only one value is present, the value will 334 /* If there is no return type but only one value is present, the value will
253 * be returned by the function. 335 * be returned by the function.
254 * So we need FFI to not take it into account when invoking the function. 336 * So we need FFI to not take it into account when invoking the function.
255 */ 337 */
256 ffi_ret_type = debug_types[params[0].value.type].ffi_type_p;
257 ffi_argc--; 338 ffi_argc--;
258 } 339 }
259 340
@@ -264,20 +345,19 @@ _function_invoke(Eo *ptr, const Eolian_Function *foo, Eolian_Function_Type foo_t
264 if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, ffi_argc, 345 if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, ffi_argc,
265 ffi_ret_type, types) == FFI_OK) 346 ffi_ret_type, types) == FFI_OK)
266 { 347 {
267 void *result; 348 ffi_call(&cif, eo_func, result?result:&result, values);
268 ffi_call(&cif, eo_func, &result, values); 349 ret->value.type = EOLIAN_DEBUG_VOID;
269 if (ret) ret->value.type = EOLIAN_DEBUG_VOID;
270 if (eo_type) 350 if (eo_type)
271 { 351 {
272 if (ret) 352 if (!param_as_ret)
273 { 353 {
274 ret->value.value.value = (uint64_t) result; 354 ret->value.value.value = (uint64_t) result;
275 ret->value.type = ed_type; 355 ret->value.type = ed_type;
276 ret->etype = eo_type; 356 ret->etype = eo_type;
277 } 357 }
358 else
359 params[0].value.value.value = (uint64_t) result;
278 } 360 }
279 else if (argc == 1 && foo_type == EOLIAN_PROP_GET)
280 params[0].value.value.value = (uint64_t) result;
281 goto success; 361 goto success;
282 } 362 }
283 363
@@ -420,6 +500,24 @@ _complex_buffer_fill(char *buf, const Eolian_Type *eo_type, uint64_t value)
420 return size; 500 return size;
421} 501}
422 502
503static int
504_struct_buffer_fill(char *buf, const Eolian_Type *eo_type, char *str_buf)
505{
506 int size = 0;
507 const Eolian_Struct_Type_Field *f;
508 const Eolian_Typedecl *tdecl = eolian_type_typedecl_get(eo_type);
509 Eina_Iterator *iter = eolian_typedecl_struct_fields_get(tdecl);
510 EINA_ITERATOR_FOREACH(iter, f)
511 {
512 const Eolian_Type *feo_type = eolian_typedecl_struct_field_type_get(f);
513 Eolian_Debug_Basic_Type ftype = _eolian_type_resolve(feo_type);
514 size += _param_buffer_fill(buf+size, *((uint64_t *)str_buf), debug_types[ftype].size);
515 str_buf += debug_types[ftype].size;
516 }
517 eina_iterator_free(iter);
518 return size;
519}
520
423static Eina_Bool 521static Eina_Bool
424_api_resolvable(Eo *obj, const Eolian_Function *function) 522_api_resolvable(Eo *obj, const Eolian_Function *function)
425{ 523{
@@ -488,6 +586,11 @@ _class_buffer_fill(Eo *obj, const Eolian_Class *ekl, char *buf)
488 memcpy(buf + size, (char *)params[i].value.value.value, len); 586 memcpy(buf + size, (char *)params[i].value.value.value, len);
489 size += len; 587 size += len;
490 } 588 }
589 else if (params[i].value.type == EOLIAN_DEBUG_STRUCT)
590 {
591 const Eolian_Type *eo_type = eolian_parameter_type_get(params[i].eparam);
592 size += _struct_buffer_fill(buf+size, eo_type, (char *)params[i].value.value.value);
593 }
491 else 594 else
492 { 595 {
493 const Eolian_Type *eo_type = eolian_parameter_type_get(params[i].eparam); 596 const Eolian_Type *eo_type = eolian_parameter_type_get(params[i].eparam);
@@ -1291,6 +1394,61 @@ _complex_buffer_decode(char *buffer, const Eolian_Type *eo_type,
1291 return size; 1394 return size;
1292} 1395}
1293 1396
1397static Eina_Bool
1398_value_decode(char **buffer, unsigned int *size, const Eolian_Type *eo_type, Eolian_Debug_Value *v)
1399{
1400 int len;
1401 Eolian_Debug_Basic_Type type = _eolian_type_resolve(eo_type);
1402 v->type = type;
1403
1404 if (type)
1405 {
1406 v->type = type;
1407 if (type == EOLIAN_DEBUG_STRING)
1408 {
1409 len = strlen(*buffer) + 1;
1410 v->value.value = (uint64_t) eina_stringshare_add(*buffer);
1411 *buffer += len;
1412 *size -= len;
1413 }
1414 else if (type == EOLIAN_DEBUG_STRUCT)
1415 {
1416 const Eolian_Struct_Type_Field *f;
1417 Eina_List *list = NULL;
1418 const Eolian_Typedecl *tdecl = eolian_type_typedecl_get(eo_type);
1419 Eina_Iterator *iter = eolian_typedecl_struct_fields_get(tdecl);
1420 EINA_ITERATOR_FOREACH(iter, f)
1421 {
1422 const Eolian_Type *feo_type = eolian_typedecl_struct_field_type_get(f);
1423 Eolian_Debug_Value *v2 = calloc(1, sizeof(*v2));
1424 _value_decode(buffer, size, feo_type, v2);
1425 list = eina_list_append(list, v2);
1426 }
1427 eina_iterator_free(iter);
1428 v->complex_type_values = list;
1429 }
1430 else
1431 {
1432 uint64_t value = 0;;
1433 EXTRACT(*buffer, &value, debug_types[type].size);
1434 v->value.value = SWAP_64(value);
1435 *size -= debug_types[type].size;
1436 if (type == EOLIAN_DEBUG_LIST)
1437 {
1438 len = _complex_buffer_decode(*buffer, eo_type, v);
1439 *buffer += len;
1440 *size -= len;
1441 }
1442 }
1443 }
1444 else
1445 {
1446 printf("Unknown parameter type %s\n", eolian_type_name_get(eo_type));
1447 return EINA_FALSE;
1448 }
1449 return EINA_TRUE;
1450}
1451
1294/* 1452/*
1295 * receive buffer of the following format: 1453 * receive buffer of the following format:
1296 * Eo *pointer (uint64_t) 1454 * Eo *pointer (uint64_t)
@@ -1371,77 +1529,20 @@ eolian_debug_object_information_decode(char *buffer, unsigned int size)
1371 itr = eolian_property_values_get(func->efunc, EOLIAN_PROP_GET); 1529 itr = eolian_property_values_get(func->efunc, EOLIAN_PROP_GET);
1372 EINA_ITERATOR_FOREACH(itr, eo_param) 1530 EINA_ITERATOR_FOREACH(itr, eo_param)
1373 { 1531 {
1532 Eolian_Debug_Parameter *p = calloc(1, sizeof(*p));
1533 p->eparam = eo_param;
1374 eo_type = eolian_parameter_type_get(eo_param); 1534 eo_type = eolian_parameter_type_get(eo_param);
1375 Eolian_Debug_Basic_Type type = _eolian_type_resolve(eo_type); 1535 if (!_value_decode(&buffer, &size, eo_type, &(p->value)))
1376 1536 goto error;
1377 if (type) 1537 func->params = eina_list_append(func->params, p);
1378 {
1379 Eolian_Debug_Parameter *p = calloc(1, sizeof(*p));
1380 p->eparam = eo_param;
1381 p->value.type = type;
1382 if (type == EOLIAN_DEBUG_STRING)
1383 {
1384 len = strlen(buffer) + 1;
1385 p->value.value.value = (uint64_t) eina_stringshare_add(buffer);
1386 buffer += len;
1387 size -= len;
1388 }
1389 else
1390 {
1391 uint64_t value = 0;;
1392 EXTRACT(buffer, &value, debug_types[type].size);
1393 p->value.value.value = SWAP_64(value);
1394 size -= debug_types[type].size;
1395 if (type == EOLIAN_DEBUG_LIST)
1396 {
1397 len = _complex_buffer_decode(buffer, eo_type, &(p->value));
1398 buffer += len;
1399 size -= len;
1400 }
1401 }
1402 func->params = eina_list_append(func->params, p);
1403 }
1404 else
1405 {
1406 printf("Unknown parameter type %s\n", eolian_type_name_get(eo_type));
1407 goto error;
1408 }
1409 } 1538 }
1410 func->ret.etype = eo_type = eolian_function_return_type_get( 1539 func->ret.etype = eo_type = eolian_function_return_type_get(
1411 func->efunc, EOLIAN_PROP_GET); 1540 func->efunc, EOLIAN_PROP_GET);
1412 func->ret.value.type = EOLIAN_DEBUG_VOID; 1541 func->ret.value.type = EOLIAN_DEBUG_VOID;
1413 if(eo_type) 1542 if(eo_type)
1414 { 1543 {
1415 Eolian_Debug_Basic_Type type = _eolian_type_resolve(eo_type); 1544 if (!_value_decode(&buffer, &size, eo_type, &(func->ret.value)))
1416 if (type) 1545 goto error;
1417 {
1418 func->ret.value.type = type;
1419 if (type == EOLIAN_DEBUG_STRING)
1420 {
1421 len = strlen(buffer) + 1;
1422 func->ret.value.value.value = (uint64_t) eina_stringshare_add(buffer);
1423 buffer += len;
1424 size -= len;
1425 }
1426 else
1427 {
1428 uint64_t value;
1429 EXTRACT(buffer, &value, debug_types[type].size);
1430 func->ret.value.value.value = SWAP_64(value);
1431 size -= debug_types[type].size;
1432 if (type == EOLIAN_DEBUG_LIST)
1433 {
1434 len = _complex_buffer_decode(buffer, eo_type, &(func->ret.value));
1435 buffer += len;
1436 size -= len;
1437 }
1438 }
1439 }
1440 else
1441 {
1442 printf("Unknown parameter type %s\n", eolian_type_name_get(eo_type));
1443 goto error;
1444 }
1445 } 1546 }
1446 eina_iterator_free(itr); 1547 eina_iterator_free(itr);
1447 } 1548 }
diff --git a/src/lib/extensions/objects_introspection/main.c b/src/lib/extensions/objects_introspection/main.c
index d1ff922..fac54e4 100644
--- a/src/lib/extensions/objects_introspection/main.c
+++ b/src/lib/extensions/objects_introspection/main.c
@@ -528,6 +528,16 @@ _eolian_value_to_string(Eolian_Debug_Value *value, Eina_Strbuf *buf)
528 eina_strbuf_append(buf, "]"); 528 eina_strbuf_append(buf, "]");
529 break; 529 break;
530 } 530 }
531 case EOLIAN_DEBUG_STRUCT:
532 {
533 Eina_List *l = value->complex_type_values, *itr;
534 EINA_LIST_FOREACH(l, itr, value)
535 {
536 if (l != itr) eina_strbuf_append(buf, ", ");
537 _eolian_value_to_string(value, buf);
538 }
539 break;
540 }
531 default: eina_strbuf_append_printf(buf, "%lX ", value->value.value); 541 default: eina_strbuf_append_printf(buf, "%lX ", value->value.value);
532 } 542 }
533} 543}