/*
 * libfdt - Flat Device Tree manipulation
 *	Testcase for fdt_path_offset()
 * Copyright (C) 2006 David Gibson, IBM Corporation.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <fdt.h>
#include <libfdt.h>

#include "tests.h"
#include "testdata.h"

int check_subnode(void *fdt, int parent, const char *name)
{
	int offset;
	int err;
	struct fdt_node_header *nh;
	uint32_t tag;

	verbose_printf("Checking subnode \"%s\" of %d...", name, parent);
	offset = fdt_subnode_offset(fdt, parent, name);
	verbose_printf("offset %d...", offset);
	if ((err = fdt_offset_error(offset)))
		FAIL("fdt_subnode_offset(\"%s\"): %s", name, fdt_strerror(err));
	nh = fdt_offset_ptr_typed(fdt, offset, nh);
	verbose_printf("pointer %p\n", nh);
	if (! nh)
		FAIL("NULL retrieving subnode \"%s\"", name);

	tag = fdt32_to_cpu(nh->tag);

	if (tag != FDT_BEGIN_NODE)
		FAIL("Incorrect tag 0x%08x on property \"%s\"", tag, name);
	if (!streq(nh->name, name))
		FAIL("Subnode name mismatch \"%s\" instead of \"%s\"",
		     nh->name, name);

	return offset;
}

int main(int argc, char *argv[])
{
	void *fdt;
	int subnode1_offset, subnode2_offset;
	int subnode1_offset_p, subnode2_offset_p;
	int subsubnode1_offset, subsubnode2_offset;
	int subsubnode1_offset_p, subsubnode2_offset_p;

	test_init(argc, argv);
	fdt = load_blob_arg(argc, argv);

	subnode1_offset = check_subnode(fdt, 0, "subnode1");
	subnode2_offset = check_subnode(fdt, 0, "subnode2");

	subnode1_offset_p = fdt_path_offset(fdt, "/subnode1");
	subnode2_offset_p = fdt_path_offset(fdt, "/subnode2");

	if (subnode1_offset != subnode1_offset_p)
		FAIL("Mismatch between subnode_offset (%d) and path_offset (%d)",
		     subnode1_offset, subnode1_offset_p);

	if (subnode2_offset != subnode2_offset_p)
		FAIL("Mismatch between subnode_offset (%d) and path_offset (%d)",
		     subnode2_offset, subnode2_offset_p);

	subsubnode1_offset = check_subnode(fdt, subnode1_offset, "subsubnode");
	subsubnode2_offset = check_subnode(fdt, subnode2_offset, "subsubnode");

	subsubnode1_offset_p = fdt_path_offset(fdt, "/subnode1/subsubnode");
	subsubnode2_offset_p = fdt_path_offset(fdt, "/subnode2/subsubnode");

	if (subsubnode1_offset != subsubnode1_offset_p)
		FAIL("Mismatch between subnode_offset (%d) and path_offset (%d)",
		     subsubnode1_offset, subsubnode1_offset_p);

	if (subsubnode2_offset != subsubnode2_offset_p)
		FAIL("Mismatch between subnode_offset (%d) and path_offset (%d)",
		     subsubnode2_offset, subsubnode2_offset_p);

	PASS();
}
