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