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