-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkernel-devicetree-traversal
More file actions
executable file
·98 lines (79 loc) · 2.67 KB
/
kernel-devicetree-traversal
File metadata and controls
executable file
·98 lines (79 loc) · 2.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/env bash
# Author: Goldie Lin
# Description: Traversal of all *included* DTSI/H for a specific Linux kernel DTS/DTSI.
# Usage: kernel-dtsi-traversal <dts/dtsi-file>
# Requirement: Git-controlled kernel source tree, i.e., has a ".git" folder in the project root.
set -euo pipefail
# variable definitions
# ====================
declare -g git_dir=""
declare -g dt_bindings_inc_dir="" # "dt-bindings".
declare -g indent_chars=" " # one indent = two space.
# Function definitions
# ====================
expand_lvl_to_indents() {
local -i lvl="$1"
local -i i=0
for ((i=0; i<lvl; i++)); do
echo -n "${indent_chars}"
done
}
# down search recursively, likes dfs.
down_search() {
local -ri lvl="$1"
local -ri type="$2"
local -r parent="$3"
local parent_name=""
local parent_dir=""
local -i child_type=1
local -i i=0
local -a siblings=()
local -a bindings=()
local j=""
[[ -f "${parent}" ]] || (echo "Error: '${parent}' does not existed!" >&2 && return 1)
parent_name="$(basename "${parent}")"
parent_dir="$(readlink -f "$(dirname "${parent}")")"
# pattern: include "..."
while IFS= read -r j; do
siblings[i++]="$j"
done < <(grep -P '^\s*(#include|\/include\/)\s+' "${parent}" | grep -Po '(?<=["])([^"]+)(?=["])')
# pattern: include <...>
while IFS= read -r j; do
bindings[i++]="$j"
done < <(grep -P '^\s*(#include|\/include\/)\s+' "${parent}" | grep -Po '(?<=[/<])([^<>]+)(?=[/>])')
# show myself.
if [[ "${type}" -eq 2 ]]; then
echo "$(expand_lvl_to_indents "$lvl")* <${parent_name}>"
else # default: 1
echo "$(expand_lvl_to_indents "$lvl")* \"${parent_name}\""
fi
# recursively search.
if [[ "${#siblings[@]}" -gt 0 ]]; then
child_type=1
for ((i=0; i<${#siblings[@]}; i++)); do
down_search "$(( lvl+1 ))" "${child_type}" "${parent_dir}/${siblings[$i]}"
done
elif [[ "${#bindings[@]}" -gt 0 ]]; then
child_type=2
for ((i=0; i<${#bindings[@]}; i++)); do
down_search "$(( lvl+1 ))" "${child_type}" "${dt_bindings_inc_dir}/${bindings[$i]}"
done
fi
}
main() {
local -i lvl=0
local -i type=1
local parent="$1"
local parent_name=""
local parent_dir=""
[[ -f "${parent}" ]] || (echo "Error: '${parent}' does not existed!" >&2 && return 2)
[[ "${parent##*.}" =~ ^(dts|dtsi)$ ]] || (echo "Error: '${parent}' not a dts/dtsi file!" >&2 && return 3)
parent="$(readlink -f "${parent}")" # relocate myself.
parent_name="$(basename "${parent}")"
parent_dir="$(readlink -f "$(dirname "${parent}")")"
# setup global vars.
git_dir="$(git -C "${parent_dir}" rev-parse --show-toplevel)"
dt_bindings_inc_dir="${git_dir}/include"
down_search "${lvl}" "${type}" "${parent}"
}
main "$@"