185071702SPeter Maydell#!/bin/sh -e 285071702SPeter Maydell# 385071702SPeter Maydell# Clean up QEMU #include lines by ensuring that qemu/osdep.h 4fd3e39a4SPeter Maydell# is the first include listed in .c files, and no headers provided 5fd3e39a4SPeter Maydell# by osdep.h itself are redundantly included in either .c or .h files. 685071702SPeter Maydell# 785071702SPeter Maydell# Copyright (c) 2015 Linaro Limited 885071702SPeter Maydell# 985071702SPeter Maydell# Authors: 1085071702SPeter Maydell# Peter Maydell <peter.maydell@linaro.org> 1185071702SPeter Maydell# 1285071702SPeter Maydell# This work is licensed under the terms of the GNU GPL, version 2 1385071702SPeter Maydell# or (at your option) any later version. See the COPYING file in 1485071702SPeter Maydell# the top-level directory. 1585071702SPeter Maydell 1685071702SPeter Maydell# Usage: 17d66253e4SAnand J# clean-includes [--git subjectprefix] [--check-dup-head] file ... 18d57106a4SPeter Maydell# or 19d66253e4SAnand J# clean-includes [--git subjectprefix] [--check-dup-head] --all 2085071702SPeter Maydell# 2185071702SPeter Maydell# If the --git subjectprefix option is given, then after making 2285071702SPeter Maydell# the changes to the files this script will create a git commit 2385071702SPeter Maydell# with the subject line "subjectprefix: Clean up includes" 2485071702SPeter Maydell# and a boilerplate commit message. 25d57106a4SPeter Maydell# 26d66253e4SAnand J# If --check-dup-head is specified, additionally check for duplicate 27d66253e4SAnand J# header includes. 28d66253e4SAnand J# 29d57106a4SPeter Maydell# Using --all will cause clean-includes to run on the whole source 30d57106a4SPeter Maydell# tree (excluding certain directories which are known not to need 31d57106a4SPeter Maydell# handling). 3285071702SPeter Maydell 3385071702SPeter Maydell# This script requires Coccinelle to be installed. 3485071702SPeter Maydell 35fd3e39a4SPeter Maydell# .c files will have the osdep.h included added, and redundant 36fd3e39a4SPeter Maydell# includes removed. 37fd3e39a4SPeter Maydell# .h files will have redundant includes (including includes of osdep.h) 38fd3e39a4SPeter Maydell# removed. 39fd3e39a4SPeter Maydell# Other files (including C++ and ObjectiveC) can't be handled by this script. 4085071702SPeter Maydell 4185071702SPeter Maydell# The following one-liner may be handy for finding files to run this on. 4285071702SPeter Maydell# However some caution is required regarding files that might be part 4385071702SPeter Maydell# of the guest agent or standalone tests. 4485071702SPeter Maydell 45bbd90802SStefan Weil# for i in $(git ls-tree --name-only HEAD) ; do test -f $i && \ 4685071702SPeter Maydell# grep -E '^# *include' $i | head -1 | grep 'osdep.h' ; test $? != 0 && \ 4785071702SPeter Maydell# echo $i ; done 4885071702SPeter Maydell 4985071702SPeter Maydell 5085071702SPeter MaydellGIT=no 51d66253e4SAnand JDUPHEAD=no 5285071702SPeter Maydell 53d57106a4SPeter Maydell# Extended regular expression defining files to ignore when using --all 54d57106a4SPeter MaydellXDIRREGEX='^(tests/tcg|tests/multiboot|pc-bios|disas/libvixl)' 55d57106a4SPeter Maydell 56d66253e4SAnand Jwhile true 57d66253e4SAnand Jdo 58d66253e4SAnand J case $1 in 59d66253e4SAnand J "--git") 6085071702SPeter Maydell if [ $# -eq 1 ]; then 6185071702SPeter Maydell echo "--git option requires an argument" 6285071702SPeter Maydell exit 1 6385071702SPeter Maydell fi 6485071702SPeter Maydell GITSUBJ="$2" 6585071702SPeter Maydell GIT=yes 6685071702SPeter Maydell shift 6785071702SPeter Maydell shift 68d66253e4SAnand J ;; 69d66253e4SAnand J "--check-dup-head") 70d66253e4SAnand J DUPHEAD=yes 71d66253e4SAnand J shift 72d66253e4SAnand J ;; 73d66253e4SAnand J "--") 74d66253e4SAnand J shift 75d66253e4SAnand J break 76d66253e4SAnand J ;; 77d66253e4SAnand J *) 78d66253e4SAnand J break 79d66253e4SAnand J ;; 80d66253e4SAnand J esac 81d66253e4SAnand Jdone 8285071702SPeter Maydell 8385071702SPeter Maydellif [ $# -eq 0 ]; then 84d66253e4SAnand J echo "Usage: clean-includes [--git subjectprefix] [--check-dup-head] [--all | foo.c ...]" 8585071702SPeter Maydell echo "(modifies the files in place)" 8685071702SPeter Maydell exit 1 8785071702SPeter Maydellfi 8885071702SPeter Maydell 89d57106a4SPeter Maydellif [ "$1" = "--all" ]; then 90d57106a4SPeter Maydell # We assume there are no files in the tree with spaces in their name 91d57106a4SPeter Maydell set -- $(git ls-files '*.[ch]' | grep -E -v "$XDIRREGEX") 92d57106a4SPeter Maydellfi 93d57106a4SPeter Maydell 9485071702SPeter Maydell# Annoyingly coccinelle won't read a scriptfile unless its 9585071702SPeter Maydell# name ends '.cocci', so write it out to a tempfile with the 9685071702SPeter Maydell# right kind of name. 9785071702SPeter MaydellCOCCIFILE="$(mktemp --suffix=.cocci)" 9885071702SPeter Maydell 9985071702SPeter Maydelltrap 'rm -f -- "$COCCIFILE"' INT TERM HUP EXIT 10085071702SPeter Maydell 10185071702SPeter Maydellcat >"$COCCIFILE" <<EOT 10285071702SPeter Maydell@@ 10385071702SPeter Maydell@@ 10485071702SPeter Maydell 10585071702SPeter Maydell( 10685071702SPeter Maydell+ #include "qemu/osdep.h" 10785071702SPeter Maydell #include "..." 10885071702SPeter Maydell| 10985071702SPeter Maydell+ #include "qemu/osdep.h" 11085071702SPeter Maydell #include <...> 11185071702SPeter Maydell) 11285071702SPeter MaydellEOT 11385071702SPeter Maydell 11485071702SPeter Maydellfor f in "$@"; do 115fd3e39a4SPeter Maydell case "$f" in 116f8e1f5d6SPeter Maydell *.inc.c) 117f8e1f5d6SPeter Maydell # These aren't standalone C source files 118f8e1f5d6SPeter Maydell echo "SKIPPING $f (not a standalone source file)" 119f8e1f5d6SPeter Maydell continue 120f8e1f5d6SPeter Maydell ;; 121fd3e39a4SPeter Maydell *.c) 122fd3e39a4SPeter Maydell MODE=c 123fd3e39a4SPeter Maydell ;; 124fd3e39a4SPeter Maydell *include/qemu/osdep.h | \ 125fd3e39a4SPeter Maydell *include/qemu/compiler.h | \ 126*a6703e65SPhilippe Mathieu-Daudé *include/qemu/qemu-plugin.h | \ 127df891b91SPeter Maydell *include/glib-compat.h | \ 12802d0e095SPaolo Bonzini *include/sysemu/os-posix.h | \ 12902d0e095SPaolo Bonzini *include/sysemu/os-win32.h | \ 130fd3e39a4SPeter Maydell *include/standard-headers/ ) 131fd3e39a4SPeter Maydell # Removing include lines from osdep.h itself would be counterproductive. 132fd3e39a4SPeter Maydell echo "SKIPPING $f (special case header)" 133fd3e39a4SPeter Maydell continue 134fd3e39a4SPeter Maydell ;; 135fd3e39a4SPeter Maydell *include/standard-headers/*) 136fd3e39a4SPeter Maydell echo "SKIPPING $f (autogenerated header)" 137fd3e39a4SPeter Maydell continue 138fd3e39a4SPeter Maydell ;; 139fd3e39a4SPeter Maydell *.h) 140fd3e39a4SPeter Maydell MODE=h 141fd3e39a4SPeter Maydell ;; 142fd3e39a4SPeter Maydell *) 143fd3e39a4SPeter Maydell echo "WARNING: ignoring $f (cannot handle non-C files)" 144fd3e39a4SPeter Maydell continue 145fd3e39a4SPeter Maydell ;; 146fd3e39a4SPeter Maydell esac 147fd3e39a4SPeter Maydell 148fd3e39a4SPeter Maydell if [ "$MODE" = "c" ]; then 149fd3e39a4SPeter Maydell # First, use Coccinelle to add qemu/osdep.h before the first existing include 15085071702SPeter Maydell # (this will add two lines if the file uses both "..." and <...> #includes, 15185071702SPeter Maydell # but we will remove the extras in the next step) 15285071702SPeter Maydell spatch --in-place --no-show-diff --cocci-file "$COCCIFILE" "$f" 15385071702SPeter Maydell 15485071702SPeter Maydell # Now remove any duplicate osdep.h includes 15585071702SPeter Maydell perl -n -i -e 'print if !/#include "qemu\/osdep.h"/ || !$n++;' "$f" 156fd3e39a4SPeter Maydell else 157fd3e39a4SPeter Maydell # Remove includes of osdep.h itself 158fd3e39a4SPeter Maydell perl -n -i -e 'print if !/\s*#\s*include\s*(["<][^>"]*[">])/ || 159fd3e39a4SPeter Maydell ! (grep { $_ eq $1 } qw ("qemu/osdep.h"))' "$f" 160fd3e39a4SPeter Maydell fi 16185071702SPeter Maydell 16285071702SPeter Maydell # Remove includes that osdep.h already provides 16385071702SPeter Maydell perl -n -i -e 'print if !/\s*#\s*include\s*(["<][^>"]*[">])/ || 16485071702SPeter Maydell ! (grep { $_ eq $1 } qw ( 165da34e65cSMarkus Armbruster "config-host.h" "config-target.h" "qemu/compiler.h" 1668ff98f1eSStefan Weil <setjmp.h> <stdarg.h> <stddef.h> <stdbool.h> <stdint.h> <sys/types.h> 16785071702SPeter Maydell <stdlib.h> <stdio.h> <string.h> <strings.h> <inttypes.h> 16885071702SPeter Maydell <limits.h> <unistd.h> <time.h> <ctype.h> <errno.h> <fcntl.h> 169df891b91SPeter Maydell <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h> 17002d0e095SPaolo Bonzini <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h> <sys/mman.h> 171da34e65cSMarkus Armbruster "sysemu/os-posix.h, sysemu/os-win32.h "glib-compat.h" 172da34e65cSMarkus Armbruster "qemu/typedefs.h" 17385071702SPeter Maydell ))' "$f" 17485071702SPeter Maydell 17585071702SPeter Maydelldone 17685071702SPeter Maydell 177d66253e4SAnand Jif [ "$DUPHEAD" = "yes" ]; then 178d66253e4SAnand J egrep "^[[:space:]]*#[[:space:]]*include" "$@" | tr -d '[:blank:]' \ 179d66253e4SAnand J | sort | uniq -c | awk '{if ($1 > 1) print $0}' 180d66253e4SAnand J if [ $? -eq 0 ]; then 181d66253e4SAnand J echo "Found duplicate header file includes. Please check the above files manually." 182d66253e4SAnand J exit 1 183d66253e4SAnand J fi 184d66253e4SAnand Jfi 185d66253e4SAnand J 18685071702SPeter Maydellif [ "$GIT" = "yes" ]; then 18785071702SPeter Maydell git add -- "$@" 18885071702SPeter Maydell git commit --signoff -F - <<EOF 18985071702SPeter Maydell$GITSUBJ: Clean up includes 19085071702SPeter Maydell 19185071702SPeter MaydellClean up includes so that osdep.h is included first and headers 19285071702SPeter Maydellwhich it implies are not included manually. 19385071702SPeter Maydell 19485071702SPeter MaydellThis commit was created with scripts/clean-includes. 19585071702SPeter Maydell 19685071702SPeter MaydellEOF 19785071702SPeter Maydell 19885071702SPeter Maydellfi 199