Coverage Report

Created: 2023-12-08 06:05

/src/capstonenext/SStream.c
Line
Count
Source (jump to first uncovered line)
1
/* Capstone Disassembly Engine */
2
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */
3
4
#include <stdarg.h>
5
#if defined(CAPSTONE_HAS_OSXKERNEL)
6
#include <Availability.h>
7
#include <libkern/libkern.h>
8
#include <i386/limits.h>
9
#else
10
#include <stdio.h>
11
#include <limits.h>
12
#endif
13
#include <string.h>
14
15
#include <capstone/platform.h>
16
17
#include "SStream.h"
18
#include "cs_priv.h"
19
#include "utils.h"
20
21
#ifdef _MSC_VER
22
#pragma warning(disable: 4996) // disable MSVC's warning on strcpy()
23
#endif
24
25
void SStream_Init(SStream *ss)
26
3.32M
{
27
3.32M
  assert(ss);
28
3.32M
  ss->index = 0;
29
3.32M
  ss->buffer[0] = '\0';
30
3.32M
  ss->is_closed = false;
31
3.32M
}
32
33
/**
34
 * Open the output stream. Every write attempt is accepted again.
35
 */
36
0
void SStream_Open(SStream *ss) {
37
0
  assert(ss);
38
0
  ss->is_closed = false;
39
0
}
40
41
/**
42
 * Closes the output stream. Every write attempt is ignored.
43
 */
44
0
void SStream_Close(SStream *ss) {
45
0
  assert(ss);
46
0
  ss->is_closed = true;
47
0
}
48
49
/**
50
 * Copy the string \p s to the buffer of \p ss and terminate it with a '\\0' byte.
51
 */
52
void SStream_concat0(SStream *ss, const char *s)
53
17.8M
{
54
17.8M
#ifndef CAPSTONE_DIET
55
17.8M
  SSTREAM_RETURN_IF_CLOSED(ss);
56
17.8M
  if (s[0] == '\0')
57
5.49M
    return;
58
12.3M
  unsigned int len = (unsigned int) strlen(s);
59
60
12.3M
  memcpy(ss->buffer + ss->index, s, len);
61
12.3M
  ss->index += len;
62
12.3M
  ss->buffer[ss->index] = '\0';
63
12.3M
#endif
64
12.3M
}
65
66
/**
67
 * Copy the single char \p c to the buffer of \p ss.
68
 */
69
void SStream_concat1(SStream *ss, const char c)
70
849k
{
71
849k
#ifndef CAPSTONE_DIET
72
849k
  SSTREAM_RETURN_IF_CLOSED(ss);
73
849k
  if (c == '\0')
74
12.8k
    return;
75
836k
  ss->buffer[ss->index] = c;
76
836k
  ss->index++;
77
836k
  ss->buffer[ss->index] = '\0';
78
836k
#endif
79
836k
}
80
81
/**
82
 * Copy all strings given to the buffer of \p ss according to formatting \p fmt.
83
 */
