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 5421166502SThomas HuthXDIRREGEX='^(tests/tcg|tests/multiboot|pc-bios)' 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 114aa735872SMarkus Armbrusterfiles= 11585071702SPeter Maydellfor f in "$@"; do 116*6a7f0515SMarkus Armbruster if [ -L "$f" ]; then 117*6a7f0515SMarkus Armbruster echo "SKIPPING $f (symbolic link)" 118*6a7f0515SMarkus Armbruster continue 119*6a7f0515SMarkus Armbruster fi 120fd3e39a4SPeter Maydell case "$f" in 121139c1837SPaolo Bonzini *.c.inc) 122f8e1f5d6SPeter Maydell # These aren't standalone C source files 123f8e1f5d6SPeter Maydell echo "SKIPPING $f (not a standalone source file)" 124f8e1f5d6SPeter Maydell continue 125f8e1f5d6SPeter Maydell ;; 126fd3e39a4SPeter Maydell *.c) 127fd3e39a4SPeter Maydell MODE=c 128fd3e39a4SPeter Maydell ;; 129fd3e39a4SPeter Maydell *include/qemu/osdep.h | \ 130fd3e39a4SPeter Maydell *include/qemu/compiler.h | \ 131a6703e65SPhilippe Mathieu-Daudé *include/qemu/qemu-plugin.h | \ 132df891b91SPeter Maydell *include/glib-compat.h | \ 13302d0e095SPaolo Bonzini *include/sysemu/os-posix.h | \ 13402d0e095SPaolo Bonzini *include/sysemu/os-win32.h | \ 135fd3e39a4SPeter Maydell *include/standard-headers/ ) 136fd3e39a4SPeter Maydell # Removing include lines from osdep.h itself would be counterproductive. 137fd3e39a4SPeter Maydell echo "SKIPPING $f (special case header)" 138fd3e39a4SPeter Maydell continue 139fd3e39a4SPeter Maydell ;; 140fd3e39a4SPeter Maydell *include/standard-headers/*) 141fd3e39a4SPeter Maydell echo "SKIPPING $f (autogenerated header)" 142fd3e39a4SPeter Maydell continue 143fd3e39a4SPeter Maydell ;; 144fd3e39a4SPeter Maydell *.h) 145fd3e39a4SPeter Maydell MODE=h 146fd3e39a4SPeter Maydell ;; 147fd3e39a4SPeter Maydell *) 148fd3e39a4SPeter Maydell echo "WARNING: ignoring $f (cannot handle non-C files)" 149fd3e39a4SPeter Maydell continue 150fd3e39a4SPeter Maydell ;; 151fd3e39a4SPeter Maydell esac 152aa735872SMarkus Armbruster files="$files $f" 153fd3e39a4SPeter Maydell 154fd3e39a4SPeter Maydell if [ "$MODE" = "c" ]; then 155fd3e39a4SPeter Maydell # First, use Coccinelle to add qemu/osdep.h before the first existing include 15685071702SPeter Maydell # (this will add two lines if the file uses both "..." and <...> #includes, 15785071702SPeter Maydell # but we will remove the extras in the next step) 15885071702SPeter Maydell spatch --in-place --no-show-diff --cocci-file "$COCCIFILE" "$f" 15985071702SPeter Maydell 16085071702SPeter Maydell # Now remove any duplicate osdep.h includes 16185071702SPeter Maydell perl -n -i -e 'print if !/#include "qemu\/osdep.h"/ || !$n++;' "$f" 162fd3e39a4SPeter Maydell else 163fd3e39a4SPeter Maydell # Remove includes of osdep.h itself 164fd3e39a4SPeter Maydell perl -n -i -e 'print if !/\s*#\s*include\s*(["<][^>"]*[">])/ || 165fd3e39a4SPeter Maydell ! (grep { $_ eq $1 } qw ("qemu/osdep.h"))' "$f" 166fd3e39a4SPeter Maydell fi 16785071702SPeter Maydell 16885071702SPeter Maydell # Remove includes that osdep.h already provides 16985071702SPeter Maydell perl -n -i -e 'print if !/\s*#\s*include\s*(["<][^>"]*[">])/ || 17085071702SPeter Maydell ! (grep { $_ eq $1 } qw ( 171da34e65cSMarkus Armbruster "config-host.h" "config-target.h" "qemu/compiler.h" 1728ff98f1eSStefan Weil <setjmp.h> <stdarg.h> <stddef.h> <stdbool.h> <stdint.h> <sys/types.h> 17385071702SPeter Maydell <stdlib.h> <stdio.h> <string.h> <strings.h> <inttypes.h> 17485071702SPeter Maydell <limits.h> <unistd.h> <time.h> <ctype.h> <errno.h> <fcntl.h> 175df891b91SPeter Maydell <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h> 17602d0e095SPaolo Bonzini <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h> <sys/mman.h> 177da34e65cSMarkus Armbruster "sysemu/os-posix.h, sysemu/os-win32.h "glib-compat.h" 178da34e65cSMarkus Armbruster "qemu/typedefs.h" 17985071702SPeter Maydell ))' "$f" 18085071702SPeter Maydell 18185071702SPeter Maydelldone 18285071702SPeter Maydell 183aa735872SMarkus Armbrusterif [ "$DUPHEAD" = "yes" ] && [ -n "$files" ]; then 18425551502SMarkus Armbruster if egrep "^[[:space:]]*#[[:space:]]*include" $files | tr -d '[:blank:]' \ 18525551502SMarkus Armbruster | sort | uniq -c | grep -v '^ *1 '; then 186d66253e4SAnand J echo "Found duplicate header file includes. Please check the above files manually." 187d66253e4SAnand J exit 1 188d66253e4SAnand J fi 189d66253e4SAnand Jfi 190d66253e4SAnand J 19185071702SPeter Maydellif [ "$GIT" = "yes" ]; then 192aa735872SMarkus Armbruster git add -- $files 19385071702SPeter Maydell git commit --signoff -F - <<EOF 19485071702SPeter Maydell$GITSUBJ: Clean up includes 19585071702SPeter Maydell 19685071702SPeter MaydellClean up includes so that osdep.h is included first and headers 19785071702SPeter Maydellwhich it implies are not included manually. 19885071702SPeter Maydell 19985071702SPeter MaydellThis commit was created with scripts/clean-includes. 20085071702SPeter Maydell 20185071702SPeter MaydellEOF 20285071702SPeter Maydell 20385071702SPeter Maydellfi 204