Rizin
unix-like reverse engineering framework and cli tools
json_indent.c File Reference
#include <rz_util.h>

Go to the source code of this file.

Macros

#define EMIT_ESC(s, code)
 
#define DSZ   128
 

Enumerations

enum  {
  JC_FALSE , JC_TRUE , JC_KEY , JC_VAL ,
  JC_RESET
}
 

Functions

static void doIndent (int idt, char **o, const char *tab)
 
RZ_API char * rz_print_json_path (const char *s, int pos)
 
RZ_API char * rz_print_json_human (const char *s)
 
RZ_API char * rz_print_json_indent (const char *s, bool color, const char *tab, const char **palette)
 

Variables

static const char * origColors []
 

Macro Definition Documentation

◆ DSZ

#define DSZ   128

◆ EMIT_ESC

#define EMIT_ESC (   s,
  code 
)
Value:
do { \
if (color) { \
const char *p = code; \
while (*p) { \
*(s)++ = *p++; \
} \
} \
} while (0);
void * p
Definition: libc.cpp:67
const char * code
Definition: pal.c:98
static RzSocket * s
Definition: rtr.c:28
static int color
Definition: visual.c:20

Definition at line 16 of file json_indent.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
JC_FALSE 
JC_TRUE 
JC_KEY 
JC_VAL 
JC_RESET 

Definition at line 26 of file json_indent.c.

26  {
27  JC_FALSE, // 31m
28  JC_TRUE, // 32m
29  JC_KEY, // 33m
30  JC_VAL, // 34m
31  JC_RESET,
32 };
@ JC_FALSE
Definition: json_indent.c:27
@ JC_TRUE
Definition: json_indent.c:28
@ JC_KEY
Definition: json_indent.c:29
@ JC_RESET
Definition: json_indent.c:31
@ JC_VAL
Definition: json_indent.c:30

Function Documentation

◆ doIndent()

static void doIndent ( int  idt,
char **  o,
const char *  tab 
)
static

Definition at line 6 of file json_indent.c.

6  {
7  int i;
8  char *x;
9  for (i = 0; i < idt; i++) {
10  for (x = (char *)tab; *x; x++) {
11  *(*o)++ = *x;
12  }
13  }
14 }
lzma_index ** i
Definition: index.h:629
int x
Definition: mipsasm.c:20
Definition: enough.c:118

References i, and x.

Referenced by rz_print_json_human(), and rz_print_json_indent().

◆ rz_print_json_human()

RZ_API char* rz_print_json_human ( const char *  s)

Definition at line 155 of file json_indent.c.

155  {
156  int indent = 0;
157  const char *tab = " ";
158  const int indentSize = strlen(tab);
159  int instr = 0;
160  char *o, *OE, *tmp;
161  if (!s) {
162  return NULL;
163  }
164  int osz = (1 + strlen(s)) * 20;
165  if (osz < 1) {
166  return NULL;
167  }
168 
169  char *O = malloc(osz);
170  if (!O) {
171  return NULL;
172  }
173  OE = O + osz;
174  for (o = O; *s; s++) {
175  if (o + (indent * indentSize) + 10 > OE) {
176  int delta = o - O;
177  osz += 0x1000 + (indent * indentSize);
178  if (osz < 1) {
179  free(O);
180  return NULL;
181  }
182  tmp = realloc(O, osz);
183  if (!tmp) {
184  free(O);
185  return NULL;
186  }
187  O = tmp;
188  OE = tmp + osz;
189  o = O + delta;
190  }
191  if (instr) {
192  if (s[0] == '"') {
193  instr = 0;
194  } else if (s[0] == '\\' && s[1] == '"') {
195  // XXX maybe buggy
196  *o++ = *s++;
197  }
198  if (*s != '"') {
199  *o++ = *s;
200  }
201  continue;
202  }
203  if (indent <= 0) {
204  // non-JSON part
205  if (s[0] != '{' && s[0] != '[') {
206  *o++ = *s;
207  continue;
208  }
209  }
210 
211  if (s[0] == '"') {
212  instr = 1;
213  }
214  if (*s == '\n' || *s == '\r' || *s == '\t' || *s == ' ') {
215  continue;
216  }
217  switch (*s) {
218  case ':':
219  *o++ = *s;
220  *o++ = ' ';
221  break;
222  case ',':
223  *o++ = '\n';
224  doIndent(indent - 1, &o, tab);
225  break;
226  case '{':
227  case '[':
228  if (indent > 0) {
229  *o++ = (indent != -1) ? '\n' : ' ';
230  }
231  if (indent > 128) {
232  eprintf("JSON indentation is too deep\n");
233  indent = 0;
234  } else {
235  indent++;
236  }
237  doIndent(indent - 1, &o, tab);
238  break;
239  case '}':
240  case ']':
241  indent--;
242  doIndent(indent - 1, &o, tab);
243  break;
244  default:
245  if (!instr) {
246  *o++ = *s;
247  }
248  }
249  }
250  *o = 0;
251  return O;
252 }
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
static void doIndent(int idt, char **o, const char *tab)
Definition: json_indent.c:6
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
#define O
Definition: rcond.c:14
#define eprintf(x, y...)
Definition: rlcc.c:7
static st64 delta
Definition: vmenus.c:2425

