1
2
3
4
5
6
7
8
9
10
11
12#include <stdarg.h>
13#include <stdio.h>
14
15#include "utils.h"
16#include "json_print.h"
17
18static json_writer_t *_jw;
19
20#define _IS_JSON_CONTEXT(type) ((type & PRINT_JSON || type & PRINT_ANY) && _jw)
21#define _IS_FP_CONTEXT(type) (!_jw && (type & PRINT_FP || type & PRINT_ANY))
22
23static void __new_json_obj(int json, bool have_array)
24{
25 if (json) {
26 _jw = jsonw_new(stdout);
27 if (!_jw) {
28 perror("json object");
29 exit(1);
30 }
31 if (pretty)
32 jsonw_pretty(_jw, true);
33 if (have_array)
34 jsonw_start_array(_jw);
35 }
36}
37
38static void __delete_json_obj(bool have_array)
39{
40 if (_jw) {
41 if (have_array)
42 jsonw_end_array(_jw);
43 jsonw_destroy(&_jw);
44 }
45}
46
47void new_json_obj(int json)
48{
49 __new_json_obj(json, true);
50}
51
52void delete_json_obj(void)
53{
54 __delete_json_obj(true);
55}
56
57void new_json_obj_plain(int json)
58{
59 __new_json_obj(json, false);
60}
61
62void delete_json_obj_plain(void)
63{
64 __delete_json_obj(false);
65}
66
67bool is_json_context(void)
68{
69 return _jw != NULL;
70}
71
72json_writer_t *get_json_writer(void)
73{
74 return _jw;
75}
76
77void open_json_object(const char *str)
78{
79 if (_IS_JSON_CONTEXT(PRINT_JSON)) {
80 if (str)
81 jsonw_name(_jw, str);
82 jsonw_start_object(_jw);
83 }
84}
85
86void close_json_object(void)
87{
88 if (_IS_JSON_CONTEXT(PRINT_JSON))
89 jsonw_end_object(_jw);
90}
91
92
93
94
95
96
97void open_json_array(enum output_type type, const char *str)
98{
99 if (_IS_JSON_CONTEXT(type)) {
100 if (str)
101 jsonw_name(_jw, str);
102 jsonw_start_array(_jw);
103 } else if (_IS_FP_CONTEXT(type)) {
104 printf("%s", str);
105 }
106}
107
108
109
110
111void close_json_array(enum output_type type, const char *str)
112{
113 if (_IS_JSON_CONTEXT(type)) {
114 jsonw_end_array(_jw);
115 } else if (_IS_FP_CONTEXT(type)) {
116 printf("%s", str);
117 }
118}
119
120
121
122
123
124#define _PRINT_FUNC(type_name, type) \
125 __attribute__((format(printf, 4, 0))) \
126 int print_color_##type_name(enum output_type t, \
127 enum color_attr color, \
128 const char *key, \
129 const char *fmt, \
130 type value) \
131 { \
132 int ret = 0; \
133 if (_IS_JSON_CONTEXT(t)) { \
134 if (!key) \
135 jsonw_##type_name(_jw, value); \
136 else \
137 jsonw_##type_name##_field(_jw, key, value); \
138 } else if (_IS_FP_CONTEXT(t)) { \
139 ret = color_fprintf(stdout, color, fmt, value); \
140 } \
141 return ret; \
142 }
143_PRINT_FUNC(int, int);
144_PRINT_FUNC(s64, int64_t);
145_PRINT_FUNC(hhu, unsigned char);
146_PRINT_FUNC(hu, unsigned short);
147_PRINT_FUNC(uint, unsigned int);
148_PRINT_FUNC(u64, uint64_t);
149_PRINT_FUNC(luint, unsigned long);
150_PRINT_FUNC(lluint, unsigned long long);
151_PRINT_FUNC(float, double);
152#undef _PRINT_FUNC
153
154#define _PRINT_NAME_VALUE_FUNC(type_name, type, format_char) \
155 void print_##type_name##_name_value(const char *name, type value)\
156 { \
157 SPRINT_BUF(format); \
158 \
159 snprintf(format, SPRINT_BSIZE, \
160 "%s %%"#format_char, name); \
161 print_##type_name(PRINT_ANY, name, format, value); \
162 }
163_PRINT_NAME_VALUE_FUNC(uint, unsigned int, u);
164_PRINT_NAME_VALUE_FUNC(string, const char*, s);
165#undef _PRINT_NAME_VALUE_FUNC
166
167int print_color_string(enum output_type type,
168 enum color_attr color,
169 const char *key,
170 const char *fmt,
171 const char *value)
172{
173 int ret = 0;
174
175 if (_IS_JSON_CONTEXT(type)) {
176 if (key && !value)
177 jsonw_name(_jw, key);
178 else if (!key && value)
179 jsonw_string(_jw, value);
180 else
181 jsonw_string_field(_jw, key, value);
182 } else if (_IS_FP_CONTEXT(type)) {
183 ret = color_fprintf(stdout, color, fmt, value);
184 }
185
186 return ret;
187}
188
189
190
191
192
193
194int print_color_bool(enum output_type type,
195 enum color_attr color,
196 const char *key,
197 const char *fmt,
198 bool value)
199{
200 int ret = 0;
201
202 if (_IS_JSON_CONTEXT(type)) {
203 if (key)
204 jsonw_bool_field(_jw, key, value);
205 else
206 jsonw_bool(_jw, value);
207 } else if (_IS_FP_CONTEXT(type)) {
208 ret = color_fprintf(stdout, color, fmt,
209 value ? "true" : "false");
210 }
211
212 return ret;
213}
214
215
216
217
218int print_color_0xhex(enum output_type type,
219 enum color_attr color,
220 const char *key,
221 const char *fmt,
222 unsigned long long hex)
223{
224 int ret = 0;
225
226 if (_IS_JSON_CONTEXT(type)) {
227 SPRINT_BUF(b1);
228
229 snprintf(b1, sizeof(b1), "%#llx", hex);
230 print_string(PRINT_JSON, key, NULL, b1);
231 } else if (_IS_FP_CONTEXT(type)) {
232 ret = color_fprintf(stdout, color, fmt, hex);
233 }
234
235 return ret;
236}
237
238int print_color_hex(enum output_type type,
239 enum color_attr color,
240 const char *key,
241 const char *fmt,
242 unsigned int hex)
243{
244 int ret = 0;
245
246 if (_IS_JSON_CONTEXT(type)) {
247 SPRINT_BUF(b1);
248
249 snprintf(b1, sizeof(b1), "%x", hex);
250 if (key)
251 jsonw_string_field(_jw, key, b1);
252 else
253 jsonw_string(_jw, b1);
254 } else if (_IS_FP_CONTEXT(type)) {
255 ret = color_fprintf(stdout, color, fmt, hex);
256 }
257
258 return ret;
259}
260
261
262
263
264
265int print_color_null(enum output_type type,
266 enum color_attr color,
267 const char *key,
268 const char *fmt,
269 const char *value)
270{
271 int ret = 0;
272
273 if (_IS_JSON_CONTEXT(type)) {
274 if (key)
275 jsonw_null_field(_jw, key);
276 else
277 jsonw_null(_jw);
278 } else if (_IS_FP_CONTEXT(type)) {
279 ret = color_fprintf(stdout, color, fmt, value);
280 }
281
282 return ret;
283}
284
285
286void print_nl(void)
287{
288 if (!_jw)
289 printf("%s", _SL_);
290}
291