Commit c2e7075c authored by Rob Herring's avatar Rob Herring

scripts/dtc: Update to upstream version v1.4.7-57-gf267e674d145

This adds the following commits from upstream:

f267e674d145 checks: Fix crash with multiple source annotations
3616b9a811b6 checks: Use source position information for check failures
2bdbd07a1223 checks: Make each message output atomic
a1eff70c02cf util: Add xa{v}sprintf_append functions
82a52ce4573b libfdt: Add a test for fdt_getprop_by_offset()
607b8586b383 PEP8 / Flake8 cleanups for setup.py
f9c0a425b648 Remove broken objdir / srcdir support
5182b5e6f28c pylibfdt: Use common PREFIX variable
d45bf1f5f2a6 Refine make tests_clean target
99284c4db9cb Refine pylibfdt_clean target
a4629cfaedfb Refine libfdt_clean target
08380fc43aa2 tests: Use modern octal literals for Python
8113c00b99d3 pylibfdt: Allow switch to Python 3 via environment variable PYTHON
11738cf01f15 libfdt: Don't use memcpy to handle unaligned reads on ARM
86a288a73670 checks: Restructure check_msg to decrease indentation
5667e7ef9a9a annotations: add the annotation functionality
8e20ccf52f90 annotations: add positions
ca930e20bb54 tests: Don't lose errors from make checkm
43366bb4eeee tests: Property count valgrind errors in wrapped tests
5062516fb8cb srcpos: Remove srcpos_empty
a3143fafbf83 Revert "annotations: add positions"
403cc79f06a1 checks: Update SPI bus check for 'spi-slave'
baa1d2cf7894 annotations: add positions
ff2ad38f6a5a Merge remote-tracking branch 'origin/pr/18'
aa7254d9cb17 libfdt: return correct value if #size-cells property is not present
49903aed7783 use ptrdiff_t modifier for printing pointer differences
da2b691ccf68 treesource: Fix dts output for phandles in middle of a sequence of ints
8f8b77a0d62d tests: Wrap check_align() calls with base_run_test()
522d81d572f2 Fix dts output with a REF_PATH marker
e45198c98359 Added test cases for target references
0fcffda15e9f Merge nodes with local target label references
1e4a0928f3b3 pylibfdt: Don't have setup.py depend on where it's invoked from
ca399b14956f pylibfdt: Eliminate run_setup make function
98972f1b3e33 pylibfdt: Improved version extraction
7ba2be6cda5f pylibfdt: Don't silence setup.py when V=1
7691f9d39301 pylibfdt: Make SETUP make variable
855b9963def9 pylibfdt: Simpler CFLAGS handling
47cafbeeb977 pylibfdt: Link extension module with libfdt rather than rebuilding
dd695d6afb19 pylibfdt: Correctly set build output directory
59327523d0d8 pylibfdt: We don't need include files from the base directory
e84742aa7b93 checks: fix simple-bus compatible matching
8c59a97ce096 Fix missing labels when emitting dts format
d448f9a5fd94 Revert dts output formatting changes of spaces around brackets
Signed-off-by: default avatarRob Herring <robh@kernel.org>
parent e8b1dee2
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
*/ */
#include "dtc.h" #include "dtc.h"
#include "srcpos.h"
#ifdef TRACE_CHECKS #ifdef TRACE_CHECKS
#define TRACE(c, ...) \ #define TRACE(c, ...) \
...@@ -78,23 +79,56 @@ static inline void PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti, ...@@ -78,23 +79,56 @@ static inline void PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti,
const char *fmt, ...) const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); char *str = NULL;
struct srcpos *pos = NULL;
char *file_str;
if (!(c->warn && (quiet < 1)) && !(c->error && (quiet < 2)))
return;
if (prop && prop->srcpos)
pos = prop->srcpos;
else if (node && node->srcpos)
pos = node->srcpos;
if (pos) {
file_str = srcpos_string(pos);
xasprintf(&str, "%s", file_str);
free(file_str);
} else if (streq(dti->outname, "-")) {
xasprintf(&str, "<stdout>");
} else {
xasprintf(&str, "%s", dti->outname);
}
if ((c->warn && (quiet < 1)) xasprintf_append(&str, ": %s (%s): ",
|| (c->error && (quiet < 2))) {
fprintf(stderr, "%s: %s (%s): ",
strcmp(dti->outname, "-") ? dti->outname : "<stdout>",
(c->error) ? "ERROR" : "Warning", c->name); (c->error) ? "ERROR" : "Warning", c->name);
if (node) { if (node) {
fprintf(stderr, "%s", node->fullpath);
if (prop) if (prop)
fprintf(stderr, ":%s", prop->name); xasprintf_append(&str, "%s:%s: ", node->fullpath, prop->name);
fputs(": ", stderr); else
} xasprintf_append(&str, "%s: ", node->fullpath);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
} }
va_start(ap, fmt);
xavsprintf_append(&str, fmt, ap);
va_end(ap); va_end(ap);
xasprintf_append(&str, "\n");
if (!prop && pos) {
pos = node->srcpos;
while (pos->next) {
pos = pos->next;
file_str = srcpos_string(pos);
xasprintf_append(&str, " also defined at %s\n", file_str);
free(file_str);
}
}
fputs(str, stderr);
} }
#define FAIL(c, dti, node, ...) \ #define FAIL(c, dti, node, ...) \
...@@ -910,7 +944,7 @@ static bool node_is_compatible(struct node *node, const char *compat) ...@@ -910,7 +944,7 @@ static bool node_is_compatible(struct node *node, const char *compat)
for (str = prop->val.val, end = str + prop->val.len; str < end; for (str = prop->val.val, end = str + prop->val.len; str < end;
str += strnlen(str, end - str) + 1) { str += strnlen(str, end - str) + 1) {
if (strprefixeq(str, end - str, compat)) if (streq(str, compat))
return true; return true;
} }
return false; return false;
...@@ -921,7 +955,8 @@ static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct ...@@ -921,7 +955,8 @@ static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct
if (node_is_compatible(node, "simple-bus")) if (node_is_compatible(node, "simple-bus"))
node->bus = &simple_bus; node->bus = &simple_bus;
} }
WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells); WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL,
&addr_size_cells, &compatible_is_string_list);
static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node) static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node)
{ {
...@@ -1035,6 +1070,7 @@ static const struct bus_type spi_bus = { ...@@ -1035,6 +1070,7 @@ static const struct bus_type spi_bus = {
static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct node *node)
{ {
int spi_addr_cells = 1;
if (strprefixeq(node->name, node->basenamelen, "spi")) { if (strprefixeq(node->name, node->basenamelen, "spi")) {
node->bus = &spi_bus; node->bus = &spi_bus;
...@@ -1063,7 +1099,9 @@ static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct no ...@@ -1063,7 +1099,9 @@ static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct no
if (node->bus != &spi_bus || !node->children) if (node->bus != &spi_bus || !node->children)
return; return;
if (node_addr_cells(node) != 1) if (get_property(node, "spi-slave"))
spi_addr_cells = 0;
if (node_addr_cells(node) != spi_addr_cells)
FAIL(c, dti, node, "incorrect #address-cells for SPI bus"); FAIL(c, dti, node, "incorrect #address-cells for SPI bus");
if (node_size_cells(node) != 0) if (node_size_cells(node) != 0)
FAIL(c, dti, node, "incorrect #size-cells for SPI bus"); FAIL(c, dti, node, "incorrect #size-cells for SPI bus");
...@@ -1082,6 +1120,9 @@ static void check_spi_bus_reg(struct check *c, struct dt_info *dti, struct node ...@@ -1082,6 +1120,9 @@ static void check_spi_bus_reg(struct check *c, struct dt_info *dti, struct node
if (!node->parent || (node->parent->bus != &spi_bus)) if (!node->parent || (node->parent->bus != &spi_bus))
return; return;
if (get_property(node->parent, "spi-slave"))
return;
prop = get_property(node, "reg"); prop = get_property(node, "reg");
if (prop) if (prop)
cells = (cell_t *)prop->val.val; cells = (cell_t *)prop->val.val;
......
...@@ -213,14 +213,14 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...); ...@@ -213,14 +213,14 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
<*>\&{LABEL} { /* label reference */ <*>\&{LABEL} { /* label reference */
DPRINT("Ref: %s\n", yytext+1); DPRINT("Ref: %s\n", yytext+1);
yylval.labelref = xstrdup(yytext+1); yylval.labelref = xstrdup(yytext+1);
return DT_REF; return DT_LABEL_REF;
} }
<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */ <*>"&{/"{PATHCHAR}*\} { /* new-style path reference */
yytext[yyleng-1] = '\0'; yytext[yyleng-1] = '\0';
DPRINT("Ref: %s\n", yytext+2); DPRINT("Ref: %s\n", yytext+2);
yylval.labelref = xstrdup(yytext+2); yylval.labelref = xstrdup(yytext+2);
return DT_REF; return DT_PATH_REF;
} }
<BYTESTRING>[0-9a-fA-F]{2} { <BYTESTRING>[0-9a-fA-F]{2} {
......
...@@ -70,7 +70,8 @@ extern bool treesource_error; ...@@ -70,7 +70,8 @@ extern bool treesource_error;
%token <byte> DT_BYTE %token <byte> DT_BYTE
%token <data> DT_STRING %token <data> DT_STRING
%token <labelref> DT_LABEL %token <labelref> DT_LABEL
%token <labelref> DT_REF %token <labelref> DT_LABEL_REF
%token <labelref> DT_PATH_REF
%token DT_INCBIN %token DT_INCBIN
%type <data> propdata %type <data> propdata
...@@ -83,6 +84,7 @@ extern bool treesource_error; ...@@ -83,6 +84,7 @@ extern bool treesource_error;
%type <data> bytestring %type <data> bytestring
%type <prop> propdef %type <prop> propdef
%type <proplist> proplist %type <proplist> proplist
%type <labelref> dt_ref
%type <node> devicetree %type <node> devicetree
%type <node> nodedef %type <node> nodedef
...@@ -158,6 +160,8 @@ memreserve: ...@@ -158,6 +160,8 @@ memreserve:
} }
; ;
dt_ref: DT_LABEL_REF | DT_PATH_REF;
devicetree: devicetree:
'/' nodedef '/' nodedef
{ {
...@@ -167,7 +171,7 @@ devicetree: ...@@ -167,7 +171,7 @@ devicetree:
{ {
$$ = merge_nodes($1, $3); $$ = merge_nodes($1, $3);
} }
| DT_REF nodedef | dt_ref nodedef
{ {
/* /*
* We rely on the rule being always: * We rely on the rule being always:
...@@ -176,9 +180,12 @@ devicetree: ...@@ -176,9 +180,12 @@ devicetree:
*/ */
if (!($<flags>-1 & DTSF_PLUGIN)) if (!($<flags>-1 & DTSF_PLUGIN))
ERROR(&@2, "Label or path %s not found", $1); ERROR(&@2, "Label or path %s not found", $1);
$$ = add_orphan_node(name_node(build_node(NULL, NULL), ""), $2, $1); $$ = add_orphan_node(
name_node(build_node(NULL, NULL, NULL),
""),
$2, $1);
} }
| devicetree DT_LABEL DT_REF nodedef | devicetree DT_LABEL dt_ref nodedef
{ {
struct node *target = get_node_by_ref($1, $3); struct node *target = get_node_by_ref($1, $3);
...@@ -189,7 +196,7 @@ devicetree: ...@@ -189,7 +196,7 @@ devicetree:
ERROR(&@3, "Label or path %s not found", $3); ERROR(&@3, "Label or path %s not found", $3);
$$ = $1; $$ = $1;
} }
| devicetree DT_REF nodedef | devicetree DT_PATH_REF nodedef
{ {
/* /*
* We rely on the rule being always: * We rely on the rule being always:
...@@ -208,7 +215,26 @@ devicetree: ...@@ -208,7 +215,26 @@ devicetree:
} }
$$ = $1; $$ = $1;
} }
| devicetree DT_DEL_NODE DT_REF ';' | devicetree DT_LABEL_REF nodedef
{
struct node *target = get_node_by_ref($1, $2);
if (target) {
merge_nodes(target, $3);
} else {
/*
* We rely on the rule being always:
* versioninfo plugindecl memreserves devicetree
* so $-1 is what we want (plugindecl)
*/
if ($<flags>-1 & DTSF_PLUGIN)
add_orphan_node($1, $3, $2);
else
ERROR(&@2, "Label or path %s not found", $2);
}
$$ = $1;
}
| devicetree DT_DEL_NODE dt_ref ';'
{ {
struct node *target = get_node_by_ref($1, $3); struct node *target = get_node_by_ref($1, $3);
...@@ -220,7 +246,7 @@ devicetree: ...@@ -220,7 +246,7 @@ devicetree:
$$ = $1; $$ = $1;
} }
| devicetree DT_OMIT_NO_REF DT_REF ';' | devicetree DT_OMIT_NO_REF dt_ref ';'
{ {
struct node *target = get_node_by_ref($1, $3); struct node *target = get_node_by_ref($1, $3);
...@@ -237,7 +263,7 @@ devicetree: ...@@ -237,7 +263,7 @@ devicetree:
nodedef: nodedef:
'{' proplist subnodes '}' ';' '{' proplist subnodes '}' ';'
{ {
$$ = build_node($2, $3); $$ = build_node($2, $3, &@$);
} }
; ;
...@@ -255,11 +281,11 @@ proplist: ...@@ -255,11 +281,11 @@ proplist:
propdef: propdef:
DT_PROPNODENAME '=' propdata ';' DT_PROPNODENAME '=' propdata ';'
{ {
$$ = build_property($1, $3); $$ = build_property($1, $3, &@$);
} }
| DT_PROPNODENAME ';' | DT_PROPNODENAME ';'
{ {
$$ = build_property($1, empty_data); $$ = build_property($1, empty_data, &@$);
} }
| DT_DEL_PROP DT_PROPNODENAME ';' | DT_DEL_PROP DT_PROPNODENAME ';'
{ {
...@@ -285,7 +311,7 @@ propdata: ...@@ -285,7 +311,7 @@ propdata:
{ {
$$ = data_merge($1, $3); $$ = data_merge($1, $3);
} }
| propdataprefix DT_REF | propdataprefix dt_ref
{ {
$1 = data_add_marker($1, TYPE_STRING, $2); $1 = data_add_marker($1, TYPE_STRING, $2);
$$ = data_add_marker($1, REF_PATH, $2); $$ = data_add_marker($1, REF_PATH, $2);
...@@ -383,7 +409,7 @@ arrayprefix: ...@@ -383,7 +409,7 @@ arrayprefix:
$$.data = data_append_integer($1.data, $2, $1.bits); $$.data = data_append_integer($1.data, $2, $1.bits);
} }
| arrayprefix DT_REF | arrayprefix dt_ref
{ {
uint64_t val = ~0ULL >> (64 - $1.bits); uint64_t val = ~0ULL >> (64 - $1.bits);
...@@ -540,7 +566,7 @@ subnode: ...@@ -540,7 +566,7 @@ subnode:
} }
| DT_DEL_NODE DT_PROPNODENAME ';' | DT_DEL_NODE DT_PROPNODENAME ';'
{ {
$$ = name_node(build_node_delete(), $2); $$ = name_node(build_node_delete(&@$), $2);
} }
| DT_OMIT_NO_REF subnode | DT_OMIT_NO_REF subnode
{ {
......
...@@ -35,6 +35,8 @@ int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties * ...@@ -35,6 +35,8 @@ int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties *
int generate_symbols; /* enable symbols & fixup support */ int generate_symbols; /* enable symbols & fixup support */
int generate_fixups; /* suppress generation of fixups on symbol support */ int generate_fixups; /* suppress generation of fixups on symbol support */
int auto_label_aliases; /* auto generate labels -> aliases */ int auto_label_aliases; /* auto generate labels -> aliases */
int annotate; /* Level of annotation: 1 for input source location
>1 for full input source location. */
static int is_power_of_2(int x) static int is_power_of_2(int x)
{ {
...@@ -60,7 +62,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) ...@@ -60,7 +62,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
/* Usage related data. */ /* Usage related data. */
static const char usage_synopsis[] = "dtc [options] <input file>"; static const char usage_synopsis[] = "dtc [options] <input file>";
static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv"; static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@AThv";
static struct option const usage_long_opts[] = { static struct option const usage_long_opts[] = {
{"quiet", no_argument, NULL, 'q'}, {"quiet", no_argument, NULL, 'q'},
{"in-format", a_argument, NULL, 'I'}, {"in-format", a_argument, NULL, 'I'},
...@@ -81,6 +83,7 @@ static struct option const usage_long_opts[] = { ...@@ -81,6 +83,7 @@ static struct option const usage_long_opts[] = {
{"error", a_argument, NULL, 'E'}, {"error", a_argument, NULL, 'E'},
{"symbols", no_argument, NULL, '@'}, {"symbols", no_argument, NULL, '@'},
{"auto-alias", no_argument, NULL, 'A'}, {"auto-alias", no_argument, NULL, 'A'},
{"annotate", no_argument, NULL, 'T'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'v'},
{NULL, no_argument, NULL, 0x0}, {NULL, no_argument, NULL, 0x0},
...@@ -117,6 +120,7 @@ static const char * const usage_opts_help[] = { ...@@ -117,6 +120,7 @@ static const char * const usage_opts_help[] = {
"\n\tEnable/disable errors (prefix with \"no-\")", "\n\tEnable/disable errors (prefix with \"no-\")",
"\n\tEnable generation of symbols", "\n\tEnable generation of symbols",
"\n\tEnable auto-alias of labels", "\n\tEnable auto-alias of labels",
"\n\tAnnotate output .dts with input source file and line (-T -T for more details)",
"\n\tPrint this help and exit", "\n\tPrint this help and exit",
"\n\tPrint version and exit", "\n\tPrint version and exit",
NULL, NULL,
...@@ -264,6 +268,9 @@ int main(int argc, char *argv[]) ...@@ -264,6 +268,9 @@ int main(int argc, char *argv[])
case 'A': case 'A':
auto_label_aliases = 1; auto_label_aliases = 1;
break; break;
case 'T':
annotate++;
break;
case 'h': case 'h':
usage(NULL); usage(NULL);
...@@ -302,6 +309,8 @@ int main(int argc, char *argv[]) ...@@ -302,6 +309,8 @@ int main(int argc, char *argv[])
outform = "dts"; outform = "dts";
} }
} }
if (annotate && (!streq(inform, "dts") || !streq(outform, "dts")))
die("--annotate requires -I dts -O dts\n");
if (streq(inform, "dts")) if (streq(inform, "dts"))
dti = dt_from_source(arg); dti = dt_from_source(arg);
else if (streq(inform, "fs")) else if (streq(inform, "fs"))
......
...@@ -58,6 +58,7 @@ extern int phandle_format; /* Use linux,phandle or phandle properties */ ...@@ -58,6 +58,7 @@ extern int phandle_format; /* Use linux,phandle or phandle properties */
extern int generate_symbols; /* generate symbols for nodes with labels */ extern int generate_symbols; /* generate symbols for nodes with labels */
extern int generate_fixups; /* generate fixups */ extern int generate_fixups; /* generate fixups */
extern int auto_label_aliases; /* auto generate labels -> aliases */ extern int auto_label_aliases; /* auto generate labels -> aliases */
extern int annotate; /* annotate .dts with input source location */
#define PHANDLE_LEGACY 0x1 #define PHANDLE_LEGACY 0x1
#define PHANDLE_EPAPR 0x2 #define PHANDLE_EPAPR 0x2
...@@ -158,6 +159,7 @@ struct property { ...@@ -158,6 +159,7 @@ struct property {
struct property *next; struct property *next;
struct label *labels; struct label *labels;
struct srcpos *srcpos;
}; };
struct node { struct node {
...@@ -177,6 +179,7 @@ struct node { ...@@ -177,6 +179,7 @@ struct node {
struct label *labels; struct label *labels;
const struct bus_type *bus; const struct bus_type *bus;
struct srcpos *srcpos;
bool omit_if_unused, is_referenced; bool omit_if_unused, is_referenced;
}; };
...@@ -205,13 +208,15 @@ struct node { ...@@ -205,13 +208,15 @@ struct node {
void add_label(struct label **labels, char *label); void add_label(struct label **labels, char *label);
void delete_labels(struct label **labels); void delete_labels(struct label **labels);
struct property *build_property(char *name, struct data val); struct property *build_property(char *name, struct data val,
struct srcpos *srcpos);
struct property *build_property_delete(char *name); struct property *build_property_delete(char *name);
struct property *chain_property(struct property *first, struct property *list); struct property *chain_property(struct property *first, struct property *list);
struct property *reverse_properties(struct property *first); struct property *reverse_properties(struct property *first);
struct node *build_node(struct property *proplist, struct node *children); struct node *build_node(struct property *proplist, struct node *children,
struct node *build_node_delete(void); struct srcpos *srcpos);
struct node *build_node_delete(struct srcpos *srcpos);
struct node *name_node(struct node *node, char *name); struct node *name_node(struct node *node, char *name);
struct node *omit_node_if_unused(struct node *node); struct node *omit_node_if_unused(struct node *node);
struct node *reference_node(struct node *node); struct node *reference_node(struct node *node);
......
...@@ -692,7 +692,7 @@ static struct property *flat_read_property(struct inbuf *dtbuf, ...@@ -692,7 +692,7 @@ static struct property *flat_read_property(struct inbuf *dtbuf,
val = flat_read_data(dtbuf, proplen); val = flat_read_data(dtbuf, proplen);
return build_property(name, val); return build_property(name, val, NULL);
} }
...@@ -750,7 +750,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, ...@@ -750,7 +750,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
char *flatname; char *flatname;
uint32_t val; uint32_t val;
node = build_node(NULL, NULL); node = build_node(NULL, NULL, NULL);
flatname = flat_read_string(dtbuf); flatname = flat_read_string(dtbuf);
......
...@@ -34,7 +34,7 @@ static struct node *read_fstree(const char *dirname) ...@@ -34,7 +34,7 @@ static struct node *read_fstree(const char *dirname)
if (!d) if (!d)
die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno)); die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno));
tree = build_node(NULL, NULL); tree = build_node(NULL, NULL, NULL);
while ((de = readdir(d)) != NULL) { while ((de = readdir(d)) != NULL) {
char *tmpname; char *tmpname;
...@@ -60,7 +60,8 @@ static struct node *read_fstree(const char *dirname) ...@@ -60,7 +60,8 @@ static struct node *read_fstree(const char *dirname)
} else { } else {
prop = build_property(xstrdup(de->d_name), prop = build_property(xstrdup(de->d_name),
data_copy_file(pfile, data_copy_file(pfile,
st.st_size)); st.st_size),
NULL);
add_property(tree, prop); add_property(tree, prop);
fclose(pfile); fclose(pfile);
} }
......
...@@ -9,3 +9,7 @@ LIBFDT_VERSION = version.lds ...@@ -9,3 +9,7 @@ LIBFDT_VERSION = version.lds
LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \ LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \
fdt_addresses.c fdt_overlay.c fdt_addresses.c fdt_overlay.c
LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o) LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
libfdt_clean:
@$(VECHO) CLEAN "(libfdt)"
rm -f $(STD_CLEANFILES:%=$(LIBFDT_dir)/%)
...@@ -64,7 +64,7 @@ static int fdt_cells(const void *fdt, int nodeoffset, const char *name) ...@@ -64,7 +64,7 @@ static int fdt_cells(const void *fdt, int nodeoffset, const char *name)
c = fdt_getprop(fdt, nodeoffset, name, &len); c = fdt_getprop(fdt, nodeoffset, name, &len);
if (!c) if (!c)
return 2; return len;
if (len != sizeof(*c)) if (len != sizeof(*c))
return -FDT_ERR_BADNCELLS; return -FDT_ERR_BADNCELLS;
...@@ -78,10 +78,20 @@ static int fdt_cells(const void *fdt, int nodeoffset, const char *name) ...@@ -78,10 +78,20 @@ static int fdt_cells(const void *fdt, int nodeoffset, const char *name)
int fdt_address_cells(const void *fdt, int nodeoffset) int fdt_address_cells(const void *fdt, int nodeoffset)
{ {
return fdt_cells(fdt, nodeoffset, "#address-cells"); int val;
val = fdt_cells(fdt, nodeoffset, "#address-cells");
if (val == -FDT_ERR_NOTFOUND)
return 2;
return val;
} }
int fdt_size_cells(const void *fdt, int nodeoffset) int fdt_size_cells(const void *fdt, int nodeoffset)
{ {
return fdt_cells(fdt, nodeoffset, "#size-cells"); int val;
val = fdt_cells(fdt, nodeoffset, "#size-cells");
if (val == -FDT_ERR_NOTFOUND)
return 1;
return val;
} }
...@@ -163,18 +163,26 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); ...@@ -163,18 +163,26 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
static inline uint32_t fdt32_ld(const fdt32_t *p) static inline uint32_t fdt32_ld(const fdt32_t *p)
{ {
fdt32_t v; const uint8_t *bp = (const uint8_t *)p;
memcpy(&v, p, sizeof(v)); return ((uint32_t)bp[0] << 24)
return fdt32_to_cpu(v); | ((uint32_t)bp[1] << 16)
| ((uint32_t)bp[2] << 8)
| bp[3];
} }
static inline uint64_t fdt64_ld(const fdt64_t *p) static inline uint64_t fdt64_ld(const fdt64_t *p)
{ {
fdt64_t v; const uint8_t *bp = (const uint8_t *)p;
memcpy(&v, p, sizeof(v)); return ((uint64_t)bp[0] << 56)
return fdt64_to_cpu(v); | ((uint64_t)bp[1] << 48)
| ((uint64_t)bp[2] << 40)
| ((uint64_t)bp[3] << 32)
| ((uint64_t)bp[4] << 24)
| ((uint64_t)bp[5] << 16)
| ((uint64_t)bp[6] << 8)
| bp[7];
} }
/**********************************************************************/ /**********************************************************************/
...@@ -1145,7 +1153,7 @@ int fdt_address_cells(const void *fdt, int nodeoffset); ...@@ -1145,7 +1153,7 @@ int fdt_address_cells(const void *fdt, int nodeoffset);
* *
* returns: * returns:
* 0 <= n < FDT_MAX_NCELLS, on success * 0 <= n < FDT_MAX_NCELLS, on success
* 2, if the node has no #size-cells property * 1, if the node has no #size-cells property
* -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
* #size-cells property * #size-cells property
* -FDT_ERR_BADMAGIC, * -FDT_ERR_BADMAGIC,
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
*/ */
#include "dtc.h" #include "dtc.h"
#include "srcpos.h"
/* /*
* Tree building functions * Tree building functions
...@@ -50,7 +51,8 @@ void delete_labels(struct label **labels) ...@@ -50,7 +51,8 @@ void delete_labels(struct label **labels)
label->deleted = 1; label->deleted = 1;
} }
struct property *build_property(char *name, struct data val) struct property *build_property(char *name, struct data val,
struct srcpos *srcpos)
{ {
struct property *new = xmalloc(sizeof(*new)); struct property *new = xmalloc(sizeof(*new));
...@@ -58,6 +60,7 @@ struct property *build_property(char *name, struct data val) ...@@ -58,6 +60,7 @@ struct property *build_property(char *name, struct data val)
new->name = name; new->name = name;
new->val = val; new->val = val;
new->srcpos = srcpos_copy(srcpos);
return new; return new;
} }
...@@ -97,7 +100,8 @@ struct property *reverse_properties(struct property *first) ...@@ -97,7 +100,8 @@ struct property *reverse_properties(struct property *first)
return head; return head;
} }
struct node *build_node(struct property *proplist, struct node *children) struct node *build_node(struct property *proplist, struct node *children,
struct srcpos *srcpos)
{ {
struct node *new = xmalloc(sizeof(*new)); struct node *new = xmalloc(sizeof(*new));
struct node *child; struct node *child;
...@@ -106,6 +110,7 @@ struct node *build_node(struct property *proplist, struct node *children) ...@@ -106,6 +110,7 @@ struct node *build_node(struct property *proplist, struct node *children)
new->proplist = reverse_properties(proplist); new->proplist = reverse_properties(proplist);
new->children = children; new->children = children;
new->srcpos = srcpos_copy(srcpos);
for_each_child(new, child) { for_each_child(new, child) {
child->parent = new; child->parent = new;
...@@ -114,13 +119,14 @@ struct node *build_node(struct property *proplist, struct node *children) ...@@ -114,13 +119,14 @@ struct node *build_node(struct property *proplist, struct node *children)
return new; return new;
} }
struct node *build_node_delete(void) struct node *build_node_delete(struct srcpos *srcpos)
{ {
struct node *new = xmalloc(sizeof(*new)); struct node *new = xmalloc(sizeof(*new));
memset(new, 0, sizeof(*new)); memset(new, 0, sizeof(*new));
new->deleted = 1; new->deleted = 1;
new->srcpos = srcpos_copy(srcpos);
return new; return new;
} }
...@@ -183,6 +189,8 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node) ...@@ -183,6 +189,8 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
old_prop->val = new_prop->val; old_prop->val = new_prop->val;
old_prop->deleted = 0; old_prop->deleted = 0;
free(old_prop->srcpos);
old_prop->srcpos = new_prop->srcpos;
free(new_prop); free(new_prop);
new_prop = NULL; new_prop = NULL;
break; break;
...@@ -223,6 +231,8 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node) ...@@ -223,6 +231,8 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
add_child(old_node, new_child); add_child(old_node, new_child);
} }
old_node->srcpos = srcpos_extend(old_node->srcpos, new_node->srcpos);
/* The new node contents are now merged into the old node. Free /* The new node contents are now merged into the old node. Free
* the new node. */ * the new node. */
free(new_node); free(new_node);
...@@ -241,18 +251,18 @@ struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref) ...@@ -241,18 +251,18 @@ struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref)
if (ref[0] == '/') { if (ref[0] == '/') {
d = data_append_data(d, ref, strlen(ref) + 1); d = data_append_data(d, ref, strlen(ref) + 1);
p = build_property("target-path", d); p = build_property("target-path", d, NULL);
} else { } else {
d = data_add_marker(d, REF_PHANDLE, ref); d = data_add_marker(d, REF_PHANDLE, ref);
d = data_append_integer(d, 0xffffffff, 32); d = data_append_integer(d, 0xffffffff, 32);
p = build_property("target", d); p = build_property("target", d, NULL);
} }
xasprintf(&name, "fragment@%u", xasprintf(&name, "fragment@%u",
next_orphan_fragment++); next_orphan_fragment++);
name_node(new_node, "__overlay__"); name_node(new_node, "__overlay__");
node = build_node(p, new_node); node = build_node(p, new_node, NULL);
name_node(node, name); name_node(node, name);
add_child(dt, node); add_child(dt, node);
...@@ -351,7 +361,7 @@ void append_to_property(struct node *node, ...@@ -351,7 +361,7 @@ void append_to_property(struct node *node,
p->val = d; p->val = d;
} else { } else {
d = data_append_data(empty_data, data, len); d = data_append_data(empty_data, data, len);
p = build_property(name, d); p = build_property(name, d, NULL);
add_property(node, p); add_property(node, p);
} }
} }
...@@ -609,11 +619,11 @@ cell_t get_node_phandle(struct node *root, struct node *node) ...@@ -609,11 +619,11 @@ cell_t get_node_phandle(struct node *root, struct node *node)
if (!get_property(node, "linux,phandle") if (!get_property(node, "linux,phandle")
&& (phandle_format & PHANDLE_LEGACY)) && (phandle_format & PHANDLE_LEGACY))
add_property(node, build_property("linux,phandle", d)); add_property(node, build_property("linux,phandle", d, NULL));
if (!get_property(node, "phandle") if (!get_property(node, "phandle")
&& (phandle_format & PHANDLE_EPAPR)) && (phandle_format & PHANDLE_EPAPR))
add_property(node, build_property("phandle", d)); add_property(node, build_property("phandle", d, NULL));
/* If the node *does* have a phandle property, we must /* If the node *does* have a phandle property, we must
* be dealing with a self-referencing phandle, which will be * be dealing with a self-referencing phandle, which will be
...@@ -787,7 +797,7 @@ static struct node *build_and_name_child_node(struct node *parent, char *name) ...@@ -787,7 +797,7 @@ static struct node *build_and_name_child_node(struct node *parent, char *name)
{ {
struct node *node; struct node *node;
node = build_node(NULL, NULL); node = build_node(NULL, NULL, NULL);
name_node(node, xstrdup(name)); name_node(node, xstrdup(name));
add_child(parent, node); add_child(parent, node);
...@@ -849,7 +859,8 @@ static void generate_label_tree_internal(struct dt_info *dti, ...@@ -849,7 +859,8 @@ static void generate_label_tree_internal(struct dt_info *dti,
/* insert it */ /* insert it */
p = build_property(l->label, p = build_property(l->label,
data_copy_mem(node->fullpath, data_copy_mem(node->fullpath,
strlen(node->fullpath) + 1)); strlen(node->fullpath) + 1),
NULL);
add_property(an, p); add_property(an, p);
} }
......
...@@ -33,6 +33,9 @@ struct search_path { ...@@ -33,6 +33,9 @@ struct search_path {
/* This is the list of directories that we search for source files */ /* This is the list of directories that we search for source files */
static struct search_path *search_path_head, **search_path_tail; static struct search_path *search_path_head, **search_path_tail;
/* Detect infinite include recursion. */
#define MAX_SRCFILE_DEPTH (100)
static int srcfile_depth; /* = 0 */
static char *get_dirname(const char *path) static char *get_dirname(const char *path)
{ {
...@@ -51,11 +54,51 @@ static char *get_dirname(const char *path) ...@@ -51,11 +54,51 @@ static char *get_dirname(const char *path)
FILE *depfile; /* = NULL */ FILE *depfile; /* = NULL */
struct srcfile_state *current_srcfile; /* = NULL */ struct srcfile_state *current_srcfile; /* = NULL */
static char *initial_path; /* = NULL */
static int initial_pathlen; /* = 0 */
static bool initial_cpp = true;
/* Detect infinite include recursion. */ static void set_initial_path(char *fname)
#define MAX_SRCFILE_DEPTH (100) {
static int srcfile_depth; /* = 0 */ int i, len = strlen(fname);
xasprintf(&initial_path, "%s", fname);
initial_pathlen = 0;
for (i = 0; i != len; i++)
if (initial_path[i] == '/')
initial_pathlen++;
}
static char *shorten_to_initial_path(char *fname)
{
char *p1, *p2, *prevslash1 = NULL;
int slashes = 0;
for (p1 = fname, p2 = initial_path; *p1 && *p2; p1++, p2++) {
if (*p1 != *p2)
break;
if (*p1 == '/') {
prevslash1 = p1;
slashes++;
}
}
p1 = prevslash1 + 1;
if (prevslash1) {
int diff = initial_pathlen - slashes, i, j;
int restlen = strlen(fname) - (p1 - fname);
char *res;
res = xmalloc((3 * diff) + restlen + 1);
for (i = 0, j = 0; i != diff; i++) {
res[j++] = '.';
res[j++] = '.';
res[j++] = '/';
}
strcpy(res + j, p1);
return res;
}
return NULL;
}
/** /**
* Try to open a file in a given directory. * Try to open a file in a given directory.
...@@ -157,6 +200,9 @@ void srcfile_push(const char *fname) ...@@ -157,6 +200,9 @@ void srcfile_push(const char *fname)
srcfile->colno = 1; srcfile->colno = 1;
current_srcfile = srcfile; current_srcfile = srcfile;
if (srcfile_depth == 1)
set_initial_path(srcfile->name);
} }
bool srcfile_pop(void) bool srcfile_pop(void)
...@@ -197,18 +243,6 @@ void srcfile_add_search_path(const char *dirname) ...@@ -197,18 +243,6 @@ void srcfile_add_search_path(const char *dirname)
search_path_tail = &node->next; search_path_tail = &node->next;
} }
/*
* The empty source position.
*/
struct srcpos srcpos_empty = {
.first_line = 0,
.first_column = 0,
.last_line = 0,
.last_column = 0,
.file = NULL,
};
void srcpos_update(struct srcpos *pos, const char *text, int len) void srcpos_update(struct srcpos *pos, const char *text, int len)
{ {
int i; int i;
...@@ -234,13 +268,35 @@ struct srcpos * ...@@ -234,13 +268,35 @@ struct srcpos *
srcpos_copy(struct srcpos *pos) srcpos_copy(struct srcpos *pos)
{ {
struct srcpos *pos_new; struct srcpos *pos_new;
struct srcfile_state *srcfile_state;
if (!pos)
return NULL;
pos_new = xmalloc(sizeof(struct srcpos)); pos_new = xmalloc(sizeof(struct srcpos));
assert(pos->next == NULL);
memcpy(pos_new, pos, sizeof(struct srcpos)); memcpy(pos_new, pos, sizeof(struct srcpos));
/* allocate without free */
srcfile_state = xmalloc(sizeof(struct srcfile_state));
memcpy(srcfile_state, pos->file, sizeof(struct srcfile_state));
pos_new->file = srcfile_state;
return pos_new; return pos_new;
} }
struct srcpos *srcpos_extend(struct srcpos *pos, struct srcpos *newtail)
{
struct srcpos *p;
if (!pos)
return newtail;
for (p = pos; p->next != NULL; p = p->next);
p->next = newtail;
return pos;
}
char * char *
srcpos_string(struct srcpos *pos) srcpos_string(struct srcpos *pos)
{ {
...@@ -266,6 +322,68 @@ srcpos_string(struct srcpos *pos) ...@@ -266,6 +322,68 @@ srcpos_string(struct srcpos *pos)
return pos_str; return pos_str;
} }
static char *
srcpos_string_comment(struct srcpos *pos, bool first_line, int level)
{
char *pos_str, *fname, *first, *rest;
bool fresh_fname = false;
if (!pos) {
if (level > 1) {
xasprintf(&pos_str, "<no-file>:<no-line>");
return pos_str;
} else {
return NULL;
}
}
if (!pos->file)
fname = "<no-file>";
else if (!pos->file->name)
fname = "<no-filename>";
else if (level > 1)
fname = pos->file->name;
else {
fname = shorten_to_initial_path(pos->file->name);
if (fname)
fresh_fname = true;
else
fname = pos->file->name;
}
if (level > 1)
xasprintf(&first, "%s:%d:%d-%d:%d", fname,
pos->first_line, pos->first_column,
pos->last_line, pos->last_column);
else
xasprintf(&first, "%s:%d", fname,
first_line ? pos->first_line : pos->last_line);
if (fresh_fname)
free(fname);
if (pos->next != NULL) {
rest = srcpos_string_comment(pos->next, first_line, level);
xasprintf(&pos_str, "%s, %s", first, rest);
free(first);
free(rest);
} else {
pos_str = first;
}
return pos_str;
}
char *srcpos_string_first(struct srcpos *pos, int level)
{
return srcpos_string_comment(pos, true, level);
}
char *srcpos_string_last(struct srcpos *pos, int level)
{
return srcpos_string_comment(pos, false, level);
}
void srcpos_verror(struct srcpos *pos, const char *prefix, void srcpos_verror(struct srcpos *pos, const char *prefix,
const char *fmt, va_list va) const char *fmt, va_list va)
{ {
...@@ -294,4 +412,9 @@ void srcpos_set_line(char *f, int l) ...@@ -294,4 +412,9 @@ void srcpos_set_line(char *f, int l)
{ {
current_srcfile->name = f; current_srcfile->name = f;
current_srcfile->lineno = l; current_srcfile->lineno = l;
if (initial_cpp) {
initial_cpp = false;
set_initial_path(f);
}
} }
...@@ -74,6 +74,7 @@ struct srcpos { ...@@ -74,6 +74,7 @@ struct srcpos {
int last_line; int last_line;
int last_column; int last_column;
struct srcfile_state *file; struct srcfile_state *file;
struct srcpos *next;
}; };
#define YYLTYPE struct srcpos #define YYLTYPE struct srcpos
...@@ -93,19 +94,18 @@ struct srcpos { ...@@ -93,19 +94,18 @@ struct srcpos {
YYRHSLOC(Rhs, 0).last_column; \ YYRHSLOC(Rhs, 0).last_column; \
(Current).file = YYRHSLOC (Rhs, 0).file; \ (Current).file = YYRHSLOC (Rhs, 0).file; \
} \ } \
(Current).next = NULL; \
} while (0) } while (0)
/*
* Fictional source position used for IR nodes that are
* created without otherwise knowing a true source position.
* For example,constant definitions from the command line.
*/
extern struct srcpos srcpos_empty;
extern void srcpos_update(struct srcpos *pos, const char *text, int len); extern void srcpos_update(struct srcpos *pos, const char *text, int len);
extern struct srcpos *srcpos_copy(struct srcpos *pos); extern struct srcpos *srcpos_copy(struct srcpos *pos);
extern struct srcpos *srcpos_extend(struct srcpos *new_srcpos,
struct srcpos *old_srcpos);
extern char *srcpos_string(struct srcpos *pos); extern char *srcpos_string(struct srcpos *pos);
extern char *srcpos_string_first(struct srcpos *pos, int level);
extern char *srcpos_string_last(struct srcpos *pos, int level);
extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix, extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix,
const char *fmt, va_list va); const char *fmt, va_list va);
......
...@@ -64,6 +64,10 @@ static bool isstring(char c) ...@@ -64,6 +64,10 @@ static bool isstring(char c)
static void write_propval_string(FILE *f, const char *s, size_t len) static void write_propval_string(FILE *f, const char *s, size_t len)
{ {
const char *end = s + len - 1; const char *end = s + len - 1;
if (!len)
return;
assert(*end == '\0'); assert(*end == '\0');
fprintf(f, "\""); fprintf(f, "\"");
...@@ -118,18 +122,20 @@ static void write_propval_int(FILE *f, const char *p, size_t len, size_t width) ...@@ -118,18 +122,20 @@ static void write_propval_int(FILE *f, const char *p, size_t len, size_t width)
for (; p < end; p += width) { for (; p < end; p += width) {
switch (width) { switch (width) {
case 1: case 1:
fprintf(f, " %02"PRIx8, *(const uint8_t*)p); fprintf(f, "%02"PRIx8, *(const uint8_t*)p);
break; break;
case 2: case 2:
fprintf(f, " 0x%02"PRIx16, fdt16_to_cpu(*(const fdt16_t*)p)); fprintf(f, "0x%02"PRIx16, fdt16_to_cpu(*(const fdt16_t*)p));
break; break;
case 4: case 4:
fprintf(f, " 0x%02"PRIx32, fdt32_to_cpu(*(const fdt32_t*)p)); fprintf(f, "0x%02"PRIx32, fdt32_to_cpu(*(const fdt32_t*)p));
break; break;
case 8: case 8:
fprintf(f, " 0x%02"PRIx64, fdt64_to_cpu(*(const fdt64_t*)p)); fprintf(f, "0x%02"PRIx64, fdt64_to_cpu(*(const fdt64_t*)p));
break; break;
} }
if (p + width < end)
fputc(' ', f);
} }
} }
...@@ -162,10 +168,10 @@ static const char *delim_start[] = { ...@@ -162,10 +168,10 @@ static const char *delim_start[] = {
[TYPE_STRING] = "", [TYPE_STRING] = "",
}; };
static const char *delim_end[] = { static const char *delim_end[] = {
[TYPE_UINT8] = " ]", [TYPE_UINT8] = "]",
[TYPE_UINT16] = " >", [TYPE_UINT16] = ">",
[TYPE_UINT32] = " >", [TYPE_UINT32] = ">",
[TYPE_UINT64] = " >", [TYPE_UINT64] = ">",
[TYPE_STRING] = "", [TYPE_STRING] = "",
}; };
...@@ -208,13 +214,22 @@ static void write_propval(FILE *f, struct property *prop) ...@@ -208,13 +214,22 @@ static void write_propval(FILE *f, struct property *prop)
struct marker *m = prop->val.markers; struct marker *m = prop->val.markers;
struct marker dummy_marker; struct marker dummy_marker;
enum markertype emit_type = TYPE_NONE; enum markertype emit_type = TYPE_NONE;
char *srcstr;
if (len == 0) { if (len == 0) {
fprintf(f, ";\n"); fprintf(f, ";");
if (annotate) {
srcstr = srcpos_string_first(prop->srcpos, annotate);
if (srcstr) {
fprintf(f, " /* %s */", srcstr);
free(srcstr);
}
}
fprintf(f, "\n");
return; return;
} }
fprintf(f, " = "); fprintf(f, " =");
if (!next_type_marker(m)) { if (!next_type_marker(m)) {
/* data type information missing, need to guess */ /* data type information missing, need to guess */
...@@ -225,32 +240,23 @@ static void write_propval(FILE *f, struct property *prop) ...@@ -225,32 +240,23 @@ static void write_propval(FILE *f, struct property *prop)
m = &dummy_marker; m = &dummy_marker;
} }
struct marker *m_label = prop->val.markers;
for_each_marker(m) { for_each_marker(m) {
size_t chunk_len; size_t chunk_len = (m->next ? m->next->offset : len) - m->offset;
size_t data_len = type_marker_length(m) ? : len - m->offset;
const char *p = &prop->val.val[m->offset]; const char *p = &prop->val.val[m->offset];
if (!has_data_type_information(m)) if (has_data_type_information(m)) {
continue;
chunk_len = type_marker_length(m);
if (!chunk_len)
chunk_len = len - m->offset;
if (emit_type != TYPE_NONE)
fprintf(f, "%s, ", delim_end[emit_type]);
emit_type = m->type; emit_type = m->type;
fprintf(f, " %s", delim_start[emit_type]);
for_each_marker_of_type(m_label, LABEL) { } else if (m->type == LABEL)
if (m_label->offset > m->offset) fprintf(f, " %s:", m->ref);
break; else if (m->offset)
fprintf(f, "%s: ", m_label->ref); fputc(' ', f);
}
if (emit_type == TYPE_NONE) {
fprintf(f, "%s", delim_start[emit_type]); assert(chunk_len == 0);
if (chunk_len <= 0)
continue; continue;
}
switch(emit_type) { switch(emit_type) {
case TYPE_UINT16: case TYPE_UINT16:
...@@ -268,15 +274,23 @@ static void write_propval(FILE *f, struct property *prop) ...@@ -268,15 +274,23 @@ static void write_propval(FILE *f, struct property *prop)
default: default:
write_propval_int(f, p, chunk_len, 1); write_propval_int(f, p, chunk_len, 1);
} }
}
/* Wrap up any labels at the end of the value */ if (chunk_len == data_len) {
for_each_marker_of_type(m_label, LABEL) { size_t pos = m->offset + chunk_len;
assert (m_label->offset == len); fprintf(f, pos == len ? "%s" : "%s,",
fprintf(f, " %s:", m_label->ref); delim_end[emit_type] ? : "");
emit_type = TYPE_NONE;
} }
}
fprintf(f, "%s;\n", delim_end[emit_type] ? : ""); fprintf(f, ";");
if (annotate) {
srcstr = srcpos_string_first(prop->srcpos, annotate);
if (srcstr) {
fprintf(f, " /* %s */", srcstr);
free(srcstr);
}
}
fprintf(f, "\n");
} }
static void write_tree_source_node(FILE *f, struct node *tree, int level) 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,14 +298,24 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
struct property *prop; struct property *prop;
struct node *child; struct node *child;
struct label *l; struct label *l;
char *srcstr;
write_prefix(f, level); write_prefix(f, level);
for_each_label(tree->labels, l) for_each_label(tree->labels, l)
fprintf(f, "%s: ", l->label); fprintf(f, "%s: ", l->label);
if (tree->name && (*tree->name)) if (tree->name && (*tree->name))
fprintf(f, "%s {\n", tree->name); fprintf(f, "%s {", tree->name);
else else
fprintf(f, "/ {\n"); fprintf(f, "/ {");
if (annotate) {
srcstr = srcpos_string_first(tree->srcpos, annotate);
if (srcstr) {
fprintf(f, " /* %s */", srcstr);
free(srcstr);
}
}
fprintf(f, "\n");
for_each_property(tree, prop) { for_each_property(tree, prop) {
write_prefix(f, level+1); write_prefix(f, level+1);
...@@ -305,10 +329,17 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level) ...@@ -305,10 +329,17 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
write_tree_source_node(f, child, level+1); write_tree_source_node(f, child, level+1);
} }
write_prefix(f, level); write_prefix(f, level);
fprintf(f, "};\n"); fprintf(f, "};");
if (annotate) {
srcstr = srcpos_string_last(tree->srcpos, annotate);
if (srcstr) {
fprintf(f, " /* %s */", srcstr);
free(srcstr);
}
}
fprintf(f, "\n");
} }
void dt_to_source(FILE *f, struct dt_info *dti) void dt_to_source(FILE *f, struct dt_info *dti)
{ {
struct reserve_info *re; struct reserve_info *re;
......
...@@ -46,34 +46,52 @@ char *xstrdup(const char *s) ...@@ -46,34 +46,52 @@ char *xstrdup(const char *s)
return d; return d;
} }
/* based in part from (3) vsnprintf */ int xavsprintf_append(char **strp, const char *fmt, va_list ap)
int xasprintf(char **strp, const char *fmt, ...)
{ {
int n, size = 128; /* start with 128 bytes */ int n, size = 0; /* start with 128 bytes */
char *p; char *p;
va_list ap_copy;
p = *strp;
if (p)
size = strlen(p);
va_copy(ap_copy, ap);
n = vsnprintf(NULL, 0, fmt, ap_copy) + 1;
va_end(ap_copy);
p = xrealloc(p, size + n);
n = vsnprintf(p + size, n, fmt, ap);
*strp = p;
return strlen(p);
}
int xasprintf_append(char **strp, const char *fmt, ...)
{
int n;
va_list ap;
va_start(ap, fmt);
n = xavsprintf_append(strp, fmt, ap);
va_end(ap);
return n;
}
int xasprintf(char **strp, const char *fmt, ...)
{
int n;
va_list ap; va_list ap;
/* initial pointer is NULL making the fist realloc to be malloc */ *strp = NULL;
p = NULL;
while (1) {
p = xrealloc(p, size);
/* Try to print in the allocated space. */
va_start(ap, fmt); va_start(ap, fmt);
n = vsnprintf(p, size, fmt, ap); n = xavsprintf_append(strp, fmt, ap);
va_end(ap); va_end(ap);
/* If that worked, return the string. */ return n;
if (n > -1 && n < size)
break;
/* Else try again with more space. */
if (n > -1) /* glibc 2.1 */
size = n + 1; /* precisely what is needed */
else /* glibc 2.0 */
size *= 2; /* twice the old size */
}
*strp = p;
return strlen(p);
} }
char *join_path(const char *path, const char *name) char *join_path(const char *path, const char *name)
......
...@@ -72,6 +72,8 @@ static inline void *xrealloc(void *p, size_t len) ...@@ -72,6 +72,8 @@ static inline void *xrealloc(void *p, size_t len)
extern char *xstrdup(const char *s); extern char *xstrdup(const char *s);
extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...); extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...);
extern int PRINTF(2, 3) xasprintf_append(char **strp, const char *fmt, ...);
extern int xavsprintf_append(char **strp, const char *fmt, va_list ap);
extern char *join_path(const char *path, const char *name); extern char *join_path(const char *path, const char *name);
/** /**
......
#define DTC_VERSION "DTC 1.4.7-gc86da84d" #define DTC_VERSION "DTC 1.4.7-gf267e674"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment