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 @@
*/
#include "dtc.h"
#include "srcpos.h"
#ifdef TRACE_CHECKS
#define TRACE(c, ...) \
......@@ -78,23 +79,56 @@ static inline void PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti,
const char *fmt, ...)
{
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))
|| (c->error && (quiet < 2))) {
fprintf(stderr, "%s: %s (%s): ",
strcmp(dti->outname, "-") ? dti->outname : "<stdout>",
xasprintf_append(&str, ": %s (%s): ",
(c->error) ? "ERROR" : "Warning", c->name);
if (node) {
fprintf(stderr, "%s", node->fullpath);
if (prop)
fprintf(stderr, ":%s", prop->name);
fputs(": ", stderr);
}
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
xasprintf_append(&str, "%s:%s: ", node->fullpath, prop->name);
else
xasprintf_append(&str, "%s: ", node->fullpath);
}
va_start(ap, fmt);
xavsprintf_append(&str, fmt, 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, ...) \
......@@ -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;
str += strnlen(str, end - str) + 1) {
if (strprefixeq(str, end - str, compat))
if (streq(str, compat))
return true;
}
return false;
......@@ -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"))
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)
{
......@@ -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)
{
int spi_addr_cells = 1;
if (strprefixeq(node->name, node->basenamelen, "spi")) {
node->bus = &spi_bus;
......@@ -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)
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");
if (node_size_cells(node) != 0)
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
if (!node->parent || (node->parent->bus != &spi_bus))
return;
if (get_property(node->parent, "spi-slave"))
return;
prop = get_property(node, "reg");
if (prop)
cells = (cell_t *)prop->val.val;
......
......@@ -213,14 +213,14 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
<*>\&{LABEL} { /* label reference */
DPRINT("Ref: %s\n", yytext+1);
yylval.labelref = xstrdup(yytext+1);
return DT_REF;
return DT_LABEL_REF;
}
<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */
yytext[yyleng-1] = '\0';
DPRINT("Ref: %s\n", yytext+2);
yylval.labelref = xstrdup(yytext+2);
return DT_REF;
return DT_PATH_REF;
}
<BYTESTRING>[0-9a-fA-F]{2} {
......
......@@ -70,7 +70,8 @@ extern bool treesource_error;
%token <byte> DT_BYTE
%token <data> DT_STRING
%token <labelref> DT_LABEL
%token <labelref> DT_REF
%token <labelref> DT_LABEL_REF
%token <labelref> DT_PATH_REF
%token DT_INCBIN
%type <data> propdata
......@@ -83,6 +84,7 @@ extern bool treesource_error;
%type <data> bytestring
%type <prop> propdef
%type <proplist> proplist
%type <labelref> dt_ref
%type <node> devicetree
%type <node> nodedef
......@@ -158,6 +160,8 @@ memreserve:
}
;
dt_ref: DT_LABEL_REF | DT_PATH_REF;
devicetree:
'/' nodedef
{
......@@ -167,7 +171,7 @@ devicetree:
{
$$ = merge_nodes($1, $3);
}
| DT_REF nodedef
| dt_ref nodedef
{
/*
* We rely on the rule being always:
......@@ -176,9 +180,12 @@ devicetree:
*/
if (!($<flags>-1 & DTSF_PLUGIN))
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);
......@@ -189,7 +196,7 @@ devicetree:
ERROR(&@3, "Label or path %s not found", $3);
$$ = $1;
}
| devicetree DT_REF nodedef
| devicetree DT_PATH_REF nodedef
{
/*
* We rely on the rule being always:
......@@ -208,7 +215,26 @@ devicetree:
}
$$ = $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);
......@@ -220,7 +246,7 @@ devicetree:
$$ = $1;
}
| devicetree DT_OMIT_NO_REF DT_REF ';'
| devicetree DT_OMIT_NO_REF dt_ref ';'
{
struct node *target = get_node_by_ref($1, $3);
......@@ -237,7 +263,7 @@ devicetree:
nodedef:
'{' proplist subnodes '}' ';'
{
$$ = build_node($2, $3);
$$ = build_node($2, $3, &@$);
}
;
......@@ -255,11 +281,11 @@ proplist:
propdef:
DT_PROPNODENAME '=' propdata ';'
{
$$ = build_property($1, $3);
$$ = build_property($1, $3, &@$);
}
| DT_PROPNODENAME ';'
{
$$ = build_property($1, empty_data);
$$ = build_property($1, empty_data, &@$);
}
| DT_DEL_PROP DT_PROPNODENAME ';'
{
......@@ -285,7 +311,7 @@ propdata:
{
$$ = data_merge($1, $3);
}
| propdataprefix DT_REF
| propdataprefix dt_ref
{
$1 = data_add_marker($1, TYPE_STRING, $2);
$$ = data_add_marker($1, REF_PATH, $2);
......@@ -383,7 +409,7 @@ arrayprefix:
$$.data = data_append_integer($1.data, $2, $1.bits);
}
| arrayprefix DT_REF
| arrayprefix dt_ref
{
uint64_t val = ~0ULL >> (64 - $1.bits);
......@@ -540,7 +566,7 @@ subnode:
}
| DT_DEL_NODE DT_PROPNODENAME ';'
{
$$ = name_node(build_node_delete(), $2);
$$ = name_node(build_node_delete(&@$), $2);
}
| DT_OMIT_NO_REF subnode
{
......
......@@ -35,6 +35,8 @@ int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties *
int generate_symbols; /* enable symbols & fixup support */
int generate_fixups; /* suppress generation of fixups on symbol support */
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)
{
......@@ -60,7 +62,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
/* Usage related data. */
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[] = {
{"quiet", no_argument, NULL, 'q'},
{"in-format", a_argument, NULL, 'I'},
......@@ -81,6 +83,7 @@ static struct option const usage_long_opts[] = {
{"error", a_argument, NULL, 'E'},
{"symbols", no_argument, NULL, '@'},
{"auto-alias", no_argument, NULL, 'A'},
{"annotate", no_argument, NULL, 'T'},
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'},
{NULL, no_argument, NULL, 0x0},
......@@ -117,6 +120,7 @@ static const char * const usage_opts_help[] = {
"\n\tEnable/disable errors (prefix with \"no-\")",
"\n\tEnable generation of symbols",
"\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 version and exit",
NULL,
......@@ -264,6 +268,9 @@ int main(int argc, char *argv[])
case 'A':
auto_label_aliases = 1;
break;
case 'T':
annotate++;
break;
case 'h':
usage(NULL);
......@@ -302,6 +309,8 @@ int main(int argc, char *argv[])
outform = "dts";
}
}
if (annotate && (!streq(inform, "dts") || !streq(outform, "dts")))
die("--annotate requires -I dts -O dts\n");
if (streq(inform, "dts"))
dti = dt_from_source(arg);
else if (streq(inform, "fs"))
......
......@@ -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_fixups; /* generate fixups */
extern int auto_label_aliases; /* auto generate labels -> aliases */
extern int annotate; /* annotate .dts with input source location */
#define PHANDLE_LEGACY 0x1
#define PHANDLE_EPAPR 0x2
......@@ -158,6 +159,7 @@ struct property {
struct property *next;
struct label *labels;
struct srcpos *srcpos;
};
struct node {
......@@ -177,6 +179,7 @@ struct node {
struct label *labels;
const struct bus_type *bus;
struct srcpos *srcpos;
bool omit_if_unused, is_referenced;
};
......@@ -205,13 +208,15 @@ struct node {
void add_label(struct label **labels, char *label);
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 *chain_property(struct property *first, struct property *list);
struct property *reverse_properties(struct property *first);
struct node *build_node(struct property *proplist, struct node *children);
struct node *build_node_delete(void);
struct node *build_node(struct property *proplist, struct node *children,
struct srcpos *srcpos);
struct node *build_node_delete(struct srcpos *srcpos);
struct node *name_node(struct node *node, char *name);
struct node *omit_node_if_unused(struct node *node);
struct node *reference_node(struct node *node);
......
......@@ -692,7 +692,7 @@ static struct property *flat_read_property(struct inbuf *dtbuf,
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,
char *flatname;
uint32_t val;
node = build_node(NULL, NULL);
node = build_node(NULL, NULL, NULL);
flatname = flat_read_string(dtbuf);
......
......@@ -34,7 +34,7 @@ static struct node *read_fstree(const char *dirname)
if (!d)
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) {
char *tmpname;
......@@ -60,7 +60,8 @@ static struct node *read_fstree(const char *dirname)
} else {
prop = build_property(xstrdup(de->d_name),
data_copy_file(pfile,
st.st_size));
st.st_size),
NULL);
add_property(tree, prop);
fclose(pfile);
}
......
......@@ -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 \
fdt_addresses.c fdt_overlay.c
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)
c = fdt_getprop(fdt, nodeoffset, name, &len);
if (!c)
return 2;
return len;
if (len != sizeof(*c))
return -FDT_ERR_BADNCELLS;
......@@ -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)
{
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)
{
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);
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 fdt32_to_cpu(v);
return ((uint32_t)bp[0] << 24)
| ((uint32_t)bp[1] << 16)
| ((uint32_t)bp[2] << 8)
| bp[3];
}
static inline uint64_t fdt64_ld(const fdt64_t *p)
{
fdt64_t v;
memcpy(&v, p, sizeof(v));
return fdt64_to_cpu(v);
const uint8_t *bp = (const uint8_t *)p;
return ((uint64_t)bp[0] << 56)
| ((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);
*
* returns:
* 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
* #size-cells property
* -FDT_ERR_BADMAGIC,
......
......@@ -19,6 +19,7 @@
*/
#include "dtc.h"
#include "srcpos.h"
/*
* Tree building functions
......@@ -50,7 +51,8 @@ void delete_labels(struct label **labels)
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));
......@@ -58,6 +60,7 @@ struct property *build_property(char *name, struct data val)
new->name = name;
new->val = val;
new->srcpos = srcpos_copy(srcpos);
return new;
}
......@@ -97,7 +100,8 @@ struct property *reverse_properties(struct property *first)
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 *child;
......@@ -106,6 +110,7 @@ struct node *build_node(struct property *proplist, struct node *children)
new->proplist = reverse_properties(proplist);
new->children = children;
new->srcpos = srcpos_copy(srcpos);
for_each_child(new, child) {
child->parent = new;
......@@ -114,13 +119,14 @@ struct node *build_node(struct property *proplist, struct node *children)
return new;
}
struct node *build_node_delete(void)
struct node *build_node_delete(struct srcpos *srcpos)
{
struct node *new = xmalloc(sizeof(*new));
memset(new, 0, sizeof(*new));
new->deleted = 1;
new->srcpos = srcpos_copy(srcpos);
return new;
}
......@@ -183,6 +189,8 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
old_prop->val = new_prop->val;
old_prop->deleted = 0;
free(old_prop->srcpos);
old_prop->srcpos = new_prop->srcpos;
free(new_prop);
new_prop = NULL;
break;
......@@ -223,6 +231,8 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
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. */
free(new_node);
......@@ -241,18 +251,18 @@ struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref)
if (ref[0] == '/') {
d = data_append_data(d, ref, strlen(ref) + 1);
p = build_property("target-path", d);
p = build_property("target-path", d, NULL);
} else {
d = data_add_marker(d, REF_PHANDLE, ref);
d = data_append_integer(d, 0xffffffff, 32);
p = build_property("target", d);
p = build_property("target", d, NULL);
}
xasprintf(&name, "fragment@%u",
next_orphan_fragment++);
name_node(new_node, "__overlay__");
node = build_node(p, new_node);
node = build_node(p, new_node, NULL);
name_node(node, name);
add_child(dt, node);
......@@ -351,7 +361,7 @@ void append_to_property(struct node *node,
p->val = d;
} else {
d = data_append_data(empty_data, data, len);
p = build_property(name, d);
p = build_property(name, d, NULL);
add_property(node, p);
}
}
......@@ -609,11 +619,11 @@ cell_t get_node_phandle(struct node *root, struct node *node)
if (!get_property(node, "linux,phandle")
&& (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")
&& (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
* 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)
{
struct node *node;
node = build_node(NULL, NULL);
node = build_node(NULL, NULL, NULL);
name_node(node, xstrdup(name));
add_child(parent, node);
......@@ -849,7 +859,8 @@ static void generate_label_tree_internal(struct dt_info *dti,
/* insert it */
p = build_property(l->label,
data_copy_mem(node->fullpath,
strlen(node->fullpath) + 1));
strlen(node->fullpath) + 1),
NULL);
add_property(an, p);
}
......
......@@ -33,6 +33,9 @@ struct search_path {
/* This is the list of directories that we search for source files */
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)
{
......@@ -51,11 +54,51 @@ static char *get_dirname(const char *path)
FILE *depfile; /* = 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. */
#define MAX_SRCFILE_DEPTH (100)
static int srcfile_depth; /* = 0 */
static void set_initial_path(char *fname)
{
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.
......@@ -157,6 +200,9 @@ void srcfile_push(const char *fname)
srcfile->colno = 1;
current_srcfile = srcfile;
if (srcfile_depth == 1)
set_initial_path(srcfile->name);
}
bool srcfile_pop(void)
......@@ -197,18 +243,6 @@ void srcfile_add_search_path(const char *dirname)
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)
{
int i;
......@@ -234,13 +268,35 @@ struct srcpos *
srcpos_copy(struct srcpos *pos)
{
struct srcpos *pos_new;
struct srcfile_state *srcfile_state;
if (!pos)
return NULL;
pos_new = xmalloc(sizeof(struct srcpos));
assert(pos->next == NULL);
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;
}
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 *
srcpos_string(struct srcpos *pos)
{
......@@ -266,6 +322,68 @@ srcpos_string(struct srcpos *pos)
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,
const char *fmt, va_list va)
{
......@@ -294,4 +412,9 @@ void srcpos_set_line(char *f, int l)
{
current_srcfile->name = f;
current_srcfile->lineno = l;
if (initial_cpp) {
initial_cpp = false;
set_initial_path(f);
}
}
......@@ -74,6 +74,7 @@ struct srcpos {
int last_line;
int last_column;
struct srcfile_state *file;
struct srcpos *next;
};
#define YYLTYPE struct srcpos
......@@ -93,19 +94,18 @@ struct srcpos {
YYRHSLOC(Rhs, 0).last_column; \
(Current).file = YYRHSLOC (Rhs, 0).file; \
} \
(Current).next = NULL; \
} 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 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_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,
const char *fmt, va_list va);
......
......@@ -64,6 +64,10 @@ static bool isstring(char c)
static void write_propval_string(FILE *f, const char *s, size_t len)
{
const char *end = s + len - 1;
if (!len)
return;
assert(*end == '\0');
fprintf(f, "\"");
......@@ -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) {
switch (width) {
case 1:
fprintf(f, " %02"PRIx8, *(const uint8_t*)p);
fprintf(f, "%02"PRIx8, *(const uint8_t*)p);
break;
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;
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;
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;
}
if (p + width < end)
fputc(' ', f);
}
}
......@@ -162,10 +168,10 @@ static const char *delim_start[] = {
[TYPE_STRING] = "",
};
static const char *delim_end[] = {
[TYPE_UINT8] = " ]",
[TYPE_UINT16] = " >",
[TYPE_UINT32] = " >",
[TYPE_UINT64] = " >",
[TYPE_UINT8] = "]",
[TYPE_UINT16] = ">",
[TYPE_UINT32] = ">",
[TYPE_UINT64] = ">",
[TYPE_STRING] = "",
};
......@@ -208,13 +214,22 @@ static void write_propval(FILE *f, struct property *prop)
struct marker *m = prop->val.markers;
struct marker dummy_marker;
enum markertype emit_type = TYPE_NONE;
char *srcstr;
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;
}
fprintf(f, " = ");
fprintf(f, " =");
if (!next_type_marker(m)) {
/* data type information missing, need to guess */
......@@ -225,32 +240,23 @@ static void write_propval(FILE *f, struct property *prop)
m = &dummy_marker;
}
struct marker *m_label = prop->val.markers;
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];
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]);
if (has_data_type_information(m)) {
emit_type = m->type;
for_each_marker_of_type(m_label, LABEL) {
if (m_label->offset > m->offset)
break;
fprintf(f, "%s: ", m_label->ref);
}
fprintf(f, "%s", delim_start[emit_type]);
if (chunk_len <= 0)
fprintf(f, " %s", delim_start[emit_type]);
} else if (m->type == LABEL)
fprintf(f, " %s:", m->ref);
else if (m->offset)
fputc(' ', f);
if (emit_type == TYPE_NONE) {
assert(chunk_len == 0);
continue;
}
switch(emit_type) {
case TYPE_UINT16:
......@@ -268,15 +274,23 @@ static void write_propval(FILE *f, struct property *prop)
default:
write_propval_int(f, p, chunk_len, 1);
}
}
/* Wrap up any labels at the end of the value */
for_each_marker_of_type(m_label, LABEL) {
assert (m_label->offset == len);
fprintf(f, " %s:", m_label->ref);
if (chunk_len == data_len) {
size_t pos = m->offset + chunk_len;
fprintf(f, pos == len ? "%s" : "%s,",
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)
......@@ -284,14 +298,24 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
struct property *prop;
struct node *child;
struct label *l;
char *srcstr;
write_prefix(f, level);
for_each_label(tree->labels, l)
fprintf(f, "%s: ", l->label);
if (tree->name && (*tree->name))
fprintf(f, "%s {\n", tree->name);
fprintf(f, "%s {", tree->name);
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) {
write_prefix(f, level+1);
......@@ -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_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)
{
struct reserve_info *re;
......
......@@ -46,34 +46,52 @@ char *xstrdup(const char *s)
return d;
}
/* based in part from (3) vsnprintf */
int xasprintf(char **strp, const char *fmt, ...)
int xavsprintf_append(char **strp, const char *fmt, va_list ap)
{
int n, size = 128; /* start with 128 bytes */
int n, size = 0; /* start with 128 bytes */
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;
/* initial pointer is NULL making the fist realloc to be malloc */
p = NULL;
while (1) {
p = xrealloc(p, size);
*strp = NULL;
/* Try to print in the allocated space. */
va_start(ap, fmt);
n = vsnprintf(p, size, fmt, ap);
n = xavsprintf_append(strp, fmt, ap);
va_end(ap);
/* If that worked, return the string. */
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);
return n;
}
char *join_path(const char *path, const char *name)
......
......@@ -72,6 +72,8 @@ static inline void *xrealloc(void *p, size_t len)
extern char *xstrdup(const char *s);
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);
/**
......
#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