84
void SStream_concat(SStream *ss, const char *fmt, ...)
85
8.72M
{
86
8.72M
#ifndef CAPSTONE_DIET
87
8.72M
  SSTREAM_RETURN_IF_CLOSED(ss);
88
8.72M
  va_list ap;
89
8.72M
  int ret;
90
91
8.72M
  va_start(ap, fmt);
92
8.72M
  ret = cs_vsnprintf(ss->buffer + ss->index, sizeof(ss->buffer) - (ss->index + 1), fmt, ap);
93
8.72M
  va_end(ap);
94
8.72M
  ss->index += ret;
95
8.72M
#endif
96
8.72M
}
97
98
// print number with prefix #
99
void printInt64Bang(SStream *O, int64_t val)
100
75.9k
{
101
75.9k
  SSTREAM_RETURN_IF_CLOSED(O);
102
75.9k
  if (val >= 0) {
103
69.4k
    if (val > HEX_THRESHOLD)
104
41.7k
      SStream_concat(O, "#0x%"PRIx64, val);
105
27.6k
    else
106
27.6k
      SStream_concat(O, "#%"PRIu64, val);
107
69.4k
  } else {
108
6.55k
    if (val <- HEX_THRESHOLD) {
109
5.14k
      if (val == LONG_MIN)
110
12
        SStream_concat(O, "#-0x%"PRIx64, (uint64_t)val);
111
5.13k
      else
112
5.13k
        SStream_concat(O, "#-0x%"PRIx64, (uint64_t)-val);
113
5.14k
    } else
114
1.41k
      SStream_concat(O, "#-%"PRIu64, -val);
115
6.55k
  }
116
75.9k
}
117
118
void printUInt64Bang(SStream *O, uint64_t val)
119
8.34k
{
120
8.34k
  SSTREAM_RETURN_IF_CLOSED(O);
121
8.34k
  if (val > HEX_THRESHOLD)
122
7.04k
    SStream_concat(O, "#0x%"PRIx64, val);
123
1.29k
  else
124
1.29k
    SStream_concat(O, "#%"PRIu64, val);
125
8.34k
}
126
127
// print number
128
void printInt64(SStream *O, int64_t val)
129
585k
{
130
585k
  SSTREAM_RETURN_IF_CLOSED(O);
131
585k
  if (val >= 0) {
132
526k
    if (val > HEX_THRESHOLD)
133
323k
      SStream_concat(O, "0x%"PRIx64, val);
134
202k
    else
135
202k
      SStream_concat(O, "%"PRIu64, val);
136
526k
  } else {
137
59.0k
    if (val <- HEX_THRESHOLD) {
138
55.2k
      if (val == LONG_MIN)
139
0
        SStream_concat(O, "-0x%"PRIx64, (uint64_t)val);
140
55.2k
      else
141
55.2k
        SStream_concat(O, "-0x%"PRIx64, (uint64_t)-val);
142
55.2k
    } else
143
3.81k
      SStream_concat(O, "-%"PRIu64, -val);
144
59.0k
  }
145
585k
}
146
147
void printUInt64(SStream *O, uint64_t val)
148
99.9k
{
149
99.9k
  SSTREAM_RETURN_IF_CLOSED(O);
150
99.9k
  if (val > HEX_THRESHOLD)
151
83.1k
    SStream_concat(O, "0x%"PRIx64, val);
152
16.7k
  else
153
16.7k
    SStream_concat(O, "%"PRIu64, val);
154
99.9k
}
155
156
// print number in decimal mode
157
void printInt32BangDec(SStream *O, int32_t val)
158
{
159
  SSTREAM_RETURN_IF_CLOSED(O);
160
  if (val >= 0)
161
    SStream_concat(O, "#%u", val);
162
  else {
163
    if (val == INT_MIN)
164
      SStream_concat(O, "#-%u", val);
165
    else
166
      SStream_concat(O, "#-%u", (uint32_t)-val);
167
  }
168
}
169
170
void printInt32Bang(SStream *O, int32_t val)
171
153k
{
172
153k
  SSTREAM_RETURN_IF_CLOSED(O);
173
153k
  if (val >= 0) {
174
113k
    if (val > HEX_THRESHOLD)
175
72.5k
      SStream_concat(O, "#0x%x", val);
176
40.9k
    else
177
40.9k
      SStream_concat(O, "#%u", val);
178
113k
  } else {
179
40.3k
    if (val <- HEX_THRESHOLD) {
180
35.9k
      if (val == INT_MIN)
181
0
        SStream_concat(O, "#-0x%x", (uint32_t)val);
182
35.9k
      else
183
35.9k
        SStream_concat(O, "#-0x%x", (uint32_t)-val);
184
35.9k
    } else
185
4.45k
      SStream_concat(O, "#-%u", -val);
186
40.3k
  }
187
153k
}
188
189
void printInt32(SStream *O, int32_t val)
190
49.9k
{
191
49.9k
  SSTREAM_RETURN_IF_CLOSED(O);
192
49.9k
  if (val >= 0) {
193
36.8k
    if (val > HEX_THRESHOLD)
194
25.2k
      SStream_concat(O, "0x%x", val);
195
11.6k
    else
196
11.6k
      SStream_concat(O, "%u", val);
197
36.8k
  } else {
198
13.0k
    if (val <- HEX_THRESHOLD) {
199
12.7k
      if (val == INT_MIN)
200
42
        SStream_concat(O, "-0x%x", (uint32_t)val);
201
12.7k
      else
202
12.7k
        SStream_concat(O, "-0x%x", (uint32_t)-val);
203
12.7k
    } else
204
343
      SStream_concat(O, "-%u", -val);
205
13.0k
  }
206
49.9k
}
207
208
void printUInt32Bang(SStream *O, uint32_t val)
209
246k
{
210
246k
  SSTREAM_RETURN_IF_CLOSED(O);
211
246k
  if (val > HEX_THRESHOLD)
212
205k
    SStream_concat(O, "#0x%x", val);
213
40.7k
  else
214
40.7k
    SStream_concat(O, "#%u", val);
215
246k
}
216
217
void printUInt32(SStream *O, uint32_t val)
218
80.2k
{
219
80.2k
  SSTREAM_RETURN_IF_CLOSED(O);
220
80.2k
  if (val > HEX_THRESHOLD)
221
54.1k
    SStream_concat(O, "0x%x", val);
222
26.0k
  else
223
26.0k
    SStream_concat(O, "%u", val);
224
80.2k
}
225
226
void printFloat(SStream *O, float val)
227
0
{
228
0
  SSTREAM_RETURN_IF_CLOSED(O);
229
0
  SStream_concat(O, "%e", val);
230
0
}
231
232
void printFloatBang(SStream *O, float val)
233
565
{
234
565
  SSTREAM_RETURN_IF_CLOSED(O);
235
565
  SStream_concat(O, "#%e", val);
236
565
}