File: addmocincludes

package info (click to toggle)
kde-dev-scripts 4%3A25.04.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,612 kB
  • sloc: perl: 15,615; lisp: 5,627; sh: 4,560; python: 3,892; ruby: 1,386; makefile: 13; sed: 9
file content (91 lines) | stat: -rwxr-xr-x 3,139 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env bash

# SPDX-FileCopyrightText: 2023 Friedrich W. H. Kossebau <kossebau@kde.org>
# SPDX-License-Identifier: BSD-2-Clause

# Tool to check if any sources have moc includes for headers need moc-generated code.
# Generates include statements matching CMake's automoc moc file naming pattern
# and appends them at the end of source files, with candidate chosen by:
# * same source directory
# * same basename or, if the header's basename ends with "_p", same basename without that suffix
#
# Usage: ./addmocincludes [--dry]
# To be called in the toplevel directory of the sources to cover
#
# To check if all moc files are covered by explicit includes, one can run this on the toplevel
# build directory and test for "0" result:
# $ find . -name mocs_compilation.cpp -exec cat {} \; | grep "#include" | wc -l

filesGettingMoced="$(grep --files-with-matches --recursive --extended-regexp '^\s*Q_OBJECT|^\s*Q_GADGET|^\s*Q_NAMESPACE' | egrep -v build)"

# mm as used with Objective C++
cppExts="cpp cc cxx c++ mm"

dryRun=
if [[ ${1} == "--dry" ]]; then
    dryRun=1
fi

for fileName in ${filesGettingMoced}; do
    ext="${fileName##*.}"
    # is not a header?
    if ! [[ "${ext}" =~ ^(h|H|hh|h++|hm|hpp|hxx|txx)$ ]]; then
        continue
    fi

    # look for paired source file
    sourceFileName=
    basename="${fileName%.*}"
    # if private header, also check for source file without _p suffix
    if [[ "${basename}" == *_p ]]; then
        cppBasenames="${basename} ${basename%??}"
    else
        cppBasenames="${basename}"
    fi

    for cppBasename in ${cppBasenames}; do
        for cppExt in ${cppExts}; do
            cppFile="${cppBasename}.${cppExt}";
            if [[ -f "${cppFile}" ]]; then
                sourceFileName=${cppFile}
                break
            fi
        done
        if [ -n "${sourceFileName}" ]; then
            break
        fi
    done

    # no paired source file found?
    if [ -z "${sourceFileName}" ]; then
        if [[ ${dryRun} ]]; then
            echo "${fileName}: NOT FOUND a matching source file for a moc include";
        fi
        continue
    fi

    # drop path & use default cpp suffix, as used by cmake's automoc
    mocIncludeFile="moc_${basename##*/}.cpp"
    mocIncludeStatement="#include \"${mocIncludeFile}\""
    # TODO: escaping somehow fails, tried: hasIncludeStatement="$(grep --quiet '${mocIncludeStatement@Q}' '${sourceFileName}')"
    if grep --quiet "#include \"${mocIncludeFile}\"" "${sourceFileName}"; then
        hasIncludeStatement=1
    else
        hasIncludeStatement=
    fi

    if [[ ${hasIncludeStatement} ]]; then
        if [[ ${dryRun} ]]; then
            echo "${fileName}: HAS moc include in ${sourceFileName}:";
        fi
    else
        # TODO: test if something else already has a matching include?
        if [[ ${dryRun} ]]; then
            echo "${fileName}: MISSES moc include in ${sourceFileName}";
        else
            echo "${fileName}: addding moc include in ${sourceFileName}:";
            echo "" >> ${sourceFileName}
            echo "${mocIncludeStatement}" >> ${sourceFileName}
        fi
    fi
done