File: linux-uapi.sh

package info (click to toggle)
dpdk 25.11-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 127,892 kB
  • sloc: ansic: 2,358,479; python: 16,426; sh: 4,474; makefile: 1,713; awk: 70
file content (189 lines) | stat: -rwxr-xr-x 3,913 bytes parent folder | download
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#!/bin/sh -e
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2024 Red Hat, Inc.

#
# Import and check Linux Kernel uAPI headers
#

base_url="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/include/uapi/"
base_path="kernel/linux/uapi/"
version=""
file=""
check_headers=false
quiet=false

print_usage()
{
	echo "Usage: $(basename $0) [-h] [-i FILE] [-u VERSION] [-c] [-q]"
	echo "-i FILE      import Linux header file. E.g. linux/vfio.h"
	echo "-u VERSION   update imported list of Linux headers to a given version. E.g. v6.10"
	echo "-c           check headers are valid"
	echo "-q           quiet mode"
}

version_older_than() {
    printf '%s\n%s' "$1" "$2" | sort -C -V
}

download_header()
{
	local header=$1
	local path=$2

	local url="$base_url$header?h=$version"

	if ! curl -s -f --create-dirs -o $path $url; then
		echo "Failed to download $url"
		return 1
	fi

	return 0
}

update_headers()
{
	local header

	$quiet || echo "Updating to $version"
	for filename in $(find $base_path -name "*.h" -type f); do
		header=${filename#$base_path}
		download_header $header $filename
	done

	return 0
}

import_header()
{
	local include
	local import
	local header=$1

	local path="$base_path$header"

	download_header $header $path

	for include in $(sed -ne 's/^#include <\(.*\)>$/\1/p' $path); do
		if [ ! -f "$base_path$include" ]; then
			read -p "Import $include (y/n): " import && [ "$import" = 'y' ] || continue
			$quiet || echo "Importing $include for $path"
			import_header "$include"
		fi
	done

	return 0
}

fixup_includes()
{
	local path=$1

	sed -i "s|^#include <linux/compiler.h>||g" $path
	sed -i "s|\<__user[[:space:]]||" $path
	sed -i 's|#\(ifndef\)[[:space:]]*_UAPI|#\1 |' $path
	sed -i 's|#\(define\)[[:space:]]*_UAPI|#\1 |' $path
	sed -i 's|#\(endif[[:space:]]*/[*]\)[[:space:]]*_UAPI|#\1 |' $path

	# Prepend include path with "uapi/" if the header is imported
	for include in $(sed -ne 's/^#include <\(.*\)>$/\1/p' $path); do
		if [ -f "$base_path$include" ]; then
			sed -i "s|$include|uapi/$include|g" $path
		fi
	done
}

update_all()
{
	if [ -n "$version" ]; then
		if version_older_than "$version" "$current_version"; then
			$quiet || echo "Headers already up to date ($current_version >= $version)"
			version=$current_version
		else
			update_headers
		fi
	else
		$quiet || echo "Version not specified, using current version ($current_version)"
		version=$current_version
	fi

	if [ -n "$file" ]; then
		import_header $file
	fi

	for filename in $(find $base_path -name "*.h" -type f); do
		fixup_includes $filename
	done

	echo $version > $base_path/version
}

check_header()
{
	$quiet || echo -n "Checking $1... "

	if ! diff -q $1 $2 >/dev/null; then
		$quiet || echo "KO"
		$quiet || diff -u $1 $2
		return 1
	else
		$quiet || echo "OK"
	fi

	return 0
}

check_all()
{
	local errors=0

	tmpheader="$(mktemp -t dpdk.checkuapi.XXXXXX)"
	trap "rm -f '$tmpheader'" INT

	$quiet || echo "Checking imported headers for version $version"
	for filename in $(find $base_path -name "*.h" -type f); do
		header=${filename#$base_path}
		download_header $header $tmpheader
		fixup_includes $tmpheader
		check_header $filename $tmpheader || errors=$((errors+1))
	done
	if [ $errors -ne 0 ] || ! $quiet; then
		echo "$errors error(s) found in Linux uAPI"
	fi

	rm -f $tmpheader
	trap - INT

	return $errors
}

while getopts i:u:cqh opt ; do
	case $opt in
		i ) file=$OPTARG ;;
		u ) version=$OPTARG ;;
		c ) check_headers=true ;;
		q ) quiet=true ;;
		h ) print_usage ; exit 0 ;;
		? ) print_usage ; exit 1 ;;
	esac
done

shift $(($OPTIND - 1))
if [ $# -ne 0 ]; then
	print_usage
	exit 1
fi
if $check_headers && [ -n "$file" -o -n "$version" ]; then
	echo "The option -c is incompatible with -i and -u"
	exit 1
fi

cd $(dirname $0)/..
current_version=$(cat $base_path/version)

if $check_headers; then
	version=$current_version
	check_all
else
	update_all
fi