1/* $NetBSD: path_offset.c,v 1.1.1.3 2019/12/22 12:34:05 skrll Exp $ */ 2 3// SPDX-License-Identifier: LGPL-2.1-or-later 4/* 5 * libfdt - Flat Device Tree manipulation 6 * Testcase for fdt_path_offset() 7 * Copyright (C) 2006 David Gibson, IBM Corporation. 8 */ 9#include <stdlib.h> 10#include <stdio.h> 11#include <string.h> 12#include <stdint.h> 13 14#include <libfdt.h> 15 16#include "tests.h" 17#include "testdata.h" 18 19static int check_subnode(void *fdt, int parent, const char *name) 20{ 21 int offset; 22 const struct fdt_node_header *nh; 23 uint32_t tag; 24 25 verbose_printf("Checking subnode \"%s\" of %d...", name, parent); 26 offset = fdt_subnode_offset(fdt, parent, name); 27 verbose_printf("offset %d...", offset); 28 if (offset < 0) 29 FAIL("fdt_subnode_offset(\"%s\"): %s", name, fdt_strerror(offset)); 30 nh = fdt_offset_ptr(fdt, offset, sizeof(*nh)); 31 verbose_printf("pointer %p\n", nh); 32 if (! nh) 33 FAIL("NULL retrieving subnode \"%s\"", name); 34 35 tag = fdt32_to_cpu(nh->tag); 36 37 if (tag != FDT_BEGIN_NODE) 38 FAIL("Incorrect tag 0x%08x on property \"%s\"", tag, name); 39 if (!nodename_eq(nh->name, name)) 40 FAIL("Subnode name mismatch \"%s\" instead of \"%s\"", 41 nh->name, name); 42 43 return offset; 44} 45 46static void check_path_offset(void *fdt, char *path, int offset) 47{ 48 int rc; 49 50 verbose_printf("Checking offset of \"%s\" is %d...\n", path, offset); 51 52 rc = fdt_path_offset(fdt, path); 53 if (rc < 0) 54 FAIL("fdt_path_offset(\"%s\") failed: %s", 55 path, fdt_strerror(rc)); 56 if (rc != offset) 57 FAIL("fdt_path_offset(\"%s\") returned incorrect offset" 58 " %d instead of %d", path, rc, offset); 59} 60 61static void check_path_offset_namelen(void *fdt, char *path, int namelen, 62 int offset) 63{ 64 int rc; 65 66 verbose_printf("Checking offset of \"%s\" [first %d characters]" 67 " is %d...\n", path, namelen, offset); 68 69 rc = fdt_path_offset_namelen(fdt, path, namelen); 70 if (rc == offset) 71 return; 72 73 if (rc < 0) 74 FAIL("fdt_path_offset_namelen(\"%s\", %d) failed: %s", 75 path, namelen, fdt_strerror(rc)); 76 else 77 FAIL("fdt_path_offset_namelen(\"%s\", %d) returned incorrect" 78 " offset %d instead of %d", path, namelen, rc, offset); 79} 80 81int main(int argc, char *argv[]) 82{ 83 void *fdt; 84 int subnode1_offset, subnode2_offset; 85 int subsubnode1_offset, subsubnode2_offset, subsubnode2_offset2; 86 87 test_init(argc, argv); 88 fdt = load_blob_arg(argc, argv); 89 90 check_path_offset(fdt, "/", 0); 91 92 subnode1_offset = check_subnode(fdt, 0, "subnode@1"); 93 subnode2_offset = check_subnode(fdt, 0, "subnode@2"); 94 95 check_path_offset(fdt, "/subnode@1", subnode1_offset); 96 check_path_offset(fdt, "/subnode@2", subnode2_offset); 97 98 subsubnode1_offset = check_subnode(fdt, subnode1_offset, "subsubnode"); 99 subsubnode2_offset = check_subnode(fdt, subnode2_offset, "subsubnode@0"); 100 subsubnode2_offset2 = check_subnode(fdt, subnode2_offset, "subsubnode"); 101 102 check_path_offset(fdt, "/subnode@1/subsubnode", subsubnode1_offset); 103 check_path_offset(fdt, "/subnode@2/subsubnode@0", subsubnode2_offset); 104 check_path_offset(fdt, "/subnode@2/subsubnode", subsubnode2_offset2); 105 106 /* Test paths with extraneous separators */ 107 check_path_offset(fdt, "//", 0); 108 check_path_offset(fdt, "///", 0); 109 check_path_offset(fdt, "//subnode@1", subnode1_offset); 110 check_path_offset(fdt, "/subnode@1/", subnode1_offset); 111 check_path_offset(fdt, "//subnode@1///", subnode1_offset); 112 check_path_offset(fdt, "/subnode@2////subsubnode", subsubnode2_offset2); 113 114 /* Test fdt_path_offset_namelen() */ 115 check_path_offset_namelen(fdt, "/subnode@1", 1, 0); 116 check_path_offset_namelen(fdt, "/subnode@1/subsubnode", 10, subnode1_offset); 117 check_path_offset_namelen(fdt, "/subnode@1/subsubnode", 11, subnode1_offset); 118 check_path_offset_namelen(fdt, "/subnode@2TRAILINGGARBAGE", 10, subnode2_offset); 119 check_path_offset_namelen(fdt, "/subnode@2TRAILINGGARBAGE", 11, -FDT_ERR_NOTFOUND); 120 check_path_offset_namelen(fdt, "/subnode@2/subsubnode@0/more", 23, subsubnode2_offset2); 121 check_path_offset_namelen(fdt, "/subnode@2/subsubnode@0/more", 22, -FDT_ERR_NOTFOUND); 122 check_path_offset_namelen(fdt, "/subnode@2/subsubnode@0/more", 24, subsubnode2_offset2); 123 check_path_offset_namelen(fdt, "/subnode@2/subsubnode@0/more", 25, -FDT_ERR_NOTFOUND); 124 125 PASS(); 126} 127