svn commit: r318093 - stable/11/usr.bin/dtc
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Tue May 9 18:46:51 UTC 2017
Author: gonzo
Date: Tue May 9 18:46:49 2017
New Revision: 318093
URL: https://svnweb.freebsd.org/changeset/base/318093
Log:
MFC r306806, r313709, r317058, r317060
r306806 by emaste:
Improvements to BSD-licensed DTC.
- Numerous crash and bug fixes
- Improved warning and error messages
- Permit multiple labels on nodes and properties
- Fix node at address references
- Add support for /delete-node/
- Consume whitespace after a node
- Read the next token before the second /memreserve/
- Fix parsing of whitespace
- Clean up /delete-node/ and add support for /delete-property/
- Handle /delete-node/ specifying a unit address
Obtained from: https://github.com/davidchisnall/dtc @df5ede4
r313709 by dim:
Fix build of BSD dtc when NDEBUG is defined (MK_ASSERT_DEBUG=no):
* Initialize correct parent in binary_operator's constructor.
* Include <errno.h> explicitly, otherwise errno is undefined (without
NDEBUG, this is accidentally 'fixed' by including <iostream>).
Reported by: matteo
r317058 by emaste:
dtc: remove unused (since r306806) string.hh
r317060 by emaste:
dtc: update to upstream 227d6a3
- Report missing includes at the correct location.
- Add initial support for the -@ option emitting a symbol table.
- Add support for running tests with and without -@
- Add support for generating __fixups__ and __local_fixups__
- Attach the to-string transform to the node path.
Deleted:
stable/11/usr.bin/dtc/string.hh
Modified:
stable/11/usr.bin/dtc/checking.cc
stable/11/usr.bin/dtc/checking.hh
stable/11/usr.bin/dtc/dtb.cc
stable/11/usr.bin/dtc/dtb.hh
stable/11/usr.bin/dtc/dtc.1
stable/11/usr.bin/dtc/dtc.cc
stable/11/usr.bin/dtc/fdt.cc
stable/11/usr.bin/dtc/fdt.hh
stable/11/usr.bin/dtc/input_buffer.cc
stable/11/usr.bin/dtc/input_buffer.hh
stable/11/usr.bin/dtc/string.cc
stable/11/usr.bin/dtc/util.hh
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/usr.bin/dtc/checking.cc
==============================================================================
--- stable/11/usr.bin/dtc/checking.cc Tue May 9 18:45:34 2017 (r318092)
+++ stable/11/usr.bin/dtc/checking.cc Tue May 9 18:46:49 2017 (r318093)
@@ -33,7 +33,7 @@
#include "checking.hh"
#include <stdio.h>
-
+using std::string;
namespace dtc
{
@@ -44,6 +44,30 @@ namespace checking
namespace
{
+ struct deleted_node_checker : public checker
+ {
+ deleted_node_checker(const char *name) : checker(name) {}
+ virtual bool check_node(device_tree *, const node_ptr &n)
+ {
+ auto &deleted = n->deleted_child_nodes();
+ if (deleted.empty())
+ {
+ return true;
+ }
+ bool plural = deleted.size() > 1;
+ string errmsg("Attempts to delete ");
+ errmsg += plural ? "nodes" : "node";
+ errmsg += " that ";
+ errmsg += plural ? "were" : "was";
+ errmsg += " not added in merge: ";
+ for (auto &d : deleted)
+ {
+ errmsg += d;
+ }
+ report_error(errmsg.c_str());
+ return false;
+ }
+ };
/**
* Checker that verifies that every node that has children has
* #address-cells and #size-cells properties.
@@ -126,11 +150,11 @@ checker::report_error(const char *errmsg
for (auto &p : path)
{
putc('/', stderr);
- p.first.dump();
+ puts(p.first.c_str());
if (!(p.second.empty()))
{
putc('@', stderr);
- p.second.dump();
+ puts(p.second.c_str());
}
}
fprintf(stderr, " [-W%s]\n", checker_name);
@@ -167,7 +191,7 @@ property_size_checker::check(device_tree
template<property_value::value_type T>
void
-check_manager::add_property_type_checker(const char *name, string prop)
+check_manager::add_property_type_checker(const char *name, const string &prop)
{
checkers.insert(std::make_pair(string(name),
new property_type_checker<T>(name, prop)));
@@ -175,7 +199,7 @@ check_manager::add_property_type_checker
void
check_manager::add_property_size_checker(const char *name,
- string prop,
+ const string &prop,
uint32_t size)
{
checkers.insert(std::make_pair(string(name),
@@ -207,6 +231,8 @@ check_manager::check_manager()
add_property_size_checker("type-phandle", string("phandle"), 4);
disabled_checkers.insert(std::make_pair(string("cells-attributes"),
new address_cells_checker("cells-attributes")));
+ checkers.insert(std::make_pair(string("deleted-nodes"),
+ new deleted_node_checker("deleted-nodes")));
}
bool
@@ -225,7 +251,7 @@ check_manager::run_checks(device_tree *t
}
bool
-check_manager::disable_checker(string name)
+check_manager::disable_checker(const string &name)
{
auto checker = checkers.find(name);
if (checker != checkers.end())
@@ -239,7 +265,7 @@ check_manager::disable_checker(string na
}
bool
-check_manager::enable_checker(string name)
+check_manager::enable_checker(const string &name)
{
auto checker = disabled_checkers.find(name);
if (checker != disabled_checkers.end())
Modified: stable/11/usr.bin/dtc/checking.hh
==============================================================================
--- stable/11/usr.bin/dtc/checking.hh Tue May 9 18:45:34 2017 (r318092)
+++ stable/11/usr.bin/dtc/checking.hh Tue May 9 18:46:49 2017 (r318093)
@@ -32,7 +32,7 @@
#ifndef _CHECKING_HH_
#define _CHECKING_HH_
-#include "string.hh"
+#include <string>
#include "fdt.hh"
namespace dtc
@@ -58,7 +58,7 @@ class checker
/**
* The name of the checker. This is used for printing error messages
* and for enabling / disabling specific checkers from the command
- * line.
+ * line.
*/
const char *checker_name;
/**
@@ -118,18 +118,18 @@ class property_checker : public checker
/**
* The name of the property that this checker is looking for.
*/
- string key;
+ std::string key;
public:
/**
* Implementation of the generic property-checking method that checks
- * for a property with the name specified in the constructor
+ * for a property with the name specified in the constructor.
*/
virtual bool check_property(device_tree *tree, const node_ptr &n, property_ptr p);
/**
* Constructor. Takes the name of the checker and the name of the
* property to check.
*/
- property_checker(const char* name, string property_name)
+ property_checker(const char* name, const std::string &property_name)
: checker(name), key(property_name) {}
/**
* The check method, which subclasses should implement.
@@ -147,7 +147,7 @@ struct property_type_checker : public pr
* Constructor, takes the name of the checker and the name of the
* property to check as arguments.
*/
- property_type_checker(const char* name, string property_name) :
+ property_type_checker(const char* name, const std::string &property_name) :
property_checker(name, property_name) {}
virtual bool check(device_tree *tree, const node_ptr &n, property_ptr p) = 0;
};
@@ -158,7 +158,7 @@ struct property_type_checker : public pr
template<>
struct property_type_checker <property_value::EMPTY> : public property_checker
{
- property_type_checker(const char* name, string property_name) :
+ property_type_checker(const char* name, const std::string &property_name) :
property_checker(name, property_name) {}
virtual bool check(device_tree *, const node_ptr &, property_ptr p)
{
@@ -173,7 +173,7 @@ struct property_type_checker <property_v
template<>
struct property_type_checker <property_value::STRING> : public property_checker
{
- property_type_checker(const char* name, string property_name) :
+ property_type_checker(const char* name, const std::string &property_name) :
property_checker(name, property_name) {}
virtual bool check(device_tree *, const node_ptr &, property_ptr p)
{
@@ -188,7 +188,7 @@ template<>
struct property_type_checker <property_value::STRING_LIST> :
public property_checker
{
- property_type_checker(const char* name, string property_name) :
+ property_type_checker(const char* name, const std::string &property_name) :
property_checker(name, property_name) {}
virtual bool check(device_tree *, const node_ptr &, property_ptr p)
{
@@ -211,11 +211,11 @@ struct property_type_checker <property_v
template<>
struct property_type_checker <property_value::PHANDLE> : public property_checker
{
- property_type_checker(const char* name, string property_name) :
+ property_type_checker(const char* name, const std::string &property_name) :
property_checker(name, property_name) {}
virtual bool check(device_tree *tree, const node_ptr &, property_ptr p)
{
- return (p->begin() + 1 == p->end()) &&
+ return (p->begin() + 1 == p->end()) &&
(tree->referenced_node(*p->begin()) != 0);
}
};
@@ -234,7 +234,9 @@ struct property_size_checker : public pr
* Constructor, takes the name of the checker, the name of the property
* to check, and its expected size as arguments.
*/
- property_size_checker(const char* name, string property_name, uint32_t bytes)
+ property_size_checker(const char* name,
+ const std::string &property_name,
+ uint32_t bytes)
: property_checker(name, property_name), size(bytes) {}
/**
* Check, validates that the property has the correct size.
@@ -254,26 +256,26 @@ class check_manager
* disabling checkers from the command line. When this manager runs,
* it will only run the checkers from this map.
*/
- std::unordered_map<string, checker*> checkers;
+ std::unordered_map<std::string, checker*> checkers;
/**
* The disabled checkers. Moving checkers to this list disables them,
* but allows them to be easily moved back.
*/
- std::unordered_map<string, checker*> disabled_checkers;
+ std::unordered_map<std::string, checker*> disabled_checkers;
/**
* Helper function for adding a property value checker.
*/
template<property_value::value_type T>
- void add_property_type_checker(const char *name, string prop);
+ void add_property_type_checker(const char *name, const std::string &prop);
/**
* Helper function for adding a simple type checker.
*/
- void add_property_type_checker(const char *name, string prop);
+ void add_property_type_checker(const char *name, const std::string &prop);
/**
* Helper function for adding a property value checker.
*/
void add_property_size_checker(const char *name,
- string prop,
+ const std::string &prop,
uint32_t size);
public:
/**
@@ -292,11 +294,11 @@ class check_manager
/**
* Disables the named checker.
*/
- bool disable_checker(string name);
+ bool disable_checker(const std::string &name);
/**
- * Enables the named checker.
+ * Enables the named checker.
*/
- bool enable_checker(string name);
+ bool enable_checker(const std::string &name);
};
} // namespace checking
Modified: stable/11/usr.bin/dtc/dtb.cc
==============================================================================
--- stable/11/usr.bin/dtc/dtb.cc Tue May 9 18:45:34 2017 (r318092)
+++ stable/11/usr.bin/dtc/dtb.cc Tue May 9 18:46:49 2017 (r318093)
@@ -36,6 +36,7 @@
#include <stdio.h>
#include <unistd.h>
+using std::string;
namespace dtc
{
@@ -51,9 +52,9 @@ void output_writer::write_data(byte_buff
}
void
-binary_writer::write_string(string name)
+binary_writer::write_string(const string &name)
{
- name.push_to_buffer(buffer);
+ push_string(buffer, name);
// Trailing nul
buffer.push_back(0);
}
@@ -98,15 +99,6 @@ binary_writer::size()
}
void
-asm_writer::write_string(const char *c)
-{
- while (*c)
- {
- buffer.push_back((uint8_t)*(c++));
- }
-}
-
-void
asm_writer::write_line(const char *c)
{
if (byte_count != 0)
@@ -142,34 +134,44 @@ asm_writer::write_byte(uint8_t b)
}
void
-asm_writer::write_label(string name)
+asm_writer::write_label(const string &name)
{
write_line("\t.globl ");
- name.push_to_buffer(buffer);
+ push_string(buffer, name);
buffer.push_back('\n');
- name.push_to_buffer(buffer);
+ push_string(buffer, name);
buffer.push_back(':');
buffer.push_back('\n');
buffer.push_back('_');
- name.push_to_buffer(buffer);
+ push_string(buffer, name);
buffer.push_back(':');
buffer.push_back('\n');
}
void
-asm_writer::write_comment(string name)
+asm_writer::write_comment(const string &name)
{
write_line("\t/* ");
- name.push_to_buffer(buffer);
+ push_string(buffer, name);
write_string(" */\n");
}
void
-asm_writer::write_string(string name)
+asm_writer::write_string(const char *c)
+{
+ while (*c)
+ {
+ buffer.push_back((uint8_t)*(c++));
+ }
+}
+
+
+void
+asm_writer::write_string(const string &name)
{
write_line("\t.string \"");
- name.push_to_buffer(buffer);
+ push_string(buffer, name);
write_line("\"\n");
bytes_written += name.size() + 1;
}
@@ -231,8 +233,8 @@ asm_writer::size()
void
header::write(output_writer &out)
{
- out.write_label(string("dt_blob_start"));
- out.write_label(string("dt_header"));
+ out.write_label("dt_blob_start");
+ out.write_label("dt_header");
out.write_comment("magic");
out.write_data(magic);
out.write_comment("totalsize");
@@ -275,7 +277,7 @@ header::read_dtb(input_buffer &input)
input.consume_binary(size_dt_struct);
}
uint32_t
-string_table::add_string(string str)
+string_table::add_string(const string &str)
{
auto old = string_offsets.find(str);
if (old == string_offsets.end())
@@ -296,13 +298,13 @@ string_table::add_string(string str)
void
string_table::write(dtb::output_writer &writer)
{
- writer.write_comment(string("Strings table."));
- writer.write_label(string("dt_strings_start"));
+ writer.write_comment("Strings table.");
+ writer.write_label("dt_strings_start");
for (auto &i : strings)
{
writer.write_string(i);
}
- writer.write_label(string("dt_strings_end"));
+ writer.write_label("dt_strings_end");
}
} // namespace dtb
Modified: stable/11/usr.bin/dtc/dtb.hh
==============================================================================
--- stable/11/usr.bin/dtc/dtb.hh Tue May 9 18:45:34 2017 (r318092)
+++ stable/11/usr.bin/dtc/dtb.hh Tue May 9 18:46:49 2017 (r318093)
@@ -33,10 +33,13 @@
#ifndef _DTB_HH_
#define _DTB_HH_
#include <map>
-#include "string.hh"
+#include <string>
#include <assert.h>
+#include "input_buffer.hh"
+#include "util.hh"
+
namespace dtc
{
/**
@@ -121,16 +124,16 @@ struct output_writer
* assembly output, where the labels become symbols that can be
* resolved at link time.
*/
- virtual void write_label(string name) = 0;
+ virtual void write_label(const std::string &name) = 0;
/**
* Writes a comment into the output stream. Useful only when debugging
* the output.
*/
- virtual void write_comment(string name) = 0;
+ virtual void write_comment(const std::string &name) = 0;
/**
* Writes a string. A nul terminator is implicitly added.
*/
- virtual void write_string(string name) = 0;
+ virtual void write_string(const std::string &name) = 0;
/**
* Writes a single 8-bit value.
*/
@@ -186,17 +189,17 @@ class binary_writer : public output_writ
* The binary format does not support labels, so this method
* does nothing.
*/
- virtual void write_label(string) {}
+ void write_label(const std::string &) override {}
/**
* Comments are ignored by the binary writer.
*/
- virtual void write_comment(string) {}
- virtual void write_string(string name);
- virtual void write_data(uint8_t v);
- virtual void write_data(uint32_t v);
- virtual void write_data(uint64_t v);
- virtual void write_to_file(int fd);
- virtual uint32_t size();
+ void write_comment(const std::string&) override {}
+ void write_string(const std::string &name) override;
+ void write_data(uint8_t v) override;
+ void write_data(uint32_t v) override;
+ void write_data(uint64_t v) override;
+ void write_to_file(int fd) override;
+ uint32_t size() override;
};
/**
* Assembly writer. This class is responsible for writing the output in an
@@ -224,11 +227,15 @@ class asm_writer : public output_writer
uint32_t bytes_written;
/**
- * Writes a C string directly to the output as-is. This is mainly used
- * for writing directives.
+ * Writes a string directly to the output as-is. This is the function that
+ * performs the real output.
*/
void write_string(const char *c);
/**
+ * Write a string to the output.
+ */
+ void write_string(const std::string &c) override;
+ /**
* Writes the string, starting on a new line.
*/
void write_line(const char *c);
@@ -239,14 +246,13 @@ class asm_writer : public output_writer
void write_byte(uint8_t b);
public:
asm_writer() : byte_count(0), bytes_written(0) {}
- virtual void write_label(string name);
- virtual void write_comment(string name);
- virtual void write_string(string name);
- virtual void write_data(uint8_t v);
- virtual void write_data(uint32_t v);
- virtual void write_data(uint64_t v);
- virtual void write_to_file(int fd);
- virtual uint32_t size();
+ void write_label(const std::string &name) override;
+ void write_comment(const std::string &name) override;
+ void write_data(uint8_t v) override;
+ void write_data(uint32_t v) override;
+ void write_data(uint64_t v) override;
+ void write_to_file(int fd) override;
+ uint32_t size() override;
};
/**
@@ -328,14 +334,14 @@ class string_table {
/**
* Map from strings to their offset.
*/
- std::map<string, uint32_t> string_offsets;
+ std::map<std::string, uint32_t> string_offsets;
/**
* The strings, in the order in which they should be written to the
* output. The order must be stable - adding another string must not
* change the offset of any that we have already referenced - and so we
* simply write the strings in the order that they are passed.
*/
- std::vector<string> strings;
+ std::vector<std::string> strings;
/**
* The current size of the strings section.
*/
@@ -351,7 +357,7 @@ class string_table {
* will return its existing offset, otherwise it will return a new
* offset.
*/
- uint32_t add_string(string str);
+ uint32_t add_string(const std::string &str);
/**
* Writes the strings table to the specified output.
*/
Modified: stable/11/usr.bin/dtc/dtc.1
==============================================================================
--- stable/11/usr.bin/dtc/dtc.1 Tue May 9 18:45:34 2017 (r318092)
+++ stable/11/usr.bin/dtc/dtc.1 Tue May 9 18:46:49 2017 (r318093)
@@ -38,7 +38,7 @@
.Nd device tree compiler
.Sh SYNOPSIS
.Nm
-.Op Fl fhsv
+.Op Fl @fhsv
.Op Fl b Ar boot_cpu_id
.Op Fl d Ar dependency_file
.Op Fl E Ar [no-]checker_name
@@ -84,6 +84,8 @@ Enable or disable a specified checker.
The argument is the name of the checker.
The full list of checkers is given in
.Sx CHECKERS .
+.It Fl @
+Emit a __symbols__ node to allow plugins to be loaded.
.It Fl f
Force the tool to attempt to generate the output, even if the input had errors.
.It Fl h
@@ -237,6 +239,10 @@ Checks that all nodes with children have
and
.Va #size-cells
properties.
+.It deleted-nodes
+Checks that all
+.Va /delete-node/
+statements refer to nodes that are merged.
.El
.Sh EXAMPLES
The command:
Modified: stable/11/usr.bin/dtc/dtc.cc
==============================================================================
--- stable/11/usr.bin/dtc/dtc.cc Tue May 9 18:45:34 2017 (r318092)
+++ stable/11/usr.bin/dtc/dtc.cc Tue May 9 18:46:49 2017 (r318093)
@@ -42,8 +42,10 @@
#include "fdt.hh"
#include "checking.hh"
+#include "util.hh"
using namespace dtc;
+using std::string;
/**
* The current major version of the tool.
@@ -52,22 +54,22 @@ int version_major = 0;
/**
* The current minor version of the tool.
*/
-int version_minor = 4;
+int version_minor = 5;
/**
* The current patch level of the tool.
*/
int version_patch = 0;
-static void usage(const char* argv0)
+static void usage(const string &argv0)
{
fprintf(stderr, "Usage:\n"
- "\t%s\t[-fhsv] [-b boot_cpu_id] [-d dependency_file]"
+ "\t%s\t[-fhsv@] [-b boot_cpu_id] [-d dependency_file]"
"[-E [no-]checker_name]\n"
"\t\t[-H phandle_format] [-I input_format]"
"[-O output_format]\n"
"\t\t[-o output_file] [-R entries] [-S bytes] [-p bytes]"
"[-V blob_version]\n"
- "\t\t-W [no-]checker_name] input_file\n", basename((char*)argv0));
+ "\t\t-W [no-]checker_name] input_file\n", basename(argv0).c_str());
}
/**
@@ -90,9 +92,8 @@ main(int argc, char **argv)
const char *in_file = "-";
FILE *depfile = 0;
bool debug_mode = false;
- void (device_tree::*write_fn)(int) = &device_tree::write_binary;
- void (device_tree::*read_fn)(const char*, FILE*) =
- &device_tree::parse_dts;
+ auto write_fn = &device_tree::write_binary;
+ auto read_fn = &device_tree::parse_dts;
uint32_t boot_cpu;
bool boot_cpu_specified = false;
bool keep_going = false;
@@ -100,7 +101,7 @@ main(int argc, char **argv)
clock_t c0 = clock();
class device_tree tree;
fdt::checking::check_manager checks;
- const char *options = "hqI:O:o:V:d:R:S:p:b:fi:svH:W:E:DP:";
+ const char *options = "@hqI:O:o:V:d:R:S:p:b:fi:svH:W:E:DP:";
// Don't forget to update the man page if any more options are added.
while ((ch = getopt(argc, argv, options)) != -1)
@@ -113,14 +114,17 @@ main(int argc, char **argv)
case 'v':
version(argv[0]);
return EXIT_SUCCESS;
+ case '@':
+ tree.write_symbols = true;
+ break;
case 'I':
{
- string arg = string(optarg);
- if (arg == string("dtb"))
+ string arg(optarg);
+ if (arg == "dtb")
{
read_fn = &device_tree::parse_dtb;
}
- else if (arg == string("dts"))
+ else if (arg == "dts")
{
read_fn = &device_tree::parse_dts;
}
@@ -133,16 +137,16 @@ main(int argc, char **argv)
}
case 'O':
{
- string arg = string(optarg);
- if (arg == string("dtb"))
+ string arg(optarg);
+ if (arg == "dtb")
{
write_fn = &device_tree::write_binary;
}
- else if (arg == string("asm"))
+ else if (arg == "asm")
{
write_fn = &device_tree::write_asm;
}
- else if (arg == string("dts"))
+ else if (arg == "dts")
{
write_fn = &device_tree::write_dts;
}
@@ -168,7 +172,7 @@ main(int argc, char **argv)
debug_mode = true;
break;
case 'V':
- if (string(optarg) != string("17"))
+ if (string(optarg) != "17")
{
fprintf(stderr, "Unknown output format version: %s\n", optarg);
return EXIT_FAILURE;
@@ -180,7 +184,7 @@ main(int argc, char **argv)
{
fclose(depfile);
}
- if (string(optarg) == string("-"))
+ if (string(optarg) == "-")
{
depfile = stdout;
}
@@ -197,16 +201,16 @@ main(int argc, char **argv)
}
case 'H':
{
- string arg = string(optarg);
- if (arg == string("both"))
+ string arg(optarg);
+ if (arg == "both")
{
tree.set_phandle_format(device_tree::BOTH);
}
- else if (arg == string("epapr"))
+ else if (arg == "epapr")
{
tree.set_phandle_format(device_tree::EPAPR);
}
- else if (arg == string("linux"))
+ else if (arg == "linux")
{
tree.set_phandle_format(device_tree::LINUX);
}
@@ -229,7 +233,7 @@ main(int argc, char **argv)
case 'W':
case 'E':
{
- string arg = string(optarg);
+ string arg(optarg);
if ((arg.size() > 3) && (strncmp(optarg, "no-", 3) == 0))
{
arg = string(optarg+3);
@@ -307,7 +311,7 @@ main(int argc, char **argv)
}
if (!(tree.is_valid() || keep_going))
{
- fprintf(stderr, "Failed to parse tree. Unhappy face!\n");
+ fprintf(stderr, "Failed to parse tree.\n");
return EXIT_FAILURE;
}
clock_t c2 = clock();
Modified: stable/11/usr.bin/dtc/fdt.cc
==============================================================================
--- stable/11/usr.bin/dtc/fdt.cc Tue May 9 18:45:34 2017 (r318092)
+++ stable/11/usr.bin/dtc/fdt.cc Tue May 9 18:46:49 2017 (r318093)
@@ -36,6 +36,7 @@
#include "dtb.hh"
#include <algorithm>
+#include <sstream>
#include <ctype.h>
#include <fcntl.h>
@@ -48,6 +49,8 @@
#include <sys/stat.h>
#include <errno.h>
+using std::string;
+
namespace dtc
{
@@ -78,7 +81,7 @@ property_value::push_to_buffer(byte_buff
}
else
{
- string_data.push_to_buffer(buffer, true);
+ push_string(buffer, string_data, true);
// Trailing nul
buffer.push_back(0);
}
@@ -166,13 +169,23 @@ property_value::resolve_type()
type = BINARY;
}
+size_t
+property_value::size()
+{
+ if (!byte_data.empty())
+ {
+ return byte_data.size();
+ }
+ return string_data.size() + 1;
+}
+
void
property_value::write_as_string(FILE *file)
{
putc('"', file);
if (byte_data.empty())
{
- string_data.print(file);
+ fputs(string_data.c_str(), file);
}
else
{
@@ -240,31 +253,32 @@ property_value::write_as_bytes(FILE *fil
}
void
-property::parse_string(input_buffer &input)
+property::parse_string(text_input_buffer &input)
{
property_value v;
- assert(input[0] == '"');
+ assert(*input == '"');
++input;
- const char *start = (const char*)input;
- int length = 0;
- while (char c = input[0])
+ std::vector<char> bytes;
+ bool isEscaped = false;
+ while (char c = *input)
{
- if (c == '"' && input[-1] != '\\')
+ if (c == '"' && !isEscaped)
{
input.consume('"');
break;
}
+ isEscaped = (c == '\\');
+ bytes.push_back(c);
++input;
- ++length;
}
- v.string_data = string(start, length);
+ v.string_data = string(bytes.begin(), bytes.end());
values.push_back(v);
}
void
-property::parse_cells(input_buffer &input, int cell_size)
+property::parse_cells(text_input_buffer &input, int cell_size)
{
- assert(input[0] == '<');
+ assert(*input == '<');
++input;
property_value v;
input.next_token();
@@ -282,9 +296,16 @@ property::parse_cells(input_buffer &inpu
return;
}
input.next_token();
- // FIXME: We should support full paths here, but we
- // don't.
- string referenced = string::parse_node_name(input);
+ string referenced;
+ if (!input.consume('{'))
+ {
+ referenced = input.parse_node_name();
+ }
+ else
+ {
+ referenced = input.parse_to('}');
+ input.consume('}');
+ }
if (referenced.empty())
{
input.parse_error("Expected node name");
@@ -343,9 +364,9 @@ property::parse_cells(input_buffer &inpu
}
void
-property::parse_bytes(input_buffer &input)
+property::parse_bytes(text_input_buffer &input)
{
- assert(input[0] == '[');
+ assert(*input == '[');
++input;
property_value v;
input.next_token();
@@ -370,13 +391,13 @@ property::parse_bytes(input_buffer &inpu
}
void
-property::parse_reference(input_buffer &input)
+property::parse_reference(text_input_buffer &input)
{
- assert(input[0] == '&');
+ assert(*input == '&');
++input;
input.next_token();
property_value v;
- v.string_data = string::parse_node_name(input);
+ v.string_data = input.parse_node_name();
if (v.string_data.empty())
{
input.parse_error("Expected node name");
@@ -400,7 +421,7 @@ property::property(input_buffer &structs
}
// Find the name
input_buffer name_buffer = strings.buffer_from_offset(name_offset);
- if (name_buffer.empty())
+ if (name_buffer.finished())
{
fprintf(stderr, "Property name offset %" PRIu32
" is past the end of the strings table\n",
@@ -408,7 +429,7 @@ property::property(input_buffer &structs
valid = false;
return;
}
- key = string(name_buffer);
+ key = name_buffer.parse_to(0);
// If we're empty, do not push anything as value.
if (!length)
@@ -429,7 +450,7 @@ property::property(input_buffer &structs
values.push_back(v);
}
-void property::parse_define(input_buffer &input, define_map *defines)
+void property::parse_define(text_input_buffer &input, define_map *defines)
{
input.consume('$');
if (!defines)
@@ -438,7 +459,7 @@ void property::parse_define(input_buffer
valid = false;
return;
}
- string name = string::parse_property_name(input);
+ string name = input.parse_property_name();
define_map::iterator found;
if ((name == string()) ||
((found = defines->find(name)) == defines->end()))
@@ -450,15 +471,15 @@ void property::parse_define(input_buffer
values.push_back((*found).second->values[0]);
}
-property::property(input_buffer &input,
- string k,
- string l,
+property::property(text_input_buffer &input,
+ string &&k,
+ string_set &&l,
bool semicolonTerminated,
- define_map *defines) : key(k), label(l), valid(true)
+ define_map *defines) : key(k), labels(l), valid(true)
{
do {
input.next_token();
- switch (input[0])
+ switch (*input)
{
case '$':
{
@@ -487,7 +508,7 @@ property::property(input_buffer &input,
}
if (!valid) return;
input.next_token();
- if (input[0] != '<')
+ if (*input != '<')
{
input.parse_error("/bits/ directive is only valid on arrays");
valid = false;
@@ -534,10 +555,14 @@ property::parse_dtb(input_buffer &struct
}
property_ptr
-property::parse(input_buffer &input, string key, string label,
+property::parse(text_input_buffer &input, string &&key, string_set &&label,
bool semicolonTerminated, define_map *defines)
{
- property_ptr p(new property(input, key, label, semicolonTerminated, defines));
+ property_ptr p(new property(input,
+ std::move(key),
+ std::move(label),
+ semicolonTerminated,
+ defines));
if (!p->valid)
{
p = nullptr;
@@ -596,14 +621,16 @@ property::write_dts(FILE *file, int inde
{
putc('\t', file);
}
- if (label != string())
+#ifdef PRINT_LABELS
+ for (auto &l : labels)
{
- label.print(file);
+ fputs(l.c_str(), file);
fputs(": ", file);
}
+#endif
if (key != string())
{
- key.print(file);
+ fputs(key.c_str(), file);
}
if (!values.empty())
{
@@ -636,8 +663,23 @@ property::write_dts(FILE *file, int inde
fputs(";\n", file);
}
+size_t
+property::offset_of_value(property_value &val)
+{
+ size_t off = 0;
+ for (auto &v : values)
+ {
+ if (&v == &val)
+ {
+ return off;
+ }
+ off += v.size();
+ }
+ return -1;
+}
+
string
-node::parse_name(input_buffer &input, bool &is_property, const char *error)
+node::parse_name(text_input_buffer &input, bool &is_property, const char *error)
{
if (!valid)
{
@@ -646,9 +688,9 @@ node::parse_name(input_buffer &input, bo
input.next_token();
if (is_property)
{
- return string::parse_property_name(input);
+ return input.parse_property_name();
}
- string n = string::parse_node_or_property_name(input, is_property);
+ string n = input.parse_node_or_property_name(is_property);
if (n.empty())
{
if (n.empty())
@@ -672,25 +714,23 @@ node::visit(std::function<void(node&)> f
node::node(input_buffer &structs, input_buffer &strings) : valid(true)
{
- const char *name_start = (const char*)structs;
- int name_length = 0;
+ std::vector<char> bytes;
while (structs[0] != '\0' && structs[0] != '@')
{
- name_length++;
+ bytes.push_back(structs[0]);
++structs;
}
- name = string(name_start, name_length);
+ name = string(bytes.begin(), bytes.end());
+ bytes.clear();
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable-11
mailing list