qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

clean-includes (5734B)


      1 #!/bin/sh -e
      2 #
      3 # Clean up QEMU #include lines by ensuring that qemu/osdep.h
      4 # is the first include listed in .c files, and no headers provided
      5 # by osdep.h itself are redundantly included in either .c or .h files.
      6 #
      7 # Copyright (c) 2015 Linaro Limited
      8 #
      9 # Authors:
     10 #  Peter Maydell <peter.maydell@linaro.org>
     11 #
     12 # This work is licensed under the terms of the GNU GPL, version 2
     13 # or (at your option) any later version. See the COPYING file in
     14 # the top-level directory.
     15 
     16 # Usage:
     17 #   clean-includes [--git subjectprefix] [--check-dup-head] file ...
     18 # or
     19 #   clean-includes [--git subjectprefix] [--check-dup-head] --all
     20 #
     21 # If the --git subjectprefix option is given, then after making
     22 # the changes to the files this script will create a git commit
     23 # with the subject line "subjectprefix: Clean up includes"
     24 # and a boilerplate commit message.
     25 #
     26 # If --check-dup-head is specified, additionally check for duplicate
     27 # header includes.
     28 #
     29 # Using --all will cause clean-includes to run on the whole source
     30 # tree (excluding certain directories which are known not to need
     31 # handling).
     32 
     33 # This script requires Coccinelle to be installed.
     34 
     35 # .c files will have the osdep.h included added, and redundant
     36 # includes removed.
     37 # .h files will have redundant includes (including includes of osdep.h)
     38 # removed.
     39 # Other files (including C++ and ObjectiveC) can't be handled by this script.
     40 
     41 # The following one-liner may be handy for finding files to run this on.
     42 # However some caution is required regarding files that might be part
     43 # of the guest agent or standalone tests.
     44 
     45 # for i in $(git ls-tree --name-only HEAD) ; do test -f $i && \
     46 #   grep -E '^# *include' $i | head -1 | grep 'osdep.h' ; test $? != 0 && \
     47 #   echo $i ; done
     48 
     49 
     50 GIT=no
     51 DUPHEAD=no
     52 
     53 # Extended regular expression defining files to ignore when using --all
     54 XDIRREGEX='^(tests/tcg|tests/multiboot|pc-bios)'
     55 
     56 while true
     57 do
     58     case $1 in
     59     "--git")
     60          if [ $# -eq 1 ]; then
     61              echo "--git option requires an argument"
     62              exit 1
     63          fi
     64          GITSUBJ="$2"
     65          GIT=yes
     66          shift
     67          shift
     68          ;;
     69     "--check-dup-head")
     70         DUPHEAD=yes
     71         shift
     72         ;;
     73     "--")
     74         shift
     75         break
     76         ;;
     77     *)
     78         break
     79         ;;
     80    esac
     81 done
     82 
     83 if [ $# -eq 0 ]; then
     84     echo "Usage: clean-includes [--git subjectprefix] [--check-dup-head] [--all | foo.c ...]"
     85     echo "(modifies the files in place)"
     86     exit 1
     87 fi
     88 
     89 if [ "$1" = "--all" ]; then
     90     # We assume there are no files in the tree with spaces in their name
     91     set -- $(git ls-files '*.[ch]' | grep -E -v "$XDIRREGEX")
     92 fi
     93 
     94 # Annoyingly coccinelle won't read a scriptfile unless its
     95 # name ends '.cocci', so write it out to a tempfile with the
     96 # right kind of name.
     97 COCCIFILE="$(mktemp --suffix=.cocci)"
     98 
     99 trap 'rm -f -- "$COCCIFILE"' INT TERM HUP EXIT
    100 
    101 cat >"$COCCIFILE" <<EOT
    102 @@
    103 @@
    104 
    105 (
    106 + #include "qemu/osdep.h"
    107  #include "..."
    108 |
    109 + #include "qemu/osdep.h"
    110  #include <...>
    111 )
    112 EOT
    113 
    114 for f in "$@"; do
    115   case "$f" in
    116     *.c.inc)
    117       # These aren't standalone C source files
    118       echo "SKIPPING $f (not a standalone source file)"
    119       continue
    120       ;;
    121     *.c)
    122       MODE=c
    123       ;;
    124     *include/qemu/osdep.h | \
    125     *include/qemu/compiler.h | \
    126     *include/qemu/qemu-plugin.h | \
    127     *include/glib-compat.h | \
    128     *include/sysemu/os-posix.h | \
    129     *include/sysemu/os-win32.h | \
    130     *include/standard-headers/ )
    131       # Removing include lines from osdep.h itself would be counterproductive.
    132       echo "SKIPPING $f (special case header)"
    133       continue
    134       ;;
    135     *include/standard-headers/*)
    136       echo "SKIPPING $f (autogenerated header)"
    137       continue
    138       ;;
    139     *.h)
    140       MODE=h
    141       ;;
    142     *)
    143       echo "WARNING: ignoring $f (cannot handle non-C files)"
    144       continue
    145       ;;
    146   esac
    147 
    148   if [ "$MODE" = "c" ]; then
    149     # First, use Coccinelle to add qemu/osdep.h before the first existing include
    150     # (this will add two lines if the file uses both "..." and <...> #includes,
    151     # but we will remove the extras in the next step)
    152     spatch  --in-place --no-show-diff --cocci-file "$COCCIFILE" "$f"
    153 
    154     # Now remove any duplicate osdep.h includes
    155     perl -n -i -e 'print if !/#include "qemu\/osdep.h"/ || !$n++;' "$f"
    156   else
    157     # Remove includes of osdep.h itself
    158     perl -n -i -e 'print if !/\s*#\s*include\s*(["<][^>"]*[">])/ ||
    159                             ! (grep { $_ eq $1 } qw ("qemu/osdep.h"))' "$f"
    160   fi
    161 
    162   # Remove includes that osdep.h already provides
    163   perl -n -i -e 'print if !/\s*#\s*include\s*(["<][^>"]*[">])/ ||
    164                           ! (grep { $_ eq $1 } qw (
    165            "config-host.h" "config-target.h" "qemu/compiler.h"
    166            <setjmp.h> <stdarg.h> <stddef.h> <stdbool.h> <stdint.h> <sys/types.h>
    167            <stdlib.h> <stdio.h> <string.h> <strings.h> <inttypes.h>
    168            <limits.h> <unistd.h> <time.h> <ctype.h> <errno.h> <fcntl.h>
    169            <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h>
    170            <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h> <sys/mman.h>
    171            "sysemu/os-posix.h, sysemu/os-win32.h "glib-compat.h"
    172            "qemu/typedefs.h"
    173             ))' "$f"
    174 
    175 done
    176 
    177 if [ "$DUPHEAD" = "yes" ]; then
    178     egrep "^[[:space:]]*#[[:space:]]*include" "$@" | tr -d '[:blank:]' \
    179         | sort | uniq -c | awk '{if ($1 > 1) print $0}'
    180     if [ $? -eq 0 ]; then
    181         echo "Found duplicate header file includes. Please check the above files manually."
    182         exit 1
    183     fi
    184 fi
    185 
    186 if [ "$GIT" = "yes" ]; then
    187     git add -- "$@"
    188     git commit --signoff -F - <<EOF
    189 $GITSUBJ: Clean up includes
    190 
    191 Clean up includes so that osdep.h is included first and headers
    192 which it implies are not included manually.
    193 
    194 This commit was created with scripts/clean-includes.
    195 
    196 EOF
    197 
    198 fi