1 #include <magic_selement.h>
3 /*===========================================================================*
4 * magic_selement_lookup_by_name *
5 *===========================================================================*/
6 PUBLIC
int magic_selement_lookup_by_name(char *name
,
7 _magic_selement_t
*selement
, struct _magic_dsentry
*dsentry_buff
)
9 char token_buff
[MAGIC_MAX_NAME_LEN
* 2 + 2];
10 char *token_start
= name
;
11 int last_num_seps
= 0;
13 if (!name
|| *name
== '\0' || *name
== MAGIC_SELEMENT_SEP
[0]) {
16 for (s
= name
; *s
; s
++) {
17 if (*(s
+ 1) == '\0' || *(s
+ 1) == MAGIC_SELEMENT_SEP
[0]) {
18 size_t len
= s
- token_start
+ 1;
19 if (len
>= MAGIC_MAX_NAME_LEN
* 2 + 1) {
22 strncpy(token_buff
, token_start
, len
);
23 token_buff
[len
] = '\0';
24 if (token_start
== name
) {
25 struct _magic_sentry
*sentry
;
26 const char *sentry_parent_name
= "", *sentry_name
= NULL
;
28 _magic_id_t dsentry_site_id
= MAGIC_DSENTRY_SITE_ID_NULL
;
29 if (!(delim
= strchr(token_buff
, MAGIC_DSENTRY_ABS_NAME_SEP
[0]))) {
30 /* Regular sentry, no parent name or site_id. */
31 sentry_name
= token_buff
;
34 * Dsentry. Will contain: sentry_id<DELIM>parent_name<DELIM>name<DELIM>site_id.
38 sentry_parent_name
= delim
+ 1;
39 delim
= strchr(delim
+ 1, MAGIC_DSENTRY_ABS_NAME_SEP
[0]);
40 assert(!delim
&& "No dsentry name found in selement name!");
42 sentry_name
= delim
+ 1;
43 delim
= strchr(delim
+ 1, MAGIC_DSENTRY_ABS_NAME_SEP
[0]);
44 assert(!delim
&& "No dsentry site id found in selement name!");
46 dsentry_site_id
= strtoul((const char*)delim
+1, NULL
, 10);
49 sentry
= magic_sentry_lookup_by_name(sentry_parent_name
, sentry_name
,
50 dsentry_site_id
, dsentry_buff
);
54 magic_selement_from_sentry(sentry
, selement
);
57 _magic_selement_t child_selement
;
58 if (!magic_selement_from_relative_name(selement
, &child_selement
, token_buff
)) {
61 *selement
= child_selement
;
65 while (*s
== MAGIC_SELEMENT_SEP
[0]) {
73 if (last_num_seps
> 0 && selement
->type
->type_id
== MAGIC_TYPE_POINTER
) {
74 int steps
= magic_selement_recurse_ptr(selement
, selement
, last_num_seps
);
75 if(steps
!= last_num_seps
) {
83 /*===========================================================================*
84 * magic_selement_name_print_cb *
85 *===========================================================================*/
86 PUBLIC
int magic_selement_name_print_cb(const struct _magic_type
* parent_type
,
87 const unsigned parent_offset
, int child_num
,
88 const struct _magic_type
* type
, const unsigned offset
, int depth
, void* cb_args
)
90 _magic_selement_t
*selement
= (_magic_selement_t
*) cb_args
;
91 struct _magic_sentry
* sentry
= selement
->sentry
;
92 void *address
= (char*)sentry
->address
+ offset
;
94 MAGIC_RANGE_SET_MIN(range
, address
);
95 MAGIC_RANGE_SET_MAX(range
, (char*) address
+ type
->size
-1);
96 if(!MAGIC_ADDR_IS_IN_RANGE(selement
->address
, range
)) {
97 return MAGIC_TYPE_WALK_SKIP_PATH
;
99 if(address
== sentry
->address
&& type
== sentry
->type
) {
100 magic_print_sentry_abs_name(sentry
);
103 short is_parent_array
= parent_type
->type_id
== MAGIC_TYPE_ARRAY
|| parent_type
->type_id
== MAGIC_TYPE_VECTOR
;
104 if(is_parent_array
) {
105 _magic_printf("%s%d", MAGIC_SELEMENT_SEP
, child_num
);
108 _magic_printf("%s%s", MAGIC_SELEMENT_SEP
, parent_type
->member_names
[child_num
]);
111 if(type
->num_child_types
== 0
112 || (address
== selement
->address
&& type
== selement
->type
)) {
113 return MAGIC_TYPE_WALK_STOP
;
115 return MAGIC_TYPE_WALK_CONTINUE
;
118 /*===========================================================================*
119 * magic_selement_name_get_cb *
120 *===========================================================================*/
121 PUBLIC
int magic_selement_name_get_cb(const struct _magic_type
*parent_type
,
122 const unsigned parent_offset
, int child_num
, const struct _magic_type
*type
,
123 const unsigned offset
, int depth
, void *args_array
)
125 void **cb_args
= (void **) args_array
;
127 _magic_selement_t
*selement
= (_magic_selement_t
*) cb_args
[0];
128 char **buf
= (char **) cb_args
+ 1;
129 int count
, *buf_size
= (int *) cb_args
+ 2;
131 short is_array
= type
->type_id
== MAGIC_TYPE_ARRAY
|| type
->type_id
== MAGIC_TYPE_VECTOR
;
133 struct _magic_sentry
*sentry
= selement
->sentry
;
134 void *address
= (char *)sentry
->address
+ offset
;
136 MAGIC_RANGE_SET_MIN(range
, address
);
137 MAGIC_RANGE_SET_MAX(range
, (char *) address
+ type
->size
- 1);
138 if (!MAGIC_ADDR_IS_IN_RANGE(selement
->address
, range
)) {
139 return MAGIC_TYPE_WALK_SKIP_PATH
;
142 if (address
== sentry
->address
&& type
== sentry
->type
) {
143 if (!(sentry
->flags
& MAGIC_STATE_DYNAMIC
)) {
144 count
= snprintf(*buf
, *buf_size
, "%s", sentry
->name
);
145 if (count
>= *buf_size
) return MAGIC_TYPE_WALK_STOP
; /* Buffer too small. */
149 struct _magic_dsentry
*dsentry
= MAGIC_DSENTRY_FROM_SENTRY(sentry
);
150 assert(dsentry
->parent_name
&& strcmp(dsentry
->parent_name
, ""));
151 assert(sentry
->name
&& strcmp(sentry
->name
, ""));
152 count
= snprintf(*buf
, *buf_size
, "%lu%s%s%s%s%s" MAGIC_ID_FORMAT
,
153 (unsigned long)MAGIC_SENTRY_ID(sentry
), MAGIC_DSENTRY_ABS_NAME_SEP
,
154 dsentry
->parent_name
, MAGIC_DSENTRY_ABS_NAME_SEP
, sentry
->name
,
155 MAGIC_DSENTRY_ABS_NAME_SEP
, dsentry
->site_id
);
156 if (count
>= *buf_size
) return MAGIC_TYPE_WALK_STOP
; /* Buffer too small. */
161 short is_parent_array
= parent_type
->type_id
== MAGIC_TYPE_ARRAY
||
162 parent_type
->type_id
== MAGIC_TYPE_VECTOR
;
163 if (is_parent_array
) {
164 count
= snprintf(*buf
, *buf_size
, "%s%d",
165 MAGIC_SELEMENT_SEP
, child_num
);
166 if (count
>= *buf_size
) return MAGIC_TYPE_WALK_STOP
; /* Buffer too small. */
170 count
= snprintf(*buf
, *buf_size
, "%s%s",
171 MAGIC_SELEMENT_SEP
, parent_type
->member_names
[child_num
]);
172 if (count
>= *buf_size
) return MAGIC_TYPE_WALK_STOP
; /* Buffer too small. */
178 if (type
->num_child_types
== 0
179 || (address
== selement
->address
&& type
== selement
->type
)
180 || (is_array
&& address
== selement
->address
&& type
== selement
->parent_type
)) {
181 return MAGIC_TYPE_WALK_STOP
;
184 return MAGIC_TYPE_WALK_CONTINUE
;
187 /*===========================================================================*
188 * magic_selement_print_value *
189 *===========================================================================*/
190 PUBLIC
void magic_selement_print_value(const _magic_selement_t
*selement
)
192 int type_id
= selement
->type
->type_id
;
193 unsigned size
= selement
->type
->size
;
196 unsigned long uvalue
;
200 case MAGIC_TYPE_FLOAT
:
201 dvalue
= magic_selement_to_float(selement
);
202 _magic_printf("float(%d):%g", size
, dvalue
);
203 _magic_printf("/%d", (long) dvalue
);
206 case MAGIC_TYPE_POINTER
:
207 pvalue
= magic_selement_to_ptr(selement
);
208 _magic_printf("ptr:%08x", pvalue
);
211 case MAGIC_TYPE_INTEGER
:
212 case MAGIC_TYPE_ENUM
:
213 if(MAGIC_TYPE_FLAG(selement
->type
, MAGIC_TYPE_UNSIGNED
)) {
214 uvalue
= magic_selement_to_unsigned(selement
);
215 _magic_printf("unsigned %s(%d):%u", type_id
== MAGIC_TYPE_INTEGER
? "int" : "enum", size
, uvalue
);
218 ivalue
= magic_selement_to_int(selement
);
219 _magic_printf("%s(%d):%d", type_id
== MAGIC_TYPE_INTEGER
? "int" : "enum", size
, ivalue
);
223 case MAGIC_TYPE_VOID
:
224 vvalue
= *((char*) selement
->address
);
225 _magic_printf("void(%d):%d", size
, vvalue
);
229 _magic_printf("???");
234 /*===========================================================================*
235 * magic_selement_to_unsigned *
236 *===========================================================================*/
237 PUBLIC
unsigned long magic_selement_to_unsigned(const _magic_selement_t
*selement
)
239 void *address
= selement
->address
;
240 const struct _magic_type
* type
= selement
->type
;
241 unsigned long value
= 0;
242 unsigned size
= type
->size
;
244 assert(type
->type_id
== MAGIC_TYPE_INTEGER
245 || type
->type_id
== MAGIC_TYPE_ENUM
);
250 if(size
== sizeof(unsigned char)) {
251 value
= (unsigned long) *((unsigned char*) address
);
253 else if(size
== sizeof(unsigned short)) {
254 value
= (unsigned long) *((unsigned short*) address
);
256 #ifdef MAGIC_LONG_LONG_SUPPORTED
257 else if(size
== sizeof(unsigned long long)) {
258 value
= (unsigned long) *((unsigned long long*) address
);
262 assert(size
== sizeof(unsigned long));
263 value
= *((unsigned long*) address
);
269 /*===========================================================================*
270 * magic_selement_to_int *
271 *===========================================================================*/
272 PUBLIC
long magic_selement_to_int(const _magic_selement_t
*selement
)
274 void *address
= selement
->address
;
275 const struct _magic_type
* type
= selement
->type
;
277 unsigned size
= type
->size
;
279 assert(type
->type_id
== MAGIC_TYPE_INTEGER
280 || type
->type_id
== MAGIC_TYPE_ENUM
);
285 if(size
== sizeof(char)) {
286 value
= (long) *((char*) address
);
288 else if(size
== sizeof(short)) {
289 value
= (long) *((short*) address
);
291 #ifdef MAGIC_LONG_LONG_SUPPORTED
292 else if(size
== sizeof(long long)) {
293 value
= (long) *((long long*) address
);
297 assert(size
== sizeof(long));
298 value
= *((long*) address
);
304 #ifdef MAGIC_LONG_LONG_SUPPORTED
305 /*===========================================================================*
306 * magic_selement_to_llu *
307 *===========================================================================*/
308 PUBLIC
unsigned long long magic_selement_to_llu(const _magic_selement_t
*selement
)
310 void *address
= selement
->address
;
311 const struct _magic_type
* type
= selement
->type
;
312 unsigned long long value
;
313 unsigned size
= type
->size
;
318 if (size
== sizeof(unsigned long long))
319 value
= *((unsigned long long*) address
);
321 value
= (unsigned long long) magic_selement_to_unsigned(selement
);
325 /*===========================================================================*
326 * magic_selement_to_ll *
327 *===========================================================================*/
328 PUBLIC
long long magic_selement_to_ll(const _magic_selement_t
*selement
)
330 void *address
= selement
->address
;
331 const struct _magic_type
* type
= selement
->type
;
333 unsigned size
= type
->size
;
338 if (size
== sizeof(long long))
339 value
= *((long long*) address
);
341 value
= (long long) magic_selement_to_int(selement
);
346 /*===========================================================================*
347 * magic_selement_to_float *
348 *===========================================================================*/
349 PUBLIC
double magic_selement_to_float(const _magic_selement_t
*selement
)
351 void *address
= selement
->address
;
352 const struct _magic_type
* type
= selement
->type
;
354 unsigned size
= type
->size
;
356 assert(type
->type_id
== MAGIC_TYPE_FLOAT
);
361 if(size
== sizeof(float)) {
362 value
= (double) *((float*) address
);
364 #ifdef MAGIC_LONG_DOUBLE_SUPPORTED
365 else if(size
== sizeof(long double)) {
366 value
= (double) *((long double*) address
);
370 assert(size
== sizeof(double));
371 value
= *((double*) address
);
377 /*===========================================================================*
378 * magic_selement_to_ptr *
379 *===========================================================================*/
380 PUBLIC
void* magic_selement_to_ptr(const _magic_selement_t
*selement
)
382 void *address
= selement
->address
;
383 const struct _magic_type
* type
= selement
->type
;
385 assert(type
->type_id
== MAGIC_TYPE_POINTER
);
389 value
= *((void**) address
);
393 /*===========================================================================*
394 * magic_selement_from_unsigned *
395 *===========================================================================*/
396 PUBLIC
void magic_selement_from_unsigned(const _magic_selement_t
*selement
, unsigned long value
)
398 void *address
= selement
->address
;
399 const struct _magic_type
* type
= selement
->type
;
400 unsigned size
= type
->size
;
402 assert(type
->type_id
== MAGIC_TYPE_INTEGER
403 || type
->type_id
== MAGIC_TYPE_ENUM
);
405 /* Prevent a store to NULL. */
409 if(size
== sizeof(unsigned char)) {
410 *((unsigned char*) address
) = (unsigned char) value
;
412 else if(size
== sizeof(unsigned short)) {
413 *((unsigned short*) address
) = (unsigned short) value
;
415 #ifdef MAGIC_LONG_LONG_SUPPORTED
416 else if(size
== sizeof(unsigned long long)) {
417 *((unsigned long long*) address
) = (unsigned long long) value
;
421 assert(size
== sizeof(unsigned long));
422 *((unsigned long*) address
) = (unsigned long) value
;
426 /*===========================================================================*
427 * magic_selement_from_int *
428 *===========================================================================*/
429 PUBLIC
void magic_selement_from_int(const _magic_selement_t
*selement
, long value
)
431 void *address
= selement
->address
;
432 const struct _magic_type
* type
= selement
->type
;
433 unsigned size
= type
->size
;
435 assert(type
->type_id
== MAGIC_TYPE_INTEGER
436 || type
->type_id
== MAGIC_TYPE_ENUM
);
438 /* Prevent a store to NULL. */
442 if(size
== sizeof(char)) {
443 *((char*) address
) = (char) value
;
445 else if(size
== sizeof(short)) {
446 *((short*) address
) = (short) value
;
448 #ifdef MAGIC_LONG_LONG_SUPPORTED
449 else if(size
== sizeof(long long)) {
450 *((long long*) address
) = (long long) value
;
454 assert(size
== sizeof(long));
455 *((long*) address
) = (long) value
;
459 /*===========================================================================*
460 * magic_selement_from_float *
461 *===========================================================================*/
462 PUBLIC
void magic_selement_from_float(const _magic_selement_t
*selement
, double value
)
464 void *address
= selement
->address
;
465 const struct _magic_type
* type
= selement
->type
;
466 unsigned size
= type
->size
;
468 assert(type
->type_id
== MAGIC_TYPE_FLOAT
);
470 /* Prevent a store to NULL. */
474 if(size
== sizeof(float)) {
475 *((float*) address
) = (float) value
;
477 #ifdef MAGIC_LONG_DOUBLE_SUPPORTED
478 else if(size
== sizeof(long double)) {
479 *((long double*) address
) = (long double) value
;
483 assert(size
== sizeof(double));
484 *((double*) address
) = (double) value
;
488 /*===========================================================================*
489 * magic_selement_ptr_value_cast *
490 *===========================================================================*/
491 PUBLIC
int magic_selement_ptr_value_cast(const _magic_selement_t
*src_selement
, const _magic_selement_t
*dst_selement
, void* value_buffer
)
493 int src_type_id
= src_selement
->type
->type_id
;
494 int dst_type_id
= dst_selement
->type
->type_id
;
495 unsigned src_size
= src_selement
->type
->size
;
496 unsigned dst_size
= dst_selement
->type
->size
;
499 assert(dst_size
> 0);
501 if(dst_type_id
!= MAGIC_TYPE_POINTER
) {
504 assert(dst_size
== sizeof(void*));
505 if(src_size
!= sizeof(void*)) {
508 switch(src_type_id
) {
509 case MAGIC_TYPE_POINTER
:
513 case MAGIC_TYPE_INTEGER
:
514 if(MAGIC_TYPE_FLAG(src_selement
->type
, MAGIC_TYPE_UNSIGNED
)) {
515 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_unsigned(src_selement
), unsigned long, src_value
, void*, &r
, 0);
519 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_int(src_selement
), long, src_value
, void*, &r
, 0);
529 MAGIC_CHECKED_VALUE_DST_CAST(src_value
, void*, value_buffer
, void*, &r
);
535 /*===========================================================================*
536 * magic_selement_unsigned_value_cast *
537 *===========================================================================*/
538 PUBLIC
int magic_selement_unsigned_value_cast(const _magic_selement_t
*src_selement
, const _magic_selement_t
*dst_selement
, void* value_buffer
)
540 int src_type_id
= src_selement
->type
->type_id
;
541 int dst_type_id
= dst_selement
->type
->type_id
;
543 unsigned src_size
= src_selement
->type
->size
;
544 unsigned dst_size
= dst_selement
->type
->size
;
545 unsigned long src_value
;
546 assert(dst_size
> 0);
548 if(dst_type_id
!= MAGIC_TYPE_INTEGER
&& dst_type_id
!= MAGIC_TYPE_ENUM
) {
551 switch(src_type_id
) {
552 case MAGIC_TYPE_FLOAT
:
553 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_float(src_selement
), double, src_value
, unsigned long, &r
, 1);
556 case MAGIC_TYPE_POINTER
:
557 if(dst_size
!= sizeof(void*)) {
560 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_ptr(src_selement
), void*, src_value
, unsigned long, &r
, 0);
564 case MAGIC_TYPE_INTEGER
:
565 case MAGIC_TYPE_ENUM
:
566 if(src_size
== dst_size
&& MAGIC_TYPE_FLAG(src_selement
->type
, MAGIC_TYPE_UNSIGNED
) == MAGIC_TYPE_FLAG(dst_selement
->type
, MAGIC_TYPE_UNSIGNED
)) {
569 if(MAGIC_TYPE_FLAG(src_selement
->type
, MAGIC_TYPE_UNSIGNED
)) {
570 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_unsigned(src_selement
), unsigned long, src_value
, unsigned long, &r
, 0);
574 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_int(src_selement
), long, src_value
, unsigned long, &r
, 1);
584 case sizeof(unsigned char):
585 MAGIC_CHECKED_VALUE_DST_CAST(src_value
, unsigned long, value_buffer
, unsigned char, &r
);
588 case sizeof(unsigned short):
589 MAGIC_CHECKED_VALUE_DST_CAST(src_value
, unsigned long, value_buffer
, unsigned short, &r
);
592 case sizeof(unsigned int):
593 MAGIC_CHECKED_VALUE_DST_CAST(src_value
, unsigned long, value_buffer
, unsigned int, &r
);
596 #ifdef MAGIC_LONG_LONG_SUPPORTED
597 case sizeof(unsigned long long):
598 MAGIC_CHECKED_VALUE_DST_CAST(src_value
, unsigned long, value_buffer
, unsigned long long, &r
);
614 /*===========================================================================*
615 * magic_selement_int_value_cast *
616 *===========================================================================*/
617 PUBLIC
int magic_selement_int_value_cast(const _magic_selement_t
*src_selement
, const _magic_selement_t
*dst_selement
, void* value_buffer
)
619 int src_type_id
= src_selement
->type
->type_id
;
620 int dst_type_id
= dst_selement
->type
->type_id
;
622 unsigned src_size
= src_selement
->type
->size
;
623 unsigned dst_size
= dst_selement
->type
->size
;
625 assert(dst_size
> 0);
627 if(dst_type_id
!= MAGIC_TYPE_INTEGER
&& dst_type_id
!= MAGIC_TYPE_ENUM
) {
631 switch(src_type_id
) {
632 case MAGIC_TYPE_FLOAT
:
633 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_float(src_selement
), double, src_value
, long, &r
, 1);
636 case MAGIC_TYPE_POINTER
:
637 if(dst_size
!= sizeof(void*)) {
640 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_ptr(src_selement
), void*, src_value
, long, &r
, 0);
644 case MAGIC_TYPE_INTEGER
:
645 case MAGIC_TYPE_ENUM
:
646 if(src_size
== dst_size
&& MAGIC_TYPE_FLAG(src_selement
->type
, MAGIC_TYPE_UNSIGNED
) == MAGIC_TYPE_FLAG(dst_selement
->type
, MAGIC_TYPE_UNSIGNED
)) {
649 if(MAGIC_TYPE_FLAG(src_selement
->type
, MAGIC_TYPE_UNSIGNED
)) {
650 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_unsigned(src_selement
), unsigned long, src_value
, long, &r
, 1);
653 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_int(src_selement
), long, src_value
, long, &r
, 0);
665 MAGIC_CHECKED_VALUE_DST_CAST(src_value
, long, value_buffer
, char, &r
);
669 MAGIC_CHECKED_VALUE_DST_CAST(src_value
, long, value_buffer
, short, &r
);
673 MAGIC_CHECKED_VALUE_DST_CAST(src_value
, long, value_buffer
, int, &r
);
676 #ifdef MAGIC_LONG_LONG_SUPPORTED
677 case sizeof(long long):
678 MAGIC_CHECKED_VALUE_DST_CAST(src_value
, long, value_buffer
, long long, &r
);
694 /*===========================================================================*
695 * magic_selement_float_value_cast *
696 *===========================================================================*/
697 PUBLIC
int magic_selement_float_value_cast(const _magic_selement_t
*src_selement
, const _magic_selement_t
*dst_selement
, void* value_buffer
)
699 int src_type_id
= src_selement
->type
->type_id
;
700 int dst_type_id
= dst_selement
->type
->type_id
;
702 unsigned src_size
= src_selement
->type
->size
;
703 unsigned dst_size
= dst_selement
->type
->size
;
705 assert(dst_size
> 0);
707 if(dst_type_id
!= MAGIC_TYPE_FLOAT
) {
710 switch(src_type_id
) {
711 case MAGIC_TYPE_FLOAT
:
712 if(src_size
== dst_size
) {
715 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_float(src_selement
), double, src_value
, double, &r
, 0);
719 case MAGIC_TYPE_INTEGER
:
720 case MAGIC_TYPE_ENUM
:
721 if(MAGIC_TYPE_FLAG(src_selement
->type
, MAGIC_TYPE_UNSIGNED
)) {
722 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_unsigned(src_selement
), unsigned long, src_value
, double, &r
, 1);
725 MAGIC_CHECKED_VALUE_SRC_CAST(magic_selement_to_int(src_selement
), long, src_value
, double, &r
, 1);
737 MAGIC_CHECKED_VALUE_DST_CAST(src_value
, double, value_buffer
, float, &r
);
741 MAGIC_CHECKED_VALUE_DST_CAST(src_value
, double, value_buffer
, double, &r
);
744 #ifdef MAGIC_LONG_DOUBLE_SUPPORTED
745 case sizeof(long double):
746 MAGIC_CHECKED_VALUE_DST_CAST(src_value
, double, value_buffer
, long double, &r
);
762 /*===========================================================================*
763 * magic_selement_value_cast *
764 *===========================================================================*/
765 PUBLIC
int magic_selement_value_cast(const _magic_selement_t
*src_selement
, const _magic_selement_t
*dst_selement
, void* value_buffer
)
767 int r
, src_type_id
, dst_type_id
;
768 size_t src_size
, dst_size
;
769 src_type_id
= src_selement
->type
->type_id
;
770 dst_type_id
= dst_selement
->type
->type_id
;
771 src_size
= src_selement
->type
->size
;
772 dst_size
= dst_selement
->type
->size
;
773 if(src_type_id
== dst_type_id
&& src_size
== dst_size
&& MAGIC_TYPE_FLAG(src_selement
->type
, MAGIC_TYPE_UNSIGNED
) == MAGIC_TYPE_FLAG(dst_selement
->type
, MAGIC_TYPE_UNSIGNED
)) {
777 /* No size change allowed in opaque value casts. */
778 if(src_type_id
== MAGIC_TYPE_OPAQUE
|| dst_type_id
== MAGIC_TYPE_OPAQUE
) {
779 return src_size
== dst_size
? 0 : EINVAL
;
782 /* No size change allowed in void value casts. */
783 if(src_type_id
== MAGIC_TYPE_VOID
|| dst_type_id
== MAGIC_TYPE_VOID
) {
784 return src_size
== dst_size
? 0 : EINVAL
;
787 switch(dst_type_id
) {
788 case MAGIC_TYPE_POINTER
:
789 /* Cast to pointer values. */
790 r
= magic_selement_ptr_value_cast(src_selement
, dst_selement
, value_buffer
);
793 case MAGIC_TYPE_FLOAT
:
794 /* Cast to float values. */
795 r
= magic_selement_float_value_cast(src_selement
, dst_selement
, value_buffer
);
798 case MAGIC_TYPE_INTEGER
:
799 case MAGIC_TYPE_ENUM
:
800 if(MAGIC_TYPE_FLAG(dst_selement
->type
, MAGIC_TYPE_UNSIGNED
)) {
801 /* Cast to unsigned values. */
802 r
= magic_selement_unsigned_value_cast(src_selement
, dst_selement
, value_buffer
);
805 /* Cast to integer values. */
806 r
= magic_selement_int_value_cast(src_selement
, dst_selement
, value_buffer
);
817 /*===========================================================================*
818 * magic_selement_get_parent *
819 *===========================================================================*/
820 PUBLIC _magic_selement_t
* magic_selement_get_parent(
821 const _magic_selement_t
*selement
, _magic_selement_t
*parent_selement
)
823 if(!selement
->parent_type
) {
827 parent_selement
->sentry
= selement
->sentry
;
828 parent_selement
->parent_type
= NULL
;
829 parent_selement
->child_num
= 0;
830 parent_selement
->type
= selement
->parent_type
;
831 parent_selement
->address
= selement
->parent_address
;
832 parent_selement
->num
= 0;
833 assert(parent_selement
->address
>= parent_selement
->sentry
->address
);
835 return parent_selement
;
838 /*===========================================================================*
839 * magic_selement_fill_from_parent_info *
840 *===========================================================================*/
841 PUBLIC
void magic_selement_fill_from_parent_info(_magic_selement_t
*selement
,
845 magic_type_walk_step(selement
->parent_type
,
846 selement
->child_num
, &selement
->type
, &offset
, walk_flags
);
847 selement
->address
= (char*) selement
->parent_address
+ offset
;
850 /*===========================================================================*
851 * magic_selement_from_sentry *
852 *===========================================================================*/
853 PUBLIC _magic_selement_t
* magic_selement_from_sentry(struct _magic_sentry
*sentry
,
854 _magic_selement_t
*selement
)
856 selement
->sentry
= sentry
;
857 selement
->parent_type
= NULL
;
858 selement
->child_num
= 0;
859 selement
->type
= sentry
->type
;
860 selement
->address
= sentry
->address
;
866 /*===========================================================================*
867 * magic_selement_from_relative_name *
868 *===========================================================================*/
869 PUBLIC _magic_selement_t
* magic_selement_from_relative_name(
870 _magic_selement_t
*parent_selement
, _magic_selement_t
*selement
, char* name
)
872 _magic_selement_t new_parent_selement
;
873 const struct _magic_type
* parent_type
= parent_selement
->type
;
874 int parent_type_id
= parent_type
->type_id
;
876 int i
, child_num
= -1;
879 if(!name
|| *name
== '\0') {
883 if(parent_type_id
== MAGIC_TYPE_UNION
&& (*name
>= '0' && *name
<= '9')) {
884 parent_type_id
= MAGIC_TYPE_ARRAY
;
885 walk_flags
= MAGIC_TYPE_WALK_UNIONS_AS_VOID
;
888 switch(parent_type_id
) {
889 case MAGIC_TYPE_ARRAY
:
890 case MAGIC_TYPE_VECTOR
:
891 child_num
= (int) strtol(name
, &end
, 10);
892 if(end
== name
|| *end
!= '\0' || errno
== ERANGE
) {
897 case MAGIC_TYPE_STRUCT
:
898 case MAGIC_TYPE_UNION
:
899 for(i
=0; (unsigned int)i
<parent_type
->num_child_types
;i
++) {
900 if(!strcmp(parent_type
->member_names
[i
], name
)) {
905 if((unsigned int)i
== parent_type
->num_child_types
) {
910 case MAGIC_TYPE_POINTER
:
911 i
= magic_selement_recurse_ptr(parent_selement
, selement
, MAGIC_SELEMENT_MAX_PTR_RECURSIONS
);
912 if(i
<= 0 || i
>= MAGIC_SELEMENT_MAX_PTR_RECURSIONS
) {
915 new_parent_selement
= *selement
;
916 return magic_selement_from_relative_name(&new_parent_selement
, selement
, name
);
924 if(child_num
!= -1) {
925 selement
->sentry
= parent_selement
->sentry
;
926 selement
->parent_type
= parent_type
;
927 selement
->parent_address
= parent_selement
->address
;
928 selement
->child_num
= child_num
;
929 selement
->num
= parent_selement
->num
+1;
930 magic_selement_fill_from_parent_info(selement
, walk_flags
);