devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
To: Devicetree Discuss
	<devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org>
Subject: [PATCH 5/5] fdtput: Add -p option to create subnodes along entire path
Date: Tue, 10 Jul 2012 05:56:48 -0700	[thread overview]
Message-ID: <1341925008-10627-5-git-send-email-sjg@chromium.org> (raw)
In-Reply-To: <1341925008-10627-1-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>

This option mimics mkdir's -p option. It automatically creates nodes
as needed along the path provided. If the node already exists, no
error is given.

Signed-off-by: Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
---
 fdtput.c           |   59 ++++++++++++++++++++++++++++++++++++++++++++++++---
 tests/run_tests.sh |   13 +++++++++++
 2 files changed, 68 insertions(+), 4 deletions(-)

diff --git a/fdtput.c b/fdtput.c
index f217f1d..637d9fa 100644
--- a/fdtput.c
+++ b/fdtput.c
@@ -39,6 +39,7 @@ struct display_info {
 	int type;		/* data type (s/i/u/x or 0 for default) */
 	int size;		/* data size (1/2/4) */
 	int verbose;		/* verbose output */
+	int auto_path;		/* automatically create all path components */
 };
 
 
@@ -151,6 +152,47 @@ static int store_key_value(void *blob, const char *node_name,
 }
 
 /**
+ * Create paths as needed for all components of a path
+ *
+ * Any components of the path that do not exist are created. Errors are
+ * reported.
+ *
+ * @param blob		FDT blob to write into
+ * @param in_path	Path to process
+ * @return 0 if ok, -1 on error
+ */
+static int create_paths(void *blob, const char *in_path)
+{
+	const char *path = in_path;
+	const char *sep;
+	int node, offset = 0;
+
+	/* skip leading '/' */
+	while (*path == '/')
+		path++;
+
+	for (sep = path; *sep; path = sep + 1, offset = node) {
+		/* equivalent to strchrnul(), but it requires _GNU_SOURCE */
+		sep = strchr(path, '/');
+		if (!sep)
+			sep = path + strlen(path);
+
+		node = fdt_subnode_offset_namelen(blob, offset, path,
+				sep - path);
+		if (node == -FDT_ERR_NOTFOUND) {
+			node = fdt_add_subnode_namelen(blob, offset, path,
+						       sep - path);
+		}
+		if (node < 0) {
+			report_error(path, sep - path, node);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/**
  * Create a new node in the fdt.
  *
  * This will overwrite the node_name string. Any error is reported.
@@ -208,13 +250,19 @@ static int do_fdtput(struct display_info *disp, const char *filename,
 		 * store them into the property.
 		 */
 		assert(arg_count >= 2);
+		if (disp->auto_path && create_paths(blob, *arg))
+			return -1;
 		if (encode_value(disp, arg + 2, arg_count - 2, &value, &len) ||
 			store_key_value(blob, *arg, arg[1], value, len))
 			ret = -1;
 		break;
 	case OPER_CREATE_NODE:
-		for (; ret >= 0 && arg_count--; arg++)
-			ret = create_node(blob, *arg);
+		for (; ret >= 0 && arg_count--; arg++) {
+			if (disp->auto_path)
+				ret = create_paths(blob, *arg);
+			else
+				ret = create_node(blob, *arg);
+		}
 		break;
 	}
 	if (ret >= 0)
@@ -234,6 +282,7 @@ static const char *usage_msg =
 	"	fdtput -c <dt file> [<node>...]\n"
 	"Options:\n"
 	"\t-c\tCreate nodes if they don't already exist\n"
+	"\t-p\tAutomatically create nodes as needed through the whole path\n"
 	"\t-t <type>\tType of data\n"
 	"\t-v\t\tVerbose: display each value decoded from command line\n"
 	"\t-h\t\tPrint this help\n\n"
@@ -257,7 +306,7 @@ int main(int argc, char *argv[])
 	disp.size = -1;
 	disp.oper = OPER_WRITE_PROP;
 	for (;;) {
-		int c = getopt(argc, argv, "cht:v");
+		int c = getopt(argc, argv, "chpt:v");
 		if (c == -1)
 			break;
 
@@ -277,7 +326,9 @@ int main(int argc, char *argv[])
 		case 'h':
 		case '?':
 			usage(NULL);
-
+		case 'p':
+			disp.auto_path = 1;
+			break;
 		case 't':
 			if (utilfdt_decode_type(optarg, &disp.type,
 					&disp.size))
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index acec2a5..b825b81 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -552,6 +552,19 @@ fdtput_tests () {
     run_wrap_error_test $DTPUT $dtb -c /chosen
     run_wrap_error_test $DTPUT $dtb -c /chosen/son
 
+    # Automatic node creation
+    run_wrap_test $DTPUT $dtb -cp /blackadder/the-second/turnip \
+	/blackadder/the-second/potato
+    run_fdtput_test 1000 $dtb /blackadder/the-second/turnip cost "" 1000
+    run_fdtput_test "fine wine" $dtb /blackadder/the-second/potato drink \
+	"-ts" "fine wine"
+    run_wrap_test $DTPUT $dtb -p /you/are/drunk/sir/winston slurp -ts twice
+    run_wrap_error_test $DTPUT $dtb -cp "$(cat $text $text)/longish"
+
+    # Allowed to create an existing node with -p
+    run_wrap_test $DTPUT $dtb -cp /chosen
+    run_wrap_test $DTPUT $dtb -cp /chosen/son
+
     # TODO: Add tests for verbose mode?
 }
 
-- 
1.7.7.3

  parent reply	other threads:[~2012-07-10 12:56 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-10 12:56 [PATCH 1/5] fdtput: Fix nit in help message Simon Glass
     [not found] ` <1341925008-10627-1-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2012-07-10 12:56   ` [PATCH 2/5] fdtput: Prepare to support multiple operations Simon Glass
     [not found]     ` <1341925008-10627-2-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2012-07-12 12:37       ` David Gibson
     [not found]         ` <20120712123745.GB11326-MK4v0fQdeXQXU02nzanrWNbf9cGiqdzd@public.gmane.org>
2012-07-12 15:49           ` Simon Glass
2012-07-10 12:56   ` [PATCH 3/5] fdtput: Add -c option to create nodes Simon Glass
     [not found]     ` <1341925008-10627-3-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2012-07-12 12:39       ` David Gibson
2012-07-10 12:56   ` [PATCH 4/5] fdtput: Adjust report_error() to use name, namelen params Simon Glass
     [not found]     ` <1341925008-10627-4-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2012-07-12 12:40       ` David Gibson
2012-07-10 12:56   ` Simon Glass [this message]
2012-07-11  0:11   ` [PATCH 1/5] fdtput: Fix nit in help message David Gibson
     [not found]     ` <20120711001124.GA6652-MK4v0fQdeXQXU02nzanrWNbf9cGiqdzd@public.gmane.org>
2012-07-11 14:40       ` Jon Loeliger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1341925008-10627-5-git-send-email-sjg@chromium.org \
    --to=sjg-f7+t8e8rja9g9huczpvpmw@public.gmane.org \
    --cc=devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).