Warning, /sdk/kde-dev-scripts/addmocincludes is written in an unsupported language. File is not indexed.
0001 #!/usr/bin/env bash
0002
0003 # SPDX-FileCopyrightText: 2023 Friedrich W. H. Kossebau <kossebau@kde.org>
0004 # SPDX-License-Identifier: BSD-2-Clause
0005
0006 # Tool to check if any sources have moc includes for headers need moc-generated code.
0007 # Generates include statements matching CMake's automoc moc file naming pattern
0008 # and appends them at the end of source files, with candidate chosen by:
0009 # * same source directory
0010 # * same basename or, if the header's basename ends with "_p", same basename without that suffix
0011 #
0012 # Usage: ./addmocincludes [--dry]
0013 # To be called in the toplevel directory of the sources to cover
0014 #
0015 # To check if all moc files are covered by explicit includes, one can run this on the toplevel
0016 # build directory and test for "0" result:
0017 # $ find . -name mocs_compilation.cpp -exec cat {} \; | grep "#include" | wc -l
0018
0019 filesGettingMoced="$(grep --files-with-matches --recursive --extended-regexp 'Q_OBJECT|Q_GADGET|Q_NAMESPACE')"
0020
0021 # mm as used with Objective C++
0022 cppExts="cpp cc cxx c++ mm"
0023
0024 dryRun=
0025 if [[ ${1} == "--dry" ]]; then
0026 dryRun=1
0027 fi
0028
0029 for fileName in ${filesGettingMoced}; do
0030 ext="${fileName##*.}"
0031 # is not a header?
0032 if ! [[ "${ext}" =~ ^(h|H|hh|h++|hm|hpp|hxx|txx)$ ]]; then
0033 continue
0034 fi
0035
0036 # look for paired source file
0037 sourceFileName=
0038 basename="${fileName%.*}"
0039 # if private header, also check for source file without _p suffix
0040 if [[ "${basename}" == *_p ]]; then
0041 cppBasenames="${basename} ${basename%??}"
0042 else
0043 cppBasenames="${basename}"
0044 fi
0045
0046 for cppBasename in ${cppBasenames}; do
0047 for cppExt in ${cppExts}; do
0048 cppFile="${cppBasename}.${cppExt}";
0049 if [[ -f "${cppFile}" ]]; then
0050 sourceFileName=${cppFile}
0051 break
0052 fi
0053 done
0054 if [ -n "${sourceFileName}" ]; then
0055 break
0056 fi
0057 done
0058
0059 # no paired source file found?
0060 if [ -z "${sourceFileName}" ]; then
0061 if [[ ${dryRun} ]]; then
0062 echo "${fileName}: NOT FOUND a matching source file for a moc include";
0063 fi
0064 continue
0065 fi
0066
0067 # drop path & use default cpp suffix, as used by cmake's automoc
0068 mocIncludeFile="moc_${basename##*/}.cpp"
0069 mocIncludeStatement="#include \"${mocIncludeFile}\""
0070 # TODO: escaping somehow fails, tried: hasIncludeStatement="$(grep --quiet '${mocIncludeStatement@Q}' '${sourceFileName}')"
0071 if grep --quiet "#include \"${mocIncludeFile}\"" "${sourceFileName}"; then
0072 hasIncludeStatement=1
0073 else
0074 hasIncludeStatement=
0075 fi
0076
0077 if [[ ${hasIncludeStatement} ]]; then
0078 if [[ ${dryRun} ]]; then
0079 echo "${fileName}: HAS moc include in ${sourceFileName}:";
0080 fi
0081 else
0082 # TODO: test if something else already has a matching include?
0083 if [[ ${dryRun} ]]; then
0084 echo "${fileName}: MISSES moc include in ${sourceFileName}";
0085 else
0086 echo "${fileName}: addding moc include in ${sourceFileName}:";
0087 echo "" >> ${sourceFileName}
0088 echo "${mocIncludeStatement}" >> ${sourceFileName}
0089 fi
0090 fi
0091 done