References delta, doIndent(), eprintf, free(), malloc(), NULL, O, realloc(), s, and autogen_x86imm::tmp.

Referenced by rz_cons_grepbuf().

◆ rz_print_json_indent()

RZ_API char* rz_print_json_indent ( const char *  s,
bool  color,
const char *  tab,
const char **  palette 
)

Definition at line 254 of file json_indent.c.

254  {
255  int indent = 0;
256  const int indentSize = strlen(tab);
257  int instr = 0;
258  bool isValue = false;
259  char *o, *OE, *tmp;
260  if (!s) {
261  return NULL;
262  }
263  const char **colors = palette ? palette : origColors;
264  int osz = (1 + strlen(s)) * 20;
265  if (osz < 1) {
266  return NULL;
267  }
268 
269  char *O = malloc(osz);
270  if (!O) {
271  return NULL;
272  }
273  OE = O + osz;
274  for (o = O; *s; s++) {
275  if (o + (indent * indentSize) + 10 > OE) {
276  int delta = o - O;
277  osz += 0x1000 + (indent * indentSize);
278  if (osz < 1) {
279  free(O);
280  return NULL;
281  }
282  tmp = realloc(O, osz);
283  if (!tmp) {
284  free(O);
285  return NULL;
286  }
287  O = tmp;
288  OE = tmp + osz;
289  o = O + delta;
290  }
291  if (instr) {
292  if (s[0] == '"') {
293  instr = 0;
294  } else if (s[0] == '\\' && s[1] == '"') {
295  *o++ = *s++;
296  }
297  if (instr) {
298  if (isValue) {
299  // TODO: do not emit color in every char
300  EMIT_ESC(o, colors[JC_VAL]);
301  } else {
302  EMIT_ESC(o, colors[JC_KEY]);
303  }
304  } else {
305  EMIT_ESC(o, colors[JC_RESET]);
306  }
307  *o++ = *s;
308  continue;
309  }
310  if (indent <= 0) {
311  // non-JSON part, skip it
312  if (s[0] != '{' && s[0] != '[') {
313  if (*s == '\n' || *s == '\r' || *s == '\t' || *s == ' ') {
314  *o++ = *s;
315  }
316  continue;
317  }
318  }
319 
320  if (s[0] == '"') {
321  instr = 1;
322  }
323  if (*s == '\n' || *s == '\r' || *s == '\t' || *s == ' ' || !IS_PRINTABLE(*s)) {
324  continue;
325  }
326  switch (*s) {
327  case ':':
328  *o++ = *s;
329  *o++ = ' ';
330  s = rz_str_trim_head_ro(s + 1);
331  if (!strncmp(s, "true", 4)) {
332  EMIT_ESC(o, colors[JC_TRUE]);
333  } else if (!strncmp(s, "false", 5)) {
334  EMIT_ESC(o, colors[JC_FALSE]);
335  }
336  s--;
337  isValue = true;
338  break;
339  case ',':
340  EMIT_ESC(o, colors[JC_RESET]);
341  *o++ = *s;
342  *o++ = '\n';
343  isValue = false;
344  doIndent(indent, &o, tab);
345  break;
346  case '{':
347  case '[':
348  isValue = false;
349  *o++ = *s;
350  *o++ = (indent != -1) ? '\n' : ' ';
351  if (indent > 128) {
352  eprintf("JSON indentation is too deep\n");
353  indent = 0;
354  } else {
355  indent++;
356  }
357  doIndent(indent, &o, tab);
358  break;
359  case '}':
360  case ']':
361  EMIT_ESC(o, colors[JC_RESET]);
362  isValue = false;
363  *o++ = '\n';
364  indent--;
365  doIndent(indent, &o, tab);
366  *o++ = *s;
367  break;
368  default:
369  *o++ = *s;
370  }
371  }
372  *o = 0;
373  return O;
374 }
static const char * origColors[]
Definition: json_indent.c:34
#define EMIT_ESC(s, code)
Definition: json_indent.c:16
struct @219 colors[]
RZ_API const char * rz_str_trim_head_ro(const char *str)
Definition: str_trim.c:86
#define IS_PRINTABLE(x)
Definition: rz_str_util.h:10

