-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgron.c
131 lines (119 loc) · 3.38 KB
/
gron.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// This example binary implements a simplified version of gron (https://github.com/tomnomnom/gron).
// Limitations compared to the original:
// - Very limited CLI arguments parsing.
// - Does not escape strings on output.
// - Can only parse, not write, JSON.
//
// To run with the example JSON file:
//
// bazel run //examples:gron examples/testdata/docker-inspect.json
//
// or
//
// bazel run //examples:gron -- - < examples/testdata/docker-inspect.json
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "src/jsonst.h"
#include "src/jsonst_util.h"
static void jsonst_path_print(const jsonst_path *path) {
printf("json");
for (const jsonst_path *p = path; p != NULL; p = p->next) {
switch (p->type) {
case jsonst_arry_elm:
printf("[%d]", p->props.arry_ix);
break;
case jsonst_obj_key:
printf(".%.*s", (int)p->props.obj_key.str_len, p->props.obj_key.str);
break;
default:
break;
}
}
}
static void cb(__attribute((unused)) void *cb_user_data, const jsonst_value *value,
const jsonst_path *p) {
switch (value->type) {
case jsonst_obj_key:
case jsonst_arry_end:
case jsonst_obj_end:
return;
default:
break;
}
jsonst_path_print(p);
printf(" = ");
switch (value->type) {
case jsonst_null:
printf("null");
break;
case jsonst_true:
printf("true");
break;
case jsonst_false:
printf("true");
break;
case jsonst_num:
printf("%.*s", (int)value->val_str.str_len, value->val_str.str);
break;
case jsonst_str:
printf("\"%.*s\"", (int)value->val_str.str_len, value->val_str.str);
break;
case jsonst_arry:
printf("[]");
break;
case jsonst_obj:
printf("{}");
break;
default:
fprintf(stderr, "Unhandled type [%d], this is a bug!\n", (int)value->type);
exit(1);
}
printf(";\n");
}
int main(const int argc, const char **argv) {
// Open file.
if (argc != 2) {
printf("usage: gron <input>.json\n");
return EXIT_FAILURE;
}
FILE *inf;
if (strlen(argv[1]) == 1 && argv[1][0] == '-') {
inf = stdin;
} else {
inf = fopen(argv[1], "r");
if (inf == NULL) {
fprintf(stderr, "Unable to open file '%s'!\n", argv[1]);
return EXIT_FAILURE;
}
}
// Prepare parser.
const ptrdiff_t memsz = 1024 * 8;
void *mem = malloc(memsz);
assert(mem != NULL);
jsonst_config conf = {0};
conf.str_alloc_bytes = 2048;
conf.obj_key_alloc_bytes = 16;
conf.num_alloc_bytes = 16;
jsonst j = new_jsonst((uint8_t *)mem, memsz, cb, NULL, conf);
// Process file.
while (1) {
int c = fgetc(inf);
if (c == EOF) {
c = JSONST_EOF;
}
const jsonst_error ret = jsonst_feed(j, (char)c);
if (ret != jsonst_success) {
fprintf(stderr, "Parsing error: %s\n", jsonst_error_to_str(ret));
return EXIT_FAILURE;
}
if (c == JSONST_EOF) {
break;
}
}
// Cleanup.
fclose(inf);
free(mem);
return EXIT_SUCCESS;
}