Home | History | Annotate | Line # | Download | only in tests
      1 /*	$NetBSD: stringlist.c,v 1.1.1.3 2019/12/22 12:34:06 skrll Exp $	*/
      2 
      3 // SPDX-License-Identifier: LGPL-2.1-or-later
      4 /*
      5  * libfdt - Flat Device Tree manipulation
      6  *	Testcase for string handling
      7  * Copyright (C) 2015 NVIDIA Corporation
      8  */
      9 
     10 #include <stdlib.h>
     11 #include <stdio.h>
     12 #include <string.h>
     13 #include <stdint.h>
     14 
     15 #include <libfdt.h>
     16 
     17 #include "tests.h"
     18 #include "testdata.h"
     19 
     20 static void check_expected_failure(const void *fdt, const char *path,
     21 				   const char *property)
     22 {
     23 	int offset, err;
     24 
     25 	offset = fdt_path_offset(fdt, "/");
     26 	if (offset < 0)
     27 		FAIL("Couldn't find path %s", path);
     28 
     29 	err = fdt_stringlist_count(fdt, offset, "#address-cells");
     30 	if (err != -FDT_ERR_BADVALUE)
     31 		FAIL("unexpectedly succeeded in parsing #address-cells\n");
     32 
     33 	err = fdt_stringlist_search(fdt, offset, "#address-cells", "foo");
     34 	if (err != -FDT_ERR_BADVALUE)
     35 		FAIL("found string in #address-cells: %d\n", err);
     36 
     37 	/*
     38 	 * Note that the #address-cells property contains a small 32-bit
     39 	 * unsigned integer, hence some bytes will be zero, and searching for
     40 	 * the empty string will succeed.
     41 	 *
     42 	 * The reason for this oddity is that the function will exit when the
     43 	 * first occurrence of the string is found, but in order to determine
     44 	 * that the property does not contain a valid string list it would
     45 	 * need to process the whole value.
     46 	 */
     47 	err = fdt_stringlist_search(fdt, offset, "#address-cells", "");
     48 	if (err != 0)
     49 		FAIL("empty string not found in #address-cells: %d\n", err);
     50 
     51 	/*
     52 	 * fdt_getprop_string() can successfully extract strings from
     53 	 * non-string properties. This is because it doesn't
     54 	 * necessarily parse the whole property value, which would be
     55 	 * necessary for it to determine if a valid string or string
     56 	 * list is present.
     57 	 */
     58 }
     59 
     60 static void check_string_count(const void *fdt, const char *path,
     61 			       const char *property, int count)
     62 {
     63 	int offset, err;
     64 
     65 	offset = fdt_path_offset(fdt, path);
     66 	if (offset < 0)
     67 		FAIL("Couldn't find path %s", path);
     68 
     69 	err = fdt_stringlist_count(fdt, offset, property);
     70 	if (err < 0)
     71 		FAIL("Couldn't count strings in property %s of node %s: %d\n",
     72 		     property, path, err);
     73 
     74 	if (err != count)
     75 		FAIL("String count for property %s of node %s is %d instead of %d\n",
     76 		     path, property, err, count);
     77 }
     78 
     79 static void check_string_index(const void *fdt, const char *path,
     80 			       const char *property, const char *string,
     81 			       int idx)
     82 {
     83 	int offset, err;
     84 
     85 	offset = fdt_path_offset(fdt, path);
     86 	if (offset < 0)
     87 		FAIL("Couldn't find path %s", path);
     88 
     89 	err = fdt_stringlist_search(fdt, offset, property, string);
     90 
     91 	if (err != idx)
     92 		FAIL("Index of %s in property %s of node %s is %d, expected %d\n",
     93 		     string, property, path, err, idx);
     94 }
     95 
     96 static void check_string(const void *fdt, const char *path,
     97 			 const char *property, int idx,
     98 			 const char *string)
     99 {
    100 	const char *result;
    101 	int offset, len;
    102 
    103 	offset = fdt_path_offset(fdt, path);
    104 	if (offset < 0)
    105 		FAIL("Couldn't find path %s", path);
    106 
    107 	result = fdt_stringlist_get(fdt, offset, property, idx, &len);
    108 	if (!result)
    109 		FAIL("Couldn't extract string %d from property %s of node %s: %d\n",
    110 		     idx, property, path, len);
    111 
    112 	if (strcmp(string, result) != 0)
    113 		FAIL("String %d in property %s of node %s is %s, expected %s\n",
    114 		     idx, property, path, result, string);
    115 }
    116 
    117 int main(int argc, char *argv[])
    118 {
    119 	void *fdt;
    120 
    121 	if (argc != 2)
    122 		CONFIG("Usage: %s <dtb file>\n", argv[0]);
    123 
    124 	test_init(argc, argv);
    125 	fdt = load_blob(argv[1]);
    126 
    127 	check_expected_failure(fdt, "/", "#address-cells");
    128 	check_expected_failure(fdt, "/", "#size-cells");
    129 
    130 	check_string_count(fdt, "/", "compatible", 1);
    131 	check_string_count(fdt, "/device", "compatible", 2);
    132 	check_string_count(fdt, "/device", "big-endian", 0);
    133 
    134 	check_string_index(fdt, "/", "compatible", "test-strings", 0);
    135 	check_string_index(fdt, "/device", "compatible", "foo", 0);
    136 	check_string_index(fdt, "/device", "compatible", "bar", 1);
    137 	check_string_index(fdt, "/device", "big-endian", "baz", -1);
    138 
    139 	check_string(fdt, "/", "compatible", 0, "test-strings");
    140 	check_string(fdt, "/device", "compatible", 0, "foo");
    141 	check_string(fdt, "/device", "compatible", 1, "bar");
    142 
    143 	PASS();
    144 }
    145