Merge pull request #4048 from kumpera/iface_casting_cleanup
[mono.git] / mono / dis / util.c
1 /*
2  * util.c: Assorted utilities for the disassembler
3  *
4  * Author:
5  *   Miguel de Icaza (miguel@ximian.com)
6  *
7  * (C) 2001 Ximian, Inc (http://www.ximian.com)
8  */
9 #include <config.h>
10 #include <glib.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <math.h>
14 #include "util.h"
15 #include "mono/utils/mono-compiler.h"
16
17 #ifdef HAVE_IEEEFP_H
18 #include <ieeefp.h>
19 #endif
20
21 /**
22  * map:
23  * @code: code to lookup in table
24  * @table: table to decode code
25  *
26  * Warning: returns static buffer.
27  */
28 const char *
29 map (guint32 code, dis_map_t *table)
30 {
31         int i;
32
33         for (i = 0; table [i].str != NULL; i++)
34                 if (table [i].code == code)
35                         return table [i].str;
36         return "invalid-flags";
37 }
38
39 /**
40  * flags:
41  * @code: bitfield
42  * @table: table to decode bitfield
43  *
44  * Warning: returns static buffer.
45  */
46 const char *
47 flags (guint32 code, dis_map_t *table)
48 {
49         static char buffer [1024];
50         int i;
51         
52         buffer [0] = 0;
53         
54         for (i = 0; code && table [i].str != NULL; i++)
55                 if (table [i].code & code) {
56                         code &= ~table [i].code;
57                         strcat (buffer, table [i].str);
58                 }
59
60         if (code)
61                 sprintf (buffer + strlen (buffer), "unknown-flag-%2x ", code);
62
63         return buffer;
64 }
65
66 /**
67  * hex_dump:
68  * @buffer: pointer to buffer to dump
69  * @base: numbering base to use
70  * @count: number of bytes to dump
71  */
72 void
73 hex_dump (const char *buffer, int base, int count)
74 {
75         int show_header = 1;
76         int i;
77
78         if (count < 0){
79                 count = -count;
80                 show_header = 0;
81         }
82         
83         for (i = 0; i < count; i++){
84                 if (show_header)
85                         if ((i % 16) == 0)
86                                 printf ("\n0x%08X: ", (unsigned char) base + i);
87
88                 printf ("%02X ", (unsigned char) (buffer [i]));
89         }
90         fflush (stdout);
91 }
92
93 char*
94 data_dump (const char *data, int len, const char* prefix) {
95         int i, j;
96         GString *str;
97         if (!len)
98                 return g_strdup (" ()\n");
99         str = g_string_new (" (");
100         for (i = 0; i + 15 < len; i += 16) {
101                 if (i == 0)
102                         g_string_append_printf (str, "\n");
103                 g_string_append_printf (str, "%s", prefix);
104                 for (j = 0; j < 16; ++j)
105                         g_string_append_printf (str, "%02X ", (unsigned char) (data [i + j]));
106                 g_string_append_printf (str, i == len - 16? ") // ": "  // ");
107                 for (j = 0; j < 16; ++j)
108                         g_string_append_printf (str, "%c", data [i + j] >= 32 && data [i + j] <= 126? data [i + j]: '.');
109                 g_string_append_printf (str, "\n");
110         }
111         if (i == len)
112                 return g_string_free (str, FALSE);
113         if (len > 16)
114                 g_string_append_printf (str, "%s", prefix);
115         j = i;
116         for (; i < len; ++i)
117                 g_string_append_printf (str, "%02X ", (unsigned char) (data [i]));
118         if (len > 16) {
119                 /* align */
120                 int count = 16 - (len % 16);
121                 for (i = 0; i < count; ++i)
122                         g_string_append_printf (str, "   ");
123         }
124         g_string_append_printf (str, ") // ");
125         for (i = j; i < len; ++i)
126                 g_string_append_printf (str, "%c", data [i] >= 32 && data [i] <= 126? data [i]: '.');
127         g_string_append_printf (str, "\n");
128         return g_string_free (str, FALSE);
129 }
130
131 int
132 dis_isinf (double num)
133 {
134 #ifdef HAVE_ISINF
135         return isinf (num);
136 #elif defined(HAVE_IEEEFP_H)
137         fpclass_t klass;
138
139         klass = fpclass (num);
140         if (klass == FP_NINF)
141                 return -1;
142
143         if (klass == FP_PINF)
144                 return 1;
145
146         return 0;
147 #elif defined(HAVE__FINITE)
148         return _finite (num) ? 0 : 1;
149 #else
150 #error "Don't know how to implement isinf for this platform."
151 #endif
152 }
153
154 int
155 dis_isnan (double num)
156 {
157 #ifdef __MINGW32_VERSION
158 return _isnan (num);
159 #else
160 return isnan (num);
161 #endif
162 }
163