References colors, delta, doIndent(), EMIT_ESC, eprintf, free(), IS_PRINTABLE, JC_FALSE, JC_KEY, JC_RESET, JC_TRUE, JC_VAL, malloc(), NULL, O, origColors, realloc(), rz_str_trim_head_ro(), s, and autogen_x86imm::tmp.

Referenced by rz_cmd_print(), and rz_cons_grepbuf().

◆ rz_print_json_path()

RZ_API char* rz_print_json_path ( const char *  s,
int  pos 
)

Definition at line 43 of file json_indent.c.

43  {
44  int indent = 0;
45 #define DSZ 128
46  const char *words[DSZ] = { NULL };
47  int lengths[DSZ] = { 0 };
48  int indexs[DSZ] = { 0 };
49  int instr = 0;
50  bool isarr = false;
51  if (!s) {
52  return NULL;
53  }
54  int arrpos = 0;
55  const char *os = s;
56  int osz = (1 + strlen(s)) * 20;
57  if (osz < 1) {
58  return NULL;
59  }
60 
61  const char *str_a = NULL;
62  for (; *s; s++) {
63  if (instr) {
64  if (s[0] == '"') {
65  instr = 0;
66  ut64 cur = str_a - os;
67  if (cur > pos) {
68  break;
69  }
70  if (indent < DSZ) {
71  words[indent - 1] = str_a;
72  lengths[indent - 1] = s - str_a;
73  indexs[indent - 1] = 0;
74  }
75  }
76  continue;
77  }
78 
79  if (s[0] == '"') {
80  instr = 1;
81  str_a = s + 1;
82  }
83  if (*s == '\n' || *s == '\r' || *s == '\t' || *s == ' ') {
84  continue;
85  }
86  switch (*s) {
87  case ':':
88  break;
89  case ',':
90  if (isarr) {
91  arrpos++;
92  if (indent < DSZ) {
93  indexs[indent - 1] = arrpos;
94  lengths[indent - 1] = (s - os);
95  }
96  }
97  break;
98  case '{':
99  case '[':
100  if (*s == '[') {
101  isarr = true;
102  arrpos = 0;
103  }
104  if (indent > 128) {
105  eprintf("JSON indentation is too deep\n");
106  indent = 0;
107  } else {
108  indent++;
109  }
110  break;
111  case '}':
112  case ']':
113  if (*s == ']') {
114  isarr = false;
115  }
116  indent--;
117  break;
118  }
119  }
120  int i;
121  ut64 opos = 0;
122  for (i = 0; i < DSZ && i < indent; i++) {
123  if ((int)(size_t)words[i] < DSZ) {
124  ut64 cur = lengths[i];
125  if (cur < opos) {
126  continue;
127  }
128  opos = cur;
129  if (cur > pos) {
130  break;
131  }
132  eprintf("0x%08" PFMT64x " %d [%d]\n", cur, i, indexs[i]);
133  } else {
134  ut64 cur = words[i] - os - 1;
135  if (cur < opos) {
136  continue;
137  }
138  opos = cur;
139  if (cur > pos) {
140  break;
141  }
142  char *a = rz_str_ndup(words[i], lengths[i]);
143  char *q = strchr(a, '"');
144  if (q) {
145  *q = 0;
146  }
147  eprintf("0x%08" PFMT64x " %d %s\n", cur, i, a);
148  free(a);
149  }
150  }
151  // TODO return something
152  return NULL;
153 }
#define DSZ
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006
#define PFMT64x
Definition: rz_types.h:393
#define a(i)
Definition: sha256.c:41
int pos
Definition: main.c:11
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References a, DSZ, eprintf, free(), i, NULL, PFMT64x, pos, rz_str_ndup(), s, and ut64().

Referenced by rz_cmd_print().

Variable Documentation

◆ origColors

const char* origColors[]
static
Initial value:
= {
"\x1b[31m",
"\x1b[32m",
"\x1b[33m",
"\x1b[34m",
"\x1b[0m",
}

Definition at line 34 of file json_indent.c.

Referenced by rz_print_json_indent().