1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 /*
3 * libfdt - Flat Device Tree manipulation
4 * Testcase for fdt_path_offset()
5 * Copyright (C) 2006 David Gibson, IBM Corporation.
6 */
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdint.h>
11 #include <stdarg.h>
12
13 #include <libfdt.h>
14
15 #include "tests.h"
16 #include "testdata.h"
17
vcheck_search(void * fdt,const char * propname,const void * propval,int proplen,va_list ap)18 static void vcheck_search(void *fdt, const char *propname, const void *propval,
19 int proplen, va_list ap)
20 {
21 int offset = -1, target;
22
23 do {
24 target = va_arg(ap, int);
25 verbose_printf("Searching (target = %d): %d ->",
26 target, offset);
27 offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
28 propval, proplen);
29 verbose_printf("%d\n", offset);
30
31 if (offset != target)
32 FAIL("fdt_node_offset_by_prop_value() returns %d "
33 "instead of %d", offset, target);
34 } while (target >= 0);
35 }
36
check_search(void * fdt,const char * propname,const void * propval,int proplen,...)37 static void check_search(void *fdt, const char *propname, const void *propval,
38 int proplen, ...)
39 {
40 va_list ap;
41
42 va_start(ap, proplen);
43 vcheck_search(fdt, propname, propval, proplen, ap);
44 va_end(ap);
45 }
46
check_search_str(void * fdt,const char * propname,const char * propval,...)47 static void check_search_str(void *fdt, const char *propname,
48 const char *propval, ...)
49 {
50 va_list ap;
51
52 va_start(ap, propval);
53 vcheck_search(fdt, propname, propval, strlen(propval)+1, ap);
54 va_end(ap);
55 }
56
57 #define check_search_cell(fdt, propname, propval, ...) \
58 { \
59 fdt32_t val = cpu_to_fdt32(propval); \
60 check_search((fdt), (propname), &val, sizeof(val), \
61 ##__VA_ARGS__); \
62 }
63
main(int argc,char * argv[])64 int main(int argc, char *argv[])
65 {
66 void *fdt;
67 int subnode1_offset, subnode2_offset;
68 int subsubnode1_offset, subsubnode2_offset;
69
70 test_init(argc, argv);
71 fdt = load_blob_arg(argc, argv);
72
73 subnode1_offset = fdt_path_offset(fdt, "/subnode@1");
74 subnode2_offset = fdt_path_offset(fdt, "/subnode@2");
75 subsubnode1_offset = fdt_path_offset(fdt, "/subnode@1/subsubnode");
76 subsubnode2_offset = fdt_path_offset(fdt, "/subnode@2/subsubnode@0");
77
78 if ((subnode1_offset < 0) || (subnode2_offset < 0)
79 || (subsubnode1_offset < 0) || (subsubnode2_offset < 0))
80 FAIL("Can't find required nodes");
81
82 check_search_cell(fdt, "prop-int", TEST_VALUE_1, 0, subnode1_offset,
83 subsubnode1_offset, -FDT_ERR_NOTFOUND);
84
85 check_search_cell(fdt, "prop-int", TEST_VALUE_2, subnode2_offset,
86 subsubnode2_offset, -FDT_ERR_NOTFOUND);
87
88 check_search_str(fdt, "prop-str", TEST_STRING_1, 0, -FDT_ERR_NOTFOUND);
89
90 check_search_str(fdt, "prop-str", "no such string", -FDT_ERR_NOTFOUND);
91
92 check_search_cell(fdt, "prop-int", TEST_VALUE_1+1, -FDT_ERR_NOTFOUND);
93
94 check_search(fdt, "no-such-prop", NULL, 0, -FDT_ERR_NOTFOUND);
95
96 PASS();
97 }
98