1 /* $NetBSD: path_offset.c,v 1.1.1.2 2017/06/08 15:59:27 skrll Exp $ */ 2 3 /* 4 * libfdt - Flat Device Tree manipulation 5 * Testcase for fdt_path_offset() 6 * Copyright (C) 2006 David Gibson, IBM Corporation. 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public License 10 * as published by the Free Software Foundation; either version 2.1 of 11 * the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 #include <stdlib.h> 23 #include <stdio.h> 24 #include <string.h> 25 #include <stdint.h> 26 27 #include <libfdt.h> 28 29 #include "tests.h" 30 #include "testdata.h" 31 32 static int check_subnode(void *fdt, int parent, const char *name) 33 { 34 int offset; 35 const struct fdt_node_header *nh; 36 uint32_t tag; 37 38 verbose_printf("Checking subnode \"%s\" of %d...", name, parent); 39 offset = fdt_subnode_offset(fdt, parent, name); 40 verbose_printf("offset %d...", offset); 41 if (offset < 0) 42 FAIL("fdt_subnode_offset(\"%s\"): %s", name, fdt_strerror(offset)); 43 nh = fdt_offset_ptr(fdt, offset, sizeof(*nh)); 44 verbose_printf("pointer %p\n", nh); 45 if (! nh) 46 FAIL("NULL retrieving subnode \"%s\"", name); 47 48 tag = fdt32_to_cpu(nh->tag); 49 50 if (tag != FDT_BEGIN_NODE) 51 FAIL("Incorrect tag 0x%08x on property \"%s\"", tag, name); 52 if (!nodename_eq(nh->name, name)) 53 FAIL("Subnode name mismatch \"%s\" instead of \"%s\"", 54 nh->name, name); 55 56 return offset; 57 } 58 59 static void check_path_offset(void *fdt, char *path, int offset) 60 { 61 int rc; 62 63 verbose_printf("Checking offset of \"%s\" is %d...\n", path, offset); 64 65 rc = fdt_path_offset(fdt, path); 66 if (rc < 0) 67 FAIL("fdt_path_offset(\"%s\") failed: %s", 68 path, fdt_strerror(rc)); 69 if (rc != offset) 70 FAIL("fdt_path_offset(\"%s\") returned incorrect offset" 71 " %d instead of %d", path, rc, offset); 72 } 73 74 static void check_path_offset_namelen(void *fdt, char *path, int namelen, 75 int offset) 76 { 77 int rc; 78 79 verbose_printf("Checking offset of \"%s\" [first %d characters]" 80 " is %d...\n", path, namelen, offset); 81 82 rc = fdt_path_offset_namelen(fdt, path, namelen); 83 if (rc == offset) 84 return; 85 86 if (rc < 0) 87 FAIL("fdt_path_offset_namelen(\"%s\", %d) failed: %s", 88 path, namelen, fdt_strerror(rc)); 89 else 90 FAIL("fdt_path_offset_namelen(\"%s\", %d) returned incorrect" 91 " offset %d instead of %d", path, namelen, rc, offset); 92 } 93 94 int main(int argc, char *argv[]) 95 { 96 void *fdt; 97 int subnode1_offset, subnode2_offset; 98 int subsubnode1_offset, subsubnode2_offset, subsubnode2_offset2; 99 100 test_init(argc, argv); 101 fdt = load_blob_arg(argc, argv); 102 103 check_path_offset(fdt, "/", 0); 104 105 subnode1_offset = check_subnode(fdt, 0, "subnode@1"); 106 subnode2_offset = check_subnode(fdt, 0, "subnode@2"); 107 108 check_path_offset(fdt, "/subnode@1", subnode1_offset); 109 check_path_offset(fdt, "/subnode@2", subnode2_offset); 110 111 subsubnode1_offset = check_subnode(fdt, subnode1_offset, "subsubnode"); 112 subsubnode2_offset = check_subnode(fdt, subnode2_offset, "subsubnode@0"); 113 subsubnode2_offset2 = check_subnode(fdt, subnode2_offset, "subsubnode"); 114 115 check_path_offset(fdt, "/subnode@1/subsubnode", subsubnode1_offset); 116 check_path_offset(fdt, "/subnode@2/subsubnode@0", subsubnode2_offset); 117 check_path_offset(fdt, "/subnode@2/subsubnode", subsubnode2_offset2); 118 119 /* Test paths with extraneous separators */ 120 check_path_offset(fdt, "//", 0); 121 check_path_offset(fdt, "///", 0); 122 check_path_offset(fdt, "//subnode@1", subnode1_offset); 123 check_path_offset(fdt, "/subnode@1/", subnode1_offset); 124 check_path_offset(fdt, "//subnode@1///", subnode1_offset); 125 check_path_offset(fdt, "/subnode@2////subsubnode", subsubnode2_offset2); 126 127 /* Test fdt_path_offset_namelen() */ 128 check_path_offset_namelen(fdt, "/subnode@1", 1, 0); 129 check_path_offset_namelen(fdt, "/subnode@1/subsubnode", 10, subnode1_offset); 130 check_path_offset_namelen(fdt, "/subnode@1/subsubnode", 11, subnode1_offset); 131 check_path_offset_namelen(fdt, "/subnode@2TRAILINGGARBAGE", 10, subnode2_offset); 132 check_path_offset_namelen(fdt, "/subnode@2TRAILINGGARBAGE", 11, -FDT_ERR_NOTFOUND); 133 check_path_offset_namelen(fdt, "/subnode@2/subsubnode@0/more", 23, subsubnode2_offset2); 134 check_path_offset_namelen(fdt, "/subnode@2/subsubnode@0/more", 22, -FDT_ERR_NOTFOUND); 135 check_path_offset_namelen(fdt, "/subnode@2/subsubnode@0/more", 24, subsubnode2_offset2); 136 check_path_offset_namelen(fdt, "/subnode@2/subsubnode@0/more", 25, -FDT_ERR_NOTFOUND); 137 138 PASS(); 139 } 140