xref: /openbmc/qemu/scripts/clean-includes (revision d66253e46ae2b9c36a9dd90b2b74c0dfa5804b22)
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