xref: /openbmc/qemu/scripts/clean-includes (revision aa735872a879075d1e9d669c8d5737f41232a3e3)
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
114*aa735872SMarkus Armbrusterfiles=
11585071702SPeter Maydellfor f in "$@"; do
116fd3e39a4SPeter Maydell  case "$f" in
117139c1837SPaolo Bonzini    *.c.inc)
118f8e1f5d6SPeter Maydell      # These aren't standalone C source files
119f8e1f5d6SPeter Maydell      echo "SKIPPING $f (not a standalone source file)"
120f8e1f5d6SPeter Maydell      continue
121f8e1f5d6SPeter Maydell      ;;
122fd3e39a4SPeter Maydell    *.c)
123fd3e39a4SPeter Maydell      MODE=c
124fd3e39a4SPeter Maydell      ;;
125fd3e39a4SPeter Maydell    *include/qemu/osdep.h | \
126fd3e39a4SPeter Maydell    *include/qemu/compiler.h | \
127a6703e65SPhilippe Mathieu-Daudé    *include/qemu/qemu-plugin.h | \
128df891b91SPeter Maydell    *include/glib-compat.h | \
12902d0e095SPaolo Bonzini    *include/sysemu/os-posix.h | \
13002d0e095SPaolo Bonzini    *include/sysemu/os-win32.h | \
131fd3e39a4SPeter Maydell    *include/standard-headers/ )
132fd3e39a4SPeter Maydell      # Removing include lines from osdep.h itself would be counterproductive.
133fd3e39a4SPeter Maydell      echo "SKIPPING $f (special case header)"
134fd3e39a4SPeter Maydell      continue
135fd3e39a4SPeter Maydell      ;;
136fd3e39a4SPeter Maydell    *include/standard-headers/*)
137fd3e39a4SPeter Maydell      echo "SKIPPING $f (autogenerated header)"
138fd3e39a4SPeter Maydell      continue
139fd3e39a4SPeter Maydell      ;;
140fd3e39a4SPeter Maydell    *.h)
141fd3e39a4SPeter Maydell      MODE=h
142fd3e39a4SPeter Maydell      ;;
143fd3e39a4SPeter Maydell    *)
144fd3e39a4SPeter Maydell      echo "WARNING: ignoring $f (cannot handle non-C files)"
145fd3e39a4SPeter Maydell      continue
146fd3e39a4SPeter Maydell      ;;
147fd3e39a4SPeter Maydell  esac
148*aa735872SMarkus Armbruster  files="$files $f"
149fd3e39a4SPeter Maydell
150fd3e39a4SPeter Maydell  if [ "$MODE" = "c" ]; then
151fd3e39a4SPeter Maydell    # First, use Coccinelle to add qemu/osdep.h before the first existing include
15285071702SPeter Maydell    # (this will add two lines if the file uses both "..." and <...> #includes,
15385071702SPeter Maydell    # but we will remove the extras in the next step)
15485071702SPeter Maydell    spatch  --in-place --no-show-diff --cocci-file "$COCCIFILE" "$f"
15585071702SPeter Maydell
15685071702SPeter Maydell    # Now remove any duplicate osdep.h includes
15785071702SPeter Maydell    perl -n -i -e 'print if !/#include "qemu\/osdep.h"/ || !$n++;' "$f"
158fd3e39a4SPeter Maydell  else
159fd3e39a4SPeter Maydell    # Remove includes of osdep.h itself
160fd3e39a4SPeter Maydell    perl -n -i -e 'print if !/\s*#\s*include\s*(["<][^>"]*[">])/ ||
161fd3e39a4SPeter Maydell                            ! (grep { $_ eq $1 } qw ("qemu/osdep.h"))' "$f"
162fd3e39a4SPeter Maydell  fi
16385071702SPeter Maydell
16485071702SPeter Maydell  # Remove includes that osdep.h already provides
16585071702SPeter Maydell  perl -n -i -e 'print if !/\s*#\s*include\s*(["<][^>"]*[">])/ ||
16685071702SPeter Maydell                          ! (grep { $_ eq $1 } qw (
167da34e65cSMarkus Armbruster           "config-host.h" "config-target.h" "qemu/compiler.h"
1688ff98f1eSStefan Weil           <setjmp.h> <stdarg.h> <stddef.h> <stdbool.h> <stdint.h> <sys/types.h>
16985071702SPeter Maydell           <stdlib.h> <stdio.h> <string.h> <strings.h> <inttypes.h>
17085071702SPeter Maydell           <limits.h> <unistd.h> <time.h> <ctype.h> <errno.h> <fcntl.h>
171df891b91SPeter Maydell           <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h>
17202d0e095SPaolo Bonzini           <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h> <sys/mman.h>
173da34e65cSMarkus Armbruster           "sysemu/os-posix.h, sysemu/os-win32.h "glib-compat.h"
174da34e65cSMarkus Armbruster           "qemu/typedefs.h"
17585071702SPeter Maydell            ))' "$f"
17685071702SPeter Maydell
17785071702SPeter Maydelldone
17885071702SPeter Maydell
179*aa735872SMarkus Armbrusterif [ "$DUPHEAD" = "yes" ] && [ -n "$files" ]; then
180*aa735872SMarkus Armbruster    egrep "^[[:space:]]*#[[:space:]]*include" $files | tr -d '[:blank:]' \
181d66253e4SAnand J        | sort | uniq -c | awk '{if ($1 > 1) print $0}'
182d66253e4SAnand J    if [ $? -eq 0 ]; then
183d66253e4SAnand J        echo "Found duplicate header file includes. Please check the above files manually."
184d66253e4SAnand J        exit 1
185d66253e4SAnand J    fi
186d66253e4SAnand Jfi
187d66253e4SAnand J
18885071702SPeter Maydellif [ "$GIT" = "yes" ]; then
189*aa735872SMarkus Armbruster    git add -- $files
19085071702SPeter Maydell    git commit --signoff -F - <<EOF
19185071702SPeter Maydell$GITSUBJ: Clean up includes
19285071702SPeter Maydell
19385071702SPeter MaydellClean up includes so that osdep.h is included first and headers
19485071702SPeter Maydellwhich it implies are not included manually.
19585071702SPeter Maydell
19685071702SPeter MaydellThis commit was created with scripts/clean-includes.
19785071702SPeter Maydell
19885071702SPeter MaydellEOF
19985071702SPeter Maydell
20085071702SPeter Maydellfi
201