/*
 * 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(struct fdt_header *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[])
{
	struct fdt_header *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();
}
