1 /*
2 * Copyright (c) 2020, Rockchip Electronics Co., Ltd
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15 #include "j2s.h"
16
17 static inline
dump_intent(int depth)18 void dump_intent(int depth) {
19 for (int i = 0; i < depth; i++)
20 printf("\t");
21 }
22
23 static
24 void dump_struct(j2s_ctx *ctx, int struct_index, bool expend, int depth);
25
26 static
dump_obj(j2s_ctx * ctx,int obj_index,bool expend,int depth)27 void dump_obj(j2s_ctx *ctx, int obj_index, bool expend, int depth) {
28 j2s_obj *obj;
29 const char *type;
30
31 if (obj_index < 0)
32 return;
33
34 obj = &ctx->objs[obj_index];
35 if (obj->type == J2S_TYPE_STRUCT && expend) {
36 j2s_struct *struct_obj = &ctx->structs[obj->struct_index];
37
38 dump_intent(depth);
39 printf("// %s %s", struct_obj->name, obj->name);
40
41 printf("; // id: %d|off: %d|", obj_index, obj->offset);
42
43 if (J2S_IS_POINTER(obj)) {
44 printf("size: %d", (int)sizeof(void *));
45 } else if (J2S_IS_ARRAY(obj)) {
46 printf("size: %d*%d", obj->elem_size, obj->num_elem);
47 } else {
48 printf("size: %d", obj->elem_size);
49 }
50
51 if (obj->len_index >= 0)
52 printf("|len: @%s", ctx->objs[obj->len_index].name);
53
54 printf("\n");
55
56 dump_struct(ctx, obj->struct_index, expend, depth);
57
58 dump_obj(ctx, obj->next_index, expend, depth);
59 return;
60 }
61
62 if (obj->type == J2S_TYPE_STRUCT) {
63 j2s_struct *struct_obj = &ctx->structs[obj->struct_index];
64 type = struct_obj->name;
65 } else if (obj->enum_index >= 0) {
66 j2s_enum *enum_obj = &ctx->enums[obj->enum_index];
67 type = enum_obj->name;
68 } else {
69 type = j2s_type_name((j2s_type)obj->type);
70 }
71
72 dump_intent(depth);
73
74 if (obj->flags & J2S_FLAG_ARRAY_POINTER)
75 printf("array_ptr_%d_", obj->elem_size / obj->base_elem_size);
76
77 printf("%s ", type);
78
79 if (!(obj->flags & J2S_FLAG_ARRAY_POINTER) &&
80 obj->flags & J2S_FLAG_POINTER) {
81 printf("*");
82
83 if (obj->flags & J2S_FLAG_DEP_POINTER)
84 printf("*");
85 }
86
87 printf("%s", obj->name);
88
89 if (J2S_IS_ARRAY(obj)) {
90 printf("[%d]", obj->num_elem);
91
92 if (obj->flags & J2S_FLAG_DEP_ARRAY)
93 printf("[%d]", obj->elem_size / obj->base_elem_size);
94 }
95
96 printf("; // id: %d|off: %d|", obj_index, obj->offset);
97
98 if (J2S_IS_POINTER(obj)) {
99 printf("size: %d", (int)sizeof(void *));
100 } else if (J2S_IS_ARRAY(obj)) {
101 printf("size: %d*%d", obj->elem_size, obj->num_elem);
102 } else {
103 printf("size: %d", obj->elem_size);
104 }
105
106 if (obj->len_index >= 0)
107 printf("|len: @%s", ctx->objs[obj->len_index].name);
108
109 printf("\n");
110
111 if (obj->next_index < 0)
112 return;
113
114 dump_obj(ctx, obj->next_index, expend, depth);
115 }
116
117 static
dump_struct(j2s_ctx * ctx,int struct_index,bool expend,int depth)118 void dump_struct(j2s_ctx *ctx, int struct_index, bool expend, int depth) {
119 j2s_struct *struct_obj;
120
121 if (struct_index < 0)
122 return;
123
124 struct_obj = &ctx->structs[struct_index];
125
126 dump_intent(depth);
127
128 if (!expend)
129 printf("typedef struct {\n");
130 else
131 printf("{ // %s\n", struct_obj->name);
132
133 dump_obj(ctx, struct_obj->child_index, expend, depth + 1);
134
135 dump_intent(depth);
136
137 if (!expend)
138 printf("} __attribute__((packed)) %s\n", struct_obj->name);
139 else
140 printf("}\n");
141 }
142
143 static
dump_enum(j2s_ctx * ctx,int enum_index)144 void dump_enum(j2s_ctx *ctx, int enum_index) {
145 j2s_enum *enum_obj;
146 j2s_enum_value *enum_value;
147
148 if (enum_index < 0)
149 return;
150
151 enum_obj = &ctx->enums[enum_index];
152
153 printf("typedef enum {\n");
154 for (int i = 0; i < enum_obj->num_value; i++) {
155 j2s_enum_value *enum_value =
156 &ctx->enum_values[enum_obj->value_index + i];
157
158 printf("\t%s = %d;\n", enum_value->name, enum_value->value);
159 }
160 printf("} %s;\n", enum_obj->name);
161 }
162
main(int argc,char ** argv)163 int main(int argc, char** argv) {
164 j2s_struct *root_struct;
165 j2s_ctx ctx = {0};
166 cJSON *json;
167 char *buf;
168 bool template_ = false;
169 bool dump_desc = true;
170 bool format = true;
171
172 for (int i = 1; i < argc; i++) {
173 if (!strcmp(argv[i], "--template")) {
174 template_ = true;
175 } else if (!strcmp(argv[i], "--nodesc")) {
176 dump_desc = false;
177 } else if (!strcmp(argv[i], "--unformat")) {
178 format = false;
179 } else {
180 ERR("unknown arg: %s\n", argv[i]);
181 return -1;
182 }
183 }
184
185 j2s_init(&ctx);
186
187 ctx.format_json = format;
188 ctx.dump_desc = dump_desc;
189
190 if (template_) {
191 INFO("Dump template JSON\n");
192
193 ctx.dump_enums = true;
194 buf = j2s_dump_template_root_struct(&ctx);
195 DASSERT(buf, return -1);
196
197 printf("%s\n", buf);
198
199 free(buf);
200
201 j2s_deinit(&ctx);
202 return 0;
203 }
204
205 INFO("\nDumping structs:\n");
206 for (int i = 0; i < ctx.num_struct; i++) {
207 dump_struct(&ctx, i, false, 0);
208 printf("\n");
209 }
210
211 INFO("\nDumping enums:\n");
212 for (int i = 0; i < ctx.num_enum; i++) {
213 dump_enum(&ctx, i);
214 printf("\n");
215 }
216
217 root_struct = &ctx.structs[ctx.root_index];
218 INFO("\nDumping root_struct: %s\n", root_struct->name);
219
220 dump_struct(&ctx, ctx.root_index, true, 0);
221
222 j2s_deinit(&ctx);
223 return 0;
224 }
225