diff options
Diffstat (limited to 'scripts/dtc/treesource.c')
| -rw-r--r-- | scripts/dtc/treesource.c | 115 |
1 files changed, 73 insertions, 42 deletions
diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c index f2874f1d1465..1af36628b75f 100644 --- a/scripts/dtc/treesource.c +++ b/scripts/dtc/treesource.c | |||
| @@ -64,6 +64,10 @@ static bool isstring(char c) | |||
| 64 | static void write_propval_string(FILE *f, const char *s, size_t len) | 64 | static void write_propval_string(FILE *f, const char *s, size_t len) |
| 65 | { | 65 | { |
| 66 | const char *end = s + len - 1; | 66 | const char *end = s + len - 1; |
| 67 | |||
| 68 | if (!len) | ||
| 69 | return; | ||
| 70 | |||
| 67 | assert(*end == '\0'); | 71 | assert(*end == '\0'); |
| 68 | 72 | ||
| 69 | fprintf(f, "\""); | 73 | fprintf(f, "\""); |
| @@ -118,18 +122,20 @@ static void write_propval_int(FILE *f, const char *p, size_t len, size_t width) | |||
| 118 | for (; p < end; p += width) { | 122 | for (; p < end; p += width) { |
| 119 | switch (width) { | 123 | switch (width) { |
| 120 | case 1: | 124 | case 1: |
| 121 | fprintf(f, " %02"PRIx8, *(const uint8_t*)p); | 125 | fprintf(f, "%02"PRIx8, *(const uint8_t*)p); |
| 122 | break; | 126 | break; |
| 123 | case 2: | 127 | case 2: |
| 124 | fprintf(f, " 0x%02"PRIx16, fdt16_to_cpu(*(const fdt16_t*)p)); | 128 | fprintf(f, "0x%02"PRIx16, fdt16_to_cpu(*(const fdt16_t*)p)); |
| 125 | break; | 129 | break; |
| 126 | case 4: | 130 | case 4: |
| 127 | fprintf(f, " 0x%02"PRIx32, fdt32_to_cpu(*(const fdt32_t*)p)); | 131 | fprintf(f, "0x%02"PRIx32, fdt32_to_cpu(*(const fdt32_t*)p)); |
| 128 | break; | 132 | break; |
| 129 | case 8: | 133 | case 8: |
| 130 | fprintf(f, " 0x%02"PRIx64, fdt64_to_cpu(*(const fdt64_t*)p)); | 134 | fprintf(f, "0x%02"PRIx64, fdt64_to_cpu(*(const fdt64_t*)p)); |
| 131 | break; | 135 | break; |
| 132 | } | 136 | } |
| 137 | if (p + width < end) | ||
| 138 | fputc(' ', f); | ||
| 133 | } | 139 | } |
| 134 | } | 140 | } |
| 135 | 141 | ||
| @@ -162,10 +168,10 @@ static const char *delim_start[] = { | |||
| 162 | [TYPE_STRING] = "", | 168 | [TYPE_STRING] = "", |
| 163 | }; | 169 | }; |
| 164 | static const char *delim_end[] = { | 170 | static const char *delim_end[] = { |
| 165 | [TYPE_UINT8] = " ]", | 171 | [TYPE_UINT8] = "]", |
| 166 | [TYPE_UINT16] = " >", | 172 | [TYPE_UINT16] = ">", |
| 167 | [TYPE_UINT32] = " >", | 173 | [TYPE_UINT32] = ">", |
| 168 | [TYPE_UINT64] = " >", | 174 | [TYPE_UINT64] = ">", |
| 169 | [TYPE_STRING] = "", | 175 | [TYPE_STRING] = "", |
| 170 | }; | 176 | }; |
| 171 | 177 | ||
| @@ -208,13 +214,22 @@ static void write_propval(FILE *f, struct property *prop) | |||
| 208 | struct marker *m = prop->val.markers; | 214 | struct marker *m = prop->val.markers; |
| 209 | struct marker dummy_marker; | 215 | struct marker dummy_marker; |
| 210 | enum markertype emit_type = TYPE_NONE; | 216 | enum markertype emit_type = TYPE_NONE; |
| 217 | char *srcstr; | ||
| 211 | 218 | ||
| 212 | if (len == 0) { | 219 | if (len == 0) { |
| 213 | fprintf(f, ";\n"); | 220 | fprintf(f, ";"); |
| 221 | if (annotate) { | ||
| 222 | srcstr = srcpos_string_first(prop->srcpos, annotate); | ||
| 223 | if (srcstr) { | ||
| 224 | fprintf(f, " /* %s */", srcstr); | ||
| 225 | free(srcstr); | ||
| 226 | } | ||
| 227 | } | ||
| 228 | fprintf(f, "\n"); | ||
| 214 | return; | 229 | return; |
| 215 | } | 230 | } |
| 216 | 231 | ||
| 217 | fprintf(f, " = "); | 232 | fprintf(f, " ="); |
| 218 | 233 | ||
| 219 | if (!next_type_marker(m)) { | 234 | if (!next_type_marker(m)) { |
| 220 | /* data type information missing, need to guess */ | 235 | /* data type information missing, need to guess */ |
| @@ -225,32 +240,23 @@ static void write_propval(FILE *f, struct property *prop) | |||
| 225 | m = &dummy_marker; | 240 | m = &dummy_marker; |
| 226 | } | 241 | } |
| 227 | 242 | ||
| 228 | struct marker *m_label = prop->val.markers; | ||
| 229 | for_each_marker(m) { | 243 | for_each_marker(m) { |
| 230 | size_t chunk_len; | 244 | size_t chunk_len = (m->next ? m->next->offset : len) - m->offset; |
| 245 | size_t data_len = type_marker_length(m) ? : len - m->offset; | ||
| 231 | const char *p = &prop->val.val[m->offset]; | 246 | const char *p = &prop->val.val[m->offset]; |
| 232 | 247 | ||
| 233 | if (!has_data_type_information(m)) | 248 | if (has_data_type_information(m)) { |
| 234 | continue; | 249 | emit_type = m->type; |
| 235 | 250 | fprintf(f, " %s", delim_start[emit_type]); | |
| 236 | chunk_len = type_marker_length(m); | 251 | } else if (m->type == LABEL) |
| 237 | if (!chunk_len) | 252 | fprintf(f, " %s:", m->ref); |
| 238 | chunk_len = len - m->offset; | 253 | else if (m->offset) |
| 239 | 254 | fputc(' ', f); | |
| 240 | if (emit_type != TYPE_NONE) | ||
| 241 | fprintf(f, "%s, ", delim_end[emit_type]); | ||
| 242 | emit_type = m->type; | ||
| 243 | |||
| 244 | for_each_marker_of_type(m_label, LABEL) { | ||
| 245 | if (m_label->offset > m->offset) | ||
| 246 | break; | ||
| 247 | fprintf(f, "%s: ", m_label->ref); | ||
| 248 | } | ||
| 249 | |||
| 250 | fprintf(f, "%s", delim_start[emit_type]); | ||
| 251 | 255 | ||
| 252 | if (chunk_len <= 0) | 256 | if (emit_type == TYPE_NONE) { |
| 257 | assert(chunk_len == 0); | ||
| 253 | continue; | 258 | continue; |
| 259 | } | ||
| 254 | 260 | ||
| 255 | switch(emit_type) { | 261 | switch(emit_type) { |
| 256 | case TYPE_UINT16: | 262 | case TYPE_UINT16: |
| @@ -268,15 +274,23 @@ static void write_propval(FILE *f, struct property *prop) | |||
| 268 | default: | 274 | default: |
| 269 | write_propval_int(f, p, chunk_len, 1); | 275 | write_propval_int(f, p, chunk_len, 1); |
| 270 | } | 276 | } |
| 271 | } | ||
| 272 | 277 | ||
| 273 | /* Wrap up any labels at the end of the value */ | 278 | if (chunk_len == data_len) { |
| 274 | for_each_marker_of_type(m_label, LABEL) { | 279 | size_t pos = m->offset + chunk_len; |
| 275 | assert (m_label->offset == len); | 280 | fprintf(f, pos == len ? "%s" : "%s,", |
| 276 | fprintf(f, " %s:", m_label->ref); | 281 | delim_end[emit_type] ? : ""); |
| 282 | emit_type = TYPE_NONE; | ||
| 283 | } | ||
| 277 | } | 284 | } |
| 278 | 285 | fprintf(f, ";"); | |
| 279 | fprintf(f, "%s;\n", delim_end[emit_type] ? : ""); | 286 | if (annotate) { |
| 287 | srcstr = srcpos_string_first(prop->srcpos, annotate); | ||
| 288 | if (srcstr) { | ||
| 289 | fprintf(f, " /* %s */", srcstr); | ||
| 290 | free(srcstr); | ||
| 291 | } | ||
| 292 | } | ||
| 293 | fprintf(f, "\n"); | ||
| 280 | } | 294 | } |
| 281 | 295 | ||
| 282 | static void write_tree_source_node(FILE *f, struct node *tree, int level) | 296 | static void write_tree_source_node(FILE *f, struct node *tree, int level) |
| @@ -284,14 +298,24 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level) | |||
| 284 | struct property *prop; | 298 | struct property *prop; |
| 285 | struct node *child; | 299 | struct node *child; |
| 286 | struct label *l; | 300 | struct label *l; |
| 301 | char *srcstr; | ||
| 287 | 302 | ||
| 288 | write_prefix(f, level); | 303 | write_prefix(f, level); |
| 289 | for_each_label(tree->labels, l) | 304 | for_each_label(tree->labels, l) |
| 290 | fprintf(f, "%s: ", l->label); | 305 | fprintf(f, "%s: ", l->label); |
| 291 | if (tree->name && (*tree->name)) | 306 | if (tree->name && (*tree->name)) |
| 292 | fprintf(f, "%s {\n", tree->name); | 307 | fprintf(f, "%s {", tree->name); |
| 293 | else | 308 | else |
| 294 | fprintf(f, "/ {\n"); | 309 | fprintf(f, "/ {"); |
| 310 | |||
| 311 | if (annotate) { | ||
| 312 | srcstr = srcpos_string_first(tree->srcpos, annotate); | ||
| 313 | if (srcstr) { | ||
| 314 | fprintf(f, " /* %s */", srcstr); | ||
| 315 | free(srcstr); | ||
| 316 | } | ||
| 317 | } | ||
| 318 | fprintf(f, "\n"); | ||
| 295 | 319 | ||
| 296 | for_each_property(tree, prop) { | 320 | for_each_property(tree, prop) { |
| 297 | write_prefix(f, level+1); | 321 | write_prefix(f, level+1); |
| @@ -305,10 +329,17 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level) | |||
| 305 | write_tree_source_node(f, child, level+1); | 329 | write_tree_source_node(f, child, level+1); |
| 306 | } | 330 | } |
| 307 | write_prefix(f, level); | 331 | write_prefix(f, level); |
| 308 | fprintf(f, "};\n"); | 332 | fprintf(f, "};"); |
| 333 | if (annotate) { | ||
| 334 | srcstr = srcpos_string_last(tree->srcpos, annotate); | ||
| 335 | if (srcstr) { | ||
| 336 | fprintf(f, " /* %s */", srcstr); | ||
| 337 | free(srcstr); | ||
| 338 | } | ||
| 339 | } | ||
| 340 | fprintf(f, "\n"); | ||
| 309 | } | 341 | } |
| 310 | 342 | ||
| 311 | |||
| 312 | void dt_to_source(FILE *f, struct dt_info *dti) | 343 | void dt_to_source(FILE *f, struct dt_info *dti) |
| 313 | { | 344 | { |
| 314 | struct reserve_info *re; | 345 | struct reserve_info *re; |
