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: 17*d66253e4SAnand J# clean-includes [--git subjectprefix] [--check-dup-head] file ... 18d57106a4SPeter Maydell# or 19*d66253e4SAnand 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# 26*d66253e4SAnand J# If --check-dup-head is specified, additionally check for duplicate 27*d66253e4SAnand J# header includes. 28*d66253e4SAnand 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 51*d66253e4SAnand 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 56*d66253e4SAnand Jwhile true 57*d66253e4SAnand Jdo 58*d66253e4SAnand J case $1 in 59*d66253e4SAnand 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 68*d66253e4SAnand J ;; 69*d66253e4SAnand J "--check-dup-head") 70*d66253e4SAnand J DUPHEAD=yes 71*d66253e4SAnand J shift 72*d66253e4SAnand J ;; 73*d66253e4SAnand J "--") 74*d66253e4SAnand J shift 75*d66253e4SAnand J break 76*d66253e4SAnand J ;; 77*d66253e4SAnand J *) 78*d66253e4SAnand J break 79*d66253e4SAnand J ;; 80*d66253e4SAnand J esac 81*d66253e4SAnand Jdone 8285071702SPeter Maydell 8385071702SPeter Maydellif [ $# -eq 0 ]; then 84*d66253e4SAnand 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 | \ 126df891b91SPeter Maydell *include/glib-compat.h | \ 12702d0e095SPaolo Bonzini *include/sysemu/os-posix.h | \ 12802d0e095SPaolo Bonzini *include/sysemu/os-win32.h | \ 129fd3e39a4SPeter Maydell *include/standard-headers/ ) 130fd3e39a4SPeter Maydell # Removing include lines from osdep.h itself would be counterproductive. 131fd3e39a4SPeter Maydell echo "SKIPPING $f (special case header)" 132fd3e39a4SPeter Maydell continue 133fd3e39a4SPeter Maydell ;; 134fd3e39a4SPeter Maydell *include/standard-headers/*) 135fd3e39a4SPeter Maydell echo "SKIPPING $f (autogenerated header)" 136fd3e39a4SPeter Maydell continue 137fd3e39a4SPeter Maydell ;; 138fd3e39a4SPeter Maydell *.h) 139fd3e39a4SPeter Maydell MODE=h 140fd3e39a4SPeter Maydell ;; 141fd3e39a4SPeter Maydell *) 142fd3e39a4SPeter Maydell echo "WARNING: ignoring $f (cannot handle non-C files)" 143fd3e39a4SPeter Maydell continue 144fd3e39a4SPeter Maydell ;; 145fd3e39a4SPeter Maydell esac 146fd3e39a4SPeter Maydell 147fd3e39a4SPeter Maydell if [ "$MODE" = "c" ]; then 148fd3e39a4SPeter Maydell # First, use Coccinelle to add qemu/osdep.h before the first existing include 14985071702SPeter Maydell # (this will add two lines if the file uses both "..." and <...> #includes, 15085071702SPeter Maydell # but we will remove the extras in the next step) 15185071702SPeter Maydell spatch --in-place --no-show-diff --cocci-file "$COCCIFILE" "$f" 15285071702SPeter Maydell 15385071702SPeter Maydell # Now remove any duplicate osdep.h includes 15485071702SPeter Maydell perl -n -i -e 'print if !/#include "qemu\/osdep.h"/ || !$n++;' "$f" 155fd3e39a4SPeter Maydell else 156fd3e39a4SPeter Maydell # Remove includes of osdep.h itself 157fd3e39a4SPeter Maydell perl -n -i -e 'print if !/\s*#\s*include\s*(["<][^>"]*[">])/ || 158fd3e39a4SPeter Maydell ! (grep { $_ eq $1 } qw ("qemu/osdep.h"))' "$f" 159fd3e39a4SPeter Maydell fi 16085071702SPeter Maydell 16185071702SPeter Maydell # Remove includes that osdep.h already provides 16285071702SPeter Maydell perl -n -i -e 'print if !/\s*#\s*include\s*(["<][^>"]*[">])/ || 16385071702SPeter Maydell ! (grep { $_ eq $1 } qw ( 164da34e65cSMarkus Armbruster "config-host.h" "config-target.h" "qemu/compiler.h" 1658ff98f1eSStefan Weil <setjmp.h> <stdarg.h> <stddef.h> <stdbool.h> <stdint.h> <sys/types.h> 16685071702SPeter Maydell <stdlib.h> <stdio.h> <string.h> <strings.h> <inttypes.h> 16785071702SPeter Maydell <limits.h> <unistd.h> <time.h> <ctype.h> <errno.h> <fcntl.h> 168df891b91SPeter Maydell <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h> 16902d0e095SPaolo Bonzini <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h> <sys/mman.h> 170da34e65cSMarkus Armbruster "sysemu/os-posix.h, sysemu/os-win32.h "glib-compat.h" 171da34e65cSMarkus Armbruster "qemu/typedefs.h" 17285071702SPeter Maydell ))' "$f" 17385071702SPeter Maydell 17485071702SPeter Maydelldone 17585071702SPeter Maydell 176*d66253e4SAnand Jif [ "$DUPHEAD" = "yes" ]; then 177*d66253e4SAnand J egrep "^[[:space:]]*#[[:space:]]*include" "$@" | tr -d '[:blank:]' \ 178*d66253e4SAnand J | sort | uniq -c | awk '{if ($1 > 1) print $0}' 179*d66253e4SAnand J if [ $? -eq 0 ]; then 180*d66253e4SAnand J echo "Found duplicate header file includes. Please check the above files manually." 181*d66253e4SAnand J exit 1 182*d66253e4SAnand J fi 183*d66253e4SAnand Jfi 184*d66253e4SAnand J 18585071702SPeter Maydellif [ "$GIT" = "yes" ]; then 18685071702SPeter Maydell git add -- "$@" 18785071702SPeter Maydell git commit --signoff -F - <<EOF 18885071702SPeter Maydell$GITSUBJ: Clean up includes 18985071702SPeter Maydell 19085071702SPeter MaydellClean up includes so that osdep.h is included first and headers 19185071702SPeter Maydellwhich it implies are not included manually. 19285071702SPeter Maydell 19385071702SPeter MaydellThis commit was created with scripts/clean-includes. 19485071702SPeter Maydell 19585071702SPeter MaydellEOF 19685071702SPeter Maydell 19785071702SPeter Maydellfi 198