// SPDX-License-Identifier: LGPL-2.1-or-later
/*
 * libfdt - Flat Device Tree manipulation
 *	Testcase for fdt_supernode_atdepth_offset()
 * Copyright (C) 2006 David Gibson, IBM Corporation.
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>

#include <libfdt.h>

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

static int path_depth(const char *path)
{
	const char *p;
	int depth = 0;

	if (path[0] != '/')
		TEST_BUG();

	if (strcmp(path, "/") == 0)
		return 0;
	for (p = path; *p; p++)
		if (*p == '/')
			depth++;

	/* Special case for path == "/" */
	if (p == (path + 1))
		return 0;
	else
		return depth;
}

static int path_prefix(const char *path, int depth)
{
	const char *p;
	int i;

	if (path[0] != '/')
		TEST_BUG();

	if (depth == 0)
		return 1;

	p = path;
	for (i = 0; i < depth; i++)
		p = p+1 + strcspn(p+1, "/");

	return p - path;
}

static void check_supernode_atdepth(struct fdt_header *fdt, const char *path,
			     int depth)
{
	int pdepth = path_depth(path);
	char *superpath;
	int nodeoffset, supernodeoffset, superpathoffset, pathprefixlen;
	int nodedepth;

	pathprefixlen = path_prefix(path, depth);
	superpath = alloca(pathprefixlen + 1);
	strncpy(superpath, path, pathprefixlen);
	superpath[pathprefixlen] = '\0';

	verbose_printf("Path %s (%d), depth %d, supernode is %s\n",
		       path, pdepth, depth, superpath);

	nodeoffset = fdt_path_offset(fdt, path);
	if (nodeoffset < 0)
		FAIL("fdt_path_offset(%s): %s", path, fdt_strerror(nodeoffset));
	superpathoffset = fdt_path_offset(fdt, superpath);
	if (superpathoffset < 0)
		FAIL("fdt_path_offset(%s): %s", superpath,
		     fdt_strerror(superpathoffset));

	supernodeoffset = fdt_supernode_atdepth_offset(fdt, nodeoffset,
						       depth, &nodedepth);
	if (supernodeoffset < 0)
		FAIL("fdt_supernode_atdepth_offset(): %s",
		     fdt_strerror(supernodeoffset));

	if (supernodeoffset != superpathoffset)
		FAIL("fdt_supernode_atdepth_offset() returns %d instead of %d",
		     supernodeoffset, superpathoffset);

	if (nodedepth != pdepth)
		FAIL("fdt_supernode_atdept_offset() returns node depth %d "
		     "instead of %d", nodedepth, pdepth);
}

static void check_supernode_overdepth(struct fdt_header *fdt, const char *path)
{
	int pdepth = path_depth(path);
	int nodeoffset, err;

	nodeoffset = fdt_path_offset(fdt, path);
	if (nodeoffset < 0)
		FAIL("fdt_path_offset(%s): %s", path, fdt_strerror(nodeoffset));

	err = fdt_supernode_atdepth_offset(fdt, nodeoffset, pdepth + 1, NULL);
	if (err != -FDT_ERR_NOTFOUND)
		FAIL("fdt_supernode_atdept_offset(%s, %d) returns %d instead "
		     "of FDT_ERR_NOTFOUND", path, pdepth+1, err);
}

static void check_path(struct fdt_header *fdt, const char *path)
{
	int i;

	for (i = 0; i <= path_depth(path); i++)
		check_supernode_atdepth(fdt, path, i);
	check_supernode_overdepth(fdt, path);
}
int main(int argc, char *argv[])
{
	void *fdt;

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

	check_path(fdt, "/");
	check_path(fdt, "/subnode@1");
	check_path(fdt, "/subnode@2");
	check_path(fdt, "/subnode@1/subsubnode");
	check_path(fdt, "/subnode@2/subsubnode@0");

	PASS();
}
