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